xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 35f7498a)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
288c520a59SGustavo Padovan #include <linux/export.h>
293df92b31SSasha Levin #include <linux/idr.h>
30611b30f7SMarcel Holtmann #include <linux/rfkill.h>
31baf27f6eSMarcel Holtmann #include <linux/debugfs.h>
3299780a7bSJohan Hedberg #include <linux/crypto.h>
3347219839SMarcel Holtmann #include <asm/unaligned.h>
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
361da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
371da177e4SLinus Torvalds 
38970c4e46SJohan Hedberg #include "smp.h"
39970c4e46SJohan Hedberg 
40b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
41c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
423eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds /* HCI device list */
451da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
461da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds /* HCI callback list */
491da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
501da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
511da177e4SLinus Torvalds 
523df92b31SSasha Levin /* HCI ID Numbering */
533df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
543df92b31SSasha Levin 
551da177e4SLinus Torvalds /* ---- HCI notifications ---- */
561da177e4SLinus Torvalds 
576516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
581da177e4SLinus Torvalds {
59040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
601da177e4SLinus Torvalds }
611da177e4SLinus Torvalds 
62baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
63baf27f6eSMarcel Holtmann 
644b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
654b4148e9SMarcel Holtmann 			     size_t count, loff_t *ppos)
664b4148e9SMarcel Holtmann {
674b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
684b4148e9SMarcel Holtmann 	char buf[3];
694b4148e9SMarcel Holtmann 
704b4148e9SMarcel Holtmann 	buf[0] = test_bit(HCI_DUT_MODE, &hdev->dev_flags) ? 'Y': 'N';
714b4148e9SMarcel Holtmann 	buf[1] = '\n';
724b4148e9SMarcel Holtmann 	buf[2] = '\0';
734b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
744b4148e9SMarcel Holtmann }
754b4148e9SMarcel Holtmann 
764b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
774b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
784b4148e9SMarcel Holtmann {
794b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
804b4148e9SMarcel Holtmann 	struct sk_buff *skb;
814b4148e9SMarcel Holtmann 	char buf[32];
824b4148e9SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
834b4148e9SMarcel Holtmann 	bool enable;
844b4148e9SMarcel Holtmann 	int err;
854b4148e9SMarcel Holtmann 
864b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
874b4148e9SMarcel Holtmann 		return -ENETDOWN;
884b4148e9SMarcel Holtmann 
894b4148e9SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
904b4148e9SMarcel Holtmann 		return -EFAULT;
914b4148e9SMarcel Holtmann 
924b4148e9SMarcel Holtmann 	buf[buf_size] = '\0';
934b4148e9SMarcel Holtmann 	if (strtobool(buf, &enable))
944b4148e9SMarcel Holtmann 		return -EINVAL;
954b4148e9SMarcel Holtmann 
964b4148e9SMarcel Holtmann 	if (enable == test_bit(HCI_DUT_MODE, &hdev->dev_flags))
974b4148e9SMarcel Holtmann 		return -EALREADY;
984b4148e9SMarcel Holtmann 
994b4148e9SMarcel Holtmann 	hci_req_lock(hdev);
1004b4148e9SMarcel Holtmann 	if (enable)
1014b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
1024b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1034b4148e9SMarcel Holtmann 	else
1044b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1054b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1064b4148e9SMarcel Holtmann 	hci_req_unlock(hdev);
1074b4148e9SMarcel Holtmann 
1084b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1094b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1104b4148e9SMarcel Holtmann 
1114b4148e9SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
1124b4148e9SMarcel Holtmann 	kfree_skb(skb);
1134b4148e9SMarcel Holtmann 
1144b4148e9SMarcel Holtmann 	if (err < 0)
1154b4148e9SMarcel Holtmann 		return err;
1164b4148e9SMarcel Holtmann 
1174b4148e9SMarcel Holtmann 	change_bit(HCI_DUT_MODE, &hdev->dev_flags);
1184b4148e9SMarcel Holtmann 
1194b4148e9SMarcel Holtmann 	return count;
1204b4148e9SMarcel Holtmann }
1214b4148e9SMarcel Holtmann 
1224b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1234b4148e9SMarcel Holtmann 	.open		= simple_open,
1244b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1254b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1264b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1274b4148e9SMarcel Holtmann };
1284b4148e9SMarcel Holtmann 
129dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr)
130dfb826a8SMarcel Holtmann {
131dfb826a8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
132dfb826a8SMarcel Holtmann 	u8 p;
133dfb826a8SMarcel Holtmann 
134dfb826a8SMarcel Holtmann 	hci_dev_lock(hdev);
135dfb826a8SMarcel Holtmann 	for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
136cfbb2b5bSMarcel Holtmann 		seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
137dfb826a8SMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p,
138dfb826a8SMarcel Holtmann 			   hdev->features[p][0], hdev->features[p][1],
139dfb826a8SMarcel Holtmann 			   hdev->features[p][2], hdev->features[p][3],
140dfb826a8SMarcel Holtmann 			   hdev->features[p][4], hdev->features[p][5],
141dfb826a8SMarcel Holtmann 			   hdev->features[p][6], hdev->features[p][7]);
142dfb826a8SMarcel Holtmann 	}
143cfbb2b5bSMarcel Holtmann 	if (lmp_le_capable(hdev))
144cfbb2b5bSMarcel Holtmann 		seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
145cfbb2b5bSMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
146cfbb2b5bSMarcel Holtmann 			   hdev->le_features[0], hdev->le_features[1],
147cfbb2b5bSMarcel Holtmann 			   hdev->le_features[2], hdev->le_features[3],
148cfbb2b5bSMarcel Holtmann 			   hdev->le_features[4], hdev->le_features[5],
149cfbb2b5bSMarcel Holtmann 			   hdev->le_features[6], hdev->le_features[7]);
150dfb826a8SMarcel Holtmann 	hci_dev_unlock(hdev);
151dfb826a8SMarcel Holtmann 
152dfb826a8SMarcel Holtmann 	return 0;
153dfb826a8SMarcel Holtmann }
154dfb826a8SMarcel Holtmann 
155dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file)
156dfb826a8SMarcel Holtmann {
157dfb826a8SMarcel Holtmann 	return single_open(file, features_show, inode->i_private);
158dfb826a8SMarcel Holtmann }
159dfb826a8SMarcel Holtmann 
160dfb826a8SMarcel Holtmann static const struct file_operations features_fops = {
161dfb826a8SMarcel Holtmann 	.open		= features_open,
162dfb826a8SMarcel Holtmann 	.read		= seq_read,
163dfb826a8SMarcel Holtmann 	.llseek		= seq_lseek,
164dfb826a8SMarcel Holtmann 	.release	= single_release,
165dfb826a8SMarcel Holtmann };
166dfb826a8SMarcel Holtmann 
16770afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p)
16870afe0b8SMarcel Holtmann {
16970afe0b8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
17070afe0b8SMarcel Holtmann 	struct bdaddr_list *b;
17170afe0b8SMarcel Holtmann 
17270afe0b8SMarcel Holtmann 	hci_dev_lock(hdev);
17370afe0b8SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list)
174b25f0785SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
17570afe0b8SMarcel Holtmann 	hci_dev_unlock(hdev);
17670afe0b8SMarcel Holtmann 
17770afe0b8SMarcel Holtmann 	return 0;
17870afe0b8SMarcel Holtmann }
17970afe0b8SMarcel Holtmann 
18070afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file)
18170afe0b8SMarcel Holtmann {
18270afe0b8SMarcel Holtmann 	return single_open(file, blacklist_show, inode->i_private);
18370afe0b8SMarcel Holtmann }
18470afe0b8SMarcel Holtmann 
18570afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = {
18670afe0b8SMarcel Holtmann 	.open		= blacklist_open,
18770afe0b8SMarcel Holtmann 	.read		= seq_read,
18870afe0b8SMarcel Holtmann 	.llseek		= seq_lseek,
18970afe0b8SMarcel Holtmann 	.release	= single_release,
19070afe0b8SMarcel Holtmann };
19170afe0b8SMarcel Holtmann 
19247219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p)
19347219839SMarcel Holtmann {
19447219839SMarcel Holtmann 	struct hci_dev *hdev = f->private;
19547219839SMarcel Holtmann 	struct bt_uuid *uuid;
19647219839SMarcel Holtmann 
19747219839SMarcel Holtmann 	hci_dev_lock(hdev);
19847219839SMarcel Holtmann 	list_for_each_entry(uuid, &hdev->uuids, list) {
19958f01aa9SMarcel Holtmann 		u8 i, val[16];
20047219839SMarcel Holtmann 
20158f01aa9SMarcel Holtmann 		/* The Bluetooth UUID values are stored in big endian,
20258f01aa9SMarcel Holtmann 		 * but with reversed byte order. So convert them into
20358f01aa9SMarcel Holtmann 		 * the right order for the %pUb modifier.
20458f01aa9SMarcel Holtmann 		 */
20558f01aa9SMarcel Holtmann 		for (i = 0; i < 16; i++)
20658f01aa9SMarcel Holtmann 			val[i] = uuid->uuid[15 - i];
20747219839SMarcel Holtmann 
20858f01aa9SMarcel Holtmann 		seq_printf(f, "%pUb\n", val);
20947219839SMarcel Holtmann 	}
21047219839SMarcel Holtmann 	hci_dev_unlock(hdev);
21147219839SMarcel Holtmann 
21247219839SMarcel Holtmann 	return 0;
21347219839SMarcel Holtmann }
21447219839SMarcel Holtmann 
21547219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file)
21647219839SMarcel Holtmann {
21747219839SMarcel Holtmann 	return single_open(file, uuids_show, inode->i_private);
21847219839SMarcel Holtmann }
21947219839SMarcel Holtmann 
22047219839SMarcel Holtmann static const struct file_operations uuids_fops = {
22147219839SMarcel Holtmann 	.open		= uuids_open,
22247219839SMarcel Holtmann 	.read		= seq_read,
22347219839SMarcel Holtmann 	.llseek		= seq_lseek,
22447219839SMarcel Holtmann 	.release	= single_release,
22547219839SMarcel Holtmann };
22647219839SMarcel Holtmann 
227baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p)
228baf27f6eSMarcel Holtmann {
229baf27f6eSMarcel Holtmann 	struct hci_dev *hdev = f->private;
230baf27f6eSMarcel Holtmann 	struct discovery_state *cache = &hdev->discovery;
231baf27f6eSMarcel Holtmann 	struct inquiry_entry *e;
232baf27f6eSMarcel Holtmann 
233baf27f6eSMarcel Holtmann 	hci_dev_lock(hdev);
234baf27f6eSMarcel Holtmann 
235baf27f6eSMarcel Holtmann 	list_for_each_entry(e, &cache->all, all) {
236baf27f6eSMarcel Holtmann 		struct inquiry_data *data = &e->data;
237baf27f6eSMarcel Holtmann 		seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
238baf27f6eSMarcel Holtmann 			   &data->bdaddr,
239baf27f6eSMarcel Holtmann 			   data->pscan_rep_mode, data->pscan_period_mode,
240baf27f6eSMarcel Holtmann 			   data->pscan_mode, data->dev_class[2],
241baf27f6eSMarcel Holtmann 			   data->dev_class[1], data->dev_class[0],
242baf27f6eSMarcel Holtmann 			   __le16_to_cpu(data->clock_offset),
243baf27f6eSMarcel Holtmann 			   data->rssi, data->ssp_mode, e->timestamp);
244baf27f6eSMarcel Holtmann 	}
245baf27f6eSMarcel Holtmann 
246baf27f6eSMarcel Holtmann 	hci_dev_unlock(hdev);
247baf27f6eSMarcel Holtmann 
248baf27f6eSMarcel Holtmann 	return 0;
249baf27f6eSMarcel Holtmann }
250baf27f6eSMarcel Holtmann 
251baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file)
252baf27f6eSMarcel Holtmann {
253baf27f6eSMarcel Holtmann 	return single_open(file, inquiry_cache_show, inode->i_private);
254baf27f6eSMarcel Holtmann }
255baf27f6eSMarcel Holtmann 
256baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = {
257baf27f6eSMarcel Holtmann 	.open		= inquiry_cache_open,
258baf27f6eSMarcel Holtmann 	.read		= seq_read,
259baf27f6eSMarcel Holtmann 	.llseek		= seq_lseek,
260baf27f6eSMarcel Holtmann 	.release	= single_release,
261baf27f6eSMarcel Holtmann };
262baf27f6eSMarcel Holtmann 
26302d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr)
26402d08d15SMarcel Holtmann {
26502d08d15SMarcel Holtmann 	struct hci_dev *hdev = f->private;
26602d08d15SMarcel Holtmann 	struct list_head *p, *n;
26702d08d15SMarcel Holtmann 
26802d08d15SMarcel Holtmann 	hci_dev_lock(hdev);
26902d08d15SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->link_keys) {
27002d08d15SMarcel Holtmann 		struct link_key *key = list_entry(p, struct link_key, list);
27102d08d15SMarcel Holtmann 		seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
27202d08d15SMarcel Holtmann 			   HCI_LINK_KEY_SIZE, key->val, key->pin_len);
27302d08d15SMarcel Holtmann 	}
27402d08d15SMarcel Holtmann 	hci_dev_unlock(hdev);
27502d08d15SMarcel Holtmann 
27602d08d15SMarcel Holtmann 	return 0;
27702d08d15SMarcel Holtmann }
27802d08d15SMarcel Holtmann 
27902d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file)
28002d08d15SMarcel Holtmann {
28102d08d15SMarcel Holtmann 	return single_open(file, link_keys_show, inode->i_private);
28202d08d15SMarcel Holtmann }
28302d08d15SMarcel Holtmann 
28402d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = {
28502d08d15SMarcel Holtmann 	.open		= link_keys_open,
28602d08d15SMarcel Holtmann 	.read		= seq_read,
28702d08d15SMarcel Holtmann 	.llseek		= seq_lseek,
28802d08d15SMarcel Holtmann 	.release	= single_release,
28902d08d15SMarcel Holtmann };
29002d08d15SMarcel Holtmann 
291babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr)
292babdbb3cSMarcel Holtmann {
293babdbb3cSMarcel Holtmann 	struct hci_dev *hdev = f->private;
294babdbb3cSMarcel Holtmann 
295babdbb3cSMarcel Holtmann 	hci_dev_lock(hdev);
296babdbb3cSMarcel Holtmann 	seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
297babdbb3cSMarcel Holtmann 		   hdev->dev_class[1], hdev->dev_class[0]);
298babdbb3cSMarcel Holtmann 	hci_dev_unlock(hdev);
299babdbb3cSMarcel Holtmann 
300babdbb3cSMarcel Holtmann 	return 0;
301babdbb3cSMarcel Holtmann }
302babdbb3cSMarcel Holtmann 
303babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file)
304babdbb3cSMarcel Holtmann {
305babdbb3cSMarcel Holtmann 	return single_open(file, dev_class_show, inode->i_private);
306babdbb3cSMarcel Holtmann }
307babdbb3cSMarcel Holtmann 
308babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = {
309babdbb3cSMarcel Holtmann 	.open		= dev_class_open,
310babdbb3cSMarcel Holtmann 	.read		= seq_read,
311babdbb3cSMarcel Holtmann 	.llseek		= seq_lseek,
312babdbb3cSMarcel Holtmann 	.release	= single_release,
313babdbb3cSMarcel Holtmann };
314babdbb3cSMarcel Holtmann 
315041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val)
316041000b9SMarcel Holtmann {
317041000b9SMarcel Holtmann 	struct hci_dev *hdev = data;
318041000b9SMarcel Holtmann 
319041000b9SMarcel Holtmann 	hci_dev_lock(hdev);
320041000b9SMarcel Holtmann 	*val = hdev->voice_setting;
321041000b9SMarcel Holtmann 	hci_dev_unlock(hdev);
322041000b9SMarcel Holtmann 
323041000b9SMarcel Holtmann 	return 0;
324041000b9SMarcel Holtmann }
325041000b9SMarcel Holtmann 
326041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
327041000b9SMarcel Holtmann 			NULL, "0x%4.4llx\n");
328041000b9SMarcel Holtmann 
329ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val)
330ebd1e33bSMarcel Holtmann {
331ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
332ebd1e33bSMarcel Holtmann 
333ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
334ebd1e33bSMarcel Holtmann 	hdev->auto_accept_delay = val;
335ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
336ebd1e33bSMarcel Holtmann 
337ebd1e33bSMarcel Holtmann 	return 0;
338ebd1e33bSMarcel Holtmann }
339ebd1e33bSMarcel Holtmann 
340ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val)
341ebd1e33bSMarcel Holtmann {
342ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
343ebd1e33bSMarcel Holtmann 
344ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
345ebd1e33bSMarcel Holtmann 	*val = hdev->auto_accept_delay;
346ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
347ebd1e33bSMarcel Holtmann 
348ebd1e33bSMarcel Holtmann 	return 0;
349ebd1e33bSMarcel Holtmann }
350ebd1e33bSMarcel Holtmann 
351ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
352ebd1e33bSMarcel Holtmann 			auto_accept_delay_set, "%llu\n");
353ebd1e33bSMarcel Holtmann 
35406f5b778SMarcel Holtmann static int ssp_debug_mode_set(void *data, u64 val)
35506f5b778SMarcel Holtmann {
35606f5b778SMarcel Holtmann 	struct hci_dev *hdev = data;
35706f5b778SMarcel Holtmann 	struct sk_buff *skb;
35806f5b778SMarcel Holtmann 	__u8 mode;
35906f5b778SMarcel Holtmann 	int err;
36006f5b778SMarcel Holtmann 
36106f5b778SMarcel Holtmann 	if (val != 0 && val != 1)
36206f5b778SMarcel Holtmann 		return -EINVAL;
36306f5b778SMarcel Holtmann 
36406f5b778SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
36506f5b778SMarcel Holtmann 		return -ENETDOWN;
36606f5b778SMarcel Holtmann 
36706f5b778SMarcel Holtmann 	hci_req_lock(hdev);
36806f5b778SMarcel Holtmann 	mode = val;
36906f5b778SMarcel Holtmann 	skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
37006f5b778SMarcel Holtmann 			     &mode, HCI_CMD_TIMEOUT);
37106f5b778SMarcel Holtmann 	hci_req_unlock(hdev);
37206f5b778SMarcel Holtmann 
37306f5b778SMarcel Holtmann 	if (IS_ERR(skb))
37406f5b778SMarcel Holtmann 		return PTR_ERR(skb);
37506f5b778SMarcel Holtmann 
37606f5b778SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
37706f5b778SMarcel Holtmann 	kfree_skb(skb);
37806f5b778SMarcel Holtmann 
37906f5b778SMarcel Holtmann 	if (err < 0)
38006f5b778SMarcel Holtmann 		return err;
38106f5b778SMarcel Holtmann 
38206f5b778SMarcel Holtmann 	hci_dev_lock(hdev);
38306f5b778SMarcel Holtmann 	hdev->ssp_debug_mode = val;
38406f5b778SMarcel Holtmann 	hci_dev_unlock(hdev);
38506f5b778SMarcel Holtmann 
38606f5b778SMarcel Holtmann 	return 0;
38706f5b778SMarcel Holtmann }
38806f5b778SMarcel Holtmann 
38906f5b778SMarcel Holtmann static int ssp_debug_mode_get(void *data, u64 *val)
39006f5b778SMarcel Holtmann {
39106f5b778SMarcel Holtmann 	struct hci_dev *hdev = data;
39206f5b778SMarcel Holtmann 
39306f5b778SMarcel Holtmann 	hci_dev_lock(hdev);
39406f5b778SMarcel Holtmann 	*val = hdev->ssp_debug_mode;
39506f5b778SMarcel Holtmann 	hci_dev_unlock(hdev);
39606f5b778SMarcel Holtmann 
39706f5b778SMarcel Holtmann 	return 0;
39806f5b778SMarcel Holtmann }
39906f5b778SMarcel Holtmann 
40006f5b778SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
40106f5b778SMarcel Holtmann 			ssp_debug_mode_set, "%llu\n");
40206f5b778SMarcel Holtmann 
4035afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
4045afeac14SMarcel Holtmann 				     size_t count, loff_t *ppos)
4055afeac14SMarcel Holtmann {
4065afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
4075afeac14SMarcel Holtmann 	char buf[3];
4085afeac14SMarcel Holtmann 
4095afeac14SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_SC, &hdev->dev_flags) ? 'Y': 'N';
4105afeac14SMarcel Holtmann 	buf[1] = '\n';
4115afeac14SMarcel Holtmann 	buf[2] = '\0';
4125afeac14SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
4135afeac14SMarcel Holtmann }
4145afeac14SMarcel Holtmann 
4155afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file,
4165afeac14SMarcel Holtmann 				      const char __user *user_buf,
4175afeac14SMarcel Holtmann 				      size_t count, loff_t *ppos)
4185afeac14SMarcel Holtmann {
4195afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
4205afeac14SMarcel Holtmann 	char buf[32];
4215afeac14SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
4225afeac14SMarcel Holtmann 	bool enable;
4235afeac14SMarcel Holtmann 
4245afeac14SMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
4255afeac14SMarcel Holtmann 		return -EBUSY;
4265afeac14SMarcel Holtmann 
4275afeac14SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
4285afeac14SMarcel Holtmann 		return -EFAULT;
4295afeac14SMarcel Holtmann 
4305afeac14SMarcel Holtmann 	buf[buf_size] = '\0';
4315afeac14SMarcel Holtmann 	if (strtobool(buf, &enable))
4325afeac14SMarcel Holtmann 		return -EINVAL;
4335afeac14SMarcel Holtmann 
4345afeac14SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_SC, &hdev->dev_flags))
4355afeac14SMarcel Holtmann 		return -EALREADY;
4365afeac14SMarcel Holtmann 
4375afeac14SMarcel Holtmann 	change_bit(HCI_FORCE_SC, &hdev->dev_flags);
4385afeac14SMarcel Holtmann 
4395afeac14SMarcel Holtmann 	return count;
4405afeac14SMarcel Holtmann }
4415afeac14SMarcel Holtmann 
4425afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = {
4435afeac14SMarcel Holtmann 	.open		= simple_open,
4445afeac14SMarcel Holtmann 	.read		= force_sc_support_read,
4455afeac14SMarcel Holtmann 	.write		= force_sc_support_write,
4465afeac14SMarcel Holtmann 	.llseek		= default_llseek,
4475afeac14SMarcel Holtmann };
4485afeac14SMarcel Holtmann 
449134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
450134c2a89SMarcel Holtmann 				 size_t count, loff_t *ppos)
451134c2a89SMarcel Holtmann {
452134c2a89SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
453134c2a89SMarcel Holtmann 	char buf[3];
454134c2a89SMarcel Holtmann 
455134c2a89SMarcel Holtmann 	buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N';
456134c2a89SMarcel Holtmann 	buf[1] = '\n';
457134c2a89SMarcel Holtmann 	buf[2] = '\0';
458134c2a89SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
459134c2a89SMarcel Holtmann }
460134c2a89SMarcel Holtmann 
461134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = {
462134c2a89SMarcel Holtmann 	.open		= simple_open,
463134c2a89SMarcel Holtmann 	.read		= sc_only_mode_read,
464134c2a89SMarcel Holtmann 	.llseek		= default_llseek,
465134c2a89SMarcel Holtmann };
466134c2a89SMarcel Holtmann 
4672bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val)
4682bfa3531SMarcel Holtmann {
4692bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4702bfa3531SMarcel Holtmann 
4712bfa3531SMarcel Holtmann 	if (val != 0 && (val < 500 || val > 3600000))
4722bfa3531SMarcel Holtmann 		return -EINVAL;
4732bfa3531SMarcel Holtmann 
4742bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4752bfa3531SMarcel Holtmann 	hdev->idle_timeout = val;
4762bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4772bfa3531SMarcel Holtmann 
4782bfa3531SMarcel Holtmann 	return 0;
4792bfa3531SMarcel Holtmann }
4802bfa3531SMarcel Holtmann 
4812bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val)
4822bfa3531SMarcel Holtmann {
4832bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4842bfa3531SMarcel Holtmann 
4852bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4862bfa3531SMarcel Holtmann 	*val = hdev->idle_timeout;
4872bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4882bfa3531SMarcel Holtmann 
4892bfa3531SMarcel Holtmann 	return 0;
4902bfa3531SMarcel Holtmann }
4912bfa3531SMarcel Holtmann 
4922bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
4932bfa3531SMarcel Holtmann 			idle_timeout_set, "%llu\n");
4942bfa3531SMarcel Holtmann 
4952bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val)
4962bfa3531SMarcel Holtmann {
4972bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4982bfa3531SMarcel Holtmann 
4992bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
5002bfa3531SMarcel Holtmann 		return -EINVAL;
5012bfa3531SMarcel Holtmann 
5022bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5032bfa3531SMarcel Holtmann 	hdev->sniff_min_interval = val;
5042bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5052bfa3531SMarcel Holtmann 
5062bfa3531SMarcel Holtmann 	return 0;
5072bfa3531SMarcel Holtmann }
5082bfa3531SMarcel Holtmann 
5092bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val)
5102bfa3531SMarcel Holtmann {
5112bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5122bfa3531SMarcel Holtmann 
5132bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5142bfa3531SMarcel Holtmann 	*val = hdev->sniff_min_interval;
5152bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5162bfa3531SMarcel Holtmann 
5172bfa3531SMarcel Holtmann 	return 0;
5182bfa3531SMarcel Holtmann }
5192bfa3531SMarcel Holtmann 
5202bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get,
5212bfa3531SMarcel Holtmann 			sniff_min_interval_set, "%llu\n");
5222bfa3531SMarcel Holtmann 
5232bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val)
5242bfa3531SMarcel Holtmann {
5252bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5262bfa3531SMarcel Holtmann 
5272bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
5282bfa3531SMarcel Holtmann 		return -EINVAL;
5292bfa3531SMarcel Holtmann 
5302bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5312bfa3531SMarcel Holtmann 	hdev->sniff_max_interval = val;
5322bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5332bfa3531SMarcel Holtmann 
5342bfa3531SMarcel Holtmann 	return 0;
5352bfa3531SMarcel Holtmann }
5362bfa3531SMarcel Holtmann 
5372bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val)
5382bfa3531SMarcel Holtmann {
5392bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5402bfa3531SMarcel Holtmann 
5412bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5422bfa3531SMarcel Holtmann 	*val = hdev->sniff_max_interval;
5432bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5442bfa3531SMarcel Holtmann 
5452bfa3531SMarcel Holtmann 	return 0;
5462bfa3531SMarcel Holtmann }
5472bfa3531SMarcel Holtmann 
5482bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
5492bfa3531SMarcel Holtmann 			sniff_max_interval_set, "%llu\n");
5502bfa3531SMarcel Holtmann 
551e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p)
552e7b8fc92SMarcel Holtmann {
553e7b8fc92SMarcel Holtmann 	struct hci_dev *hdev = f->private;
554e7b8fc92SMarcel Holtmann 
555e7b8fc92SMarcel Holtmann 	hci_dev_lock(hdev);
556e7b8fc92SMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->static_addr);
557e7b8fc92SMarcel Holtmann 	hci_dev_unlock(hdev);
558e7b8fc92SMarcel Holtmann 
559e7b8fc92SMarcel Holtmann 	return 0;
560e7b8fc92SMarcel Holtmann }
561e7b8fc92SMarcel Holtmann 
562e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file)
563e7b8fc92SMarcel Holtmann {
564e7b8fc92SMarcel Holtmann 	return single_open(file, static_address_show, inode->i_private);
565e7b8fc92SMarcel Holtmann }
566e7b8fc92SMarcel Holtmann 
567e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = {
568e7b8fc92SMarcel Holtmann 	.open		= static_address_open,
569e7b8fc92SMarcel Holtmann 	.read		= seq_read,
570e7b8fc92SMarcel Holtmann 	.llseek		= seq_lseek,
571e7b8fc92SMarcel Holtmann 	.release	= single_release,
572e7b8fc92SMarcel Holtmann };
573e7b8fc92SMarcel Holtmann 
57492202185SMarcel Holtmann static int own_address_type_set(void *data, u64 val)
57592202185SMarcel Holtmann {
57692202185SMarcel Holtmann 	struct hci_dev *hdev = data;
57792202185SMarcel Holtmann 
57892202185SMarcel Holtmann 	if (val != 0 && val != 1)
57992202185SMarcel Holtmann 		return -EINVAL;
58092202185SMarcel Holtmann 
58192202185SMarcel Holtmann 	hci_dev_lock(hdev);
58292202185SMarcel Holtmann 	hdev->own_addr_type = val;
58392202185SMarcel Holtmann 	hci_dev_unlock(hdev);
58492202185SMarcel Holtmann 
58592202185SMarcel Holtmann 	return 0;
58692202185SMarcel Holtmann }
58792202185SMarcel Holtmann 
58892202185SMarcel Holtmann static int own_address_type_get(void *data, u64 *val)
58992202185SMarcel Holtmann {
59092202185SMarcel Holtmann 	struct hci_dev *hdev = data;
59192202185SMarcel Holtmann 
59292202185SMarcel Holtmann 	hci_dev_lock(hdev);
59392202185SMarcel Holtmann 	*val = hdev->own_addr_type;
59492202185SMarcel Holtmann 	hci_dev_unlock(hdev);
59592202185SMarcel Holtmann 
59692202185SMarcel Holtmann 	return 0;
59792202185SMarcel Holtmann }
59892202185SMarcel Holtmann 
59992202185SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get,
60092202185SMarcel Holtmann 			own_address_type_set, "%llu\n");
60192202185SMarcel Holtmann 
6028f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr)
6038f8625cdSMarcel Holtmann {
6048f8625cdSMarcel Holtmann 	struct hci_dev *hdev = f->private;
6058f8625cdSMarcel Holtmann 	struct list_head *p, *n;
6068f8625cdSMarcel Holtmann 
6078f8625cdSMarcel Holtmann 	hci_dev_lock(hdev);
608f813f1beSJohan Hedberg 	list_for_each_safe(p, n, &hdev->long_term_keys) {
6098f8625cdSMarcel Holtmann 		struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list);
610f813f1beSJohan Hedberg 		seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %*phN %*phN\n",
6118f8625cdSMarcel Holtmann 			   &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
6128f8625cdSMarcel Holtmann 			   ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
6138f8625cdSMarcel Holtmann 			   8, ltk->rand, 16, ltk->val);
6148f8625cdSMarcel Holtmann 	}
6158f8625cdSMarcel Holtmann 	hci_dev_unlock(hdev);
6168f8625cdSMarcel Holtmann 
6178f8625cdSMarcel Holtmann 	return 0;
6188f8625cdSMarcel Holtmann }
6198f8625cdSMarcel Holtmann 
6208f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file)
6218f8625cdSMarcel Holtmann {
6228f8625cdSMarcel Holtmann 	return single_open(file, long_term_keys_show, inode->i_private);
6238f8625cdSMarcel Holtmann }
6248f8625cdSMarcel Holtmann 
6258f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = {
6268f8625cdSMarcel Holtmann 	.open		= long_term_keys_open,
6278f8625cdSMarcel Holtmann 	.read		= seq_read,
6288f8625cdSMarcel Holtmann 	.llseek		= seq_lseek,
6298f8625cdSMarcel Holtmann 	.release	= single_release,
6308f8625cdSMarcel Holtmann };
6318f8625cdSMarcel Holtmann 
6324e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val)
6334e70c7e7SMarcel Holtmann {
6344e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6354e70c7e7SMarcel Holtmann 
6364e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
6374e70c7e7SMarcel Holtmann 		return -EINVAL;
6384e70c7e7SMarcel Holtmann 
6394e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6404e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = val;
6414e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
6424e70c7e7SMarcel Holtmann 
6434e70c7e7SMarcel Holtmann 	return 0;
6444e70c7e7SMarcel Holtmann }
6454e70c7e7SMarcel Holtmann 
6464e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val)
6474e70c7e7SMarcel Holtmann {
6484e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6494e70c7e7SMarcel Holtmann 
6504e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6514e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_min_interval;
6524e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
6534e70c7e7SMarcel Holtmann 
6544e70c7e7SMarcel Holtmann 	return 0;
6554e70c7e7SMarcel Holtmann }
6564e70c7e7SMarcel Holtmann 
6574e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
6584e70c7e7SMarcel Holtmann 			conn_min_interval_set, "%llu\n");
6594e70c7e7SMarcel Holtmann 
6604e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val)
6614e70c7e7SMarcel Holtmann {
6624e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6634e70c7e7SMarcel Holtmann 
6644e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
6654e70c7e7SMarcel Holtmann 		return -EINVAL;
6664e70c7e7SMarcel Holtmann 
6674e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6684e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = val;
6694e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
6704e70c7e7SMarcel Holtmann 
6714e70c7e7SMarcel Holtmann 	return 0;
6724e70c7e7SMarcel Holtmann }
6734e70c7e7SMarcel Holtmann 
6744e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val)
6754e70c7e7SMarcel Holtmann {
6764e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6774e70c7e7SMarcel Holtmann 
6784e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6794e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_max_interval;
6804e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
6814e70c7e7SMarcel Holtmann 
6824e70c7e7SMarcel Holtmann 	return 0;
6834e70c7e7SMarcel Holtmann }
6844e70c7e7SMarcel Holtmann 
6854e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
6864e70c7e7SMarcel Holtmann 			conn_max_interval_set, "%llu\n");
6874e70c7e7SMarcel Holtmann 
68889863109SJukka Rissanen static ssize_t lowpan_read(struct file *file, char __user *user_buf,
68989863109SJukka Rissanen 			   size_t count, loff_t *ppos)
69089863109SJukka Rissanen {
69189863109SJukka Rissanen 	struct hci_dev *hdev = file->private_data;
69289863109SJukka Rissanen 	char buf[3];
69389863109SJukka Rissanen 
69489863109SJukka Rissanen 	buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N';
69589863109SJukka Rissanen 	buf[1] = '\n';
69689863109SJukka Rissanen 	buf[2] = '\0';
69789863109SJukka Rissanen 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
69889863109SJukka Rissanen }
69989863109SJukka Rissanen 
70089863109SJukka Rissanen static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer,
70189863109SJukka Rissanen 			    size_t count, loff_t *position)
70289863109SJukka Rissanen {
70389863109SJukka Rissanen 	struct hci_dev *hdev = fp->private_data;
70489863109SJukka Rissanen 	bool enable;
70589863109SJukka Rissanen 	char buf[32];
70689863109SJukka Rissanen 	size_t buf_size = min(count, (sizeof(buf)-1));
70789863109SJukka Rissanen 
70889863109SJukka Rissanen 	if (copy_from_user(buf, user_buffer, buf_size))
70989863109SJukka Rissanen 		return -EFAULT;
71089863109SJukka Rissanen 
71189863109SJukka Rissanen 	buf[buf_size] = '\0';
71289863109SJukka Rissanen 
71389863109SJukka Rissanen 	if (strtobool(buf, &enable) < 0)
71489863109SJukka Rissanen 		return -EINVAL;
71589863109SJukka Rissanen 
71689863109SJukka Rissanen 	if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
71789863109SJukka Rissanen 		return -EALREADY;
71889863109SJukka Rissanen 
71989863109SJukka Rissanen 	change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags);
72089863109SJukka Rissanen 
72189863109SJukka Rissanen 	return count;
72289863109SJukka Rissanen }
72389863109SJukka Rissanen 
72489863109SJukka Rissanen static const struct file_operations lowpan_debugfs_fops = {
72589863109SJukka Rissanen 	.open		= simple_open,
72689863109SJukka Rissanen 	.read		= lowpan_read,
72789863109SJukka Rissanen 	.write		= lowpan_write,
72889863109SJukka Rissanen 	.llseek		= default_llseek,
72989863109SJukka Rissanen };
73089863109SJukka Rissanen 
7311da177e4SLinus Torvalds /* ---- HCI requests ---- */
7321da177e4SLinus Torvalds 
73342c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
7341da177e4SLinus Torvalds {
73542c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
73675fb0e32SJohan Hedberg 
7371da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
7381da177e4SLinus Torvalds 		hdev->req_result = result;
7391da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
7401da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
7411da177e4SLinus Torvalds 	}
7421da177e4SLinus Torvalds }
7431da177e4SLinus Torvalds 
7441da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
7451da177e4SLinus Torvalds {
7461da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
7471da177e4SLinus Torvalds 
7481da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
7491da177e4SLinus Torvalds 		hdev->req_result = err;
7501da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
7511da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
7521da177e4SLinus Torvalds 	}
7531da177e4SLinus Torvalds }
7541da177e4SLinus Torvalds 
75577a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
75677a63e0aSFengguang Wu 					    u8 event)
75775e84b7cSJohan Hedberg {
75875e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
75975e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
76075e84b7cSJohan Hedberg 	struct sk_buff *skb;
76175e84b7cSJohan Hedberg 
76275e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
76375e84b7cSJohan Hedberg 
76475e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
76575e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
76675e84b7cSJohan Hedberg 
76775e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
76875e84b7cSJohan Hedberg 
76975e84b7cSJohan Hedberg 	if (!skb)
77075e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
77175e84b7cSJohan Hedberg 
77275e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
77375e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
77475e84b7cSJohan Hedberg 		goto failed;
77575e84b7cSJohan Hedberg 	}
77675e84b7cSJohan Hedberg 
77775e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
77875e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
77975e84b7cSJohan Hedberg 
7807b1abbbeSJohan Hedberg 	if (event) {
7817b1abbbeSJohan Hedberg 		if (hdr->evt != event)
7827b1abbbeSJohan Hedberg 			goto failed;
7837b1abbbeSJohan Hedberg 		return skb;
7847b1abbbeSJohan Hedberg 	}
7857b1abbbeSJohan Hedberg 
78675e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
78775e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
78875e84b7cSJohan Hedberg 		goto failed;
78975e84b7cSJohan Hedberg 	}
79075e84b7cSJohan Hedberg 
79175e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
79275e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
79375e84b7cSJohan Hedberg 		goto failed;
79475e84b7cSJohan Hedberg 	}
79575e84b7cSJohan Hedberg 
79675e84b7cSJohan Hedberg 	ev = (void *) skb->data;
79775e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
79875e84b7cSJohan Hedberg 
79975e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
80075e84b7cSJohan Hedberg 		return skb;
80175e84b7cSJohan Hedberg 
80275e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
80375e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
80475e84b7cSJohan Hedberg 
80575e84b7cSJohan Hedberg failed:
80675e84b7cSJohan Hedberg 	kfree_skb(skb);
80775e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
80875e84b7cSJohan Hedberg }
80975e84b7cSJohan Hedberg 
8107b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
81107dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
81275e84b7cSJohan Hedberg {
81375e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
81475e84b7cSJohan Hedberg 	struct hci_request req;
81575e84b7cSJohan Hedberg 	int err = 0;
81675e84b7cSJohan Hedberg 
81775e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
81875e84b7cSJohan Hedberg 
81975e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
82075e84b7cSJohan Hedberg 
8217b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
82275e84b7cSJohan Hedberg 
82375e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
82475e84b7cSJohan Hedberg 
82575e84b7cSJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
82675e84b7cSJohan Hedberg 	if (err < 0)
82775e84b7cSJohan Hedberg 		return ERR_PTR(err);
82875e84b7cSJohan Hedberg 
82975e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
83075e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
83175e84b7cSJohan Hedberg 
83275e84b7cSJohan Hedberg 	schedule_timeout(timeout);
83375e84b7cSJohan Hedberg 
83475e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
83575e84b7cSJohan Hedberg 
83675e84b7cSJohan Hedberg 	if (signal_pending(current))
83775e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
83875e84b7cSJohan Hedberg 
83975e84b7cSJohan Hedberg 	switch (hdev->req_status) {
84075e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
84175e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
84275e84b7cSJohan Hedberg 		break;
84375e84b7cSJohan Hedberg 
84475e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
84575e84b7cSJohan Hedberg 		err = -hdev->req_result;
84675e84b7cSJohan Hedberg 		break;
84775e84b7cSJohan Hedberg 
84875e84b7cSJohan Hedberg 	default:
84975e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
85075e84b7cSJohan Hedberg 		break;
85175e84b7cSJohan Hedberg 	}
85275e84b7cSJohan Hedberg 
85375e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
85475e84b7cSJohan Hedberg 
85575e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
85675e84b7cSJohan Hedberg 
85775e84b7cSJohan Hedberg 	if (err < 0)
85875e84b7cSJohan Hedberg 		return ERR_PTR(err);
85975e84b7cSJohan Hedberg 
8607b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
8617b1abbbeSJohan Hedberg }
8627b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
8637b1abbbeSJohan Hedberg 
8647b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
86507dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
8667b1abbbeSJohan Hedberg {
8677b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
86875e84b7cSJohan Hedberg }
86975e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
87075e84b7cSJohan Hedberg 
8711da177e4SLinus Torvalds /* Execute request and wait for completion. */
87201178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
87342c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
87442c6b129SJohan Hedberg 				      unsigned long opt),
8751da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
8761da177e4SLinus Torvalds {
87742c6b129SJohan Hedberg 	struct hci_request req;
8781da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
8791da177e4SLinus Torvalds 	int err = 0;
8801da177e4SLinus Torvalds 
8811da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
8821da177e4SLinus Torvalds 
88342c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
88442c6b129SJohan Hedberg 
8851da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
8861da177e4SLinus Torvalds 
88742c6b129SJohan Hedberg 	func(&req, opt);
88853cce22dSJohan Hedberg 
88942c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
89042c6b129SJohan Hedberg 	if (err < 0) {
89153cce22dSJohan Hedberg 		hdev->req_status = 0;
892920c8300SAndre Guedes 
893920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
894920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
895920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
896920c8300SAndre Guedes 		 * and should not trigger an error return.
89742c6b129SJohan Hedberg 		 */
898920c8300SAndre Guedes 		if (err == -ENODATA)
89942c6b129SJohan Hedberg 			return 0;
900920c8300SAndre Guedes 
901920c8300SAndre Guedes 		return err;
90253cce22dSJohan Hedberg 	}
90353cce22dSJohan Hedberg 
904bc4445c7SAndre Guedes 	add_wait_queue(&hdev->req_wait_q, &wait);
905bc4445c7SAndre Guedes 	set_current_state(TASK_INTERRUPTIBLE);
906bc4445c7SAndre Guedes 
9071da177e4SLinus Torvalds 	schedule_timeout(timeout);
9081da177e4SLinus Torvalds 
9091da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
9101da177e4SLinus Torvalds 
9111da177e4SLinus Torvalds 	if (signal_pending(current))
9121da177e4SLinus Torvalds 		return -EINTR;
9131da177e4SLinus Torvalds 
9141da177e4SLinus Torvalds 	switch (hdev->req_status) {
9151da177e4SLinus Torvalds 	case HCI_REQ_DONE:
916e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
9171da177e4SLinus Torvalds 		break;
9181da177e4SLinus Torvalds 
9191da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
9201da177e4SLinus Torvalds 		err = -hdev->req_result;
9211da177e4SLinus Torvalds 		break;
9221da177e4SLinus Torvalds 
9231da177e4SLinus Torvalds 	default:
9241da177e4SLinus Torvalds 		err = -ETIMEDOUT;
9251da177e4SLinus Torvalds 		break;
9263ff50b79SStephen Hemminger 	}
9271da177e4SLinus Torvalds 
928a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
9291da177e4SLinus Torvalds 
9301da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
9311da177e4SLinus Torvalds 
9321da177e4SLinus Torvalds 	return err;
9331da177e4SLinus Torvalds }
9341da177e4SLinus Torvalds 
93501178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
93642c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
93742c6b129SJohan Hedberg 				    unsigned long opt),
9381da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
9391da177e4SLinus Torvalds {
9401da177e4SLinus Torvalds 	int ret;
9411da177e4SLinus Torvalds 
9427c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
9437c6a329eSMarcel Holtmann 		return -ENETDOWN;
9447c6a329eSMarcel Holtmann 
9451da177e4SLinus Torvalds 	/* Serialize all requests */
9461da177e4SLinus Torvalds 	hci_req_lock(hdev);
94701178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
9481da177e4SLinus Torvalds 	hci_req_unlock(hdev);
9491da177e4SLinus Torvalds 
9501da177e4SLinus Torvalds 	return ret;
9511da177e4SLinus Torvalds }
9521da177e4SLinus Torvalds 
95342c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
9541da177e4SLinus Torvalds {
95542c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
9561da177e4SLinus Torvalds 
9571da177e4SLinus Torvalds 	/* Reset device */
95842c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
95942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
9601da177e4SLinus Torvalds }
9611da177e4SLinus Torvalds 
96242c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
9631da177e4SLinus Torvalds {
96442c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
9652455a3eaSAndrei Emeltchenko 
9661da177e4SLinus Torvalds 	/* Read Local Supported Features */
96742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
9681da177e4SLinus Torvalds 
9691143e5a6SMarcel Holtmann 	/* Read Local Version */
97042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
9712177bab5SJohan Hedberg 
9722177bab5SJohan Hedberg 	/* Read BD Address */
97342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
9741da177e4SLinus Torvalds }
9751da177e4SLinus Torvalds 
97642c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
977e61ef499SAndrei Emeltchenko {
97842c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
9792455a3eaSAndrei Emeltchenko 
980e61ef499SAndrei Emeltchenko 	/* Read Local Version */
98142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
9826bcbc489SAndrei Emeltchenko 
983f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
984f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
985f6996cfeSMarcel Holtmann 
986f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
987f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
988f6996cfeSMarcel Holtmann 
9896bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
99042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
991e71dfabaSAndrei Emeltchenko 
992e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
99342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
9947528ca1cSMarcel Holtmann 
995f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
996f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
997f38ba941SMarcel Holtmann 
9987528ca1cSMarcel Holtmann 	/* Read Location Data */
9997528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
1000e61ef499SAndrei Emeltchenko }
1001e61ef499SAndrei Emeltchenko 
100242c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
1003e61ef499SAndrei Emeltchenko {
100442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1005e61ef499SAndrei Emeltchenko 
1006e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
1007e61ef499SAndrei Emeltchenko 
100811778716SAndrei Emeltchenko 	/* Reset */
100911778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
101042c6b129SJohan Hedberg 		hci_reset_req(req, 0);
101111778716SAndrei Emeltchenko 
1012e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
1013e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
101442c6b129SJohan Hedberg 		bredr_init(req);
1015e61ef499SAndrei Emeltchenko 		break;
1016e61ef499SAndrei Emeltchenko 
1017e61ef499SAndrei Emeltchenko 	case HCI_AMP:
101842c6b129SJohan Hedberg 		amp_init(req);
1019e61ef499SAndrei Emeltchenko 		break;
1020e61ef499SAndrei Emeltchenko 
1021e61ef499SAndrei Emeltchenko 	default:
1022e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
1023e61ef499SAndrei Emeltchenko 		break;
1024e61ef499SAndrei Emeltchenko 	}
1025e61ef499SAndrei Emeltchenko }
1026e61ef499SAndrei Emeltchenko 
102742c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
10282177bab5SJohan Hedberg {
10294ca048e3SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
10304ca048e3SMarcel Holtmann 
10312177bab5SJohan Hedberg 	__le16 param;
10322177bab5SJohan Hedberg 	__u8 flt_type;
10332177bab5SJohan Hedberg 
10342177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
103542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
10362177bab5SJohan Hedberg 
10372177bab5SJohan Hedberg 	/* Read Class of Device */
103842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
10392177bab5SJohan Hedberg 
10402177bab5SJohan Hedberg 	/* Read Local Name */
104142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
10422177bab5SJohan Hedberg 
10432177bab5SJohan Hedberg 	/* Read Voice Setting */
104442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
10452177bab5SJohan Hedberg 
1046b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
1047b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
1048b4cb9fb2SMarcel Holtmann 
10494b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
10504b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
10514b836f39SMarcel Holtmann 
10522177bab5SJohan Hedberg 	/* Clear Event Filters */
10532177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
105442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
10552177bab5SJohan Hedberg 
10562177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
10572177bab5SJohan Hedberg 	param = __constant_cpu_to_le16(0x7d00);
105842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
10592177bab5SJohan Hedberg 
10604ca048e3SMarcel Holtmann 	/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
10614ca048e3SMarcel Holtmann 	 * but it does not support page scan related HCI commands.
10624ca048e3SMarcel Holtmann 	 */
10634ca048e3SMarcel Holtmann 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
1064f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
1065f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
1066f332ec66SJohan Hedberg 	}
10672177bab5SJohan Hedberg }
10682177bab5SJohan Hedberg 
106942c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
10702177bab5SJohan Hedberg {
1071c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1072c73eee91SJohan Hedberg 
10732177bab5SJohan Hedberg 	/* Read LE Buffer Size */
107442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
10752177bab5SJohan Hedberg 
10762177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
107742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
10782177bab5SJohan Hedberg 
10792177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
108042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
10812177bab5SJohan Hedberg 
10822177bab5SJohan Hedberg 	/* Read LE White List Size */
108342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
10842177bab5SJohan Hedberg 
10852177bab5SJohan Hedberg 	/* Read LE Supported States */
108642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
1087c73eee91SJohan Hedberg 
1088c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
1089c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1090c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
10912177bab5SJohan Hedberg }
10922177bab5SJohan Hedberg 
10932177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
10942177bab5SJohan Hedberg {
10952177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
10962177bab5SJohan Hedberg 		return 0x02;
10972177bab5SJohan Hedberg 
10982177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
10992177bab5SJohan Hedberg 		return 0x01;
11002177bab5SJohan Hedberg 
11012177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
11022177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
11032177bab5SJohan Hedberg 		return 0x01;
11042177bab5SJohan Hedberg 
11052177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
11062177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
11072177bab5SJohan Hedberg 			return 0x01;
11082177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
11092177bab5SJohan Hedberg 			return 0x01;
11102177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
11112177bab5SJohan Hedberg 			return 0x01;
11122177bab5SJohan Hedberg 	}
11132177bab5SJohan Hedberg 
11142177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
11152177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
11162177bab5SJohan Hedberg 		return 0x01;
11172177bab5SJohan Hedberg 
11182177bab5SJohan Hedberg 	return 0x00;
11192177bab5SJohan Hedberg }
11202177bab5SJohan Hedberg 
112142c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
11222177bab5SJohan Hedberg {
11232177bab5SJohan Hedberg 	u8 mode;
11242177bab5SJohan Hedberg 
112542c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
11262177bab5SJohan Hedberg 
112742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
11282177bab5SJohan Hedberg }
11292177bab5SJohan Hedberg 
113042c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
11312177bab5SJohan Hedberg {
113242c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
113342c6b129SJohan Hedberg 
11342177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
11352177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
11362177bab5SJohan Hedberg 	 * command otherwise.
11372177bab5SJohan Hedberg 	 */
11382177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
11392177bab5SJohan Hedberg 
11402177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
11412177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
11422177bab5SJohan Hedberg 	 */
11432177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
11442177bab5SJohan Hedberg 		return;
11452177bab5SJohan Hedberg 
11462177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
11472177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
11482177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
11492177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
11502177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
11512177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
1152c7882cbdSMarcel Holtmann 	} else {
1153c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
1154c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
1155c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
1156c7882cbdSMarcel Holtmann 		events[0] |= 0x80; /* Encryption Change */
1157c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
1158c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
1159c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
1160c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
1161c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
1162c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
1163c7882cbdSMarcel Holtmann 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
11642177bab5SJohan Hedberg 	}
11652177bab5SJohan Hedberg 
11662177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
11672177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
11682177bab5SJohan Hedberg 
11692177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
11702177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
11712177bab5SJohan Hedberg 
11722177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
11732177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
11742177bab5SJohan Hedberg 
11752177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
11762177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
11772177bab5SJohan Hedberg 
11782177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
11792177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
11802177bab5SJohan Hedberg 
11812177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
11822177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
11832177bab5SJohan Hedberg 
11842177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
11852177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
11862177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
11872177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
11882177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
11892177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
11902177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
11912177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
11922177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
11932177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
11942177bab5SJohan Hedberg 					 * Features Notification
11952177bab5SJohan Hedberg 					 */
11962177bab5SJohan Hedberg 	}
11972177bab5SJohan Hedberg 
11982177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
11992177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
12002177bab5SJohan Hedberg 
120142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
12022177bab5SJohan Hedberg 
12032177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
12042177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
12052177bab5SJohan Hedberg 		events[0] = 0x1f;
120642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
12072177bab5SJohan Hedberg 			    sizeof(events), events);
12082177bab5SJohan Hedberg 	}
12092177bab5SJohan Hedberg }
12102177bab5SJohan Hedberg 
121142c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
12122177bab5SJohan Hedberg {
121342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
121442c6b129SJohan Hedberg 
12152177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
121642c6b129SJohan Hedberg 		bredr_setup(req);
121756f87901SJohan Hedberg 	else
121856f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
12192177bab5SJohan Hedberg 
12202177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
122142c6b129SJohan Hedberg 		le_setup(req);
12222177bab5SJohan Hedberg 
122342c6b129SJohan Hedberg 	hci_setup_event_mask(req);
12242177bab5SJohan Hedberg 
12253f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
12263f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
12273f8e2d75SJohan Hedberg 	 */
12283f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
122942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
12302177bab5SJohan Hedberg 
12312177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
123257af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
123357af75a8SMarcel Holtmann 		 * should also be available as well. However some
123457af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
123557af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
123657af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
123757af75a8SMarcel Holtmann 		 */
123857af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
123957af75a8SMarcel Holtmann 
12402177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
12412177bab5SJohan Hedberg 			u8 mode = 0x01;
124242c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
12432177bab5SJohan Hedberg 				    sizeof(mode), &mode);
12442177bab5SJohan Hedberg 		} else {
12452177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
12462177bab5SJohan Hedberg 
12472177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
12482177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
12492177bab5SJohan Hedberg 
125042c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
12512177bab5SJohan Hedberg 		}
12522177bab5SJohan Hedberg 	}
12532177bab5SJohan Hedberg 
12542177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
125542c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
12562177bab5SJohan Hedberg 
12572177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
125842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
12592177bab5SJohan Hedberg 
12602177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
12612177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
12622177bab5SJohan Hedberg 
12632177bab5SJohan Hedberg 		cp.page = 0x01;
126442c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
126542c6b129SJohan Hedberg 			    sizeof(cp), &cp);
12662177bab5SJohan Hedberg 	}
12672177bab5SJohan Hedberg 
12682177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
12692177bab5SJohan Hedberg 		u8 enable = 1;
127042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
12712177bab5SJohan Hedberg 			    &enable);
12722177bab5SJohan Hedberg 	}
12732177bab5SJohan Hedberg }
12742177bab5SJohan Hedberg 
127542c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
12762177bab5SJohan Hedberg {
127742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
12782177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
12792177bab5SJohan Hedberg 	u16 link_policy = 0;
12802177bab5SJohan Hedberg 
12812177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
12822177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
12832177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
12842177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
12852177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
12862177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
12872177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
12882177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
12892177bab5SJohan Hedberg 
12902177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
129142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
12922177bab5SJohan Hedberg }
12932177bab5SJohan Hedberg 
129442c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
12952177bab5SJohan Hedberg {
129642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
12972177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
12982177bab5SJohan Hedberg 
1299c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
1300c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1301c73eee91SJohan Hedberg 		return;
1302c73eee91SJohan Hedberg 
13032177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
13042177bab5SJohan Hedberg 
13052177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
13062177bab5SJohan Hedberg 		cp.le = 0x01;
13072177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
13082177bab5SJohan Hedberg 	}
13092177bab5SJohan Hedberg 
13102177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
131142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
13122177bab5SJohan Hedberg 			    &cp);
13132177bab5SJohan Hedberg }
13142177bab5SJohan Hedberg 
1315d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
1316d62e6d67SJohan Hedberg {
1317d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1318d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1319d62e6d67SJohan Hedberg 
1320d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
1321d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1322d62e6d67SJohan Hedberg 	 */
132353b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
1324d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
1325d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
1326d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
1327d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
1328d62e6d67SJohan Hedberg 	}
1329d62e6d67SJohan Hedberg 
1330d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
1331d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1332d62e6d67SJohan Hedberg 	 */
133353b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
1334d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
1335d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
1336d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
1337d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
1338d62e6d67SJohan Hedberg 	}
1339d62e6d67SJohan Hedberg 
134040c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
134140c59fcbSMarcel Holtmann 	if (lmp_ping_capable(hdev))
134240c59fcbSMarcel Holtmann 		events[2] |= 0x80;
134340c59fcbSMarcel Holtmann 
1344d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
1345d62e6d67SJohan Hedberg }
1346d62e6d67SJohan Hedberg 
134742c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
13482177bab5SJohan Hedberg {
134942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1350d2c5d77fSJohan Hedberg 	u8 p;
135142c6b129SJohan Hedberg 
1352b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
1353b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
1354b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
1355b8f4e068SGustavo Padovan 	 *
1356b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
1357b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
1358b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
1359b8f4e068SGustavo Padovan 	 * command redundant anyway.
1360f9f462faSMarcel Holtmann 	 *
1361f9f462faSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
1362f9f462faSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
1363f9f462faSMarcel Holtmann 	 * just disable this command.
1364b8f4e068SGustavo Padovan 	 */
1365f9f462faSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
1366f9f462faSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
136759f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
136859f45d57SJohan Hedberg 
136959f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
137059f45d57SJohan Hedberg 		cp.delete_all = 0x01;
137159f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
137259f45d57SJohan Hedberg 			    sizeof(cp), &cp);
137359f45d57SJohan Hedberg 	}
137459f45d57SJohan Hedberg 
13752177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
137642c6b129SJohan Hedberg 		hci_setup_link_policy(req);
13772177bab5SJohan Hedberg 
137879830f66SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1379bef34c0aSMarcel Holtmann 		if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
1380bef34c0aSMarcel Holtmann 			/* If the controller has a public BD_ADDR, then
1381bef34c0aSMarcel Holtmann 			 * by default use that one. If this is a LE only
1382bef34c0aSMarcel Holtmann 			 * controller without a public address, default
1383bef34c0aSMarcel Holtmann 			 * to the random address.
138479830f66SMarcel Holtmann 			 */
138579830f66SMarcel Holtmann 			if (bacmp(&hdev->bdaddr, BDADDR_ANY))
138679830f66SMarcel Holtmann 				hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
138779830f66SMarcel Holtmann 			else
138879830f66SMarcel Holtmann 				hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
1389bef34c0aSMarcel Holtmann 		}
139079830f66SMarcel Holtmann 
139142c6b129SJohan Hedberg 		hci_set_le_support(req);
139279830f66SMarcel Holtmann 	}
1393d2c5d77fSJohan Hedberg 
1394d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
1395d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
1396d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
1397d2c5d77fSJohan Hedberg 
1398d2c5d77fSJohan Hedberg 		cp.page = p;
1399d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
1400d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
1401d2c5d77fSJohan Hedberg 	}
14022177bab5SJohan Hedberg }
14032177bab5SJohan Hedberg 
14045d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
14055d4e7e8dSJohan Hedberg {
14065d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
14075d4e7e8dSJohan Hedberg 
1408d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
1409d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
1410d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
1411d62e6d67SJohan Hedberg 
14125d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
141353b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
14145d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
1415a6d0d690SMarcel Holtmann 
1416a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
14175afeac14SMarcel Holtmann 	if ((lmp_sc_capable(hdev) ||
14185afeac14SMarcel Holtmann 	     test_bit(HCI_FORCE_SC, &hdev->dev_flags)) &&
1419a6d0d690SMarcel Holtmann 	    test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
1420a6d0d690SMarcel Holtmann 		u8 support = 0x01;
1421a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
1422a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
1423a6d0d690SMarcel Holtmann 	}
14245d4e7e8dSJohan Hedberg }
14255d4e7e8dSJohan Hedberg 
14262177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
14272177bab5SJohan Hedberg {
14282177bab5SJohan Hedberg 	int err;
14292177bab5SJohan Hedberg 
14302177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
14312177bab5SJohan Hedberg 	if (err < 0)
14322177bab5SJohan Hedberg 		return err;
14332177bab5SJohan Hedberg 
14344b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
14354b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
14364b4148e9SMarcel Holtmann 	 */
14374b4148e9SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
14384b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
14394b4148e9SMarcel Holtmann 				    &dut_mode_fops);
14404b4148e9SMarcel Holtmann 	}
14414b4148e9SMarcel Holtmann 
14422177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
14432177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
14442177bab5SJohan Hedberg 	 * first stage init.
14452177bab5SJohan Hedberg 	 */
14462177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
14472177bab5SJohan Hedberg 		return 0;
14482177bab5SJohan Hedberg 
14492177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
14502177bab5SJohan Hedberg 	if (err < 0)
14512177bab5SJohan Hedberg 		return err;
14522177bab5SJohan Hedberg 
14535d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
14545d4e7e8dSJohan Hedberg 	if (err < 0)
14555d4e7e8dSJohan Hedberg 		return err;
14565d4e7e8dSJohan Hedberg 
1457baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
1458baf27f6eSMarcel Holtmann 	if (err < 0)
1459baf27f6eSMarcel Holtmann 		return err;
1460baf27f6eSMarcel Holtmann 
1461baf27f6eSMarcel Holtmann 	/* Only create debugfs entries during the initial setup
1462baf27f6eSMarcel Holtmann 	 * phase and not every time the controller gets powered on.
1463baf27f6eSMarcel Holtmann 	 */
1464baf27f6eSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1465baf27f6eSMarcel Holtmann 		return 0;
1466baf27f6eSMarcel Holtmann 
1467dfb826a8SMarcel Holtmann 	debugfs_create_file("features", 0444, hdev->debugfs, hdev,
1468dfb826a8SMarcel Holtmann 			    &features_fops);
1469ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
1470ceeb3bc0SMarcel Holtmann 			   &hdev->manufacturer);
1471ceeb3bc0SMarcel Holtmann 	debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
1472ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
147370afe0b8SMarcel Holtmann 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
147470afe0b8SMarcel Holtmann 			    &blacklist_fops);
147547219839SMarcel Holtmann 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
147647219839SMarcel Holtmann 
1477baf27f6eSMarcel Holtmann 	if (lmp_bredr_capable(hdev)) {
1478baf27f6eSMarcel Holtmann 		debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
1479baf27f6eSMarcel Holtmann 				    hdev, &inquiry_cache_fops);
148002d08d15SMarcel Holtmann 		debugfs_create_file("link_keys", 0400, hdev->debugfs,
148102d08d15SMarcel Holtmann 				    hdev, &link_keys_fops);
1482babdbb3cSMarcel Holtmann 		debugfs_create_file("dev_class", 0444, hdev->debugfs,
1483babdbb3cSMarcel Holtmann 				    hdev, &dev_class_fops);
1484041000b9SMarcel Holtmann 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
1485041000b9SMarcel Holtmann 				    hdev, &voice_setting_fops);
1486baf27f6eSMarcel Holtmann 	}
1487baf27f6eSMarcel Holtmann 
148806f5b778SMarcel Holtmann 	if (lmp_ssp_capable(hdev)) {
1489ebd1e33bSMarcel Holtmann 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
1490ebd1e33bSMarcel Holtmann 				    hdev, &auto_accept_delay_fops);
149106f5b778SMarcel Holtmann 		debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
149206f5b778SMarcel Holtmann 				    hdev, &ssp_debug_mode_fops);
14935afeac14SMarcel Holtmann 		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
14945afeac14SMarcel Holtmann 				    hdev, &force_sc_support_fops);
1495134c2a89SMarcel Holtmann 		debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
1496134c2a89SMarcel Holtmann 				    hdev, &sc_only_mode_fops);
149706f5b778SMarcel Holtmann 	}
1498ebd1e33bSMarcel Holtmann 
14992bfa3531SMarcel Holtmann 	if (lmp_sniff_capable(hdev)) {
15002bfa3531SMarcel Holtmann 		debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
15012bfa3531SMarcel Holtmann 				    hdev, &idle_timeout_fops);
15022bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
15032bfa3531SMarcel Holtmann 				    hdev, &sniff_min_interval_fops);
15042bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
15052bfa3531SMarcel Holtmann 				    hdev, &sniff_max_interval_fops);
15062bfa3531SMarcel Holtmann 	}
15072bfa3531SMarcel Holtmann 
1508d0f729b8SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1509d0f729b8SMarcel Holtmann 		debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1510d0f729b8SMarcel Holtmann 				  &hdev->le_white_list_size);
1511e7b8fc92SMarcel Holtmann 		debugfs_create_file("static_address", 0444, hdev->debugfs,
1512e7b8fc92SMarcel Holtmann 				   hdev, &static_address_fops);
151392202185SMarcel Holtmann 		debugfs_create_file("own_address_type", 0644, hdev->debugfs,
151492202185SMarcel Holtmann 				    hdev, &own_address_type_fops);
15158f8625cdSMarcel Holtmann 		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
15168f8625cdSMarcel Holtmann 				    hdev, &long_term_keys_fops);
15174e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
15184e70c7e7SMarcel Holtmann 				    hdev, &conn_min_interval_fops);
15194e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
15204e70c7e7SMarcel Holtmann 				    hdev, &conn_max_interval_fops);
152189863109SJukka Rissanen 		debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
152289863109SJukka Rissanen 				    &lowpan_debugfs_fops);
1523d0f729b8SMarcel Holtmann 	}
1524e7b8fc92SMarcel Holtmann 
1525baf27f6eSMarcel Holtmann 	return 0;
15262177bab5SJohan Hedberg }
15272177bab5SJohan Hedberg 
152842c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
15291da177e4SLinus Torvalds {
15301da177e4SLinus Torvalds 	__u8 scan = opt;
15311da177e4SLinus Torvalds 
153242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
15331da177e4SLinus Torvalds 
15341da177e4SLinus Torvalds 	/* Inquiry and Page scans */
153542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
15361da177e4SLinus Torvalds }
15371da177e4SLinus Torvalds 
153842c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
15391da177e4SLinus Torvalds {
15401da177e4SLinus Torvalds 	__u8 auth = opt;
15411da177e4SLinus Torvalds 
154242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
15431da177e4SLinus Torvalds 
15441da177e4SLinus Torvalds 	/* Authentication */
154542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
15461da177e4SLinus Torvalds }
15471da177e4SLinus Torvalds 
154842c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
15491da177e4SLinus Torvalds {
15501da177e4SLinus Torvalds 	__u8 encrypt = opt;
15511da177e4SLinus Torvalds 
155242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
15531da177e4SLinus Torvalds 
1554e4e8e37cSMarcel Holtmann 	/* Encryption */
155542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
15561da177e4SLinus Torvalds }
15571da177e4SLinus Torvalds 
155842c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
1559e4e8e37cSMarcel Holtmann {
1560e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
1561e4e8e37cSMarcel Holtmann 
156242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
1563e4e8e37cSMarcel Holtmann 
1564e4e8e37cSMarcel Holtmann 	/* Default link policy */
156542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
1566e4e8e37cSMarcel Holtmann }
1567e4e8e37cSMarcel Holtmann 
15681da177e4SLinus Torvalds /* Get HCI device by index.
15691da177e4SLinus Torvalds  * Device is held on return. */
15701da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
15711da177e4SLinus Torvalds {
15728035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
15731da177e4SLinus Torvalds 
15741da177e4SLinus Torvalds 	BT_DBG("%d", index);
15751da177e4SLinus Torvalds 
15761da177e4SLinus Torvalds 	if (index < 0)
15771da177e4SLinus Torvalds 		return NULL;
15781da177e4SLinus Torvalds 
15791da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
15808035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
15811da177e4SLinus Torvalds 		if (d->id == index) {
15821da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
15831da177e4SLinus Torvalds 			break;
15841da177e4SLinus Torvalds 		}
15851da177e4SLinus Torvalds 	}
15861da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
15871da177e4SLinus Torvalds 	return hdev;
15881da177e4SLinus Torvalds }
15891da177e4SLinus Torvalds 
15901da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1591ff9ef578SJohan Hedberg 
159230dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
159330dc78e1SJohan Hedberg {
159430dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
159530dc78e1SJohan Hedberg 
15966fbe195dSAndre Guedes 	switch (discov->state) {
1597343f935bSAndre Guedes 	case DISCOVERY_FINDING:
15986fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
159930dc78e1SJohan Hedberg 		return true;
160030dc78e1SJohan Hedberg 
16016fbe195dSAndre Guedes 	default:
160230dc78e1SJohan Hedberg 		return false;
160330dc78e1SJohan Hedberg 	}
16046fbe195dSAndre Guedes }
160530dc78e1SJohan Hedberg 
1606ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1607ff9ef578SJohan Hedberg {
1608ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1609ff9ef578SJohan Hedberg 
1610ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
1611ff9ef578SJohan Hedberg 		return;
1612ff9ef578SJohan Hedberg 
1613ff9ef578SJohan Hedberg 	switch (state) {
1614ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
16157b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
1616ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1617ff9ef578SJohan Hedberg 		break;
1618ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1619ff9ef578SJohan Hedberg 		break;
1620343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1621ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1622ff9ef578SJohan Hedberg 		break;
162330dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
162430dc78e1SJohan Hedberg 		break;
1625ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1626ff9ef578SJohan Hedberg 		break;
1627ff9ef578SJohan Hedberg 	}
1628ff9ef578SJohan Hedberg 
1629ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
1630ff9ef578SJohan Hedberg }
1631ff9ef578SJohan Hedberg 
16321f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
16331da177e4SLinus Torvalds {
163430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1635b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
16361da177e4SLinus Torvalds 
1637561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
1638561aafbcSJohan Hedberg 		list_del(&p->all);
1639b57c1a56SJohan Hedberg 		kfree(p);
16401da177e4SLinus Torvalds 	}
1641561aafbcSJohan Hedberg 
1642561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
1643561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
16441da177e4SLinus Torvalds }
16451da177e4SLinus Torvalds 
1646a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
1647a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
16481da177e4SLinus Torvalds {
164930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
16501da177e4SLinus Torvalds 	struct inquiry_entry *e;
16511da177e4SLinus Torvalds 
16526ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
16531da177e4SLinus Torvalds 
1654561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
16551da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
16561da177e4SLinus Torvalds 			return e;
16571da177e4SLinus Torvalds 	}
16581da177e4SLinus Torvalds 
1659b57c1a56SJohan Hedberg 	return NULL;
1660b57c1a56SJohan Hedberg }
1661b57c1a56SJohan Hedberg 
1662561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
1663561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
1664561aafbcSJohan Hedberg {
166530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1666561aafbcSJohan Hedberg 	struct inquiry_entry *e;
1667561aafbcSJohan Hedberg 
16686ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1669561aafbcSJohan Hedberg 
1670561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
1671561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
1672561aafbcSJohan Hedberg 			return e;
1673561aafbcSJohan Hedberg 	}
1674561aafbcSJohan Hedberg 
1675561aafbcSJohan Hedberg 	return NULL;
1676561aafbcSJohan Hedberg }
1677561aafbcSJohan Hedberg 
167830dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
167930dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
168030dc78e1SJohan Hedberg 						       int state)
168130dc78e1SJohan Hedberg {
168230dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
168330dc78e1SJohan Hedberg 	struct inquiry_entry *e;
168430dc78e1SJohan Hedberg 
16856ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
168630dc78e1SJohan Hedberg 
168730dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
168830dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
168930dc78e1SJohan Hedberg 			return e;
169030dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
169130dc78e1SJohan Hedberg 			return e;
169230dc78e1SJohan Hedberg 	}
169330dc78e1SJohan Hedberg 
169430dc78e1SJohan Hedberg 	return NULL;
169530dc78e1SJohan Hedberg }
169630dc78e1SJohan Hedberg 
1697a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
1698a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
1699a3d4e20aSJohan Hedberg {
1700a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1701a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
1702a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
1703a3d4e20aSJohan Hedberg 
1704a3d4e20aSJohan Hedberg 	list_del(&ie->list);
1705a3d4e20aSJohan Hedberg 
1706a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
1707a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
1708a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
1709a3d4e20aSJohan Hedberg 			break;
1710a3d4e20aSJohan Hedberg 		pos = &p->list;
1711a3d4e20aSJohan Hedberg 	}
1712a3d4e20aSJohan Hedberg 
1713a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
1714a3d4e20aSJohan Hedberg }
1715a3d4e20aSJohan Hedberg 
17163175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
1717388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
17181da177e4SLinus Torvalds {
171930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
172070f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
17211da177e4SLinus Torvalds 
17226ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
17231da177e4SLinus Torvalds 
17242b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
17252b2fec4dSSzymon Janc 
1726388fc8faSJohan Hedberg 	if (ssp)
1727388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
1728388fc8faSJohan Hedberg 
172970f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
1730a3d4e20aSJohan Hedberg 	if (ie) {
1731388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
1732388fc8faSJohan Hedberg 			*ssp = true;
1733388fc8faSJohan Hedberg 
1734a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
1735a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
1736a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
1737a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
1738a3d4e20aSJohan Hedberg 		}
1739a3d4e20aSJohan Hedberg 
1740561aafbcSJohan Hedberg 		goto update;
1741a3d4e20aSJohan Hedberg 	}
1742561aafbcSJohan Hedberg 
17431da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
174470f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
174570f23020SAndrei Emeltchenko 	if (!ie)
17463175405bSJohan Hedberg 		return false;
174770f23020SAndrei Emeltchenko 
1748561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
1749561aafbcSJohan Hedberg 
1750561aafbcSJohan Hedberg 	if (name_known) {
1751561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1752561aafbcSJohan Hedberg 	} else {
1753561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
1754561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
1755561aafbcSJohan Hedberg 	}
1756561aafbcSJohan Hedberg 
1757561aafbcSJohan Hedberg update:
1758561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
1759561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
1760561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1761561aafbcSJohan Hedberg 		list_del(&ie->list);
17621da177e4SLinus Torvalds 	}
17631da177e4SLinus Torvalds 
176470f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
176570f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
17661da177e4SLinus Torvalds 	cache->timestamp = jiffies;
17673175405bSJohan Hedberg 
17683175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
17693175405bSJohan Hedberg 		return false;
17703175405bSJohan Hedberg 
17713175405bSJohan Hedberg 	return true;
17721da177e4SLinus Torvalds }
17731da177e4SLinus Torvalds 
17741da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
17751da177e4SLinus Torvalds {
177630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
17771da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
17781da177e4SLinus Torvalds 	struct inquiry_entry *e;
17791da177e4SLinus Torvalds 	int copied = 0;
17801da177e4SLinus Torvalds 
1781561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
17821da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
1783b57c1a56SJohan Hedberg 
1784b57c1a56SJohan Hedberg 		if (copied >= num)
1785b57c1a56SJohan Hedberg 			break;
1786b57c1a56SJohan Hedberg 
17871da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
17881da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
17891da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
17901da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
17911da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
17921da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1793b57c1a56SJohan Hedberg 
17941da177e4SLinus Torvalds 		info++;
1795b57c1a56SJohan Hedberg 		copied++;
17961da177e4SLinus Torvalds 	}
17971da177e4SLinus Torvalds 
17981da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
17991da177e4SLinus Torvalds 	return copied;
18001da177e4SLinus Torvalds }
18011da177e4SLinus Torvalds 
180242c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
18031da177e4SLinus Torvalds {
18041da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
180542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
18061da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
18071da177e4SLinus Torvalds 
18081da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
18091da177e4SLinus Torvalds 
18101da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
18111da177e4SLinus Torvalds 		return;
18121da177e4SLinus Torvalds 
18131da177e4SLinus Torvalds 	/* Start Inquiry */
18141da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
18151da177e4SLinus Torvalds 	cp.length  = ir->length;
18161da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
181742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
18181da177e4SLinus Torvalds }
18191da177e4SLinus Torvalds 
18203e13fa1eSAndre Guedes static int wait_inquiry(void *word)
18213e13fa1eSAndre Guedes {
18223e13fa1eSAndre Guedes 	schedule();
18233e13fa1eSAndre Guedes 	return signal_pending(current);
18243e13fa1eSAndre Guedes }
18253e13fa1eSAndre Guedes 
18261da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
18271da177e4SLinus Torvalds {
18281da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
18291da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
18301da177e4SLinus Torvalds 	struct hci_dev *hdev;
18311da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
18321da177e4SLinus Torvalds 	long timeo;
18331da177e4SLinus Torvalds 	__u8 *buf;
18341da177e4SLinus Torvalds 
18351da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
18361da177e4SLinus Torvalds 		return -EFAULT;
18371da177e4SLinus Torvalds 
18385a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
18395a08ecceSAndrei Emeltchenko 	if (!hdev)
18401da177e4SLinus Torvalds 		return -ENODEV;
18411da177e4SLinus Torvalds 
18420736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
18430736cfa8SMarcel Holtmann 		err = -EBUSY;
18440736cfa8SMarcel Holtmann 		goto done;
18450736cfa8SMarcel Holtmann 	}
18460736cfa8SMarcel Holtmann 
18475b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
18485b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
18495b69bef5SMarcel Holtmann 		goto done;
18505b69bef5SMarcel Holtmann 	}
18515b69bef5SMarcel Holtmann 
185256f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
185356f87901SJohan Hedberg 		err = -EOPNOTSUPP;
185456f87901SJohan Hedberg 		goto done;
185556f87901SJohan Hedberg 	}
185656f87901SJohan Hedberg 
185709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
18581da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1859a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
18601f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
18611da177e4SLinus Torvalds 		do_inquiry = 1;
18621da177e4SLinus Torvalds 	}
186309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
18641da177e4SLinus Torvalds 
186504837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
186670f23020SAndrei Emeltchenko 
186770f23020SAndrei Emeltchenko 	if (do_inquiry) {
186801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
186901178cd4SJohan Hedberg 				   timeo);
187070f23020SAndrei Emeltchenko 		if (err < 0)
18711da177e4SLinus Torvalds 			goto done;
18723e13fa1eSAndre Guedes 
18733e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
18743e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
18753e13fa1eSAndre Guedes 		 */
18763e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
18773e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
18783e13fa1eSAndre Guedes 			return -EINTR;
187970f23020SAndrei Emeltchenko 	}
18801da177e4SLinus Torvalds 
18818fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
18828fc9ced3SGustavo Padovan 	 * 255 entries
18838fc9ced3SGustavo Padovan 	 */
18841da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
18851da177e4SLinus Torvalds 
18861da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
18871da177e4SLinus Torvalds 	 * copy it to the user space.
18881da177e4SLinus Torvalds 	 */
188970f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
189070f23020SAndrei Emeltchenko 	if (!buf) {
18911da177e4SLinus Torvalds 		err = -ENOMEM;
18921da177e4SLinus Torvalds 		goto done;
18931da177e4SLinus Torvalds 	}
18941da177e4SLinus Torvalds 
189509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
18961da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
189709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
18981da177e4SLinus Torvalds 
18991da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
19001da177e4SLinus Torvalds 
19011da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
19021da177e4SLinus Torvalds 		ptr += sizeof(ir);
19031da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
19041da177e4SLinus Torvalds 				 ir.num_rsp))
19051da177e4SLinus Torvalds 			err = -EFAULT;
19061da177e4SLinus Torvalds 	} else
19071da177e4SLinus Torvalds 		err = -EFAULT;
19081da177e4SLinus Torvalds 
19091da177e4SLinus Torvalds 	kfree(buf);
19101da177e4SLinus Torvalds 
19111da177e4SLinus Torvalds done:
19121da177e4SLinus Torvalds 	hci_dev_put(hdev);
19131da177e4SLinus Torvalds 	return err;
19141da177e4SLinus Torvalds }
19151da177e4SLinus Torvalds 
1916cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
19171da177e4SLinus Torvalds {
19181da177e4SLinus Torvalds 	int ret = 0;
19191da177e4SLinus Torvalds 
19201da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
19211da177e4SLinus Torvalds 
19221da177e4SLinus Torvalds 	hci_req_lock(hdev);
19231da177e4SLinus Torvalds 
192494324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
192594324962SJohan Hovold 		ret = -ENODEV;
192694324962SJohan Hovold 		goto done;
192794324962SJohan Hovold 	}
192894324962SJohan Hovold 
1929a5c8f270SMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
1930a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1931a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1932bf543036SJohan Hedberg 		 */
1933a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
1934611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1935611b30f7SMarcel Holtmann 			goto done;
1936611b30f7SMarcel Holtmann 		}
1937611b30f7SMarcel Holtmann 
1938a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1939a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1940a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1941a5c8f270SMarcel Holtmann 		 * or not.
1942a5c8f270SMarcel Holtmann 		 *
1943c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
1944c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
1945c6beca0eSMarcel Holtmann 		 * available.
1946c6beca0eSMarcel Holtmann 		 *
1947a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1948a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1949a5c8f270SMarcel Holtmann 		 */
1950c6beca0eSMarcel Holtmann 		if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
1951c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
1952a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1953a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1954a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1955a5c8f270SMarcel Holtmann 			goto done;
1956a5c8f270SMarcel Holtmann 		}
1957a5c8f270SMarcel Holtmann 	}
1958a5c8f270SMarcel Holtmann 
19591da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
19601da177e4SLinus Torvalds 		ret = -EALREADY;
19611da177e4SLinus Torvalds 		goto done;
19621da177e4SLinus Torvalds 	}
19631da177e4SLinus Torvalds 
19641da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
19651da177e4SLinus Torvalds 		ret = -EIO;
19661da177e4SLinus Torvalds 		goto done;
19671da177e4SLinus Torvalds 	}
19681da177e4SLinus Torvalds 
19691da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
19701da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1971f41c70c4SMarcel Holtmann 
1972f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
1973f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
1974f41c70c4SMarcel Holtmann 
1975f41c70c4SMarcel Holtmann 	if (!ret) {
1976f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1977f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1978f41c70c4SMarcel Holtmann 
19790736cfa8SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags) &&
19800736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
19812177bab5SJohan Hedberg 			ret = __hci_init(hdev);
19821da177e4SLinus Torvalds 	}
19831da177e4SLinus Torvalds 
1984f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1985f41c70c4SMarcel Holtmann 
19861da177e4SLinus Torvalds 	if (!ret) {
19871da177e4SLinus Torvalds 		hci_dev_hold(hdev);
19881da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
19891da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1990bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
19910736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
19921514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
199309fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1994744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
199509fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
199656e5cb86SJohan Hedberg 		}
19971da177e4SLinus Torvalds 	} else {
19981da177e4SLinus Torvalds 		/* Init failed, cleanup */
19993eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
2000c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
2001b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
20021da177e4SLinus Torvalds 
20031da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
20041da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
20051da177e4SLinus Torvalds 
20061da177e4SLinus Torvalds 		if (hdev->flush)
20071da177e4SLinus Torvalds 			hdev->flush(hdev);
20081da177e4SLinus Torvalds 
20091da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
20101da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
20111da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
20121da177e4SLinus Torvalds 		}
20131da177e4SLinus Torvalds 
20141da177e4SLinus Torvalds 		hdev->close(hdev);
20151da177e4SLinus Torvalds 		hdev->flags = 0;
20161da177e4SLinus Torvalds 	}
20171da177e4SLinus Torvalds 
20181da177e4SLinus Torvalds done:
20191da177e4SLinus Torvalds 	hci_req_unlock(hdev);
20201da177e4SLinus Torvalds 	return ret;
20211da177e4SLinus Torvalds }
20221da177e4SLinus Torvalds 
2023cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
2024cbed0ca1SJohan Hedberg 
2025cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
2026cbed0ca1SJohan Hedberg {
2027cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
2028cbed0ca1SJohan Hedberg 	int err;
2029cbed0ca1SJohan Hedberg 
2030cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
2031cbed0ca1SJohan Hedberg 	if (!hdev)
2032cbed0ca1SJohan Hedberg 		return -ENODEV;
2033cbed0ca1SJohan Hedberg 
2034e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
2035e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
2036e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
2037e1d08f40SJohan Hedberg 	 * completed.
2038e1d08f40SJohan Hedberg 	 */
2039e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2040e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
2041e1d08f40SJohan Hedberg 
2042a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
2043a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
2044a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
2045a5c8f270SMarcel Holtmann 	 */
2046e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
2047e1d08f40SJohan Hedberg 
2048cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
2049cbed0ca1SJohan Hedberg 
2050cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
2051cbed0ca1SJohan Hedberg 
2052cbed0ca1SJohan Hedberg 	return err;
2053cbed0ca1SJohan Hedberg }
2054cbed0ca1SJohan Hedberg 
20551da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
20561da177e4SLinus Torvalds {
20571da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
20581da177e4SLinus Torvalds 
205978c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
206078c04c0bSVinicius Costa Gomes 
20611da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
20621da177e4SLinus Torvalds 	hci_req_lock(hdev);
20631da177e4SLinus Torvalds 
20641da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
2065b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
20661da177e4SLinus Torvalds 		hci_req_unlock(hdev);
20671da177e4SLinus Torvalds 		return 0;
20681da177e4SLinus Torvalds 	}
20691da177e4SLinus Torvalds 
20703eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
20713eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
2072b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
20731da177e4SLinus Torvalds 
207416ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
2075e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
207616ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
20775e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
2078310a3d48SMarcel Holtmann 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
207916ab91abSJohan Hedberg 	}
208016ab91abSJohan Hedberg 
2081a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
20827d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
20837d78525dSJohan Hedberg 
20847ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
20857ba8b4beSAndre Guedes 
208609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
20871f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
20881da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
208909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
20901da177e4SLinus Torvalds 
20911da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
20921da177e4SLinus Torvalds 
20931da177e4SLinus Torvalds 	if (hdev->flush)
20941da177e4SLinus Torvalds 		hdev->flush(hdev);
20951da177e4SLinus Torvalds 
20961da177e4SLinus Torvalds 	/* Reset device */
20971da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
20981da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
20998af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
21003a6afbd2SMarcel Holtmann 	    !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
2101a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
21021da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
210301178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
21041da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
21051da177e4SLinus Torvalds 	}
21061da177e4SLinus Torvalds 
2107c347b765SGustavo F. Padovan 	/* flush cmd  work */
2108c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
21091da177e4SLinus Torvalds 
21101da177e4SLinus Torvalds 	/* Drop queues */
21111da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
21121da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
21131da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
21141da177e4SLinus Torvalds 
21151da177e4SLinus Torvalds 	/* Drop last sent command */
21161da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
2117b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
21181da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
21191da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
21201da177e4SLinus Torvalds 	}
21211da177e4SLinus Torvalds 
2122b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
2123b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
2124b6ddb638SJohan Hedberg 
21251da177e4SLinus Torvalds 	/* After this point our queues are empty
21261da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
21271da177e4SLinus Torvalds 	hdev->close(hdev);
21281da177e4SLinus Torvalds 
212935b973c9SJohan Hedberg 	/* Clear flags */
213035b973c9SJohan Hedberg 	hdev->flags = 0;
213135b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
213235b973c9SJohan Hedberg 
213393c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
213493c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
213509fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2136744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
213709fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
21388ee56540SMarcel Holtmann 		}
213993c311a0SMarcel Holtmann 	}
21405add6af8SJohan Hedberg 
2141ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
2142536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
2143ced5c338SAndrei Emeltchenko 
2144e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
214509b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
2146e59fda8dSJohan Hedberg 
21471da177e4SLinus Torvalds 	hci_req_unlock(hdev);
21481da177e4SLinus Torvalds 
21491da177e4SLinus Torvalds 	hci_dev_put(hdev);
21501da177e4SLinus Torvalds 	return 0;
21511da177e4SLinus Torvalds }
21521da177e4SLinus Torvalds 
21531da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
21541da177e4SLinus Torvalds {
21551da177e4SLinus Torvalds 	struct hci_dev *hdev;
21561da177e4SLinus Torvalds 	int err;
21571da177e4SLinus Torvalds 
215870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
215970f23020SAndrei Emeltchenko 	if (!hdev)
21601da177e4SLinus Torvalds 		return -ENODEV;
21618ee56540SMarcel Holtmann 
21620736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
21630736cfa8SMarcel Holtmann 		err = -EBUSY;
21640736cfa8SMarcel Holtmann 		goto done;
21650736cfa8SMarcel Holtmann 	}
21660736cfa8SMarcel Holtmann 
21678ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
21688ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
21698ee56540SMarcel Holtmann 
21701da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
21718ee56540SMarcel Holtmann 
21720736cfa8SMarcel Holtmann done:
21731da177e4SLinus Torvalds 	hci_dev_put(hdev);
21741da177e4SLinus Torvalds 	return err;
21751da177e4SLinus Torvalds }
21761da177e4SLinus Torvalds 
21771da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
21781da177e4SLinus Torvalds {
21791da177e4SLinus Torvalds 	struct hci_dev *hdev;
21801da177e4SLinus Torvalds 	int ret = 0;
21811da177e4SLinus Torvalds 
218270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
218370f23020SAndrei Emeltchenko 	if (!hdev)
21841da177e4SLinus Torvalds 		return -ENODEV;
21851da177e4SLinus Torvalds 
21861da177e4SLinus Torvalds 	hci_req_lock(hdev);
21871da177e4SLinus Torvalds 
2188808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
2189808a049eSMarcel Holtmann 		ret = -ENETDOWN;
21901da177e4SLinus Torvalds 		goto done;
2191808a049eSMarcel Holtmann 	}
21921da177e4SLinus Torvalds 
21930736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
21940736cfa8SMarcel Holtmann 		ret = -EBUSY;
21950736cfa8SMarcel Holtmann 		goto done;
21960736cfa8SMarcel Holtmann 	}
21970736cfa8SMarcel Holtmann 
21981da177e4SLinus Torvalds 	/* Drop queues */
21991da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
22001da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
22011da177e4SLinus Torvalds 
220209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
22031f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
22041da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
220509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
22061da177e4SLinus Torvalds 
22071da177e4SLinus Torvalds 	if (hdev->flush)
22081da177e4SLinus Torvalds 		hdev->flush(hdev);
22091da177e4SLinus Torvalds 
22101da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
22116ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
22121da177e4SLinus Torvalds 
22131da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
221401178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
22151da177e4SLinus Torvalds 
22161da177e4SLinus Torvalds done:
22171da177e4SLinus Torvalds 	hci_req_unlock(hdev);
22181da177e4SLinus Torvalds 	hci_dev_put(hdev);
22191da177e4SLinus Torvalds 	return ret;
22201da177e4SLinus Torvalds }
22211da177e4SLinus Torvalds 
22221da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
22231da177e4SLinus Torvalds {
22241da177e4SLinus Torvalds 	struct hci_dev *hdev;
22251da177e4SLinus Torvalds 	int ret = 0;
22261da177e4SLinus Torvalds 
222770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
222870f23020SAndrei Emeltchenko 	if (!hdev)
22291da177e4SLinus Torvalds 		return -ENODEV;
22301da177e4SLinus Torvalds 
22310736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22320736cfa8SMarcel Holtmann 		ret = -EBUSY;
22330736cfa8SMarcel Holtmann 		goto done;
22340736cfa8SMarcel Holtmann 	}
22350736cfa8SMarcel Holtmann 
22361da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
22371da177e4SLinus Torvalds 
22380736cfa8SMarcel Holtmann done:
22391da177e4SLinus Torvalds 	hci_dev_put(hdev);
22401da177e4SLinus Torvalds 	return ret;
22411da177e4SLinus Torvalds }
22421da177e4SLinus Torvalds 
22431da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
22441da177e4SLinus Torvalds {
22451da177e4SLinus Torvalds 	struct hci_dev *hdev;
22461da177e4SLinus Torvalds 	struct hci_dev_req dr;
22471da177e4SLinus Torvalds 	int err = 0;
22481da177e4SLinus Torvalds 
22491da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
22501da177e4SLinus Torvalds 		return -EFAULT;
22511da177e4SLinus Torvalds 
225270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
225370f23020SAndrei Emeltchenko 	if (!hdev)
22541da177e4SLinus Torvalds 		return -ENODEV;
22551da177e4SLinus Torvalds 
22560736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22570736cfa8SMarcel Holtmann 		err = -EBUSY;
22580736cfa8SMarcel Holtmann 		goto done;
22590736cfa8SMarcel Holtmann 	}
22600736cfa8SMarcel Holtmann 
22615b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
22625b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
22635b69bef5SMarcel Holtmann 		goto done;
22645b69bef5SMarcel Holtmann 	}
22655b69bef5SMarcel Holtmann 
226656f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
226756f87901SJohan Hedberg 		err = -EOPNOTSUPP;
226856f87901SJohan Hedberg 		goto done;
226956f87901SJohan Hedberg 	}
227056f87901SJohan Hedberg 
22711da177e4SLinus Torvalds 	switch (cmd) {
22721da177e4SLinus Torvalds 	case HCISETAUTH:
227301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
22745f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
22751da177e4SLinus Torvalds 		break;
22761da177e4SLinus Torvalds 
22771da177e4SLinus Torvalds 	case HCISETENCRYPT:
22781da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
22791da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
22801da177e4SLinus Torvalds 			break;
22811da177e4SLinus Torvalds 		}
22821da177e4SLinus Torvalds 
22831da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
22841da177e4SLinus Torvalds 			/* Auth must be enabled first */
228501178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
22865f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
22871da177e4SLinus Torvalds 			if (err)
22881da177e4SLinus Torvalds 				break;
22891da177e4SLinus Torvalds 		}
22901da177e4SLinus Torvalds 
229101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
22925f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
22931da177e4SLinus Torvalds 		break;
22941da177e4SLinus Torvalds 
22951da177e4SLinus Torvalds 	case HCISETSCAN:
229601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
22975f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
22981da177e4SLinus Torvalds 		break;
22991da177e4SLinus Torvalds 
23001da177e4SLinus Torvalds 	case HCISETLINKPOL:
230101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
23025f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23031da177e4SLinus Torvalds 		break;
23041da177e4SLinus Torvalds 
23051da177e4SLinus Torvalds 	case HCISETLINKMODE:
2306e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2307e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2308e4e8e37cSMarcel Holtmann 		break;
2309e4e8e37cSMarcel Holtmann 
2310e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2311e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
23121da177e4SLinus Torvalds 		break;
23131da177e4SLinus Torvalds 
23141da177e4SLinus Torvalds 	case HCISETACLMTU:
23151da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
23161da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
23171da177e4SLinus Torvalds 		break;
23181da177e4SLinus Torvalds 
23191da177e4SLinus Torvalds 	case HCISETSCOMTU:
23201da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
23211da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
23221da177e4SLinus Torvalds 		break;
23231da177e4SLinus Torvalds 
23241da177e4SLinus Torvalds 	default:
23251da177e4SLinus Torvalds 		err = -EINVAL;
23261da177e4SLinus Torvalds 		break;
23271da177e4SLinus Torvalds 	}
2328e4e8e37cSMarcel Holtmann 
23290736cfa8SMarcel Holtmann done:
23301da177e4SLinus Torvalds 	hci_dev_put(hdev);
23311da177e4SLinus Torvalds 	return err;
23321da177e4SLinus Torvalds }
23331da177e4SLinus Torvalds 
23341da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
23351da177e4SLinus Torvalds {
23368035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
23371da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
23381da177e4SLinus Torvalds 	struct hci_dev_req *dr;
23391da177e4SLinus Torvalds 	int n = 0, size, err;
23401da177e4SLinus Torvalds 	__u16 dev_num;
23411da177e4SLinus Torvalds 
23421da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
23431da177e4SLinus Torvalds 		return -EFAULT;
23441da177e4SLinus Torvalds 
23451da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
23461da177e4SLinus Torvalds 		return -EINVAL;
23471da177e4SLinus Torvalds 
23481da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
23491da177e4SLinus Torvalds 
235070f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
235170f23020SAndrei Emeltchenko 	if (!dl)
23521da177e4SLinus Torvalds 		return -ENOMEM;
23531da177e4SLinus Torvalds 
23541da177e4SLinus Torvalds 	dr = dl->dev_req;
23551da177e4SLinus Torvalds 
2356f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
23578035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
2358a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2359e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
2360c542a06cSJohan Hedberg 
2361a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2362a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
2363c542a06cSJohan Hedberg 
23641da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
23651da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
2366c542a06cSJohan Hedberg 
23671da177e4SLinus Torvalds 		if (++n >= dev_num)
23681da177e4SLinus Torvalds 			break;
23691da177e4SLinus Torvalds 	}
2370f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
23711da177e4SLinus Torvalds 
23721da177e4SLinus Torvalds 	dl->dev_num = n;
23731da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
23741da177e4SLinus Torvalds 
23751da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
23761da177e4SLinus Torvalds 	kfree(dl);
23771da177e4SLinus Torvalds 
23781da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
23791da177e4SLinus Torvalds }
23801da177e4SLinus Torvalds 
23811da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
23821da177e4SLinus Torvalds {
23831da177e4SLinus Torvalds 	struct hci_dev *hdev;
23841da177e4SLinus Torvalds 	struct hci_dev_info di;
23851da177e4SLinus Torvalds 	int err = 0;
23861da177e4SLinus Torvalds 
23871da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
23881da177e4SLinus Torvalds 		return -EFAULT;
23891da177e4SLinus Torvalds 
239070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
239170f23020SAndrei Emeltchenko 	if (!hdev)
23921da177e4SLinus Torvalds 		return -ENODEV;
23931da177e4SLinus Torvalds 
2394a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
23953243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
2396ab81cbf9SJohan Hedberg 
2397a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2398a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
2399c542a06cSJohan Hedberg 
24001da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
24011da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
240260f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
24031da177e4SLinus Torvalds 	di.flags    = hdev->flags;
24041da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2405572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
24061da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
24071da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
24081da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
24091da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2410572c7f84SJohan Hedberg 	} else {
2411572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2412572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2413572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2414572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2415572c7f84SJohan Hedberg 	}
24161da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
24171da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
24181da177e4SLinus Torvalds 
24191da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
24201da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
24211da177e4SLinus Torvalds 
24221da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
24231da177e4SLinus Torvalds 		err = -EFAULT;
24241da177e4SLinus Torvalds 
24251da177e4SLinus Torvalds 	hci_dev_put(hdev);
24261da177e4SLinus Torvalds 
24271da177e4SLinus Torvalds 	return err;
24281da177e4SLinus Torvalds }
24291da177e4SLinus Torvalds 
24301da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
24311da177e4SLinus Torvalds 
2432611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2433611b30f7SMarcel Holtmann {
2434611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2435611b30f7SMarcel Holtmann 
2436611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2437611b30f7SMarcel Holtmann 
24380736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
24390736cfa8SMarcel Holtmann 		return -EBUSY;
24400736cfa8SMarcel Holtmann 
24415e130367SJohan Hedberg 	if (blocked) {
24425e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
2443bf543036SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags))
2444611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
24455e130367SJohan Hedberg 	} else {
24465e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
24475e130367SJohan Hedberg 	}
2448611b30f7SMarcel Holtmann 
2449611b30f7SMarcel Holtmann 	return 0;
2450611b30f7SMarcel Holtmann }
2451611b30f7SMarcel Holtmann 
2452611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2453611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2454611b30f7SMarcel Holtmann };
2455611b30f7SMarcel Holtmann 
2456ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2457ab81cbf9SJohan Hedberg {
2458ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
245996570ffcSJohan Hedberg 	int err;
2460ab81cbf9SJohan Hedberg 
2461ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2462ab81cbf9SJohan Hedberg 
2463cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
246496570ffcSJohan Hedberg 	if (err < 0) {
246596570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
2466ab81cbf9SJohan Hedberg 		return;
246796570ffcSJohan Hedberg 	}
2468ab81cbf9SJohan Hedberg 
2469a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2470a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2471a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2472a5c8f270SMarcel Holtmann 	 */
2473a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
2474a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
2475a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2476a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2477bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2478bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2479bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
248019202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
248119202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2482bf543036SJohan Hedberg 	}
2483ab81cbf9SJohan Hedberg 
2484a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
2485744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2486ab81cbf9SJohan Hedberg }
2487ab81cbf9SJohan Hedberg 
2488ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2489ab81cbf9SJohan Hedberg {
24903243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
24913243553fSJohan Hedberg 					    power_off.work);
2492ab81cbf9SJohan Hedberg 
2493ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2494ab81cbf9SJohan Hedberg 
24958ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2496ab81cbf9SJohan Hedberg }
2497ab81cbf9SJohan Hedberg 
249816ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
249916ab91abSJohan Hedberg {
250016ab91abSJohan Hedberg 	struct hci_dev *hdev;
250116ab91abSJohan Hedberg 
250216ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
250316ab91abSJohan Hedberg 
250416ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
250516ab91abSJohan Hedberg 
2506d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
250716ab91abSJohan Hedberg }
250816ab91abSJohan Hedberg 
2509*35f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
25102aeb9a1aSJohan Hedberg {
25114821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
25122aeb9a1aSJohan Hedberg 
25134821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
25144821002cSJohan Hedberg 		list_del(&uuid->list);
25152aeb9a1aSJohan Hedberg 		kfree(uuid);
25162aeb9a1aSJohan Hedberg 	}
25172aeb9a1aSJohan Hedberg }
25182aeb9a1aSJohan Hedberg 
2519*35f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
252055ed8ca1SJohan Hedberg {
252155ed8ca1SJohan Hedberg 	struct list_head *p, *n;
252255ed8ca1SJohan Hedberg 
252355ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
252455ed8ca1SJohan Hedberg 		struct link_key *key;
252555ed8ca1SJohan Hedberg 
252655ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
252755ed8ca1SJohan Hedberg 
252855ed8ca1SJohan Hedberg 		list_del(p);
252955ed8ca1SJohan Hedberg 		kfree(key);
253055ed8ca1SJohan Hedberg 	}
253155ed8ca1SJohan Hedberg }
253255ed8ca1SJohan Hedberg 
2533*35f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2534b899efafSVinicius Costa Gomes {
2535b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2536b899efafSVinicius Costa Gomes 
2537b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2538b899efafSVinicius Costa Gomes 		list_del(&k->list);
2539b899efafSVinicius Costa Gomes 		kfree(k);
2540b899efafSVinicius Costa Gomes 	}
2541b899efafSVinicius Costa Gomes }
2542b899efafSVinicius Costa Gomes 
2543970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2544970c4e46SJohan Hedberg {
2545970c4e46SJohan Hedberg 	struct smp_irk *k, *tmp;
2546970c4e46SJohan Hedberg 
2547970c4e46SJohan Hedberg 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
2548970c4e46SJohan Hedberg 		list_del(&k->list);
2549970c4e46SJohan Hedberg 		kfree(k);
2550970c4e46SJohan Hedberg 	}
2551970c4e46SJohan Hedberg }
2552970c4e46SJohan Hedberg 
255355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
255455ed8ca1SJohan Hedberg {
255555ed8ca1SJohan Hedberg 	struct link_key *k;
255655ed8ca1SJohan Hedberg 
25578035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
255855ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
255955ed8ca1SJohan Hedberg 			return k;
256055ed8ca1SJohan Hedberg 
256155ed8ca1SJohan Hedberg 	return NULL;
256255ed8ca1SJohan Hedberg }
256355ed8ca1SJohan Hedberg 
2564745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2565d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2566d25e28abSJohan Hedberg {
2567d25e28abSJohan Hedberg 	/* Legacy key */
2568d25e28abSJohan Hedberg 	if (key_type < 0x03)
2569745c0ce3SVishal Agarwal 		return true;
2570d25e28abSJohan Hedberg 
2571d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2572d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2573745c0ce3SVishal Agarwal 		return false;
2574d25e28abSJohan Hedberg 
2575d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2576d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2577745c0ce3SVishal Agarwal 		return false;
2578d25e28abSJohan Hedberg 
2579d25e28abSJohan Hedberg 	/* Security mode 3 case */
2580d25e28abSJohan Hedberg 	if (!conn)
2581745c0ce3SVishal Agarwal 		return true;
2582d25e28abSJohan Hedberg 
2583d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2584d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2585745c0ce3SVishal Agarwal 		return true;
2586d25e28abSJohan Hedberg 
2587d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2588d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2589745c0ce3SVishal Agarwal 		return true;
2590d25e28abSJohan Hedberg 
2591d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2592d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2593745c0ce3SVishal Agarwal 		return true;
2594d25e28abSJohan Hedberg 
2595d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2596d25e28abSJohan Hedberg 	 * persistently */
2597745c0ce3SVishal Agarwal 	return false;
2598d25e28abSJohan Hedberg }
2599d25e28abSJohan Hedberg 
260098a0b845SJohan Hedberg static bool ltk_type_master(u8 type)
260198a0b845SJohan Hedberg {
260298a0b845SJohan Hedberg 	if (type == HCI_SMP_STK || type == HCI_SMP_LTK)
260398a0b845SJohan Hedberg 		return true;
260498a0b845SJohan Hedberg 
260598a0b845SJohan Hedberg 	return false;
260698a0b845SJohan Hedberg }
260798a0b845SJohan Hedberg 
260898a0b845SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8],
260998a0b845SJohan Hedberg 			     bool master)
261075d262c2SVinicius Costa Gomes {
2611c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
261275d262c2SVinicius Costa Gomes 
2613c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
2614c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
2615c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
261675d262c2SVinicius Costa Gomes 			continue;
261775d262c2SVinicius Costa Gomes 
261898a0b845SJohan Hedberg 		if (ltk_type_master(k->type) != master)
261998a0b845SJohan Hedberg 			continue;
262098a0b845SJohan Hedberg 
262175d262c2SVinicius Costa Gomes 		return k;
262275d262c2SVinicius Costa Gomes 	}
262375d262c2SVinicius Costa Gomes 
262475d262c2SVinicius Costa Gomes 	return NULL;
262575d262c2SVinicius Costa Gomes }
262675d262c2SVinicius Costa Gomes 
2627c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
262898a0b845SJohan Hedberg 				     u8 addr_type, bool master)
262975d262c2SVinicius Costa Gomes {
2630c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
263175d262c2SVinicius Costa Gomes 
2632c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
2633c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
263498a0b845SJohan Hedberg 		    bacmp(bdaddr, &k->bdaddr) == 0 &&
263598a0b845SJohan Hedberg 		    ltk_type_master(k->type) == master)
263675d262c2SVinicius Costa Gomes 			return k;
263775d262c2SVinicius Costa Gomes 
263875d262c2SVinicius Costa Gomes 	return NULL;
263975d262c2SVinicius Costa Gomes }
264075d262c2SVinicius Costa Gomes 
2641970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2642970c4e46SJohan Hedberg {
2643970c4e46SJohan Hedberg 	struct smp_irk *irk;
2644970c4e46SJohan Hedberg 
2645970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2646970c4e46SJohan Hedberg 		if (!bacmp(&irk->rpa, rpa))
2647970c4e46SJohan Hedberg 			return irk;
2648970c4e46SJohan Hedberg 	}
2649970c4e46SJohan Hedberg 
2650970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2651970c4e46SJohan Hedberg 		if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) {
2652970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
2653970c4e46SJohan Hedberg 			return irk;
2654970c4e46SJohan Hedberg 		}
2655970c4e46SJohan Hedberg 	}
2656970c4e46SJohan Hedberg 
2657970c4e46SJohan Hedberg 	return NULL;
2658970c4e46SJohan Hedberg }
2659970c4e46SJohan Hedberg 
2660970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2661970c4e46SJohan Hedberg 				     u8 addr_type)
2662970c4e46SJohan Hedberg {
2663970c4e46SJohan Hedberg 	struct smp_irk *irk;
2664970c4e46SJohan Hedberg 
2665970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2666970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
2667970c4e46SJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0)
2668970c4e46SJohan Hedberg 			return irk;
2669970c4e46SJohan Hedberg 	}
2670970c4e46SJohan Hedberg 
2671970c4e46SJohan Hedberg 	return NULL;
2672970c4e46SJohan Hedberg }
2673970c4e46SJohan Hedberg 
2674d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
2675d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
267655ed8ca1SJohan Hedberg {
267755ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2678745c0ce3SVishal Agarwal 	u8 old_key_type;
2679745c0ce3SVishal Agarwal 	bool persistent;
268055ed8ca1SJohan Hedberg 
268155ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
268255ed8ca1SJohan Hedberg 	if (old_key) {
268355ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
268455ed8ca1SJohan Hedberg 		key = old_key;
268555ed8ca1SJohan Hedberg 	} else {
268612adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
268755ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
268855ed8ca1SJohan Hedberg 		if (!key)
268955ed8ca1SJohan Hedberg 			return -ENOMEM;
269055ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
269155ed8ca1SJohan Hedberg 	}
269255ed8ca1SJohan Hedberg 
26936ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
269455ed8ca1SJohan Hedberg 
2695d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2696d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2697d25e28abSJohan Hedberg 	 * previous key */
2698d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2699a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2700d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2701655fe6ecSJohan Hedberg 		if (conn)
2702655fe6ecSJohan Hedberg 			conn->key_type = type;
2703655fe6ecSJohan Hedberg 	}
2704d25e28abSJohan Hedberg 
270555ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
27069b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
270755ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
270855ed8ca1SJohan Hedberg 
2709b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
271055ed8ca1SJohan Hedberg 		key->type = old_key_type;
27114748fed2SJohan Hedberg 	else
27124748fed2SJohan Hedberg 		key->type = type;
27134748fed2SJohan Hedberg 
27144df378a1SJohan Hedberg 	if (!new_key)
27154df378a1SJohan Hedberg 		return 0;
27164df378a1SJohan Hedberg 
27174df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
27184df378a1SJohan Hedberg 
2719744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
27204df378a1SJohan Hedberg 
27216ec5bcadSVishal Agarwal 	if (conn)
27226ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
272355ed8ca1SJohan Hedberg 
272455ed8ca1SJohan Hedberg 	return 0;
272555ed8ca1SJohan Hedberg }
272655ed8ca1SJohan Hedberg 
2727c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
27289a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
272904124681SGustavo F. Padovan 		ediv, u8 rand[8])
273075d262c2SVinicius Costa Gomes {
2731c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
273298a0b845SJohan Hedberg 	bool master = ltk_type_master(type);
27330fe442ffSMarcel Holtmann 	u8 persistent;
273475d262c2SVinicius Costa Gomes 
273598a0b845SJohan Hedberg 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master);
2736c9839a11SVinicius Costa Gomes 	if (old_key)
273775d262c2SVinicius Costa Gomes 		key = old_key;
2738c9839a11SVinicius Costa Gomes 	else {
2739c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
274075d262c2SVinicius Costa Gomes 		if (!key)
274175d262c2SVinicius Costa Gomes 			return -ENOMEM;
2742c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
274375d262c2SVinicius Costa Gomes 	}
274475d262c2SVinicius Costa Gomes 
274575d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2746c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2747c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2748c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2749c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2750c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2751c9839a11SVinicius Costa Gomes 	key->type = type;
2752c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
275375d262c2SVinicius Costa Gomes 
2754c9839a11SVinicius Costa Gomes 	if (!new_key)
2755c9839a11SVinicius Costa Gomes 		return 0;
275675d262c2SVinicius Costa Gomes 
27570fe442ffSMarcel Holtmann 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
27580fe442ffSMarcel Holtmann 		persistent = 0;
27590fe442ffSMarcel Holtmann 	else
27600fe442ffSMarcel Holtmann 		persistent = 1;
27610fe442ffSMarcel Holtmann 
276221b93b75SJohan Hedberg 	if (type == HCI_SMP_LTK || type == HCI_SMP_LTK_SLAVE)
27630fe442ffSMarcel Holtmann 		mgmt_new_ltk(hdev, key, persistent);
2764261cc5aaSVinicius Costa Gomes 
276575d262c2SVinicius Costa Gomes 	return 0;
276675d262c2SVinicius Costa Gomes }
276775d262c2SVinicius Costa Gomes 
2768970c4e46SJohan Hedberg int hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type,
2769970c4e46SJohan Hedberg 		u8 val[16], bdaddr_t *rpa)
2770970c4e46SJohan Hedberg {
2771970c4e46SJohan Hedberg 	struct smp_irk *irk;
2772970c4e46SJohan Hedberg 
2773970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2774970c4e46SJohan Hedberg 	if (!irk) {
2775970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
2776970c4e46SJohan Hedberg 		if (!irk)
2777970c4e46SJohan Hedberg 			return -ENOMEM;
2778970c4e46SJohan Hedberg 
2779970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
2780970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
2781970c4e46SJohan Hedberg 
2782970c4e46SJohan Hedberg 		list_add(&irk->list, &hdev->identity_resolving_keys);
2783970c4e46SJohan Hedberg 	}
2784970c4e46SJohan Hedberg 
2785970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
2786970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
2787970c4e46SJohan Hedberg 
2788970c4e46SJohan Hedberg 	return 0;
2789970c4e46SJohan Hedberg }
2790970c4e46SJohan Hedberg 
279155ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
279255ed8ca1SJohan Hedberg {
279355ed8ca1SJohan Hedberg 	struct link_key *key;
279455ed8ca1SJohan Hedberg 
279555ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
279655ed8ca1SJohan Hedberg 	if (!key)
279755ed8ca1SJohan Hedberg 		return -ENOENT;
279855ed8ca1SJohan Hedberg 
27996ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
280055ed8ca1SJohan Hedberg 
280155ed8ca1SJohan Hedberg 	list_del(&key->list);
280255ed8ca1SJohan Hedberg 	kfree(key);
280355ed8ca1SJohan Hedberg 
280455ed8ca1SJohan Hedberg 	return 0;
280555ed8ca1SJohan Hedberg }
280655ed8ca1SJohan Hedberg 
2807e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2808b899efafSVinicius Costa Gomes {
2809b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2810b899efafSVinicius Costa Gomes 
2811b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2812e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2813b899efafSVinicius Costa Gomes 			continue;
2814b899efafSVinicius Costa Gomes 
28156ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2816b899efafSVinicius Costa Gomes 
2817b899efafSVinicius Costa Gomes 		list_del(&k->list);
2818b899efafSVinicius Costa Gomes 		kfree(k);
2819b899efafSVinicius Costa Gomes 	}
2820b899efafSVinicius Costa Gomes 
2821b899efafSVinicius Costa Gomes 	return 0;
2822b899efafSVinicius Costa Gomes }
2823b899efafSVinicius Costa Gomes 
28246bd32326SVille Tervo /* HCI command timer function */
2825bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
28266bd32326SVille Tervo {
28276bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
28286bd32326SVille Tervo 
2829bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2830bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2831bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2832bda4f23aSAndrei Emeltchenko 
2833bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
2834bda4f23aSAndrei Emeltchenko 	} else {
28356bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
2836bda4f23aSAndrei Emeltchenko 	}
2837bda4f23aSAndrei Emeltchenko 
28386bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2839c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
28406bd32326SVille Tervo }
28416bd32326SVille Tervo 
28422763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
28432763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
28442763eda6SSzymon Janc {
28452763eda6SSzymon Janc 	struct oob_data *data;
28462763eda6SSzymon Janc 
28472763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
28482763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
28492763eda6SSzymon Janc 			return data;
28502763eda6SSzymon Janc 
28512763eda6SSzymon Janc 	return NULL;
28522763eda6SSzymon Janc }
28532763eda6SSzymon Janc 
28542763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
28552763eda6SSzymon Janc {
28562763eda6SSzymon Janc 	struct oob_data *data;
28572763eda6SSzymon Janc 
28582763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
28592763eda6SSzymon Janc 	if (!data)
28602763eda6SSzymon Janc 		return -ENOENT;
28612763eda6SSzymon Janc 
28626ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
28632763eda6SSzymon Janc 
28642763eda6SSzymon Janc 	list_del(&data->list);
28652763eda6SSzymon Janc 	kfree(data);
28662763eda6SSzymon Janc 
28672763eda6SSzymon Janc 	return 0;
28682763eda6SSzymon Janc }
28692763eda6SSzymon Janc 
2870*35f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
28712763eda6SSzymon Janc {
28722763eda6SSzymon Janc 	struct oob_data *data, *n;
28732763eda6SSzymon Janc 
28742763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
28752763eda6SSzymon Janc 		list_del(&data->list);
28762763eda6SSzymon Janc 		kfree(data);
28772763eda6SSzymon Janc 	}
28782763eda6SSzymon Janc }
28792763eda6SSzymon Janc 
28800798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
28810798872eSMarcel Holtmann 			    u8 *hash, u8 *randomizer)
28822763eda6SSzymon Janc {
28832763eda6SSzymon Janc 	struct oob_data *data;
28842763eda6SSzymon Janc 
28852763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
28862763eda6SSzymon Janc 	if (!data) {
28870798872eSMarcel Holtmann 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
28882763eda6SSzymon Janc 		if (!data)
28892763eda6SSzymon Janc 			return -ENOMEM;
28902763eda6SSzymon Janc 
28912763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
28922763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
28932763eda6SSzymon Janc 	}
28942763eda6SSzymon Janc 
2895519ca9d0SMarcel Holtmann 	memcpy(data->hash192, hash, sizeof(data->hash192));
2896519ca9d0SMarcel Holtmann 	memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
28972763eda6SSzymon Janc 
28980798872eSMarcel Holtmann 	memset(data->hash256, 0, sizeof(data->hash256));
28990798872eSMarcel Holtmann 	memset(data->randomizer256, 0, sizeof(data->randomizer256));
29000798872eSMarcel Holtmann 
29010798872eSMarcel Holtmann 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
29020798872eSMarcel Holtmann 
29030798872eSMarcel Holtmann 	return 0;
29040798872eSMarcel Holtmann }
29050798872eSMarcel Holtmann 
29060798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
29070798872eSMarcel Holtmann 				u8 *hash192, u8 *randomizer192,
29080798872eSMarcel Holtmann 				u8 *hash256, u8 *randomizer256)
29090798872eSMarcel Holtmann {
29100798872eSMarcel Holtmann 	struct oob_data *data;
29110798872eSMarcel Holtmann 
29120798872eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, bdaddr);
29130798872eSMarcel Holtmann 	if (!data) {
29140798872eSMarcel Holtmann 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
29150798872eSMarcel Holtmann 		if (!data)
29160798872eSMarcel Holtmann 			return -ENOMEM;
29170798872eSMarcel Holtmann 
29180798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
29190798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
29200798872eSMarcel Holtmann 	}
29210798872eSMarcel Holtmann 
29220798872eSMarcel Holtmann 	memcpy(data->hash192, hash192, sizeof(data->hash192));
29230798872eSMarcel Holtmann 	memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192));
29240798872eSMarcel Holtmann 
29250798872eSMarcel Holtmann 	memcpy(data->hash256, hash256, sizeof(data->hash256));
29260798872eSMarcel Holtmann 	memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256));
29270798872eSMarcel Holtmann 
29286ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
29292763eda6SSzymon Janc 
29302763eda6SSzymon Janc 	return 0;
29312763eda6SSzymon Janc }
29322763eda6SSzymon Janc 
2933b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
2934b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
2935b2a66aadSAntti Julku {
2936b2a66aadSAntti Julku 	struct bdaddr_list *b;
2937b2a66aadSAntti Julku 
2938b9ee0a78SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list) {
2939b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2940b2a66aadSAntti Julku 			return b;
2941b9ee0a78SMarcel Holtmann 	}
2942b2a66aadSAntti Julku 
2943b2a66aadSAntti Julku 	return NULL;
2944b2a66aadSAntti Julku }
2945b2a66aadSAntti Julku 
2946*35f7498aSJohan Hedberg void hci_blacklist_clear(struct hci_dev *hdev)
2947b2a66aadSAntti Julku {
2948b2a66aadSAntti Julku 	struct list_head *p, *n;
2949b2a66aadSAntti Julku 
2950b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
2951b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
2952b2a66aadSAntti Julku 
2953b2a66aadSAntti Julku 		list_del(p);
2954b2a66aadSAntti Julku 		kfree(b);
2955b2a66aadSAntti Julku 	}
2956b2a66aadSAntti Julku }
2957b2a66aadSAntti Julku 
295888c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2959b2a66aadSAntti Julku {
2960b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2961b2a66aadSAntti Julku 
2962b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
2963b2a66aadSAntti Julku 		return -EBADF;
2964b2a66aadSAntti Julku 
2965b9ee0a78SMarcel Holtmann 	if (hci_blacklist_lookup(hdev, bdaddr, type))
29665e762444SAntti Julku 		return -EEXIST;
2967b2a66aadSAntti Julku 
2968b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
29695e762444SAntti Julku 	if (!entry)
29705e762444SAntti Julku 		return -ENOMEM;
2971b2a66aadSAntti Julku 
2972b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2973b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
2974b2a66aadSAntti Julku 
2975b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
2976b2a66aadSAntti Julku 
297788c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
2978b2a66aadSAntti Julku }
2979b2a66aadSAntti Julku 
298088c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2981b2a66aadSAntti Julku {
2982b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2983b2a66aadSAntti Julku 
2984*35f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2985*35f7498aSJohan Hedberg 		hci_blacklist_clear(hdev);
2986*35f7498aSJohan Hedberg 		return 0;
2987*35f7498aSJohan Hedberg 	}
2988b2a66aadSAntti Julku 
2989b9ee0a78SMarcel Holtmann 	entry = hci_blacklist_lookup(hdev, bdaddr, type);
29901ec918ceSSzymon Janc 	if (!entry)
29915e762444SAntti Julku 		return -ENOENT;
2992b2a66aadSAntti Julku 
2993b2a66aadSAntti Julku 	list_del(&entry->list);
2994b2a66aadSAntti Julku 	kfree(entry);
2995b2a66aadSAntti Julku 
299688c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
2997b2a66aadSAntti Julku }
2998b2a66aadSAntti Julku 
299915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
300015819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
300115819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
300215819a70SAndre Guedes {
300315819a70SAndre Guedes 	struct hci_conn_params *params;
300415819a70SAndre Guedes 
300515819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
300615819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
300715819a70SAndre Guedes 		    params->addr_type == addr_type) {
300815819a70SAndre Guedes 			return params;
300915819a70SAndre Guedes 		}
301015819a70SAndre Guedes 	}
301115819a70SAndre Guedes 
301215819a70SAndre Guedes 	return NULL;
301315819a70SAndre Guedes }
301415819a70SAndre Guedes 
301515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
301615819a70SAndre Guedes void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
301715819a70SAndre Guedes 			 u16 conn_min_interval, u16 conn_max_interval)
301815819a70SAndre Guedes {
301915819a70SAndre Guedes 	struct hci_conn_params *params;
302015819a70SAndre Guedes 
302115819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
302215819a70SAndre Guedes 	if (params) {
302315819a70SAndre Guedes 		params->conn_min_interval = conn_min_interval;
302415819a70SAndre Guedes 		params->conn_max_interval = conn_max_interval;
302515819a70SAndre Guedes 		return;
302615819a70SAndre Guedes 	}
302715819a70SAndre Guedes 
302815819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
302915819a70SAndre Guedes 	if (!params) {
303015819a70SAndre Guedes 		BT_ERR("Out of memory");
303115819a70SAndre Guedes 		return;
303215819a70SAndre Guedes 	}
303315819a70SAndre Guedes 
303415819a70SAndre Guedes 	bacpy(&params->addr, addr);
303515819a70SAndre Guedes 	params->addr_type = addr_type;
303615819a70SAndre Guedes 	params->conn_min_interval = conn_min_interval;
303715819a70SAndre Guedes 	params->conn_max_interval = conn_max_interval;
303815819a70SAndre Guedes 
303915819a70SAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
304015819a70SAndre Guedes 
304115819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u) conn_min_interval 0x%.4x "
304215819a70SAndre Guedes 	       "conn_max_interval 0x%.4x", addr, addr_type, conn_min_interval,
304315819a70SAndre Guedes 	       conn_max_interval);
304415819a70SAndre Guedes }
304515819a70SAndre Guedes 
304615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
304715819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
304815819a70SAndre Guedes {
304915819a70SAndre Guedes 	struct hci_conn_params *params;
305015819a70SAndre Guedes 
305115819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
305215819a70SAndre Guedes 	if (!params)
305315819a70SAndre Guedes 		return;
305415819a70SAndre Guedes 
305515819a70SAndre Guedes 	list_del(&params->list);
305615819a70SAndre Guedes 	kfree(params);
305715819a70SAndre Guedes 
305815819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
305915819a70SAndre Guedes }
306015819a70SAndre Guedes 
306115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
306215819a70SAndre Guedes void hci_conn_params_clear(struct hci_dev *hdev)
306315819a70SAndre Guedes {
306415819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
306515819a70SAndre Guedes 
306615819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
306715819a70SAndre Guedes 		list_del(&params->list);
306815819a70SAndre Guedes 		kfree(params);
306915819a70SAndre Guedes 	}
307015819a70SAndre Guedes 
307115819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
307215819a70SAndre Guedes }
307315819a70SAndre Guedes 
30744c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
30757ba8b4beSAndre Guedes {
30764c87eaabSAndre Guedes 	if (status) {
30774c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
30787ba8b4beSAndre Guedes 
30794c87eaabSAndre Guedes 		hci_dev_lock(hdev);
30804c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
30814c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
30824c87eaabSAndre Guedes 		return;
30834c87eaabSAndre Guedes 	}
30847ba8b4beSAndre Guedes }
30857ba8b4beSAndre Guedes 
30864c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
30877ba8b4beSAndre Guedes {
30884c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
30894c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
30904c87eaabSAndre Guedes 	struct hci_request req;
30914c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
30927ba8b4beSAndre Guedes 	int err;
30937ba8b4beSAndre Guedes 
30944c87eaabSAndre Guedes 	if (status) {
30954c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
30964c87eaabSAndre Guedes 		return;
30977ba8b4beSAndre Guedes 	}
30987ba8b4beSAndre Guedes 
30994c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
31004c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
31014c87eaabSAndre Guedes 		hci_dev_lock(hdev);
31024c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
31034c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
31044c87eaabSAndre Guedes 		break;
31057dbfac1dSAndre Guedes 
31064c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
31074c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
31087dbfac1dSAndre Guedes 
31097dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
31104c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
31114c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
31124c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
31134c87eaabSAndre Guedes 
31144c87eaabSAndre Guedes 		hci_dev_lock(hdev);
31154c87eaabSAndre Guedes 
31164c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
31174c87eaabSAndre Guedes 
31184c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
31194c87eaabSAndre Guedes 		if (err) {
31204c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
31214c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
31227dbfac1dSAndre Guedes 		}
31237dbfac1dSAndre Guedes 
31244c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
31254c87eaabSAndre Guedes 		break;
31264c87eaabSAndre Guedes 	}
31277dbfac1dSAndre Guedes }
31287dbfac1dSAndre Guedes 
31297ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
31307ba8b4beSAndre Guedes {
31317ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
31327ba8b4beSAndre Guedes 					    le_scan_disable.work);
31337ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
31344c87eaabSAndre Guedes 	struct hci_request req;
31354c87eaabSAndre Guedes 	int err;
31367ba8b4beSAndre Guedes 
31377ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
31387ba8b4beSAndre Guedes 
31394c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
31407ba8b4beSAndre Guedes 
31417ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
31424c87eaabSAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
31434c87eaabSAndre Guedes 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
31447ba8b4beSAndre Guedes 
31454c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
31464c87eaabSAndre Guedes 	if (err)
31474c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
314828b75a89SAndre Guedes }
314928b75a89SAndre Guedes 
31509be0dab7SDavid Herrmann /* Alloc HCI device */
31519be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
31529be0dab7SDavid Herrmann {
31539be0dab7SDavid Herrmann 	struct hci_dev *hdev;
31549be0dab7SDavid Herrmann 
31559be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
31569be0dab7SDavid Herrmann 	if (!hdev)
31579be0dab7SDavid Herrmann 		return NULL;
31589be0dab7SDavid Herrmann 
3159b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3160b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3161b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3162b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3163b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
3164bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3165bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3166b1b813d4SDavid Herrmann 
3167b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3168b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3169b1b813d4SDavid Herrmann 
3170bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3171bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
31724e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
31734e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
3174bef64738SMarcel Holtmann 
3175b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3176b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3177b1b813d4SDavid Herrmann 
3178b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3179b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
3180b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3181b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3182b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3183970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3184b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
318515819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
31866b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3187b1b813d4SDavid Herrmann 
3188b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3189b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3190b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3191b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3192b1b813d4SDavid Herrmann 
3193b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3194b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
3195b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
3196b1b813d4SDavid Herrmann 
3197b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3198b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3199b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3200b1b813d4SDavid Herrmann 
3201b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
3202b1b813d4SDavid Herrmann 
3203bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
3204b1b813d4SDavid Herrmann 
3205b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3206b1b813d4SDavid Herrmann 	discovery_init(hdev);
32079be0dab7SDavid Herrmann 
32089be0dab7SDavid Herrmann 	return hdev;
32099be0dab7SDavid Herrmann }
32109be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
32119be0dab7SDavid Herrmann 
32129be0dab7SDavid Herrmann /* Free HCI device */
32139be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
32149be0dab7SDavid Herrmann {
32159be0dab7SDavid Herrmann 	/* will free via device release */
32169be0dab7SDavid Herrmann 	put_device(&hdev->dev);
32179be0dab7SDavid Herrmann }
32189be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
32199be0dab7SDavid Herrmann 
32201da177e4SLinus Torvalds /* Register HCI device */
32211da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
32221da177e4SLinus Torvalds {
3223b1b813d4SDavid Herrmann 	int id, error;
32241da177e4SLinus Torvalds 
3225010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
32261da177e4SLinus Torvalds 		return -EINVAL;
32271da177e4SLinus Torvalds 
322808add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
322908add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
323008add513SMat Martineau 	 */
32313df92b31SSasha Levin 	switch (hdev->dev_type) {
32323df92b31SSasha Levin 	case HCI_BREDR:
32333df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
32341da177e4SLinus Torvalds 		break;
32353df92b31SSasha Levin 	case HCI_AMP:
32363df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
32373df92b31SSasha Levin 		break;
32383df92b31SSasha Levin 	default:
32393df92b31SSasha Levin 		return -EINVAL;
32401da177e4SLinus Torvalds 	}
32411da177e4SLinus Torvalds 
32423df92b31SSasha Levin 	if (id < 0)
32433df92b31SSasha Levin 		return id;
32443df92b31SSasha Levin 
32451da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
32461da177e4SLinus Torvalds 	hdev->id = id;
32472d8b3a11SAndrei Emeltchenko 
32482d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
32492d8b3a11SAndrei Emeltchenko 
3250d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3251d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
325233ca954dSDavid Herrmann 	if (!hdev->workqueue) {
325333ca954dSDavid Herrmann 		error = -ENOMEM;
325433ca954dSDavid Herrmann 		goto err;
325533ca954dSDavid Herrmann 	}
3256f48fd9c8SMarcel Holtmann 
3257d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3258d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
32596ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
32606ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
32616ead1bbcSJohan Hedberg 		error = -ENOMEM;
32626ead1bbcSJohan Hedberg 		goto err;
32636ead1bbcSJohan Hedberg 	}
32646ead1bbcSJohan Hedberg 
32650153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
32660153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
32670153e2ecSMarcel Holtmann 
3268bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3269bdc3e0f1SMarcel Holtmann 
327099780a7bSJohan Hedberg 	hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0,
327199780a7bSJohan Hedberg 					       CRYPTO_ALG_ASYNC);
327299780a7bSJohan Hedberg 	if (IS_ERR(hdev->tfm_aes)) {
327399780a7bSJohan Hedberg 		BT_ERR("Unable to create crypto context");
327499780a7bSJohan Hedberg 		error = PTR_ERR(hdev->tfm_aes);
327599780a7bSJohan Hedberg 		hdev->tfm_aes = NULL;
327699780a7bSJohan Hedberg 		goto err_wqueue;
327799780a7bSJohan Hedberg 	}
327899780a7bSJohan Hedberg 
3279bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
328033ca954dSDavid Herrmann 	if (error < 0)
328199780a7bSJohan Hedberg 		goto err_tfm;
32821da177e4SLinus Torvalds 
3283611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3284a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3285a8c5fb1aSGustavo Padovan 				    hdev);
3286611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3287611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3288611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3289611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3290611b30f7SMarcel Holtmann 		}
3291611b30f7SMarcel Holtmann 	}
3292611b30f7SMarcel Holtmann 
32935e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
32945e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
32955e130367SJohan Hedberg 
3296a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
3297004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
3298ce2be9acSAndrei Emeltchenko 
329901cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
330056f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
330156f87901SJohan Hedberg 		 * through reading supported features during init.
330256f87901SJohan Hedberg 		 */
330356f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
330456f87901SJohan Hedberg 	}
3305ce2be9acSAndrei Emeltchenko 
3306fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3307fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3308fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3309fcee3377SGustavo Padovan 
33101da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
3311dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
33121da177e4SLinus Torvalds 
331319202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3314fbe96d6fSMarcel Holtmann 
33151da177e4SLinus Torvalds 	return id;
3316f48fd9c8SMarcel Holtmann 
331799780a7bSJohan Hedberg err_tfm:
331899780a7bSJohan Hedberg 	crypto_free_blkcipher(hdev->tfm_aes);
331933ca954dSDavid Herrmann err_wqueue:
332033ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
33216ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
332233ca954dSDavid Herrmann err:
33233df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
3324f48fd9c8SMarcel Holtmann 
332533ca954dSDavid Herrmann 	return error;
33261da177e4SLinus Torvalds }
33271da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
33281da177e4SLinus Torvalds 
33291da177e4SLinus Torvalds /* Unregister HCI device */
333059735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
33311da177e4SLinus Torvalds {
33323df92b31SSasha Levin 	int i, id;
3333ef222013SMarcel Holtmann 
3334c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
33351da177e4SLinus Torvalds 
333694324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
333794324962SJohan Hovold 
33383df92b31SSasha Levin 	id = hdev->id;
33393df92b31SSasha Levin 
3340f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
33411da177e4SLinus Torvalds 	list_del(&hdev->list);
3342f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
33431da177e4SLinus Torvalds 
33441da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
33451da177e4SLinus Torvalds 
3346cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
3347ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
3348ef222013SMarcel Holtmann 
3349b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
3350b9b5ef18SGustavo Padovan 
3351ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
3352a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
335309fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
3354744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
335509fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
335656e5cb86SJohan Hedberg 	}
3357ab81cbf9SJohan Hedberg 
33582e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
33592e58ef3eSJohan Hedberg 	 * pending list */
33602e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
33612e58ef3eSJohan Hedberg 
33621da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
33631da177e4SLinus Torvalds 
3364611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3365611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
3366611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
3367611b30f7SMarcel Holtmann 	}
3368611b30f7SMarcel Holtmann 
336999780a7bSJohan Hedberg 	if (hdev->tfm_aes)
337099780a7bSJohan Hedberg 		crypto_free_blkcipher(hdev->tfm_aes);
337199780a7bSJohan Hedberg 
3372bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
3373147e2d59SDave Young 
33740153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
33750153e2ecSMarcel Holtmann 
3376f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
33776ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
3378f48fd9c8SMarcel Holtmann 
337909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
3380e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
33812aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
338255ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
3383b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
3384970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
33852763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
338615819a70SAndre Guedes 	hci_conn_params_clear(hdev);
338709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
3388e2e0cacbSJohan Hedberg 
3389dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
33903df92b31SSasha Levin 
33913df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
33921da177e4SLinus Torvalds }
33931da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
33941da177e4SLinus Torvalds 
33951da177e4SLinus Torvalds /* Suspend HCI device */
33961da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
33971da177e4SLinus Torvalds {
33981da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
33991da177e4SLinus Torvalds 	return 0;
34001da177e4SLinus Torvalds }
34011da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
34021da177e4SLinus Torvalds 
34031da177e4SLinus Torvalds /* Resume HCI device */
34041da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
34051da177e4SLinus Torvalds {
34061da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
34071da177e4SLinus Torvalds 	return 0;
34081da177e4SLinus Torvalds }
34091da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
34101da177e4SLinus Torvalds 
341176bca880SMarcel Holtmann /* Receive frame from HCI drivers */
3412e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
341376bca880SMarcel Holtmann {
341476bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
341576bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
341676bca880SMarcel Holtmann 		kfree_skb(skb);
341776bca880SMarcel Holtmann 		return -ENXIO;
341876bca880SMarcel Holtmann 	}
341976bca880SMarcel Holtmann 
3420d82603c6SJorrit Schippers 	/* Incoming skb */
342176bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
342276bca880SMarcel Holtmann 
342376bca880SMarcel Holtmann 	/* Time stamp */
342476bca880SMarcel Holtmann 	__net_timestamp(skb);
342576bca880SMarcel Holtmann 
342676bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3427b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3428c78ae283SMarcel Holtmann 
342976bca880SMarcel Holtmann 	return 0;
343076bca880SMarcel Holtmann }
343176bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
343276bca880SMarcel Holtmann 
343333e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
34341e429f38SGustavo F. Padovan 			  int count, __u8 index)
343533e882a5SSuraj Sumangala {
343633e882a5SSuraj Sumangala 	int len = 0;
343733e882a5SSuraj Sumangala 	int hlen = 0;
343833e882a5SSuraj Sumangala 	int remain = count;
343933e882a5SSuraj Sumangala 	struct sk_buff *skb;
344033e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
344133e882a5SSuraj Sumangala 
344233e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
344333e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
344433e882a5SSuraj Sumangala 		return -EILSEQ;
344533e882a5SSuraj Sumangala 
344633e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
344733e882a5SSuraj Sumangala 
344833e882a5SSuraj Sumangala 	if (!skb) {
344933e882a5SSuraj Sumangala 		switch (type) {
345033e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
345133e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
345233e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
345333e882a5SSuraj Sumangala 			break;
345433e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
345533e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
345633e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
345733e882a5SSuraj Sumangala 			break;
345833e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
345933e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
346033e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
346133e882a5SSuraj Sumangala 			break;
346233e882a5SSuraj Sumangala 		}
346333e882a5SSuraj Sumangala 
34641e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
346533e882a5SSuraj Sumangala 		if (!skb)
346633e882a5SSuraj Sumangala 			return -ENOMEM;
346733e882a5SSuraj Sumangala 
346833e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
346933e882a5SSuraj Sumangala 		scb->expect = hlen;
347033e882a5SSuraj Sumangala 		scb->pkt_type = type;
347133e882a5SSuraj Sumangala 
347233e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
347333e882a5SSuraj Sumangala 	}
347433e882a5SSuraj Sumangala 
347533e882a5SSuraj Sumangala 	while (count) {
347633e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
347789bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
347833e882a5SSuraj Sumangala 
347933e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
348033e882a5SSuraj Sumangala 
348133e882a5SSuraj Sumangala 		count -= len;
348233e882a5SSuraj Sumangala 		data += len;
348333e882a5SSuraj Sumangala 		scb->expect -= len;
348433e882a5SSuraj Sumangala 		remain = count;
348533e882a5SSuraj Sumangala 
348633e882a5SSuraj Sumangala 		switch (type) {
348733e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
348833e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
348933e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
349033e882a5SSuraj Sumangala 				scb->expect = h->plen;
349133e882a5SSuraj Sumangala 
349233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
349333e882a5SSuraj Sumangala 					kfree_skb(skb);
349433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
349533e882a5SSuraj Sumangala 					return -ENOMEM;
349633e882a5SSuraj Sumangala 				}
349733e882a5SSuraj Sumangala 			}
349833e882a5SSuraj Sumangala 			break;
349933e882a5SSuraj Sumangala 
350033e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
350133e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
350233e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
350333e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
350433e882a5SSuraj Sumangala 
350533e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
350633e882a5SSuraj Sumangala 					kfree_skb(skb);
350733e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
350833e882a5SSuraj Sumangala 					return -ENOMEM;
350933e882a5SSuraj Sumangala 				}
351033e882a5SSuraj Sumangala 			}
351133e882a5SSuraj Sumangala 			break;
351233e882a5SSuraj Sumangala 
351333e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
351433e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
351533e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
351633e882a5SSuraj Sumangala 				scb->expect = h->dlen;
351733e882a5SSuraj Sumangala 
351833e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
351933e882a5SSuraj Sumangala 					kfree_skb(skb);
352033e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
352133e882a5SSuraj Sumangala 					return -ENOMEM;
352233e882a5SSuraj Sumangala 				}
352333e882a5SSuraj Sumangala 			}
352433e882a5SSuraj Sumangala 			break;
352533e882a5SSuraj Sumangala 		}
352633e882a5SSuraj Sumangala 
352733e882a5SSuraj Sumangala 		if (scb->expect == 0) {
352833e882a5SSuraj Sumangala 			/* Complete frame */
352933e882a5SSuraj Sumangala 
353033e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
3531e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
353233e882a5SSuraj Sumangala 
353333e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
353433e882a5SSuraj Sumangala 			return remain;
353533e882a5SSuraj Sumangala 		}
353633e882a5SSuraj Sumangala 	}
353733e882a5SSuraj Sumangala 
353833e882a5SSuraj Sumangala 	return remain;
353933e882a5SSuraj Sumangala }
354033e882a5SSuraj Sumangala 
3541ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
3542ef222013SMarcel Holtmann {
3543f39a3c06SSuraj Sumangala 	int rem = 0;
3544f39a3c06SSuraj Sumangala 
3545ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
3546ef222013SMarcel Holtmann 		return -EILSEQ;
3547ef222013SMarcel Holtmann 
3548da5f6c37SGustavo F. Padovan 	while (count) {
35491e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
3550f39a3c06SSuraj Sumangala 		if (rem < 0)
3551f39a3c06SSuraj Sumangala 			return rem;
3552ef222013SMarcel Holtmann 
3553f39a3c06SSuraj Sumangala 		data += (count - rem);
3554f39a3c06SSuraj Sumangala 		count = rem;
3555f81c6224SJoe Perches 	}
3556ef222013SMarcel Holtmann 
3557f39a3c06SSuraj Sumangala 	return rem;
3558ef222013SMarcel Holtmann }
3559ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
3560ef222013SMarcel Holtmann 
356199811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
356299811510SSuraj Sumangala 
356399811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
356499811510SSuraj Sumangala {
356599811510SSuraj Sumangala 	int type;
356699811510SSuraj Sumangala 	int rem = 0;
356799811510SSuraj Sumangala 
3568da5f6c37SGustavo F. Padovan 	while (count) {
356999811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
357099811510SSuraj Sumangala 
357199811510SSuraj Sumangala 		if (!skb) {
357299811510SSuraj Sumangala 			struct { char type; } *pkt;
357399811510SSuraj Sumangala 
357499811510SSuraj Sumangala 			/* Start of the frame */
357599811510SSuraj Sumangala 			pkt = data;
357699811510SSuraj Sumangala 			type = pkt->type;
357799811510SSuraj Sumangala 
357899811510SSuraj Sumangala 			data++;
357999811510SSuraj Sumangala 			count--;
358099811510SSuraj Sumangala 		} else
358199811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
358299811510SSuraj Sumangala 
35831e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
35841e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
358599811510SSuraj Sumangala 		if (rem < 0)
358699811510SSuraj Sumangala 			return rem;
358799811510SSuraj Sumangala 
358899811510SSuraj Sumangala 		data += (count - rem);
358999811510SSuraj Sumangala 		count = rem;
3590f81c6224SJoe Perches 	}
359199811510SSuraj Sumangala 
359299811510SSuraj Sumangala 	return rem;
359399811510SSuraj Sumangala }
359499811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
359599811510SSuraj Sumangala 
35961da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
35971da177e4SLinus Torvalds 
35981da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
35991da177e4SLinus Torvalds {
36001da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
36011da177e4SLinus Torvalds 
3602f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
36031da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
3604f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
36051da177e4SLinus Torvalds 
36061da177e4SLinus Torvalds 	return 0;
36071da177e4SLinus Torvalds }
36081da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
36091da177e4SLinus Torvalds 
36101da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
36111da177e4SLinus Torvalds {
36121da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
36131da177e4SLinus Torvalds 
3614f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
36151da177e4SLinus Torvalds 	list_del(&cb->list);
3616f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
36171da177e4SLinus Torvalds 
36181da177e4SLinus Torvalds 	return 0;
36191da177e4SLinus Torvalds }
36201da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
36211da177e4SLinus Torvalds 
362251086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
36231da177e4SLinus Torvalds {
36240d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
36251da177e4SLinus Torvalds 
36261da177e4SLinus Torvalds 	/* Time stamp */
3627a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
36281da177e4SLinus Torvalds 
3629cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3630cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3631cd82e61cSMarcel Holtmann 
3632cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3633cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3634470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
36351da177e4SLinus Torvalds 	}
36361da177e4SLinus Torvalds 
36371da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
36381da177e4SLinus Torvalds 	skb_orphan(skb);
36391da177e4SLinus Torvalds 
36407bd8f09fSMarcel Holtmann 	if (hdev->send(hdev, skb) < 0)
364151086991SMarcel Holtmann 		BT_ERR("%s sending frame failed", hdev->name);
36421da177e4SLinus Torvalds }
36431da177e4SLinus Torvalds 
36443119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
36453119ae95SJohan Hedberg {
36463119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
36473119ae95SJohan Hedberg 	req->hdev = hdev;
36485d73e034SAndre Guedes 	req->err = 0;
36493119ae95SJohan Hedberg }
36503119ae95SJohan Hedberg 
36513119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
36523119ae95SJohan Hedberg {
36533119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
36543119ae95SJohan Hedberg 	struct sk_buff *skb;
36553119ae95SJohan Hedberg 	unsigned long flags;
36563119ae95SJohan Hedberg 
36573119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
36583119ae95SJohan Hedberg 
36595d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
36605d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
36615d73e034SAndre Guedes 	 */
36625d73e034SAndre Guedes 	if (req->err) {
36635d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
36645d73e034SAndre Guedes 		return req->err;
36655d73e034SAndre Guedes 	}
36665d73e034SAndre Guedes 
36673119ae95SJohan Hedberg 	/* Do not allow empty requests */
36683119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
3669382b0c39SAndre Guedes 		return -ENODATA;
36703119ae95SJohan Hedberg 
36713119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
36723119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
36733119ae95SJohan Hedberg 
36743119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
36753119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
36763119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
36773119ae95SJohan Hedberg 
36783119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
36793119ae95SJohan Hedberg 
36803119ae95SJohan Hedberg 	return 0;
36813119ae95SJohan Hedberg }
36823119ae95SJohan Hedberg 
36831ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
368407dc93ddSJohan Hedberg 				       u32 plen, const void *param)
36851da177e4SLinus Torvalds {
36861da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
36871da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
36881da177e4SLinus Torvalds 	struct sk_buff *skb;
36891da177e4SLinus Torvalds 
36901da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
36911ca3a9d0SJohan Hedberg 	if (!skb)
36921ca3a9d0SJohan Hedberg 		return NULL;
36931da177e4SLinus Torvalds 
36941da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
3695a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
36961da177e4SLinus Torvalds 	hdr->plen   = plen;
36971da177e4SLinus Torvalds 
36981da177e4SLinus Torvalds 	if (plen)
36991da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
37001da177e4SLinus Torvalds 
37011da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
37021da177e4SLinus Torvalds 
37030d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
3704c78ae283SMarcel Holtmann 
37051ca3a9d0SJohan Hedberg 	return skb;
37061ca3a9d0SJohan Hedberg }
37071ca3a9d0SJohan Hedberg 
37081ca3a9d0SJohan Hedberg /* Send HCI command */
370907dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
371007dc93ddSJohan Hedberg 		 const void *param)
37111ca3a9d0SJohan Hedberg {
37121ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
37131ca3a9d0SJohan Hedberg 
37141ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
37151ca3a9d0SJohan Hedberg 
37161ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
37171ca3a9d0SJohan Hedberg 	if (!skb) {
37181ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
37191ca3a9d0SJohan Hedberg 		return -ENOMEM;
37201ca3a9d0SJohan Hedberg 	}
37211ca3a9d0SJohan Hedberg 
372211714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
372311714b3dSJohan Hedberg 	 * single-command requests.
372411714b3dSJohan Hedberg 	 */
372511714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
372611714b3dSJohan Hedberg 
37271da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3728c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
37291da177e4SLinus Torvalds 
37301da177e4SLinus Torvalds 	return 0;
37311da177e4SLinus Torvalds }
37321da177e4SLinus Torvalds 
373371c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
373407dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
373507dc93ddSJohan Hedberg 		    const void *param, u8 event)
373671c76a17SJohan Hedberg {
373771c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
373871c76a17SJohan Hedberg 	struct sk_buff *skb;
373971c76a17SJohan Hedberg 
374071c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
374171c76a17SJohan Hedberg 
374234739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
374334739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
374434739c1eSAndre Guedes 	 */
374534739c1eSAndre Guedes 	if (req->err)
374634739c1eSAndre Guedes 		return;
374734739c1eSAndre Guedes 
374871c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
374971c76a17SJohan Hedberg 	if (!skb) {
37505d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
37515d73e034SAndre Guedes 		       hdev->name, opcode);
37525d73e034SAndre Guedes 		req->err = -ENOMEM;
3753e348fe6bSAndre Guedes 		return;
375471c76a17SJohan Hedberg 	}
375571c76a17SJohan Hedberg 
375671c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
375771c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
375871c76a17SJohan Hedberg 
375902350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
376002350a72SJohan Hedberg 
376171c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
376271c76a17SJohan Hedberg }
376371c76a17SJohan Hedberg 
376407dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
376507dc93ddSJohan Hedberg 		 const void *param)
376602350a72SJohan Hedberg {
376702350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
376802350a72SJohan Hedberg }
376902350a72SJohan Hedberg 
37701da177e4SLinus Torvalds /* Get data from the previously sent command */
3771a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
37721da177e4SLinus Torvalds {
37731da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
37741da177e4SLinus Torvalds 
37751da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
37761da177e4SLinus Torvalds 		return NULL;
37771da177e4SLinus Torvalds 
37781da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
37791da177e4SLinus Torvalds 
3780a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
37811da177e4SLinus Torvalds 		return NULL;
37821da177e4SLinus Torvalds 
3783f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
37841da177e4SLinus Torvalds 
37851da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
37861da177e4SLinus Torvalds }
37871da177e4SLinus Torvalds 
37881da177e4SLinus Torvalds /* Send ACL data */
37891da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
37901da177e4SLinus Torvalds {
37911da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
37921da177e4SLinus Torvalds 	int len = skb->len;
37931da177e4SLinus Torvalds 
3794badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3795badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
37969c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3797aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3798aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
37991da177e4SLinus Torvalds }
38001da177e4SLinus Torvalds 
3801ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
380273d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
38031da177e4SLinus Torvalds {
3804ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
38051da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
38061da177e4SLinus Torvalds 	struct sk_buff *list;
38071da177e4SLinus Torvalds 
3808087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3809087bfd99SGustavo Padovan 	skb->data_len = 0;
3810087bfd99SGustavo Padovan 
3811087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3812204a6e54SAndrei Emeltchenko 
3813204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3814204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
3815087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3816204a6e54SAndrei Emeltchenko 		break;
3817204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3818204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3819204a6e54SAndrei Emeltchenko 		break;
3820204a6e54SAndrei Emeltchenko 	default:
3821204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
3822204a6e54SAndrei Emeltchenko 		return;
3823204a6e54SAndrei Emeltchenko 	}
3824087bfd99SGustavo Padovan 
382570f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
382670f23020SAndrei Emeltchenko 	if (!list) {
38271da177e4SLinus Torvalds 		/* Non fragmented */
38281da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
38291da177e4SLinus Torvalds 
383073d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
38311da177e4SLinus Torvalds 	} else {
38321da177e4SLinus Torvalds 		/* Fragmented */
38331da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
38341da177e4SLinus Torvalds 
38351da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
38361da177e4SLinus Torvalds 
38371da177e4SLinus Torvalds 		/* Queue all fragments atomically */
3838af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
38391da177e4SLinus Torvalds 
384073d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3841e702112fSAndrei Emeltchenko 
3842e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3843e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
38441da177e4SLinus Torvalds 		do {
38451da177e4SLinus Torvalds 			skb = list; list = list->next;
38461da177e4SLinus Torvalds 
38470d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3848e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
38491da177e4SLinus Torvalds 
38501da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
38511da177e4SLinus Torvalds 
385273d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
38531da177e4SLinus Torvalds 		} while (list);
38541da177e4SLinus Torvalds 
3855af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
38561da177e4SLinus Torvalds 	}
385773d80debSLuiz Augusto von Dentz }
385873d80debSLuiz Augusto von Dentz 
385973d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
386073d80debSLuiz Augusto von Dentz {
3861ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
386273d80debSLuiz Augusto von Dentz 
3863f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
386473d80debSLuiz Augusto von Dentz 
3865ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
38661da177e4SLinus Torvalds 
38673eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
38681da177e4SLinus Torvalds }
38691da177e4SLinus Torvalds 
38701da177e4SLinus Torvalds /* Send SCO data */
38710d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
38721da177e4SLinus Torvalds {
38731da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
38741da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
38751da177e4SLinus Torvalds 
38761da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
38771da177e4SLinus Torvalds 
3878aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
38791da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
38801da177e4SLinus Torvalds 
3881badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3882badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
38839c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
38841da177e4SLinus Torvalds 
38850d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
3886c78ae283SMarcel Holtmann 
38871da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
38883eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
38891da177e4SLinus Torvalds }
38901da177e4SLinus Torvalds 
38911da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
38921da177e4SLinus Torvalds 
38931da177e4SLinus Torvalds /* HCI Connection scheduler */
38946039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3895a8c5fb1aSGustavo Padovan 				     int *quote)
38961da177e4SLinus Torvalds {
38971da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
38988035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3899abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
39001da177e4SLinus Torvalds 
39011da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
39021da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3903bf4c6325SGustavo F. Padovan 
3904bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3905bf4c6325SGustavo F. Padovan 
3906bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3907769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
39081da177e4SLinus Torvalds 			continue;
3909769be974SMarcel Holtmann 
3910769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3911769be974SMarcel Holtmann 			continue;
3912769be974SMarcel Holtmann 
39131da177e4SLinus Torvalds 		num++;
39141da177e4SLinus Torvalds 
39151da177e4SLinus Torvalds 		if (c->sent < min) {
39161da177e4SLinus Torvalds 			min  = c->sent;
39171da177e4SLinus Torvalds 			conn = c;
39181da177e4SLinus Torvalds 		}
391952087a79SLuiz Augusto von Dentz 
392052087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
392152087a79SLuiz Augusto von Dentz 			break;
39221da177e4SLinus Torvalds 	}
39231da177e4SLinus Torvalds 
3924bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3925bf4c6325SGustavo F. Padovan 
39261da177e4SLinus Torvalds 	if (conn) {
39276ed58ec5SVille Tervo 		int cnt, q;
39286ed58ec5SVille Tervo 
39296ed58ec5SVille Tervo 		switch (conn->type) {
39306ed58ec5SVille Tervo 		case ACL_LINK:
39316ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
39326ed58ec5SVille Tervo 			break;
39336ed58ec5SVille Tervo 		case SCO_LINK:
39346ed58ec5SVille Tervo 		case ESCO_LINK:
39356ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
39366ed58ec5SVille Tervo 			break;
39376ed58ec5SVille Tervo 		case LE_LINK:
39386ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
39396ed58ec5SVille Tervo 			break;
39406ed58ec5SVille Tervo 		default:
39416ed58ec5SVille Tervo 			cnt = 0;
39426ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
39436ed58ec5SVille Tervo 		}
39446ed58ec5SVille Tervo 
39456ed58ec5SVille Tervo 		q = cnt / num;
39461da177e4SLinus Torvalds 		*quote = q ? q : 1;
39471da177e4SLinus Torvalds 	} else
39481da177e4SLinus Torvalds 		*quote = 0;
39491da177e4SLinus Torvalds 
39501da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
39511da177e4SLinus Torvalds 	return conn;
39521da177e4SLinus Torvalds }
39531da177e4SLinus Torvalds 
39546039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
39551da177e4SLinus Torvalds {
39561da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
39571da177e4SLinus Torvalds 	struct hci_conn *c;
39581da177e4SLinus Torvalds 
3959bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
39601da177e4SLinus Torvalds 
3961bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3962bf4c6325SGustavo F. Padovan 
39631da177e4SLinus Torvalds 	/* Kill stalled connections */
3964bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3965bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
39666ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
39676ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
3968bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
39691da177e4SLinus Torvalds 		}
39701da177e4SLinus Torvalds 	}
3971bf4c6325SGustavo F. Padovan 
3972bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
39731da177e4SLinus Torvalds }
39741da177e4SLinus Torvalds 
39756039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
397673d80debSLuiz Augusto von Dentz 				      int *quote)
397773d80debSLuiz Augusto von Dentz {
397873d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
397973d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3980abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
398173d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
398273d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
398373d80debSLuiz Augusto von Dentz 
398473d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
398573d80debSLuiz Augusto von Dentz 
3986bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3987bf4c6325SGustavo F. Padovan 
3988bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
398973d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
399073d80debSLuiz Augusto von Dentz 
399173d80debSLuiz Augusto von Dentz 		if (conn->type != type)
399273d80debSLuiz Augusto von Dentz 			continue;
399373d80debSLuiz Augusto von Dentz 
399473d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
399573d80debSLuiz Augusto von Dentz 			continue;
399673d80debSLuiz Augusto von Dentz 
399773d80debSLuiz Augusto von Dentz 		conn_num++;
399873d80debSLuiz Augusto von Dentz 
39998192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
400073d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
400173d80debSLuiz Augusto von Dentz 
400273d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
400373d80debSLuiz Augusto von Dentz 				continue;
400473d80debSLuiz Augusto von Dentz 
400573d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
400673d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
400773d80debSLuiz Augusto von Dentz 				continue;
400873d80debSLuiz Augusto von Dentz 
400973d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
401073d80debSLuiz Augusto von Dentz 				num = 0;
401173d80debSLuiz Augusto von Dentz 				min = ~0;
401273d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
401373d80debSLuiz Augusto von Dentz 			}
401473d80debSLuiz Augusto von Dentz 
401573d80debSLuiz Augusto von Dentz 			num++;
401673d80debSLuiz Augusto von Dentz 
401773d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
401873d80debSLuiz Augusto von Dentz 				min  = conn->sent;
401973d80debSLuiz Augusto von Dentz 				chan = tmp;
402073d80debSLuiz Augusto von Dentz 			}
402173d80debSLuiz Augusto von Dentz 		}
402273d80debSLuiz Augusto von Dentz 
402373d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
402473d80debSLuiz Augusto von Dentz 			break;
402573d80debSLuiz Augusto von Dentz 	}
402673d80debSLuiz Augusto von Dentz 
4027bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4028bf4c6325SGustavo F. Padovan 
402973d80debSLuiz Augusto von Dentz 	if (!chan)
403073d80debSLuiz Augusto von Dentz 		return NULL;
403173d80debSLuiz Augusto von Dentz 
403273d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
403373d80debSLuiz Augusto von Dentz 	case ACL_LINK:
403473d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
403573d80debSLuiz Augusto von Dentz 		break;
4036bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4037bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4038bd1eb66bSAndrei Emeltchenko 		break;
403973d80debSLuiz Augusto von Dentz 	case SCO_LINK:
404073d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
404173d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
404273d80debSLuiz Augusto von Dentz 		break;
404373d80debSLuiz Augusto von Dentz 	case LE_LINK:
404473d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
404573d80debSLuiz Augusto von Dentz 		break;
404673d80debSLuiz Augusto von Dentz 	default:
404773d80debSLuiz Augusto von Dentz 		cnt = 0;
404873d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
404973d80debSLuiz Augusto von Dentz 	}
405073d80debSLuiz Augusto von Dentz 
405173d80debSLuiz Augusto von Dentz 	q = cnt / num;
405273d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
405373d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
405473d80debSLuiz Augusto von Dentz 	return chan;
405573d80debSLuiz Augusto von Dentz }
405673d80debSLuiz Augusto von Dentz 
405702b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
405802b20f0bSLuiz Augusto von Dentz {
405902b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
406002b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
406102b20f0bSLuiz Augusto von Dentz 	int num = 0;
406202b20f0bSLuiz Augusto von Dentz 
406302b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
406402b20f0bSLuiz Augusto von Dentz 
4065bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4066bf4c6325SGustavo F. Padovan 
4067bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
406802b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
406902b20f0bSLuiz Augusto von Dentz 
407002b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
407102b20f0bSLuiz Augusto von Dentz 			continue;
407202b20f0bSLuiz Augusto von Dentz 
407302b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
407402b20f0bSLuiz Augusto von Dentz 			continue;
407502b20f0bSLuiz Augusto von Dentz 
407602b20f0bSLuiz Augusto von Dentz 		num++;
407702b20f0bSLuiz Augusto von Dentz 
40788192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
407902b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
408002b20f0bSLuiz Augusto von Dentz 
408102b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
408202b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
408302b20f0bSLuiz Augusto von Dentz 				continue;
408402b20f0bSLuiz Augusto von Dentz 			}
408502b20f0bSLuiz Augusto von Dentz 
408602b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
408702b20f0bSLuiz Augusto von Dentz 				continue;
408802b20f0bSLuiz Augusto von Dentz 
408902b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
409002b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
409102b20f0bSLuiz Augusto von Dentz 				continue;
409202b20f0bSLuiz Augusto von Dentz 
409302b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
409402b20f0bSLuiz Augusto von Dentz 
409502b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
409602b20f0bSLuiz Augusto von Dentz 			       skb->priority);
409702b20f0bSLuiz Augusto von Dentz 		}
409802b20f0bSLuiz Augusto von Dentz 
409902b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
410002b20f0bSLuiz Augusto von Dentz 			break;
410102b20f0bSLuiz Augusto von Dentz 	}
4102bf4c6325SGustavo F. Padovan 
4103bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4104bf4c6325SGustavo F. Padovan 
410502b20f0bSLuiz Augusto von Dentz }
410602b20f0bSLuiz Augusto von Dentz 
4107b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4108b71d385aSAndrei Emeltchenko {
4109b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4110b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4111b71d385aSAndrei Emeltchenko }
4112b71d385aSAndrei Emeltchenko 
41136039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
41141da177e4SLinus Torvalds {
41151da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
41161da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
41171da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
411863d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
41195f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4120bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
41211da177e4SLinus Torvalds 	}
412263d2bc1bSAndrei Emeltchenko }
41231da177e4SLinus Torvalds 
41246039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
412563d2bc1bSAndrei Emeltchenko {
412663d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
412763d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
412863d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
412963d2bc1bSAndrei Emeltchenko 	int quote;
413063d2bc1bSAndrei Emeltchenko 
413163d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
413204837f64SMarcel Holtmann 
413373d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
413473d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4135ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4136ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
413773d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
413873d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
413973d80debSLuiz Augusto von Dentz 
4140ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4141ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4142ec1cce24SLuiz Augusto von Dentz 				break;
4143ec1cce24SLuiz Augusto von Dentz 
4144ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4145ec1cce24SLuiz Augusto von Dentz 
414673d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
414773d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
414804837f64SMarcel Holtmann 
414957d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
41501da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
41511da177e4SLinus Torvalds 
41521da177e4SLinus Torvalds 			hdev->acl_cnt--;
415373d80debSLuiz Augusto von Dentz 			chan->sent++;
415473d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
41551da177e4SLinus Torvalds 		}
41561da177e4SLinus Torvalds 	}
415702b20f0bSLuiz Augusto von Dentz 
415802b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
415902b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
41601da177e4SLinus Torvalds }
41611da177e4SLinus Torvalds 
41626039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4163b71d385aSAndrei Emeltchenko {
416463d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4165b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4166b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4167b71d385aSAndrei Emeltchenko 	int quote;
4168bd1eb66bSAndrei Emeltchenko 	u8 type;
4169b71d385aSAndrei Emeltchenko 
417063d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
4171b71d385aSAndrei Emeltchenko 
4172bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4173bd1eb66bSAndrei Emeltchenko 
4174bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
4175bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
4176bd1eb66bSAndrei Emeltchenko 	else
4177bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
4178bd1eb66bSAndrei Emeltchenko 
4179b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
4180bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
4181b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
4182b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
4183b71d385aSAndrei Emeltchenko 			int blocks;
4184b71d385aSAndrei Emeltchenko 
4185b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
4186b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
4187b71d385aSAndrei Emeltchenko 
4188b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
4189b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
4190b71d385aSAndrei Emeltchenko 				break;
4191b71d385aSAndrei Emeltchenko 
4192b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
4193b71d385aSAndrei Emeltchenko 
4194b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
4195b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
4196b71d385aSAndrei Emeltchenko 				return;
4197b71d385aSAndrei Emeltchenko 
4198b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
4199b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
4200b71d385aSAndrei Emeltchenko 
420157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4202b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4203b71d385aSAndrei Emeltchenko 
4204b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4205b71d385aSAndrei Emeltchenko 			quote -= blocks;
4206b71d385aSAndrei Emeltchenko 
4207b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4208b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4209b71d385aSAndrei Emeltchenko 		}
4210b71d385aSAndrei Emeltchenko 	}
4211b71d385aSAndrei Emeltchenko 
4212b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4213bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4214b71d385aSAndrei Emeltchenko }
4215b71d385aSAndrei Emeltchenko 
42166039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4217b71d385aSAndrei Emeltchenko {
4218b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4219b71d385aSAndrei Emeltchenko 
4220bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4221bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
4222bd1eb66bSAndrei Emeltchenko 		return;
4223bd1eb66bSAndrei Emeltchenko 
4224bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4225bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4226b71d385aSAndrei Emeltchenko 		return;
4227b71d385aSAndrei Emeltchenko 
4228b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4229b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4230b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4231b71d385aSAndrei Emeltchenko 		break;
4232b71d385aSAndrei Emeltchenko 
4233b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4234b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4235b71d385aSAndrei Emeltchenko 		break;
4236b71d385aSAndrei Emeltchenko 	}
4237b71d385aSAndrei Emeltchenko }
4238b71d385aSAndrei Emeltchenko 
42391da177e4SLinus Torvalds /* Schedule SCO */
42406039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
42411da177e4SLinus Torvalds {
42421da177e4SLinus Torvalds 	struct hci_conn *conn;
42431da177e4SLinus Torvalds 	struct sk_buff *skb;
42441da177e4SLinus Torvalds 	int quote;
42451da177e4SLinus Torvalds 
42461da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
42471da177e4SLinus Torvalds 
424852087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
424952087a79SLuiz Augusto von Dentz 		return;
425052087a79SLuiz Augusto von Dentz 
42511da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
42521da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
42531da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
425457d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
42551da177e4SLinus Torvalds 
42561da177e4SLinus Torvalds 			conn->sent++;
42571da177e4SLinus Torvalds 			if (conn->sent == ~0)
42581da177e4SLinus Torvalds 				conn->sent = 0;
42591da177e4SLinus Torvalds 		}
42601da177e4SLinus Torvalds 	}
42611da177e4SLinus Torvalds }
42621da177e4SLinus Torvalds 
42636039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
4264b6a0dc82SMarcel Holtmann {
4265b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4266b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
4267b6a0dc82SMarcel Holtmann 	int quote;
4268b6a0dc82SMarcel Holtmann 
4269b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
4270b6a0dc82SMarcel Holtmann 
427152087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
427252087a79SLuiz Augusto von Dentz 		return;
427352087a79SLuiz Augusto von Dentz 
42748fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
42758fc9ced3SGustavo Padovan 						     &quote))) {
4276b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
4277b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
427857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4279b6a0dc82SMarcel Holtmann 
4280b6a0dc82SMarcel Holtmann 			conn->sent++;
4281b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
4282b6a0dc82SMarcel Holtmann 				conn->sent = 0;
4283b6a0dc82SMarcel Holtmann 		}
4284b6a0dc82SMarcel Holtmann 	}
4285b6a0dc82SMarcel Holtmann }
4286b6a0dc82SMarcel Holtmann 
42876039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
42886ed58ec5SVille Tervo {
428973d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
42906ed58ec5SVille Tervo 	struct sk_buff *skb;
429102b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
42926ed58ec5SVille Tervo 
42936ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
42946ed58ec5SVille Tervo 
429552087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
429652087a79SLuiz Augusto von Dentz 		return;
429752087a79SLuiz Augusto von Dentz 
42986ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
42996ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
43006ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
4301bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
43026ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
4303bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
43046ed58ec5SVille Tervo 	}
43056ed58ec5SVille Tervo 
43066ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
430702b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
430873d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4309ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4310ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
431173d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
431273d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
43136ed58ec5SVille Tervo 
4314ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4315ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4316ec1cce24SLuiz Augusto von Dentz 				break;
4317ec1cce24SLuiz Augusto von Dentz 
4318ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4319ec1cce24SLuiz Augusto von Dentz 
432057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
43216ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
43226ed58ec5SVille Tervo 
43236ed58ec5SVille Tervo 			cnt--;
432473d80debSLuiz Augusto von Dentz 			chan->sent++;
432573d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
43266ed58ec5SVille Tervo 		}
43276ed58ec5SVille Tervo 	}
432873d80debSLuiz Augusto von Dentz 
43296ed58ec5SVille Tervo 	if (hdev->le_pkts)
43306ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
43316ed58ec5SVille Tervo 	else
43326ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
433302b20f0bSLuiz Augusto von Dentz 
433402b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
433502b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
43366ed58ec5SVille Tervo }
43376ed58ec5SVille Tervo 
43383eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
43391da177e4SLinus Torvalds {
43403eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
43411da177e4SLinus Torvalds 	struct sk_buff *skb;
43421da177e4SLinus Torvalds 
43436ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
43446ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
43451da177e4SLinus Torvalds 
434652de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
43471da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
43481da177e4SLinus Torvalds 		hci_sched_acl(hdev);
43491da177e4SLinus Torvalds 		hci_sched_sco(hdev);
4350b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
43516ed58ec5SVille Tervo 		hci_sched_le(hdev);
435252de599eSMarcel Holtmann 	}
43536ed58ec5SVille Tervo 
43541da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
43551da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
435657d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
43571da177e4SLinus Torvalds }
43581da177e4SLinus Torvalds 
435925985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
43601da177e4SLinus Torvalds 
43611da177e4SLinus Torvalds /* ACL data packet */
43626039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
43631da177e4SLinus Torvalds {
43641da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
43651da177e4SLinus Torvalds 	struct hci_conn *conn;
43661da177e4SLinus Torvalds 	__u16 handle, flags;
43671da177e4SLinus Torvalds 
43681da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
43691da177e4SLinus Torvalds 
43701da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
43711da177e4SLinus Torvalds 	flags  = hci_flags(handle);
43721da177e4SLinus Torvalds 	handle = hci_handle(handle);
43731da177e4SLinus Torvalds 
4374f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4375a8c5fb1aSGustavo Padovan 	       handle, flags);
43761da177e4SLinus Torvalds 
43771da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
43781da177e4SLinus Torvalds 
43791da177e4SLinus Torvalds 	hci_dev_lock(hdev);
43801da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
43811da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
43821da177e4SLinus Torvalds 
43831da177e4SLinus Torvalds 	if (conn) {
438465983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
438504837f64SMarcel Holtmann 
43861da177e4SLinus Torvalds 		/* Send to upper protocol */
4387686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
43881da177e4SLinus Torvalds 		return;
43891da177e4SLinus Torvalds 	} else {
43901da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
43911da177e4SLinus Torvalds 		       hdev->name, handle);
43921da177e4SLinus Torvalds 	}
43931da177e4SLinus Torvalds 
43941da177e4SLinus Torvalds 	kfree_skb(skb);
43951da177e4SLinus Torvalds }
43961da177e4SLinus Torvalds 
43971da177e4SLinus Torvalds /* SCO data packet */
43986039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
43991da177e4SLinus Torvalds {
44001da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
44011da177e4SLinus Torvalds 	struct hci_conn *conn;
44021da177e4SLinus Torvalds 	__u16 handle;
44031da177e4SLinus Torvalds 
44041da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
44051da177e4SLinus Torvalds 
44061da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
44071da177e4SLinus Torvalds 
4408f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
44091da177e4SLinus Torvalds 
44101da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
44111da177e4SLinus Torvalds 
44121da177e4SLinus Torvalds 	hci_dev_lock(hdev);
44131da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
44141da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
44151da177e4SLinus Torvalds 
44161da177e4SLinus Torvalds 	if (conn) {
44171da177e4SLinus Torvalds 		/* Send to upper protocol */
4418686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
44191da177e4SLinus Torvalds 		return;
44201da177e4SLinus Torvalds 	} else {
44211da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
44221da177e4SLinus Torvalds 		       hdev->name, handle);
44231da177e4SLinus Torvalds 	}
44241da177e4SLinus Torvalds 
44251da177e4SLinus Torvalds 	kfree_skb(skb);
44261da177e4SLinus Torvalds }
44271da177e4SLinus Torvalds 
44289238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
44299238f36aSJohan Hedberg {
44309238f36aSJohan Hedberg 	struct sk_buff *skb;
44319238f36aSJohan Hedberg 
44329238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
44339238f36aSJohan Hedberg 	if (!skb)
44349238f36aSJohan Hedberg 		return true;
44359238f36aSJohan Hedberg 
44369238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
44379238f36aSJohan Hedberg }
44389238f36aSJohan Hedberg 
443942c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
444042c6b129SJohan Hedberg {
444142c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
444242c6b129SJohan Hedberg 	struct sk_buff *skb;
444342c6b129SJohan Hedberg 	u16 opcode;
444442c6b129SJohan Hedberg 
444542c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
444642c6b129SJohan Hedberg 		return;
444742c6b129SJohan Hedberg 
444842c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
444942c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
445042c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
445142c6b129SJohan Hedberg 		return;
445242c6b129SJohan Hedberg 
445342c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
445442c6b129SJohan Hedberg 	if (!skb)
445542c6b129SJohan Hedberg 		return;
445642c6b129SJohan Hedberg 
445742c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
445842c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
445942c6b129SJohan Hedberg }
446042c6b129SJohan Hedberg 
44619238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
44629238f36aSJohan Hedberg {
44639238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
44649238f36aSJohan Hedberg 	struct sk_buff *skb;
44659238f36aSJohan Hedberg 	unsigned long flags;
44669238f36aSJohan Hedberg 
44679238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
44689238f36aSJohan Hedberg 
446942c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
447042c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
44719238f36aSJohan Hedberg 	 */
447242c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
447342c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
447442c6b129SJohan Hedberg 		 * reset complete event during init and any pending
447542c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
447642c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
447742c6b129SJohan Hedberg 		 * command.
447842c6b129SJohan Hedberg 		 */
447942c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
448042c6b129SJohan Hedberg 			hci_resend_last(hdev);
448142c6b129SJohan Hedberg 
44829238f36aSJohan Hedberg 		return;
448342c6b129SJohan Hedberg 	}
44849238f36aSJohan Hedberg 
44859238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
44869238f36aSJohan Hedberg 	 * this request the request is not yet complete.
44879238f36aSJohan Hedberg 	 */
44889238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
44899238f36aSJohan Hedberg 		return;
44909238f36aSJohan Hedberg 
44919238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
44929238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
44939238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
44949238f36aSJohan Hedberg 	 */
44959238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
44969238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
449753e21fbcSJohan Hedberg 
449853e21fbcSJohan Hedberg 		if (req_complete) {
449953e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
450053e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
450153e21fbcSJohan Hedberg 			 * this function gets called again.
450253e21fbcSJohan Hedberg 			 */
450353e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
450453e21fbcSJohan Hedberg 
45059238f36aSJohan Hedberg 			goto call_complete;
45069238f36aSJohan Hedberg 		}
450753e21fbcSJohan Hedberg 	}
45089238f36aSJohan Hedberg 
45099238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
45109238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
45119238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
45129238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
45139238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
45149238f36aSJohan Hedberg 			break;
45159238f36aSJohan Hedberg 		}
45169238f36aSJohan Hedberg 
45179238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
45189238f36aSJohan Hedberg 		kfree_skb(skb);
45199238f36aSJohan Hedberg 	}
45209238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
45219238f36aSJohan Hedberg 
45229238f36aSJohan Hedberg call_complete:
45239238f36aSJohan Hedberg 	if (req_complete)
45249238f36aSJohan Hedberg 		req_complete(hdev, status);
45259238f36aSJohan Hedberg }
45269238f36aSJohan Hedberg 
4527b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
45281da177e4SLinus Torvalds {
4529b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
45301da177e4SLinus Torvalds 	struct sk_buff *skb;
45311da177e4SLinus Torvalds 
45321da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
45331da177e4SLinus Torvalds 
45341da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
4535cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4536cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4537cd82e61cSMarcel Holtmann 
45381da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
45391da177e4SLinus Torvalds 			/* Send copy to the sockets */
4540470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
45411da177e4SLinus Torvalds 		}
45421da177e4SLinus Torvalds 
45430736cfa8SMarcel Holtmann 		if (test_bit(HCI_RAW, &hdev->flags) ||
45440736cfa8SMarcel Holtmann 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
45451da177e4SLinus Torvalds 			kfree_skb(skb);
45461da177e4SLinus Torvalds 			continue;
45471da177e4SLinus Torvalds 		}
45481da177e4SLinus Torvalds 
45491da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
45501da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
45510d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
45521da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
45531da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
45541da177e4SLinus Torvalds 				kfree_skb(skb);
45551da177e4SLinus Torvalds 				continue;
45563ff50b79SStephen Hemminger 			}
45571da177e4SLinus Torvalds 		}
45581da177e4SLinus Torvalds 
45591da177e4SLinus Torvalds 		/* Process frame */
45600d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
45611da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4562b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
45631da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
45641da177e4SLinus Torvalds 			break;
45651da177e4SLinus Torvalds 
45661da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
45671da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
45681da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
45691da177e4SLinus Torvalds 			break;
45701da177e4SLinus Torvalds 
45711da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
45721da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
45731da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
45741da177e4SLinus Torvalds 			break;
45751da177e4SLinus Torvalds 
45761da177e4SLinus Torvalds 		default:
45771da177e4SLinus Torvalds 			kfree_skb(skb);
45781da177e4SLinus Torvalds 			break;
45791da177e4SLinus Torvalds 		}
45801da177e4SLinus Torvalds 	}
45811da177e4SLinus Torvalds }
45821da177e4SLinus Torvalds 
4583c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
45841da177e4SLinus Torvalds {
4585c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
45861da177e4SLinus Torvalds 	struct sk_buff *skb;
45871da177e4SLinus Torvalds 
45882104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
45892104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
45901da177e4SLinus Torvalds 
45911da177e4SLinus Torvalds 	/* Send queued commands */
45925a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
45935a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
45945a08ecceSAndrei Emeltchenko 		if (!skb)
45955a08ecceSAndrei Emeltchenko 			return;
45965a08ecceSAndrei Emeltchenko 
45971da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
45981da177e4SLinus Torvalds 
4599a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
460070f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
46011da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
460257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
46037bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
46047bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
46057bdb8a5cSSzymon Janc 			else
46066bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
46075f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
46081da177e4SLinus Torvalds 		} else {
46091da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
4610c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
46111da177e4SLinus Torvalds 		}
46121da177e4SLinus Torvalds 	}
46131da177e4SLinus Torvalds }
4614