xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 15819a70)
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>
3247219839SMarcel Holtmann #include <asm/unaligned.h>
331da177e4SLinus Torvalds 
341da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
351da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
361da177e4SLinus Torvalds 
37b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
38c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
393eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds /* HCI device list */
421da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
431da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds /* HCI callback list */
461da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
471da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
481da177e4SLinus Torvalds 
493df92b31SSasha Levin /* HCI ID Numbering */
503df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
513df92b31SSasha Levin 
521da177e4SLinus Torvalds /* ---- HCI notifications ---- */
531da177e4SLinus Torvalds 
546516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
551da177e4SLinus Torvalds {
56040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
571da177e4SLinus Torvalds }
581da177e4SLinus Torvalds 
59baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
60baf27f6eSMarcel Holtmann 
614b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
624b4148e9SMarcel Holtmann 			     size_t count, loff_t *ppos)
634b4148e9SMarcel Holtmann {
644b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
654b4148e9SMarcel Holtmann 	char buf[3];
664b4148e9SMarcel Holtmann 
674b4148e9SMarcel Holtmann 	buf[0] = test_bit(HCI_DUT_MODE, &hdev->dev_flags) ? 'Y': 'N';
684b4148e9SMarcel Holtmann 	buf[1] = '\n';
694b4148e9SMarcel Holtmann 	buf[2] = '\0';
704b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
714b4148e9SMarcel Holtmann }
724b4148e9SMarcel Holtmann 
734b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
744b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
754b4148e9SMarcel Holtmann {
764b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
774b4148e9SMarcel Holtmann 	struct sk_buff *skb;
784b4148e9SMarcel Holtmann 	char buf[32];
794b4148e9SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
804b4148e9SMarcel Holtmann 	bool enable;
814b4148e9SMarcel Holtmann 	int err;
824b4148e9SMarcel Holtmann 
834b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
844b4148e9SMarcel Holtmann 		return -ENETDOWN;
854b4148e9SMarcel Holtmann 
864b4148e9SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
874b4148e9SMarcel Holtmann 		return -EFAULT;
884b4148e9SMarcel Holtmann 
894b4148e9SMarcel Holtmann 	buf[buf_size] = '\0';
904b4148e9SMarcel Holtmann 	if (strtobool(buf, &enable))
914b4148e9SMarcel Holtmann 		return -EINVAL;
924b4148e9SMarcel Holtmann 
934b4148e9SMarcel Holtmann 	if (enable == test_bit(HCI_DUT_MODE, &hdev->dev_flags))
944b4148e9SMarcel Holtmann 		return -EALREADY;
954b4148e9SMarcel Holtmann 
964b4148e9SMarcel Holtmann 	hci_req_lock(hdev);
974b4148e9SMarcel Holtmann 	if (enable)
984b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
994b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1004b4148e9SMarcel Holtmann 	else
1014b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1024b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1034b4148e9SMarcel Holtmann 	hci_req_unlock(hdev);
1044b4148e9SMarcel Holtmann 
1054b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1064b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1074b4148e9SMarcel Holtmann 
1084b4148e9SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
1094b4148e9SMarcel Holtmann 	kfree_skb(skb);
1104b4148e9SMarcel Holtmann 
1114b4148e9SMarcel Holtmann 	if (err < 0)
1124b4148e9SMarcel Holtmann 		return err;
1134b4148e9SMarcel Holtmann 
1144b4148e9SMarcel Holtmann 	change_bit(HCI_DUT_MODE, &hdev->dev_flags);
1154b4148e9SMarcel Holtmann 
1164b4148e9SMarcel Holtmann 	return count;
1174b4148e9SMarcel Holtmann }
1184b4148e9SMarcel Holtmann 
1194b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1204b4148e9SMarcel Holtmann 	.open		= simple_open,
1214b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1224b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1234b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1244b4148e9SMarcel Holtmann };
1254b4148e9SMarcel Holtmann 
126dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr)
127dfb826a8SMarcel Holtmann {
128dfb826a8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
129dfb826a8SMarcel Holtmann 	u8 p;
130dfb826a8SMarcel Holtmann 
131dfb826a8SMarcel Holtmann 	hci_dev_lock(hdev);
132dfb826a8SMarcel Holtmann 	for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
133cfbb2b5bSMarcel Holtmann 		seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
134dfb826a8SMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p,
135dfb826a8SMarcel Holtmann 			   hdev->features[p][0], hdev->features[p][1],
136dfb826a8SMarcel Holtmann 			   hdev->features[p][2], hdev->features[p][3],
137dfb826a8SMarcel Holtmann 			   hdev->features[p][4], hdev->features[p][5],
138dfb826a8SMarcel Holtmann 			   hdev->features[p][6], hdev->features[p][7]);
139dfb826a8SMarcel Holtmann 	}
140cfbb2b5bSMarcel Holtmann 	if (lmp_le_capable(hdev))
141cfbb2b5bSMarcel Holtmann 		seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
142cfbb2b5bSMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
143cfbb2b5bSMarcel Holtmann 			   hdev->le_features[0], hdev->le_features[1],
144cfbb2b5bSMarcel Holtmann 			   hdev->le_features[2], hdev->le_features[3],
145cfbb2b5bSMarcel Holtmann 			   hdev->le_features[4], hdev->le_features[5],
146cfbb2b5bSMarcel Holtmann 			   hdev->le_features[6], hdev->le_features[7]);
147dfb826a8SMarcel Holtmann 	hci_dev_unlock(hdev);
148dfb826a8SMarcel Holtmann 
149dfb826a8SMarcel Holtmann 	return 0;
150dfb826a8SMarcel Holtmann }
151dfb826a8SMarcel Holtmann 
152dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file)
153dfb826a8SMarcel Holtmann {
154dfb826a8SMarcel Holtmann 	return single_open(file, features_show, inode->i_private);
155dfb826a8SMarcel Holtmann }
156dfb826a8SMarcel Holtmann 
157dfb826a8SMarcel Holtmann static const struct file_operations features_fops = {
158dfb826a8SMarcel Holtmann 	.open		= features_open,
159dfb826a8SMarcel Holtmann 	.read		= seq_read,
160dfb826a8SMarcel Holtmann 	.llseek		= seq_lseek,
161dfb826a8SMarcel Holtmann 	.release	= single_release,
162dfb826a8SMarcel Holtmann };
163dfb826a8SMarcel Holtmann 
16470afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p)
16570afe0b8SMarcel Holtmann {
16670afe0b8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
16770afe0b8SMarcel Holtmann 	struct bdaddr_list *b;
16870afe0b8SMarcel Holtmann 
16970afe0b8SMarcel Holtmann 	hci_dev_lock(hdev);
17070afe0b8SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list)
171b25f0785SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
17270afe0b8SMarcel Holtmann 	hci_dev_unlock(hdev);
17370afe0b8SMarcel Holtmann 
17470afe0b8SMarcel Holtmann 	return 0;
17570afe0b8SMarcel Holtmann }
17670afe0b8SMarcel Holtmann 
17770afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file)
17870afe0b8SMarcel Holtmann {
17970afe0b8SMarcel Holtmann 	return single_open(file, blacklist_show, inode->i_private);
18070afe0b8SMarcel Holtmann }
18170afe0b8SMarcel Holtmann 
18270afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = {
18370afe0b8SMarcel Holtmann 	.open		= blacklist_open,
18470afe0b8SMarcel Holtmann 	.read		= seq_read,
18570afe0b8SMarcel Holtmann 	.llseek		= seq_lseek,
18670afe0b8SMarcel Holtmann 	.release	= single_release,
18770afe0b8SMarcel Holtmann };
18870afe0b8SMarcel Holtmann 
18947219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p)
19047219839SMarcel Holtmann {
19147219839SMarcel Holtmann 	struct hci_dev *hdev = f->private;
19247219839SMarcel Holtmann 	struct bt_uuid *uuid;
19347219839SMarcel Holtmann 
19447219839SMarcel Holtmann 	hci_dev_lock(hdev);
19547219839SMarcel Holtmann 	list_for_each_entry(uuid, &hdev->uuids, list) {
19658f01aa9SMarcel Holtmann 		u8 i, val[16];
19747219839SMarcel Holtmann 
19858f01aa9SMarcel Holtmann 		/* The Bluetooth UUID values are stored in big endian,
19958f01aa9SMarcel Holtmann 		 * but with reversed byte order. So convert them into
20058f01aa9SMarcel Holtmann 		 * the right order for the %pUb modifier.
20158f01aa9SMarcel Holtmann 		 */
20258f01aa9SMarcel Holtmann 		for (i = 0; i < 16; i++)
20358f01aa9SMarcel Holtmann 			val[i] = uuid->uuid[15 - i];
20447219839SMarcel Holtmann 
20558f01aa9SMarcel Holtmann 		seq_printf(f, "%pUb\n", val);
20647219839SMarcel Holtmann 	}
20747219839SMarcel Holtmann 	hci_dev_unlock(hdev);
20847219839SMarcel Holtmann 
20947219839SMarcel Holtmann 	return 0;
21047219839SMarcel Holtmann }
21147219839SMarcel Holtmann 
21247219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file)
21347219839SMarcel Holtmann {
21447219839SMarcel Holtmann 	return single_open(file, uuids_show, inode->i_private);
21547219839SMarcel Holtmann }
21647219839SMarcel Holtmann 
21747219839SMarcel Holtmann static const struct file_operations uuids_fops = {
21847219839SMarcel Holtmann 	.open		= uuids_open,
21947219839SMarcel Holtmann 	.read		= seq_read,
22047219839SMarcel Holtmann 	.llseek		= seq_lseek,
22147219839SMarcel Holtmann 	.release	= single_release,
22247219839SMarcel Holtmann };
22347219839SMarcel Holtmann 
224baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p)
225baf27f6eSMarcel Holtmann {
226baf27f6eSMarcel Holtmann 	struct hci_dev *hdev = f->private;
227baf27f6eSMarcel Holtmann 	struct discovery_state *cache = &hdev->discovery;
228baf27f6eSMarcel Holtmann 	struct inquiry_entry *e;
229baf27f6eSMarcel Holtmann 
230baf27f6eSMarcel Holtmann 	hci_dev_lock(hdev);
231baf27f6eSMarcel Holtmann 
232baf27f6eSMarcel Holtmann 	list_for_each_entry(e, &cache->all, all) {
233baf27f6eSMarcel Holtmann 		struct inquiry_data *data = &e->data;
234baf27f6eSMarcel Holtmann 		seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
235baf27f6eSMarcel Holtmann 			   &data->bdaddr,
236baf27f6eSMarcel Holtmann 			   data->pscan_rep_mode, data->pscan_period_mode,
237baf27f6eSMarcel Holtmann 			   data->pscan_mode, data->dev_class[2],
238baf27f6eSMarcel Holtmann 			   data->dev_class[1], data->dev_class[0],
239baf27f6eSMarcel Holtmann 			   __le16_to_cpu(data->clock_offset),
240baf27f6eSMarcel Holtmann 			   data->rssi, data->ssp_mode, e->timestamp);
241baf27f6eSMarcel Holtmann 	}
242baf27f6eSMarcel Holtmann 
243baf27f6eSMarcel Holtmann 	hci_dev_unlock(hdev);
244baf27f6eSMarcel Holtmann 
245baf27f6eSMarcel Holtmann 	return 0;
246baf27f6eSMarcel Holtmann }
247baf27f6eSMarcel Holtmann 
248baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file)
249baf27f6eSMarcel Holtmann {
250baf27f6eSMarcel Holtmann 	return single_open(file, inquiry_cache_show, inode->i_private);
251baf27f6eSMarcel Holtmann }
252baf27f6eSMarcel Holtmann 
253baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = {
254baf27f6eSMarcel Holtmann 	.open		= inquiry_cache_open,
255baf27f6eSMarcel Holtmann 	.read		= seq_read,
256baf27f6eSMarcel Holtmann 	.llseek		= seq_lseek,
257baf27f6eSMarcel Holtmann 	.release	= single_release,
258baf27f6eSMarcel Holtmann };
259baf27f6eSMarcel Holtmann 
26002d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr)
26102d08d15SMarcel Holtmann {
26202d08d15SMarcel Holtmann 	struct hci_dev *hdev = f->private;
26302d08d15SMarcel Holtmann 	struct list_head *p, *n;
26402d08d15SMarcel Holtmann 
26502d08d15SMarcel Holtmann 	hci_dev_lock(hdev);
26602d08d15SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->link_keys) {
26702d08d15SMarcel Holtmann 		struct link_key *key = list_entry(p, struct link_key, list);
26802d08d15SMarcel Holtmann 		seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
26902d08d15SMarcel Holtmann 			   HCI_LINK_KEY_SIZE, key->val, key->pin_len);
27002d08d15SMarcel Holtmann 	}
27102d08d15SMarcel Holtmann 	hci_dev_unlock(hdev);
27202d08d15SMarcel Holtmann 
27302d08d15SMarcel Holtmann 	return 0;
27402d08d15SMarcel Holtmann }
27502d08d15SMarcel Holtmann 
27602d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file)
27702d08d15SMarcel Holtmann {
27802d08d15SMarcel Holtmann 	return single_open(file, link_keys_show, inode->i_private);
27902d08d15SMarcel Holtmann }
28002d08d15SMarcel Holtmann 
28102d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = {
28202d08d15SMarcel Holtmann 	.open		= link_keys_open,
28302d08d15SMarcel Holtmann 	.read		= seq_read,
28402d08d15SMarcel Holtmann 	.llseek		= seq_lseek,
28502d08d15SMarcel Holtmann 	.release	= single_release,
28602d08d15SMarcel Holtmann };
28702d08d15SMarcel Holtmann 
288babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr)
289babdbb3cSMarcel Holtmann {
290babdbb3cSMarcel Holtmann 	struct hci_dev *hdev = f->private;
291babdbb3cSMarcel Holtmann 
292babdbb3cSMarcel Holtmann 	hci_dev_lock(hdev);
293babdbb3cSMarcel Holtmann 	seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
294babdbb3cSMarcel Holtmann 		   hdev->dev_class[1], hdev->dev_class[0]);
295babdbb3cSMarcel Holtmann 	hci_dev_unlock(hdev);
296babdbb3cSMarcel Holtmann 
297babdbb3cSMarcel Holtmann 	return 0;
298babdbb3cSMarcel Holtmann }
299babdbb3cSMarcel Holtmann 
300babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file)
301babdbb3cSMarcel Holtmann {
302babdbb3cSMarcel Holtmann 	return single_open(file, dev_class_show, inode->i_private);
303babdbb3cSMarcel Holtmann }
304babdbb3cSMarcel Holtmann 
305babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = {
306babdbb3cSMarcel Holtmann 	.open		= dev_class_open,
307babdbb3cSMarcel Holtmann 	.read		= seq_read,
308babdbb3cSMarcel Holtmann 	.llseek		= seq_lseek,
309babdbb3cSMarcel Holtmann 	.release	= single_release,
310babdbb3cSMarcel Holtmann };
311babdbb3cSMarcel Holtmann 
312041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val)
313041000b9SMarcel Holtmann {
314041000b9SMarcel Holtmann 	struct hci_dev *hdev = data;
315041000b9SMarcel Holtmann 
316041000b9SMarcel Holtmann 	hci_dev_lock(hdev);
317041000b9SMarcel Holtmann 	*val = hdev->voice_setting;
318041000b9SMarcel Holtmann 	hci_dev_unlock(hdev);
319041000b9SMarcel Holtmann 
320041000b9SMarcel Holtmann 	return 0;
321041000b9SMarcel Holtmann }
322041000b9SMarcel Holtmann 
323041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
324041000b9SMarcel Holtmann 			NULL, "0x%4.4llx\n");
325041000b9SMarcel Holtmann 
326ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val)
327ebd1e33bSMarcel Holtmann {
328ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
329ebd1e33bSMarcel Holtmann 
330ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
331ebd1e33bSMarcel Holtmann 	hdev->auto_accept_delay = val;
332ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
333ebd1e33bSMarcel Holtmann 
334ebd1e33bSMarcel Holtmann 	return 0;
335ebd1e33bSMarcel Holtmann }
336ebd1e33bSMarcel Holtmann 
337ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val)
338ebd1e33bSMarcel Holtmann {
339ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
340ebd1e33bSMarcel Holtmann 
341ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
342ebd1e33bSMarcel Holtmann 	*val = hdev->auto_accept_delay;
343ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
344ebd1e33bSMarcel Holtmann 
345ebd1e33bSMarcel Holtmann 	return 0;
346ebd1e33bSMarcel Holtmann }
347ebd1e33bSMarcel Holtmann 
348ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
349ebd1e33bSMarcel Holtmann 			auto_accept_delay_set, "%llu\n");
350ebd1e33bSMarcel Holtmann 
35106f5b778SMarcel Holtmann static int ssp_debug_mode_set(void *data, u64 val)
35206f5b778SMarcel Holtmann {
35306f5b778SMarcel Holtmann 	struct hci_dev *hdev = data;
35406f5b778SMarcel Holtmann 	struct sk_buff *skb;
35506f5b778SMarcel Holtmann 	__u8 mode;
35606f5b778SMarcel Holtmann 	int err;
35706f5b778SMarcel Holtmann 
35806f5b778SMarcel Holtmann 	if (val != 0 && val != 1)
35906f5b778SMarcel Holtmann 		return -EINVAL;
36006f5b778SMarcel Holtmann 
36106f5b778SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
36206f5b778SMarcel Holtmann 		return -ENETDOWN;
36306f5b778SMarcel Holtmann 
36406f5b778SMarcel Holtmann 	hci_req_lock(hdev);
36506f5b778SMarcel Holtmann 	mode = val;
36606f5b778SMarcel Holtmann 	skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
36706f5b778SMarcel Holtmann 			     &mode, HCI_CMD_TIMEOUT);
36806f5b778SMarcel Holtmann 	hci_req_unlock(hdev);
36906f5b778SMarcel Holtmann 
37006f5b778SMarcel Holtmann 	if (IS_ERR(skb))
37106f5b778SMarcel Holtmann 		return PTR_ERR(skb);
37206f5b778SMarcel Holtmann 
37306f5b778SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
37406f5b778SMarcel Holtmann 	kfree_skb(skb);
37506f5b778SMarcel Holtmann 
37606f5b778SMarcel Holtmann 	if (err < 0)
37706f5b778SMarcel Holtmann 		return err;
37806f5b778SMarcel Holtmann 
37906f5b778SMarcel Holtmann 	hci_dev_lock(hdev);
38006f5b778SMarcel Holtmann 	hdev->ssp_debug_mode = val;
38106f5b778SMarcel Holtmann 	hci_dev_unlock(hdev);
38206f5b778SMarcel Holtmann 
38306f5b778SMarcel Holtmann 	return 0;
38406f5b778SMarcel Holtmann }
38506f5b778SMarcel Holtmann 
38606f5b778SMarcel Holtmann static int ssp_debug_mode_get(void *data, u64 *val)
38706f5b778SMarcel Holtmann {
38806f5b778SMarcel Holtmann 	struct hci_dev *hdev = data;
38906f5b778SMarcel Holtmann 
39006f5b778SMarcel Holtmann 	hci_dev_lock(hdev);
39106f5b778SMarcel Holtmann 	*val = hdev->ssp_debug_mode;
39206f5b778SMarcel Holtmann 	hci_dev_unlock(hdev);
39306f5b778SMarcel Holtmann 
39406f5b778SMarcel Holtmann 	return 0;
39506f5b778SMarcel Holtmann }
39606f5b778SMarcel Holtmann 
39706f5b778SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
39806f5b778SMarcel Holtmann 			ssp_debug_mode_set, "%llu\n");
39906f5b778SMarcel Holtmann 
4005afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
4015afeac14SMarcel Holtmann 				     size_t count, loff_t *ppos)
4025afeac14SMarcel Holtmann {
4035afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
4045afeac14SMarcel Holtmann 	char buf[3];
4055afeac14SMarcel Holtmann 
4065afeac14SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_SC, &hdev->dev_flags) ? 'Y': 'N';
4075afeac14SMarcel Holtmann 	buf[1] = '\n';
4085afeac14SMarcel Holtmann 	buf[2] = '\0';
4095afeac14SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
4105afeac14SMarcel Holtmann }
4115afeac14SMarcel Holtmann 
4125afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file,
4135afeac14SMarcel Holtmann 				      const char __user *user_buf,
4145afeac14SMarcel Holtmann 				      size_t count, loff_t *ppos)
4155afeac14SMarcel Holtmann {
4165afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
4175afeac14SMarcel Holtmann 	char buf[32];
4185afeac14SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
4195afeac14SMarcel Holtmann 	bool enable;
4205afeac14SMarcel Holtmann 
4215afeac14SMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
4225afeac14SMarcel Holtmann 		return -EBUSY;
4235afeac14SMarcel Holtmann 
4245afeac14SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
4255afeac14SMarcel Holtmann 		return -EFAULT;
4265afeac14SMarcel Holtmann 
4275afeac14SMarcel Holtmann 	buf[buf_size] = '\0';
4285afeac14SMarcel Holtmann 	if (strtobool(buf, &enable))
4295afeac14SMarcel Holtmann 		return -EINVAL;
4305afeac14SMarcel Holtmann 
4315afeac14SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_SC, &hdev->dev_flags))
4325afeac14SMarcel Holtmann 		return -EALREADY;
4335afeac14SMarcel Holtmann 
4345afeac14SMarcel Holtmann 	change_bit(HCI_FORCE_SC, &hdev->dev_flags);
4355afeac14SMarcel Holtmann 
4365afeac14SMarcel Holtmann 	return count;
4375afeac14SMarcel Holtmann }
4385afeac14SMarcel Holtmann 
4395afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = {
4405afeac14SMarcel Holtmann 	.open		= simple_open,
4415afeac14SMarcel Holtmann 	.read		= force_sc_support_read,
4425afeac14SMarcel Holtmann 	.write		= force_sc_support_write,
4435afeac14SMarcel Holtmann 	.llseek		= default_llseek,
4445afeac14SMarcel Holtmann };
4455afeac14SMarcel Holtmann 
446134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
447134c2a89SMarcel Holtmann 				 size_t count, loff_t *ppos)
448134c2a89SMarcel Holtmann {
449134c2a89SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
450134c2a89SMarcel Holtmann 	char buf[3];
451134c2a89SMarcel Holtmann 
452134c2a89SMarcel Holtmann 	buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N';
453134c2a89SMarcel Holtmann 	buf[1] = '\n';
454134c2a89SMarcel Holtmann 	buf[2] = '\0';
455134c2a89SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
456134c2a89SMarcel Holtmann }
457134c2a89SMarcel Holtmann 
458134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = {
459134c2a89SMarcel Holtmann 	.open		= simple_open,
460134c2a89SMarcel Holtmann 	.read		= sc_only_mode_read,
461134c2a89SMarcel Holtmann 	.llseek		= default_llseek,
462134c2a89SMarcel Holtmann };
463134c2a89SMarcel Holtmann 
4642bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val)
4652bfa3531SMarcel Holtmann {
4662bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4672bfa3531SMarcel Holtmann 
4682bfa3531SMarcel Holtmann 	if (val != 0 && (val < 500 || val > 3600000))
4692bfa3531SMarcel Holtmann 		return -EINVAL;
4702bfa3531SMarcel Holtmann 
4712bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4722bfa3531SMarcel Holtmann 	hdev->idle_timeout = val;
4732bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4742bfa3531SMarcel Holtmann 
4752bfa3531SMarcel Holtmann 	return 0;
4762bfa3531SMarcel Holtmann }
4772bfa3531SMarcel Holtmann 
4782bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val)
4792bfa3531SMarcel Holtmann {
4802bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4812bfa3531SMarcel Holtmann 
4822bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4832bfa3531SMarcel Holtmann 	*val = hdev->idle_timeout;
4842bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4852bfa3531SMarcel Holtmann 
4862bfa3531SMarcel Holtmann 	return 0;
4872bfa3531SMarcel Holtmann }
4882bfa3531SMarcel Holtmann 
4892bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
4902bfa3531SMarcel Holtmann 			idle_timeout_set, "%llu\n");
4912bfa3531SMarcel Holtmann 
4922bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val)
4932bfa3531SMarcel Holtmann {
4942bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4952bfa3531SMarcel Holtmann 
4962bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
4972bfa3531SMarcel Holtmann 		return -EINVAL;
4982bfa3531SMarcel Holtmann 
4992bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5002bfa3531SMarcel Holtmann 	hdev->sniff_min_interval = val;
5012bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5022bfa3531SMarcel Holtmann 
5032bfa3531SMarcel Holtmann 	return 0;
5042bfa3531SMarcel Holtmann }
5052bfa3531SMarcel Holtmann 
5062bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val)
5072bfa3531SMarcel Holtmann {
5082bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5092bfa3531SMarcel Holtmann 
5102bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5112bfa3531SMarcel Holtmann 	*val = hdev->sniff_min_interval;
5122bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5132bfa3531SMarcel Holtmann 
5142bfa3531SMarcel Holtmann 	return 0;
5152bfa3531SMarcel Holtmann }
5162bfa3531SMarcel Holtmann 
5172bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get,
5182bfa3531SMarcel Holtmann 			sniff_min_interval_set, "%llu\n");
5192bfa3531SMarcel Holtmann 
5202bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val)
5212bfa3531SMarcel Holtmann {
5222bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5232bfa3531SMarcel Holtmann 
5242bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
5252bfa3531SMarcel Holtmann 		return -EINVAL;
5262bfa3531SMarcel Holtmann 
5272bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5282bfa3531SMarcel Holtmann 	hdev->sniff_max_interval = val;
5292bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5302bfa3531SMarcel Holtmann 
5312bfa3531SMarcel Holtmann 	return 0;
5322bfa3531SMarcel Holtmann }
5332bfa3531SMarcel Holtmann 
5342bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val)
5352bfa3531SMarcel Holtmann {
5362bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5372bfa3531SMarcel Holtmann 
5382bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5392bfa3531SMarcel Holtmann 	*val = hdev->sniff_max_interval;
5402bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5412bfa3531SMarcel Holtmann 
5422bfa3531SMarcel Holtmann 	return 0;
5432bfa3531SMarcel Holtmann }
5442bfa3531SMarcel Holtmann 
5452bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
5462bfa3531SMarcel Holtmann 			sniff_max_interval_set, "%llu\n");
5472bfa3531SMarcel Holtmann 
548e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p)
549e7b8fc92SMarcel Holtmann {
550e7b8fc92SMarcel Holtmann 	struct hci_dev *hdev = f->private;
551e7b8fc92SMarcel Holtmann 
552e7b8fc92SMarcel Holtmann 	hci_dev_lock(hdev);
553e7b8fc92SMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->static_addr);
554e7b8fc92SMarcel Holtmann 	hci_dev_unlock(hdev);
555e7b8fc92SMarcel Holtmann 
556e7b8fc92SMarcel Holtmann 	return 0;
557e7b8fc92SMarcel Holtmann }
558e7b8fc92SMarcel Holtmann 
559e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file)
560e7b8fc92SMarcel Holtmann {
561e7b8fc92SMarcel Holtmann 	return single_open(file, static_address_show, inode->i_private);
562e7b8fc92SMarcel Holtmann }
563e7b8fc92SMarcel Holtmann 
564e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = {
565e7b8fc92SMarcel Holtmann 	.open		= static_address_open,
566e7b8fc92SMarcel Holtmann 	.read		= seq_read,
567e7b8fc92SMarcel Holtmann 	.llseek		= seq_lseek,
568e7b8fc92SMarcel Holtmann 	.release	= single_release,
569e7b8fc92SMarcel Holtmann };
570e7b8fc92SMarcel Holtmann 
57192202185SMarcel Holtmann static int own_address_type_set(void *data, u64 val)
57292202185SMarcel Holtmann {
57392202185SMarcel Holtmann 	struct hci_dev *hdev = data;
57492202185SMarcel Holtmann 
57592202185SMarcel Holtmann 	if (val != 0 && val != 1)
57692202185SMarcel Holtmann 		return -EINVAL;
57792202185SMarcel Holtmann 
57892202185SMarcel Holtmann 	hci_dev_lock(hdev);
57992202185SMarcel Holtmann 	hdev->own_addr_type = val;
58092202185SMarcel Holtmann 	hci_dev_unlock(hdev);
58192202185SMarcel Holtmann 
58292202185SMarcel Holtmann 	return 0;
58392202185SMarcel Holtmann }
58492202185SMarcel Holtmann 
58592202185SMarcel Holtmann static int own_address_type_get(void *data, u64 *val)
58692202185SMarcel Holtmann {
58792202185SMarcel Holtmann 	struct hci_dev *hdev = data;
58892202185SMarcel Holtmann 
58992202185SMarcel Holtmann 	hci_dev_lock(hdev);
59092202185SMarcel Holtmann 	*val = hdev->own_addr_type;
59192202185SMarcel Holtmann 	hci_dev_unlock(hdev);
59292202185SMarcel Holtmann 
59392202185SMarcel Holtmann 	return 0;
59492202185SMarcel Holtmann }
59592202185SMarcel Holtmann 
59692202185SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get,
59792202185SMarcel Holtmann 			own_address_type_set, "%llu\n");
59892202185SMarcel Holtmann 
5998f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr)
6008f8625cdSMarcel Holtmann {
6018f8625cdSMarcel Holtmann 	struct hci_dev *hdev = f->private;
6028f8625cdSMarcel Holtmann 	struct list_head *p, *n;
6038f8625cdSMarcel Holtmann 
6048f8625cdSMarcel Holtmann 	hci_dev_lock(hdev);
605f813f1beSJohan Hedberg 	list_for_each_safe(p, n, &hdev->long_term_keys) {
6068f8625cdSMarcel Holtmann 		struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list);
607f813f1beSJohan Hedberg 		seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %*phN %*phN\n",
6088f8625cdSMarcel Holtmann 			   &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
6098f8625cdSMarcel Holtmann 			   ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
6108f8625cdSMarcel Holtmann 			   8, ltk->rand, 16, ltk->val);
6118f8625cdSMarcel Holtmann 	}
6128f8625cdSMarcel Holtmann 	hci_dev_unlock(hdev);
6138f8625cdSMarcel Holtmann 
6148f8625cdSMarcel Holtmann 	return 0;
6158f8625cdSMarcel Holtmann }
6168f8625cdSMarcel Holtmann 
6178f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file)
6188f8625cdSMarcel Holtmann {
6198f8625cdSMarcel Holtmann 	return single_open(file, long_term_keys_show, inode->i_private);
6208f8625cdSMarcel Holtmann }
6218f8625cdSMarcel Holtmann 
6228f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = {
6238f8625cdSMarcel Holtmann 	.open		= long_term_keys_open,
6248f8625cdSMarcel Holtmann 	.read		= seq_read,
6258f8625cdSMarcel Holtmann 	.llseek		= seq_lseek,
6268f8625cdSMarcel Holtmann 	.release	= single_release,
6278f8625cdSMarcel Holtmann };
6288f8625cdSMarcel Holtmann 
6294e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val)
6304e70c7e7SMarcel Holtmann {
6314e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6324e70c7e7SMarcel Holtmann 
6334e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
6344e70c7e7SMarcel Holtmann 		return -EINVAL;
6354e70c7e7SMarcel Holtmann 
6364e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6374e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = val;
6384e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
6394e70c7e7SMarcel Holtmann 
6404e70c7e7SMarcel Holtmann 	return 0;
6414e70c7e7SMarcel Holtmann }
6424e70c7e7SMarcel Holtmann 
6434e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val)
6444e70c7e7SMarcel Holtmann {
6454e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6464e70c7e7SMarcel Holtmann 
6474e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6484e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_min_interval;
6494e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
6504e70c7e7SMarcel Holtmann 
6514e70c7e7SMarcel Holtmann 	return 0;
6524e70c7e7SMarcel Holtmann }
6534e70c7e7SMarcel Holtmann 
6544e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
6554e70c7e7SMarcel Holtmann 			conn_min_interval_set, "%llu\n");
6564e70c7e7SMarcel Holtmann 
6574e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val)
6584e70c7e7SMarcel Holtmann {
6594e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6604e70c7e7SMarcel Holtmann 
6614e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
6624e70c7e7SMarcel Holtmann 		return -EINVAL;
6634e70c7e7SMarcel Holtmann 
6644e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6654e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = val;
6664e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
6674e70c7e7SMarcel Holtmann 
6684e70c7e7SMarcel Holtmann 	return 0;
6694e70c7e7SMarcel Holtmann }
6704e70c7e7SMarcel Holtmann 
6714e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val)
6724e70c7e7SMarcel Holtmann {
6734e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6744e70c7e7SMarcel Holtmann 
6754e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6764e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_max_interval;
6774e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
6784e70c7e7SMarcel Holtmann 
6794e70c7e7SMarcel Holtmann 	return 0;
6804e70c7e7SMarcel Holtmann }
6814e70c7e7SMarcel Holtmann 
6824e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
6834e70c7e7SMarcel Holtmann 			conn_max_interval_set, "%llu\n");
6844e70c7e7SMarcel Holtmann 
68589863109SJukka Rissanen static ssize_t lowpan_read(struct file *file, char __user *user_buf,
68689863109SJukka Rissanen 			   size_t count, loff_t *ppos)
68789863109SJukka Rissanen {
68889863109SJukka Rissanen 	struct hci_dev *hdev = file->private_data;
68989863109SJukka Rissanen 	char buf[3];
69089863109SJukka Rissanen 
69189863109SJukka Rissanen 	buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N';
69289863109SJukka Rissanen 	buf[1] = '\n';
69389863109SJukka Rissanen 	buf[2] = '\0';
69489863109SJukka Rissanen 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
69589863109SJukka Rissanen }
69689863109SJukka Rissanen 
69789863109SJukka Rissanen static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer,
69889863109SJukka Rissanen 			    size_t count, loff_t *position)
69989863109SJukka Rissanen {
70089863109SJukka Rissanen 	struct hci_dev *hdev = fp->private_data;
70189863109SJukka Rissanen 	bool enable;
70289863109SJukka Rissanen 	char buf[32];
70389863109SJukka Rissanen 	size_t buf_size = min(count, (sizeof(buf)-1));
70489863109SJukka Rissanen 
70589863109SJukka Rissanen 	if (copy_from_user(buf, user_buffer, buf_size))
70689863109SJukka Rissanen 		return -EFAULT;
70789863109SJukka Rissanen 
70889863109SJukka Rissanen 	buf[buf_size] = '\0';
70989863109SJukka Rissanen 
71089863109SJukka Rissanen 	if (strtobool(buf, &enable) < 0)
71189863109SJukka Rissanen 		return -EINVAL;
71289863109SJukka Rissanen 
71389863109SJukka Rissanen 	if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
71489863109SJukka Rissanen 		return -EALREADY;
71589863109SJukka Rissanen 
71689863109SJukka Rissanen 	change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags);
71789863109SJukka Rissanen 
71889863109SJukka Rissanen 	return count;
71989863109SJukka Rissanen }
72089863109SJukka Rissanen 
72189863109SJukka Rissanen static const struct file_operations lowpan_debugfs_fops = {
72289863109SJukka Rissanen 	.open		= simple_open,
72389863109SJukka Rissanen 	.read		= lowpan_read,
72489863109SJukka Rissanen 	.write		= lowpan_write,
72589863109SJukka Rissanen 	.llseek		= default_llseek,
72689863109SJukka Rissanen };
72789863109SJukka Rissanen 
7281da177e4SLinus Torvalds /* ---- HCI requests ---- */
7291da177e4SLinus Torvalds 
73042c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
7311da177e4SLinus Torvalds {
73242c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
73375fb0e32SJohan Hedberg 
7341da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
7351da177e4SLinus Torvalds 		hdev->req_result = result;
7361da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
7371da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
7381da177e4SLinus Torvalds 	}
7391da177e4SLinus Torvalds }
7401da177e4SLinus Torvalds 
7411da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
7421da177e4SLinus Torvalds {
7431da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
7441da177e4SLinus Torvalds 
7451da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
7461da177e4SLinus Torvalds 		hdev->req_result = err;
7471da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
7481da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
7491da177e4SLinus Torvalds 	}
7501da177e4SLinus Torvalds }
7511da177e4SLinus Torvalds 
75277a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
75377a63e0aSFengguang Wu 					    u8 event)
75475e84b7cSJohan Hedberg {
75575e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
75675e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
75775e84b7cSJohan Hedberg 	struct sk_buff *skb;
75875e84b7cSJohan Hedberg 
75975e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
76075e84b7cSJohan Hedberg 
76175e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
76275e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
76375e84b7cSJohan Hedberg 
76475e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
76575e84b7cSJohan Hedberg 
76675e84b7cSJohan Hedberg 	if (!skb)
76775e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
76875e84b7cSJohan Hedberg 
76975e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
77075e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
77175e84b7cSJohan Hedberg 		goto failed;
77275e84b7cSJohan Hedberg 	}
77375e84b7cSJohan Hedberg 
77475e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
77575e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
77675e84b7cSJohan Hedberg 
7777b1abbbeSJohan Hedberg 	if (event) {
7787b1abbbeSJohan Hedberg 		if (hdr->evt != event)
7797b1abbbeSJohan Hedberg 			goto failed;
7807b1abbbeSJohan Hedberg 		return skb;
7817b1abbbeSJohan Hedberg 	}
7827b1abbbeSJohan Hedberg 
78375e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
78475e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
78575e84b7cSJohan Hedberg 		goto failed;
78675e84b7cSJohan Hedberg 	}
78775e84b7cSJohan Hedberg 
78875e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
78975e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
79075e84b7cSJohan Hedberg 		goto failed;
79175e84b7cSJohan Hedberg 	}
79275e84b7cSJohan Hedberg 
79375e84b7cSJohan Hedberg 	ev = (void *) skb->data;
79475e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
79575e84b7cSJohan Hedberg 
79675e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
79775e84b7cSJohan Hedberg 		return skb;
79875e84b7cSJohan Hedberg 
79975e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
80075e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
80175e84b7cSJohan Hedberg 
80275e84b7cSJohan Hedberg failed:
80375e84b7cSJohan Hedberg 	kfree_skb(skb);
80475e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
80575e84b7cSJohan Hedberg }
80675e84b7cSJohan Hedberg 
8077b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
80807dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
80975e84b7cSJohan Hedberg {
81075e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
81175e84b7cSJohan Hedberg 	struct hci_request req;
81275e84b7cSJohan Hedberg 	int err = 0;
81375e84b7cSJohan Hedberg 
81475e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
81575e84b7cSJohan Hedberg 
81675e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
81775e84b7cSJohan Hedberg 
8187b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
81975e84b7cSJohan Hedberg 
82075e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
82175e84b7cSJohan Hedberg 
82275e84b7cSJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
82375e84b7cSJohan Hedberg 	if (err < 0)
82475e84b7cSJohan Hedberg 		return ERR_PTR(err);
82575e84b7cSJohan Hedberg 
82675e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
82775e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
82875e84b7cSJohan Hedberg 
82975e84b7cSJohan Hedberg 	schedule_timeout(timeout);
83075e84b7cSJohan Hedberg 
83175e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
83275e84b7cSJohan Hedberg 
83375e84b7cSJohan Hedberg 	if (signal_pending(current))
83475e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
83575e84b7cSJohan Hedberg 
83675e84b7cSJohan Hedberg 	switch (hdev->req_status) {
83775e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
83875e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
83975e84b7cSJohan Hedberg 		break;
84075e84b7cSJohan Hedberg 
84175e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
84275e84b7cSJohan Hedberg 		err = -hdev->req_result;
84375e84b7cSJohan Hedberg 		break;
84475e84b7cSJohan Hedberg 
84575e84b7cSJohan Hedberg 	default:
84675e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
84775e84b7cSJohan Hedberg 		break;
84875e84b7cSJohan Hedberg 	}
84975e84b7cSJohan Hedberg 
85075e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
85175e84b7cSJohan Hedberg 
85275e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
85375e84b7cSJohan Hedberg 
85475e84b7cSJohan Hedberg 	if (err < 0)
85575e84b7cSJohan Hedberg 		return ERR_PTR(err);
85675e84b7cSJohan Hedberg 
8577b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
8587b1abbbeSJohan Hedberg }
8597b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
8607b1abbbeSJohan Hedberg 
8617b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
86207dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
8637b1abbbeSJohan Hedberg {
8647b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
86575e84b7cSJohan Hedberg }
86675e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
86775e84b7cSJohan Hedberg 
8681da177e4SLinus Torvalds /* Execute request and wait for completion. */
86901178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
87042c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
87142c6b129SJohan Hedberg 				      unsigned long opt),
8721da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
8731da177e4SLinus Torvalds {
87442c6b129SJohan Hedberg 	struct hci_request req;
8751da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
8761da177e4SLinus Torvalds 	int err = 0;
8771da177e4SLinus Torvalds 
8781da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
8791da177e4SLinus Torvalds 
88042c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
88142c6b129SJohan Hedberg 
8821da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
8831da177e4SLinus Torvalds 
88442c6b129SJohan Hedberg 	func(&req, opt);
88553cce22dSJohan Hedberg 
88642c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
88742c6b129SJohan Hedberg 	if (err < 0) {
88853cce22dSJohan Hedberg 		hdev->req_status = 0;
889920c8300SAndre Guedes 
890920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
891920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
892920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
893920c8300SAndre Guedes 		 * and should not trigger an error return.
89442c6b129SJohan Hedberg 		 */
895920c8300SAndre Guedes 		if (err == -ENODATA)
89642c6b129SJohan Hedberg 			return 0;
897920c8300SAndre Guedes 
898920c8300SAndre Guedes 		return err;
89953cce22dSJohan Hedberg 	}
90053cce22dSJohan Hedberg 
901bc4445c7SAndre Guedes 	add_wait_queue(&hdev->req_wait_q, &wait);
902bc4445c7SAndre Guedes 	set_current_state(TASK_INTERRUPTIBLE);
903bc4445c7SAndre Guedes 
9041da177e4SLinus Torvalds 	schedule_timeout(timeout);
9051da177e4SLinus Torvalds 
9061da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
9071da177e4SLinus Torvalds 
9081da177e4SLinus Torvalds 	if (signal_pending(current))
9091da177e4SLinus Torvalds 		return -EINTR;
9101da177e4SLinus Torvalds 
9111da177e4SLinus Torvalds 	switch (hdev->req_status) {
9121da177e4SLinus Torvalds 	case HCI_REQ_DONE:
913e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
9141da177e4SLinus Torvalds 		break;
9151da177e4SLinus Torvalds 
9161da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
9171da177e4SLinus Torvalds 		err = -hdev->req_result;
9181da177e4SLinus Torvalds 		break;
9191da177e4SLinus Torvalds 
9201da177e4SLinus Torvalds 	default:
9211da177e4SLinus Torvalds 		err = -ETIMEDOUT;
9221da177e4SLinus Torvalds 		break;
9233ff50b79SStephen Hemminger 	}
9241da177e4SLinus Torvalds 
925a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
9261da177e4SLinus Torvalds 
9271da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
9281da177e4SLinus Torvalds 
9291da177e4SLinus Torvalds 	return err;
9301da177e4SLinus Torvalds }
9311da177e4SLinus Torvalds 
93201178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
93342c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
93442c6b129SJohan Hedberg 				    unsigned long opt),
9351da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
9361da177e4SLinus Torvalds {
9371da177e4SLinus Torvalds 	int ret;
9381da177e4SLinus Torvalds 
9397c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
9407c6a329eSMarcel Holtmann 		return -ENETDOWN;
9417c6a329eSMarcel Holtmann 
9421da177e4SLinus Torvalds 	/* Serialize all requests */
9431da177e4SLinus Torvalds 	hci_req_lock(hdev);
94401178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
9451da177e4SLinus Torvalds 	hci_req_unlock(hdev);
9461da177e4SLinus Torvalds 
9471da177e4SLinus Torvalds 	return ret;
9481da177e4SLinus Torvalds }
9491da177e4SLinus Torvalds 
95042c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
9511da177e4SLinus Torvalds {
95242c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
9531da177e4SLinus Torvalds 
9541da177e4SLinus Torvalds 	/* Reset device */
95542c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
95642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
9571da177e4SLinus Torvalds }
9581da177e4SLinus Torvalds 
95942c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
9601da177e4SLinus Torvalds {
96142c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
9622455a3eaSAndrei Emeltchenko 
9631da177e4SLinus Torvalds 	/* Read Local Supported Features */
96442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
9651da177e4SLinus Torvalds 
9661143e5a6SMarcel Holtmann 	/* Read Local Version */
96742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
9682177bab5SJohan Hedberg 
9692177bab5SJohan Hedberg 	/* Read BD Address */
97042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
9711da177e4SLinus Torvalds }
9721da177e4SLinus Torvalds 
97342c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
974e61ef499SAndrei Emeltchenko {
97542c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
9762455a3eaSAndrei Emeltchenko 
977e61ef499SAndrei Emeltchenko 	/* Read Local Version */
97842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
9796bcbc489SAndrei Emeltchenko 
980f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
981f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
982f6996cfeSMarcel Holtmann 
983f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
984f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
985f6996cfeSMarcel Holtmann 
9866bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
98742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
988e71dfabaSAndrei Emeltchenko 
989e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
99042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
9917528ca1cSMarcel Holtmann 
992f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
993f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
994f38ba941SMarcel Holtmann 
9957528ca1cSMarcel Holtmann 	/* Read Location Data */
9967528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
997e61ef499SAndrei Emeltchenko }
998e61ef499SAndrei Emeltchenko 
99942c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
1000e61ef499SAndrei Emeltchenko {
100142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1002e61ef499SAndrei Emeltchenko 
1003e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
1004e61ef499SAndrei Emeltchenko 
100511778716SAndrei Emeltchenko 	/* Reset */
100611778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
100742c6b129SJohan Hedberg 		hci_reset_req(req, 0);
100811778716SAndrei Emeltchenko 
1009e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
1010e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
101142c6b129SJohan Hedberg 		bredr_init(req);
1012e61ef499SAndrei Emeltchenko 		break;
1013e61ef499SAndrei Emeltchenko 
1014e61ef499SAndrei Emeltchenko 	case HCI_AMP:
101542c6b129SJohan Hedberg 		amp_init(req);
1016e61ef499SAndrei Emeltchenko 		break;
1017e61ef499SAndrei Emeltchenko 
1018e61ef499SAndrei Emeltchenko 	default:
1019e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
1020e61ef499SAndrei Emeltchenko 		break;
1021e61ef499SAndrei Emeltchenko 	}
1022e61ef499SAndrei Emeltchenko }
1023e61ef499SAndrei Emeltchenko 
102442c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
10252177bab5SJohan Hedberg {
10264ca048e3SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
10274ca048e3SMarcel Holtmann 
10282177bab5SJohan Hedberg 	__le16 param;
10292177bab5SJohan Hedberg 	__u8 flt_type;
10302177bab5SJohan Hedberg 
10312177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
103242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
10332177bab5SJohan Hedberg 
10342177bab5SJohan Hedberg 	/* Read Class of Device */
103542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
10362177bab5SJohan Hedberg 
10372177bab5SJohan Hedberg 	/* Read Local Name */
103842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
10392177bab5SJohan Hedberg 
10402177bab5SJohan Hedberg 	/* Read Voice Setting */
104142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
10422177bab5SJohan Hedberg 
1043b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
1044b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
1045b4cb9fb2SMarcel Holtmann 
10464b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
10474b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
10484b836f39SMarcel Holtmann 
10492177bab5SJohan Hedberg 	/* Clear Event Filters */
10502177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
105142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
10522177bab5SJohan Hedberg 
10532177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
10542177bab5SJohan Hedberg 	param = __constant_cpu_to_le16(0x7d00);
105542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
10562177bab5SJohan Hedberg 
10574ca048e3SMarcel Holtmann 	/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
10584ca048e3SMarcel Holtmann 	 * but it does not support page scan related HCI commands.
10594ca048e3SMarcel Holtmann 	 */
10604ca048e3SMarcel Holtmann 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
1061f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
1062f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
1063f332ec66SJohan Hedberg 	}
10642177bab5SJohan Hedberg }
10652177bab5SJohan Hedberg 
106642c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
10672177bab5SJohan Hedberg {
1068c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1069c73eee91SJohan Hedberg 
10702177bab5SJohan Hedberg 	/* Read LE Buffer Size */
107142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
10722177bab5SJohan Hedberg 
10732177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
107442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
10752177bab5SJohan Hedberg 
10762177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
107742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
10782177bab5SJohan Hedberg 
10792177bab5SJohan Hedberg 	/* Read LE White List Size */
108042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
10812177bab5SJohan Hedberg 
10822177bab5SJohan Hedberg 	/* Read LE Supported States */
108342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
1084c73eee91SJohan Hedberg 
1085c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
1086c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1087c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
10882177bab5SJohan Hedberg }
10892177bab5SJohan Hedberg 
10902177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
10912177bab5SJohan Hedberg {
10922177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
10932177bab5SJohan Hedberg 		return 0x02;
10942177bab5SJohan Hedberg 
10952177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
10962177bab5SJohan Hedberg 		return 0x01;
10972177bab5SJohan Hedberg 
10982177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
10992177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
11002177bab5SJohan Hedberg 		return 0x01;
11012177bab5SJohan Hedberg 
11022177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
11032177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
11042177bab5SJohan Hedberg 			return 0x01;
11052177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
11062177bab5SJohan Hedberg 			return 0x01;
11072177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
11082177bab5SJohan Hedberg 			return 0x01;
11092177bab5SJohan Hedberg 	}
11102177bab5SJohan Hedberg 
11112177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
11122177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
11132177bab5SJohan Hedberg 		return 0x01;
11142177bab5SJohan Hedberg 
11152177bab5SJohan Hedberg 	return 0x00;
11162177bab5SJohan Hedberg }
11172177bab5SJohan Hedberg 
111842c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
11192177bab5SJohan Hedberg {
11202177bab5SJohan Hedberg 	u8 mode;
11212177bab5SJohan Hedberg 
112242c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
11232177bab5SJohan Hedberg 
112442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
11252177bab5SJohan Hedberg }
11262177bab5SJohan Hedberg 
112742c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
11282177bab5SJohan Hedberg {
112942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
113042c6b129SJohan Hedberg 
11312177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
11322177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
11332177bab5SJohan Hedberg 	 * command otherwise.
11342177bab5SJohan Hedberg 	 */
11352177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
11362177bab5SJohan Hedberg 
11372177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
11382177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
11392177bab5SJohan Hedberg 	 */
11402177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
11412177bab5SJohan Hedberg 		return;
11422177bab5SJohan Hedberg 
11432177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
11442177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
11452177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
11462177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
11472177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
11482177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
1149c7882cbdSMarcel Holtmann 	} else {
1150c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
1151c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
1152c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
1153c7882cbdSMarcel Holtmann 		events[0] |= 0x80; /* Encryption Change */
1154c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
1155c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
1156c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
1157c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
1158c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
1159c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
1160c7882cbdSMarcel Holtmann 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
11612177bab5SJohan Hedberg 	}
11622177bab5SJohan Hedberg 
11632177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
11642177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
11652177bab5SJohan Hedberg 
11662177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
11672177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
11682177bab5SJohan Hedberg 
11692177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
11702177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
11712177bab5SJohan Hedberg 
11722177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
11732177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
11742177bab5SJohan Hedberg 
11752177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
11762177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
11772177bab5SJohan Hedberg 
11782177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
11792177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
11802177bab5SJohan Hedberg 
11812177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
11822177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
11832177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
11842177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
11852177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
11862177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
11872177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
11882177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
11892177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
11902177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
11912177bab5SJohan Hedberg 					 * Features Notification
11922177bab5SJohan Hedberg 					 */
11932177bab5SJohan Hedberg 	}
11942177bab5SJohan Hedberg 
11952177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
11962177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
11972177bab5SJohan Hedberg 
119842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
11992177bab5SJohan Hedberg 
12002177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
12012177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
12022177bab5SJohan Hedberg 		events[0] = 0x1f;
120342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
12042177bab5SJohan Hedberg 			    sizeof(events), events);
12052177bab5SJohan Hedberg 	}
12062177bab5SJohan Hedberg }
12072177bab5SJohan Hedberg 
120842c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
12092177bab5SJohan Hedberg {
121042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
121142c6b129SJohan Hedberg 
12122177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
121342c6b129SJohan Hedberg 		bredr_setup(req);
121456f87901SJohan Hedberg 	else
121556f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
12162177bab5SJohan Hedberg 
12172177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
121842c6b129SJohan Hedberg 		le_setup(req);
12192177bab5SJohan Hedberg 
122042c6b129SJohan Hedberg 	hci_setup_event_mask(req);
12212177bab5SJohan Hedberg 
12223f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
12233f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
12243f8e2d75SJohan Hedberg 	 */
12253f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
122642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
12272177bab5SJohan Hedberg 
12282177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
122957af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
123057af75a8SMarcel Holtmann 		 * should also be available as well. However some
123157af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
123257af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
123357af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
123457af75a8SMarcel Holtmann 		 */
123557af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
123657af75a8SMarcel Holtmann 
12372177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
12382177bab5SJohan Hedberg 			u8 mode = 0x01;
123942c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
12402177bab5SJohan Hedberg 				    sizeof(mode), &mode);
12412177bab5SJohan Hedberg 		} else {
12422177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
12432177bab5SJohan Hedberg 
12442177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
12452177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
12462177bab5SJohan Hedberg 
124742c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
12482177bab5SJohan Hedberg 		}
12492177bab5SJohan Hedberg 	}
12502177bab5SJohan Hedberg 
12512177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
125242c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
12532177bab5SJohan Hedberg 
12542177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
125542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
12562177bab5SJohan Hedberg 
12572177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
12582177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
12592177bab5SJohan Hedberg 
12602177bab5SJohan Hedberg 		cp.page = 0x01;
126142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
126242c6b129SJohan Hedberg 			    sizeof(cp), &cp);
12632177bab5SJohan Hedberg 	}
12642177bab5SJohan Hedberg 
12652177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
12662177bab5SJohan Hedberg 		u8 enable = 1;
126742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
12682177bab5SJohan Hedberg 			    &enable);
12692177bab5SJohan Hedberg 	}
12702177bab5SJohan Hedberg }
12712177bab5SJohan Hedberg 
127242c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
12732177bab5SJohan Hedberg {
127442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
12752177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
12762177bab5SJohan Hedberg 	u16 link_policy = 0;
12772177bab5SJohan Hedberg 
12782177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
12792177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
12802177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
12812177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
12822177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
12832177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
12842177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
12852177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
12862177bab5SJohan Hedberg 
12872177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
128842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
12892177bab5SJohan Hedberg }
12902177bab5SJohan Hedberg 
129142c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
12922177bab5SJohan Hedberg {
129342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
12942177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
12952177bab5SJohan Hedberg 
1296c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
1297c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1298c73eee91SJohan Hedberg 		return;
1299c73eee91SJohan Hedberg 
13002177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
13012177bab5SJohan Hedberg 
13022177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
13032177bab5SJohan Hedberg 		cp.le = 0x01;
13042177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
13052177bab5SJohan Hedberg 	}
13062177bab5SJohan Hedberg 
13072177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
130842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
13092177bab5SJohan Hedberg 			    &cp);
13102177bab5SJohan Hedberg }
13112177bab5SJohan Hedberg 
1312d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
1313d62e6d67SJohan Hedberg {
1314d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1315d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1316d62e6d67SJohan Hedberg 
1317d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
1318d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1319d62e6d67SJohan Hedberg 	 */
132053b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
1321d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
1322d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
1323d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
1324d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
1325d62e6d67SJohan Hedberg 	}
1326d62e6d67SJohan Hedberg 
1327d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
1328d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1329d62e6d67SJohan Hedberg 	 */
133053b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
1331d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
1332d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
1333d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
1334d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
1335d62e6d67SJohan Hedberg 	}
1336d62e6d67SJohan Hedberg 
133740c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
133840c59fcbSMarcel Holtmann 	if (lmp_ping_capable(hdev))
133940c59fcbSMarcel Holtmann 		events[2] |= 0x80;
134040c59fcbSMarcel Holtmann 
1341d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
1342d62e6d67SJohan Hedberg }
1343d62e6d67SJohan Hedberg 
134442c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
13452177bab5SJohan Hedberg {
134642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1347d2c5d77fSJohan Hedberg 	u8 p;
134842c6b129SJohan Hedberg 
1349b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
1350b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
1351b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
1352b8f4e068SGustavo Padovan 	 *
1353b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
1354b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
1355b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
1356b8f4e068SGustavo Padovan 	 * command redundant anyway.
1357f9f462faSMarcel Holtmann 	 *
1358f9f462faSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
1359f9f462faSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
1360f9f462faSMarcel Holtmann 	 * just disable this command.
1361b8f4e068SGustavo Padovan 	 */
1362f9f462faSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
1363f9f462faSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
136459f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
136559f45d57SJohan Hedberg 
136659f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
136759f45d57SJohan Hedberg 		cp.delete_all = 0x01;
136859f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
136959f45d57SJohan Hedberg 			    sizeof(cp), &cp);
137059f45d57SJohan Hedberg 	}
137159f45d57SJohan Hedberg 
13722177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
137342c6b129SJohan Hedberg 		hci_setup_link_policy(req);
13742177bab5SJohan Hedberg 
137579830f66SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1376bef34c0aSMarcel Holtmann 		if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
1377bef34c0aSMarcel Holtmann 			/* If the controller has a public BD_ADDR, then
1378bef34c0aSMarcel Holtmann 			 * by default use that one. If this is a LE only
1379bef34c0aSMarcel Holtmann 			 * controller without a public address, default
1380bef34c0aSMarcel Holtmann 			 * to the random address.
138179830f66SMarcel Holtmann 			 */
138279830f66SMarcel Holtmann 			if (bacmp(&hdev->bdaddr, BDADDR_ANY))
138379830f66SMarcel Holtmann 				hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
138479830f66SMarcel Holtmann 			else
138579830f66SMarcel Holtmann 				hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
1386bef34c0aSMarcel Holtmann 		}
138779830f66SMarcel Holtmann 
138842c6b129SJohan Hedberg 		hci_set_le_support(req);
138979830f66SMarcel Holtmann 	}
1390d2c5d77fSJohan Hedberg 
1391d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
1392d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
1393d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
1394d2c5d77fSJohan Hedberg 
1395d2c5d77fSJohan Hedberg 		cp.page = p;
1396d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
1397d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
1398d2c5d77fSJohan Hedberg 	}
13992177bab5SJohan Hedberg }
14002177bab5SJohan Hedberg 
14015d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
14025d4e7e8dSJohan Hedberg {
14035d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
14045d4e7e8dSJohan Hedberg 
1405d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
1406d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
1407d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
1408d62e6d67SJohan Hedberg 
14095d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
141053b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
14115d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
1412a6d0d690SMarcel Holtmann 
1413a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
14145afeac14SMarcel Holtmann 	if ((lmp_sc_capable(hdev) ||
14155afeac14SMarcel Holtmann 	     test_bit(HCI_FORCE_SC, &hdev->dev_flags)) &&
1416a6d0d690SMarcel Holtmann 	    test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
1417a6d0d690SMarcel Holtmann 		u8 support = 0x01;
1418a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
1419a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
1420a6d0d690SMarcel Holtmann 	}
14215d4e7e8dSJohan Hedberg }
14225d4e7e8dSJohan Hedberg 
14232177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
14242177bab5SJohan Hedberg {
14252177bab5SJohan Hedberg 	int err;
14262177bab5SJohan Hedberg 
14272177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
14282177bab5SJohan Hedberg 	if (err < 0)
14292177bab5SJohan Hedberg 		return err;
14302177bab5SJohan Hedberg 
14314b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
14324b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
14334b4148e9SMarcel Holtmann 	 */
14344b4148e9SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
14354b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
14364b4148e9SMarcel Holtmann 				    &dut_mode_fops);
14374b4148e9SMarcel Holtmann 	}
14384b4148e9SMarcel Holtmann 
14392177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
14402177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
14412177bab5SJohan Hedberg 	 * first stage init.
14422177bab5SJohan Hedberg 	 */
14432177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
14442177bab5SJohan Hedberg 		return 0;
14452177bab5SJohan Hedberg 
14462177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
14472177bab5SJohan Hedberg 	if (err < 0)
14482177bab5SJohan Hedberg 		return err;
14492177bab5SJohan Hedberg 
14505d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
14515d4e7e8dSJohan Hedberg 	if (err < 0)
14525d4e7e8dSJohan Hedberg 		return err;
14535d4e7e8dSJohan Hedberg 
1454baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
1455baf27f6eSMarcel Holtmann 	if (err < 0)
1456baf27f6eSMarcel Holtmann 		return err;
1457baf27f6eSMarcel Holtmann 
1458baf27f6eSMarcel Holtmann 	/* Only create debugfs entries during the initial setup
1459baf27f6eSMarcel Holtmann 	 * phase and not every time the controller gets powered on.
1460baf27f6eSMarcel Holtmann 	 */
1461baf27f6eSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1462baf27f6eSMarcel Holtmann 		return 0;
1463baf27f6eSMarcel Holtmann 
1464dfb826a8SMarcel Holtmann 	debugfs_create_file("features", 0444, hdev->debugfs, hdev,
1465dfb826a8SMarcel Holtmann 			    &features_fops);
1466ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
1467ceeb3bc0SMarcel Holtmann 			   &hdev->manufacturer);
1468ceeb3bc0SMarcel Holtmann 	debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
1469ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
147070afe0b8SMarcel Holtmann 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
147170afe0b8SMarcel Holtmann 			    &blacklist_fops);
147247219839SMarcel Holtmann 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
147347219839SMarcel Holtmann 
1474baf27f6eSMarcel Holtmann 	if (lmp_bredr_capable(hdev)) {
1475baf27f6eSMarcel Holtmann 		debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
1476baf27f6eSMarcel Holtmann 				    hdev, &inquiry_cache_fops);
147702d08d15SMarcel Holtmann 		debugfs_create_file("link_keys", 0400, hdev->debugfs,
147802d08d15SMarcel Holtmann 				    hdev, &link_keys_fops);
1479babdbb3cSMarcel Holtmann 		debugfs_create_file("dev_class", 0444, hdev->debugfs,
1480babdbb3cSMarcel Holtmann 				    hdev, &dev_class_fops);
1481041000b9SMarcel Holtmann 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
1482041000b9SMarcel Holtmann 				    hdev, &voice_setting_fops);
1483baf27f6eSMarcel Holtmann 	}
1484baf27f6eSMarcel Holtmann 
148506f5b778SMarcel Holtmann 	if (lmp_ssp_capable(hdev)) {
1486ebd1e33bSMarcel Holtmann 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
1487ebd1e33bSMarcel Holtmann 				    hdev, &auto_accept_delay_fops);
148806f5b778SMarcel Holtmann 		debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
148906f5b778SMarcel Holtmann 				    hdev, &ssp_debug_mode_fops);
14905afeac14SMarcel Holtmann 		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
14915afeac14SMarcel Holtmann 				    hdev, &force_sc_support_fops);
1492134c2a89SMarcel Holtmann 		debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
1493134c2a89SMarcel Holtmann 				    hdev, &sc_only_mode_fops);
149406f5b778SMarcel Holtmann 	}
1495ebd1e33bSMarcel Holtmann 
14962bfa3531SMarcel Holtmann 	if (lmp_sniff_capable(hdev)) {
14972bfa3531SMarcel Holtmann 		debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
14982bfa3531SMarcel Holtmann 				    hdev, &idle_timeout_fops);
14992bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
15002bfa3531SMarcel Holtmann 				    hdev, &sniff_min_interval_fops);
15012bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
15022bfa3531SMarcel Holtmann 				    hdev, &sniff_max_interval_fops);
15032bfa3531SMarcel Holtmann 	}
15042bfa3531SMarcel Holtmann 
1505d0f729b8SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1506d0f729b8SMarcel Holtmann 		debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1507d0f729b8SMarcel Holtmann 				  &hdev->le_white_list_size);
1508e7b8fc92SMarcel Holtmann 		debugfs_create_file("static_address", 0444, hdev->debugfs,
1509e7b8fc92SMarcel Holtmann 				   hdev, &static_address_fops);
151092202185SMarcel Holtmann 		debugfs_create_file("own_address_type", 0644, hdev->debugfs,
151192202185SMarcel Holtmann 				    hdev, &own_address_type_fops);
15128f8625cdSMarcel Holtmann 		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
15138f8625cdSMarcel Holtmann 				    hdev, &long_term_keys_fops);
15144e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
15154e70c7e7SMarcel Holtmann 				    hdev, &conn_min_interval_fops);
15164e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
15174e70c7e7SMarcel Holtmann 				    hdev, &conn_max_interval_fops);
151889863109SJukka Rissanen 		debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
151989863109SJukka Rissanen 				    &lowpan_debugfs_fops);
1520d0f729b8SMarcel Holtmann 	}
1521e7b8fc92SMarcel Holtmann 
1522baf27f6eSMarcel Holtmann 	return 0;
15232177bab5SJohan Hedberg }
15242177bab5SJohan Hedberg 
152542c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
15261da177e4SLinus Torvalds {
15271da177e4SLinus Torvalds 	__u8 scan = opt;
15281da177e4SLinus Torvalds 
152942c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
15301da177e4SLinus Torvalds 
15311da177e4SLinus Torvalds 	/* Inquiry and Page scans */
153242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
15331da177e4SLinus Torvalds }
15341da177e4SLinus Torvalds 
153542c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
15361da177e4SLinus Torvalds {
15371da177e4SLinus Torvalds 	__u8 auth = opt;
15381da177e4SLinus Torvalds 
153942c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
15401da177e4SLinus Torvalds 
15411da177e4SLinus Torvalds 	/* Authentication */
154242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
15431da177e4SLinus Torvalds }
15441da177e4SLinus Torvalds 
154542c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
15461da177e4SLinus Torvalds {
15471da177e4SLinus Torvalds 	__u8 encrypt = opt;
15481da177e4SLinus Torvalds 
154942c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
15501da177e4SLinus Torvalds 
1551e4e8e37cSMarcel Holtmann 	/* Encryption */
155242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
15531da177e4SLinus Torvalds }
15541da177e4SLinus Torvalds 
155542c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
1556e4e8e37cSMarcel Holtmann {
1557e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
1558e4e8e37cSMarcel Holtmann 
155942c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
1560e4e8e37cSMarcel Holtmann 
1561e4e8e37cSMarcel Holtmann 	/* Default link policy */
156242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
1563e4e8e37cSMarcel Holtmann }
1564e4e8e37cSMarcel Holtmann 
15651da177e4SLinus Torvalds /* Get HCI device by index.
15661da177e4SLinus Torvalds  * Device is held on return. */
15671da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
15681da177e4SLinus Torvalds {
15698035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
15701da177e4SLinus Torvalds 
15711da177e4SLinus Torvalds 	BT_DBG("%d", index);
15721da177e4SLinus Torvalds 
15731da177e4SLinus Torvalds 	if (index < 0)
15741da177e4SLinus Torvalds 		return NULL;
15751da177e4SLinus Torvalds 
15761da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
15778035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
15781da177e4SLinus Torvalds 		if (d->id == index) {
15791da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
15801da177e4SLinus Torvalds 			break;
15811da177e4SLinus Torvalds 		}
15821da177e4SLinus Torvalds 	}
15831da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
15841da177e4SLinus Torvalds 	return hdev;
15851da177e4SLinus Torvalds }
15861da177e4SLinus Torvalds 
15871da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1588ff9ef578SJohan Hedberg 
158930dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
159030dc78e1SJohan Hedberg {
159130dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
159230dc78e1SJohan Hedberg 
15936fbe195dSAndre Guedes 	switch (discov->state) {
1594343f935bSAndre Guedes 	case DISCOVERY_FINDING:
15956fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
159630dc78e1SJohan Hedberg 		return true;
159730dc78e1SJohan Hedberg 
15986fbe195dSAndre Guedes 	default:
159930dc78e1SJohan Hedberg 		return false;
160030dc78e1SJohan Hedberg 	}
16016fbe195dSAndre Guedes }
160230dc78e1SJohan Hedberg 
1603ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1604ff9ef578SJohan Hedberg {
1605ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1606ff9ef578SJohan Hedberg 
1607ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
1608ff9ef578SJohan Hedberg 		return;
1609ff9ef578SJohan Hedberg 
1610ff9ef578SJohan Hedberg 	switch (state) {
1611ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
16127b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
1613ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1614ff9ef578SJohan Hedberg 		break;
1615ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1616ff9ef578SJohan Hedberg 		break;
1617343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1618ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1619ff9ef578SJohan Hedberg 		break;
162030dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
162130dc78e1SJohan Hedberg 		break;
1622ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1623ff9ef578SJohan Hedberg 		break;
1624ff9ef578SJohan Hedberg 	}
1625ff9ef578SJohan Hedberg 
1626ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
1627ff9ef578SJohan Hedberg }
1628ff9ef578SJohan Hedberg 
16291f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
16301da177e4SLinus Torvalds {
163130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1632b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
16331da177e4SLinus Torvalds 
1634561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
1635561aafbcSJohan Hedberg 		list_del(&p->all);
1636b57c1a56SJohan Hedberg 		kfree(p);
16371da177e4SLinus Torvalds 	}
1638561aafbcSJohan Hedberg 
1639561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
1640561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
16411da177e4SLinus Torvalds }
16421da177e4SLinus Torvalds 
1643a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
1644a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
16451da177e4SLinus Torvalds {
164630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
16471da177e4SLinus Torvalds 	struct inquiry_entry *e;
16481da177e4SLinus Torvalds 
16496ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
16501da177e4SLinus Torvalds 
1651561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
16521da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
16531da177e4SLinus Torvalds 			return e;
16541da177e4SLinus Torvalds 	}
16551da177e4SLinus Torvalds 
1656b57c1a56SJohan Hedberg 	return NULL;
1657b57c1a56SJohan Hedberg }
1658b57c1a56SJohan Hedberg 
1659561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
1660561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
1661561aafbcSJohan Hedberg {
166230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1663561aafbcSJohan Hedberg 	struct inquiry_entry *e;
1664561aafbcSJohan Hedberg 
16656ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1666561aafbcSJohan Hedberg 
1667561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
1668561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
1669561aafbcSJohan Hedberg 			return e;
1670561aafbcSJohan Hedberg 	}
1671561aafbcSJohan Hedberg 
1672561aafbcSJohan Hedberg 	return NULL;
1673561aafbcSJohan Hedberg }
1674561aafbcSJohan Hedberg 
167530dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
167630dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
167730dc78e1SJohan Hedberg 						       int state)
167830dc78e1SJohan Hedberg {
167930dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
168030dc78e1SJohan Hedberg 	struct inquiry_entry *e;
168130dc78e1SJohan Hedberg 
16826ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
168330dc78e1SJohan Hedberg 
168430dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
168530dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
168630dc78e1SJohan Hedberg 			return e;
168730dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
168830dc78e1SJohan Hedberg 			return e;
168930dc78e1SJohan Hedberg 	}
169030dc78e1SJohan Hedberg 
169130dc78e1SJohan Hedberg 	return NULL;
169230dc78e1SJohan Hedberg }
169330dc78e1SJohan Hedberg 
1694a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
1695a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
1696a3d4e20aSJohan Hedberg {
1697a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1698a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
1699a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
1700a3d4e20aSJohan Hedberg 
1701a3d4e20aSJohan Hedberg 	list_del(&ie->list);
1702a3d4e20aSJohan Hedberg 
1703a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
1704a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
1705a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
1706a3d4e20aSJohan Hedberg 			break;
1707a3d4e20aSJohan Hedberg 		pos = &p->list;
1708a3d4e20aSJohan Hedberg 	}
1709a3d4e20aSJohan Hedberg 
1710a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
1711a3d4e20aSJohan Hedberg }
1712a3d4e20aSJohan Hedberg 
17133175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
1714388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
17151da177e4SLinus Torvalds {
171630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
171770f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
17181da177e4SLinus Torvalds 
17196ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
17201da177e4SLinus Torvalds 
17212b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
17222b2fec4dSSzymon Janc 
1723388fc8faSJohan Hedberg 	if (ssp)
1724388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
1725388fc8faSJohan Hedberg 
172670f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
1727a3d4e20aSJohan Hedberg 	if (ie) {
1728388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
1729388fc8faSJohan Hedberg 			*ssp = true;
1730388fc8faSJohan Hedberg 
1731a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
1732a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
1733a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
1734a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
1735a3d4e20aSJohan Hedberg 		}
1736a3d4e20aSJohan Hedberg 
1737561aafbcSJohan Hedberg 		goto update;
1738a3d4e20aSJohan Hedberg 	}
1739561aafbcSJohan Hedberg 
17401da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
174170f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
174270f23020SAndrei Emeltchenko 	if (!ie)
17433175405bSJohan Hedberg 		return false;
174470f23020SAndrei Emeltchenko 
1745561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
1746561aafbcSJohan Hedberg 
1747561aafbcSJohan Hedberg 	if (name_known) {
1748561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1749561aafbcSJohan Hedberg 	} else {
1750561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
1751561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
1752561aafbcSJohan Hedberg 	}
1753561aafbcSJohan Hedberg 
1754561aafbcSJohan Hedberg update:
1755561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
1756561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
1757561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1758561aafbcSJohan Hedberg 		list_del(&ie->list);
17591da177e4SLinus Torvalds 	}
17601da177e4SLinus Torvalds 
176170f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
176270f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
17631da177e4SLinus Torvalds 	cache->timestamp = jiffies;
17643175405bSJohan Hedberg 
17653175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
17663175405bSJohan Hedberg 		return false;
17673175405bSJohan Hedberg 
17683175405bSJohan Hedberg 	return true;
17691da177e4SLinus Torvalds }
17701da177e4SLinus Torvalds 
17711da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
17721da177e4SLinus Torvalds {
177330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
17741da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
17751da177e4SLinus Torvalds 	struct inquiry_entry *e;
17761da177e4SLinus Torvalds 	int copied = 0;
17771da177e4SLinus Torvalds 
1778561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
17791da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
1780b57c1a56SJohan Hedberg 
1781b57c1a56SJohan Hedberg 		if (copied >= num)
1782b57c1a56SJohan Hedberg 			break;
1783b57c1a56SJohan Hedberg 
17841da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
17851da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
17861da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
17871da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
17881da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
17891da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1790b57c1a56SJohan Hedberg 
17911da177e4SLinus Torvalds 		info++;
1792b57c1a56SJohan Hedberg 		copied++;
17931da177e4SLinus Torvalds 	}
17941da177e4SLinus Torvalds 
17951da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
17961da177e4SLinus Torvalds 	return copied;
17971da177e4SLinus Torvalds }
17981da177e4SLinus Torvalds 
179942c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
18001da177e4SLinus Torvalds {
18011da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
180242c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
18031da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
18041da177e4SLinus Torvalds 
18051da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
18061da177e4SLinus Torvalds 
18071da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
18081da177e4SLinus Torvalds 		return;
18091da177e4SLinus Torvalds 
18101da177e4SLinus Torvalds 	/* Start Inquiry */
18111da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
18121da177e4SLinus Torvalds 	cp.length  = ir->length;
18131da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
181442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
18151da177e4SLinus Torvalds }
18161da177e4SLinus Torvalds 
18173e13fa1eSAndre Guedes static int wait_inquiry(void *word)
18183e13fa1eSAndre Guedes {
18193e13fa1eSAndre Guedes 	schedule();
18203e13fa1eSAndre Guedes 	return signal_pending(current);
18213e13fa1eSAndre Guedes }
18223e13fa1eSAndre Guedes 
18231da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
18241da177e4SLinus Torvalds {
18251da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
18261da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
18271da177e4SLinus Torvalds 	struct hci_dev *hdev;
18281da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
18291da177e4SLinus Torvalds 	long timeo;
18301da177e4SLinus Torvalds 	__u8 *buf;
18311da177e4SLinus Torvalds 
18321da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
18331da177e4SLinus Torvalds 		return -EFAULT;
18341da177e4SLinus Torvalds 
18355a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
18365a08ecceSAndrei Emeltchenko 	if (!hdev)
18371da177e4SLinus Torvalds 		return -ENODEV;
18381da177e4SLinus Torvalds 
18390736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
18400736cfa8SMarcel Holtmann 		err = -EBUSY;
18410736cfa8SMarcel Holtmann 		goto done;
18420736cfa8SMarcel Holtmann 	}
18430736cfa8SMarcel Holtmann 
18445b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
18455b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
18465b69bef5SMarcel Holtmann 		goto done;
18475b69bef5SMarcel Holtmann 	}
18485b69bef5SMarcel Holtmann 
184956f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
185056f87901SJohan Hedberg 		err = -EOPNOTSUPP;
185156f87901SJohan Hedberg 		goto done;
185256f87901SJohan Hedberg 	}
185356f87901SJohan Hedberg 
185409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
18551da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1856a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
18571f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
18581da177e4SLinus Torvalds 		do_inquiry = 1;
18591da177e4SLinus Torvalds 	}
186009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
18611da177e4SLinus Torvalds 
186204837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
186370f23020SAndrei Emeltchenko 
186470f23020SAndrei Emeltchenko 	if (do_inquiry) {
186501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
186601178cd4SJohan Hedberg 				   timeo);
186770f23020SAndrei Emeltchenko 		if (err < 0)
18681da177e4SLinus Torvalds 			goto done;
18693e13fa1eSAndre Guedes 
18703e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
18713e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
18723e13fa1eSAndre Guedes 		 */
18733e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
18743e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
18753e13fa1eSAndre Guedes 			return -EINTR;
187670f23020SAndrei Emeltchenko 	}
18771da177e4SLinus Torvalds 
18788fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
18798fc9ced3SGustavo Padovan 	 * 255 entries
18808fc9ced3SGustavo Padovan 	 */
18811da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
18821da177e4SLinus Torvalds 
18831da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
18841da177e4SLinus Torvalds 	 * copy it to the user space.
18851da177e4SLinus Torvalds 	 */
188670f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
188770f23020SAndrei Emeltchenko 	if (!buf) {
18881da177e4SLinus Torvalds 		err = -ENOMEM;
18891da177e4SLinus Torvalds 		goto done;
18901da177e4SLinus Torvalds 	}
18911da177e4SLinus Torvalds 
189209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
18931da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
189409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
18951da177e4SLinus Torvalds 
18961da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
18971da177e4SLinus Torvalds 
18981da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
18991da177e4SLinus Torvalds 		ptr += sizeof(ir);
19001da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
19011da177e4SLinus Torvalds 				 ir.num_rsp))
19021da177e4SLinus Torvalds 			err = -EFAULT;
19031da177e4SLinus Torvalds 	} else
19041da177e4SLinus Torvalds 		err = -EFAULT;
19051da177e4SLinus Torvalds 
19061da177e4SLinus Torvalds 	kfree(buf);
19071da177e4SLinus Torvalds 
19081da177e4SLinus Torvalds done:
19091da177e4SLinus Torvalds 	hci_dev_put(hdev);
19101da177e4SLinus Torvalds 	return err;
19111da177e4SLinus Torvalds }
19121da177e4SLinus Torvalds 
1913cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
19141da177e4SLinus Torvalds {
19151da177e4SLinus Torvalds 	int ret = 0;
19161da177e4SLinus Torvalds 
19171da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
19181da177e4SLinus Torvalds 
19191da177e4SLinus Torvalds 	hci_req_lock(hdev);
19201da177e4SLinus Torvalds 
192194324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
192294324962SJohan Hovold 		ret = -ENODEV;
192394324962SJohan Hovold 		goto done;
192494324962SJohan Hovold 	}
192594324962SJohan Hovold 
1926a5c8f270SMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
1927a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1928a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1929bf543036SJohan Hedberg 		 */
1930a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
1931611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1932611b30f7SMarcel Holtmann 			goto done;
1933611b30f7SMarcel Holtmann 		}
1934611b30f7SMarcel Holtmann 
1935a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1936a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1937a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1938a5c8f270SMarcel Holtmann 		 * or not.
1939a5c8f270SMarcel Holtmann 		 *
1940a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1941a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1942a5c8f270SMarcel Holtmann 		 */
1943a5c8f270SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR &&
1944a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1945a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1946a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1947a5c8f270SMarcel Holtmann 			goto done;
1948a5c8f270SMarcel Holtmann 		}
1949a5c8f270SMarcel Holtmann 	}
1950a5c8f270SMarcel Holtmann 
19511da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
19521da177e4SLinus Torvalds 		ret = -EALREADY;
19531da177e4SLinus Torvalds 		goto done;
19541da177e4SLinus Torvalds 	}
19551da177e4SLinus Torvalds 
19561da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
19571da177e4SLinus Torvalds 		ret = -EIO;
19581da177e4SLinus Torvalds 		goto done;
19591da177e4SLinus Torvalds 	}
19601da177e4SLinus Torvalds 
19611da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
19621da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1963f41c70c4SMarcel Holtmann 
1964f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
1965f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
1966f41c70c4SMarcel Holtmann 
1967f41c70c4SMarcel Holtmann 	if (!ret) {
1968f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1969f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1970f41c70c4SMarcel Holtmann 
19710736cfa8SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags) &&
19720736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
19732177bab5SJohan Hedberg 			ret = __hci_init(hdev);
19741da177e4SLinus Torvalds 	}
19751da177e4SLinus Torvalds 
1976f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1977f41c70c4SMarcel Holtmann 
19781da177e4SLinus Torvalds 	if (!ret) {
19791da177e4SLinus Torvalds 		hci_dev_hold(hdev);
19801da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
19811da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1982bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
19830736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
19841514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
198509fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1986744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
198709fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
198856e5cb86SJohan Hedberg 		}
19891da177e4SLinus Torvalds 	} else {
19901da177e4SLinus Torvalds 		/* Init failed, cleanup */
19913eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1992c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1993b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
19941da177e4SLinus Torvalds 
19951da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
19961da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
19971da177e4SLinus Torvalds 
19981da177e4SLinus Torvalds 		if (hdev->flush)
19991da177e4SLinus Torvalds 			hdev->flush(hdev);
20001da177e4SLinus Torvalds 
20011da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
20021da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
20031da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
20041da177e4SLinus Torvalds 		}
20051da177e4SLinus Torvalds 
20061da177e4SLinus Torvalds 		hdev->close(hdev);
20071da177e4SLinus Torvalds 		hdev->flags = 0;
20081da177e4SLinus Torvalds 	}
20091da177e4SLinus Torvalds 
20101da177e4SLinus Torvalds done:
20111da177e4SLinus Torvalds 	hci_req_unlock(hdev);
20121da177e4SLinus Torvalds 	return ret;
20131da177e4SLinus Torvalds }
20141da177e4SLinus Torvalds 
2015cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
2016cbed0ca1SJohan Hedberg 
2017cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
2018cbed0ca1SJohan Hedberg {
2019cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
2020cbed0ca1SJohan Hedberg 	int err;
2021cbed0ca1SJohan Hedberg 
2022cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
2023cbed0ca1SJohan Hedberg 	if (!hdev)
2024cbed0ca1SJohan Hedberg 		return -ENODEV;
2025cbed0ca1SJohan Hedberg 
2026e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
2027e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
2028e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
2029e1d08f40SJohan Hedberg 	 * completed.
2030e1d08f40SJohan Hedberg 	 */
2031e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2032e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
2033e1d08f40SJohan Hedberg 
2034a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
2035a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
2036a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
2037a5c8f270SMarcel Holtmann 	 */
2038e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
2039e1d08f40SJohan Hedberg 
2040cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
2041cbed0ca1SJohan Hedberg 
2042cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
2043cbed0ca1SJohan Hedberg 
2044cbed0ca1SJohan Hedberg 	return err;
2045cbed0ca1SJohan Hedberg }
2046cbed0ca1SJohan Hedberg 
20471da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
20481da177e4SLinus Torvalds {
20491da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
20501da177e4SLinus Torvalds 
205178c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
205278c04c0bSVinicius Costa Gomes 
20531da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
20541da177e4SLinus Torvalds 	hci_req_lock(hdev);
20551da177e4SLinus Torvalds 
20561da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
2057b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
20581da177e4SLinus Torvalds 		hci_req_unlock(hdev);
20591da177e4SLinus Torvalds 		return 0;
20601da177e4SLinus Torvalds 	}
20611da177e4SLinus Torvalds 
20623eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
20633eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
2064b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
20651da177e4SLinus Torvalds 
206616ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
2067e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
206816ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
20695e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
2070310a3d48SMarcel Holtmann 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
207116ab91abSJohan Hedberg 	}
207216ab91abSJohan Hedberg 
2073a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
20747d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
20757d78525dSJohan Hedberg 
20767ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
20777ba8b4beSAndre Guedes 
207809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
20791f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
20801da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
208109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
20821da177e4SLinus Torvalds 
20831da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
20841da177e4SLinus Torvalds 
20851da177e4SLinus Torvalds 	if (hdev->flush)
20861da177e4SLinus Torvalds 		hdev->flush(hdev);
20871da177e4SLinus Torvalds 
20881da177e4SLinus Torvalds 	/* Reset device */
20891da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
20901da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
20918af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
20923a6afbd2SMarcel Holtmann 	    !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
2093a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
20941da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
209501178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
20961da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
20971da177e4SLinus Torvalds 	}
20981da177e4SLinus Torvalds 
2099c347b765SGustavo F. Padovan 	/* flush cmd  work */
2100c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
21011da177e4SLinus Torvalds 
21021da177e4SLinus Torvalds 	/* Drop queues */
21031da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
21041da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
21051da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
21061da177e4SLinus Torvalds 
21071da177e4SLinus Torvalds 	/* Drop last sent command */
21081da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
2109b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
21101da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
21111da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
21121da177e4SLinus Torvalds 	}
21131da177e4SLinus Torvalds 
2114b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
2115b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
2116b6ddb638SJohan Hedberg 
21171da177e4SLinus Torvalds 	/* After this point our queues are empty
21181da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
21191da177e4SLinus Torvalds 	hdev->close(hdev);
21201da177e4SLinus Torvalds 
212135b973c9SJohan Hedberg 	/* Clear flags */
212235b973c9SJohan Hedberg 	hdev->flags = 0;
212335b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
212435b973c9SJohan Hedberg 
212593c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
212693c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
212709fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2128744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
212909fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
21308ee56540SMarcel Holtmann 		}
213193c311a0SMarcel Holtmann 	}
21325add6af8SJohan Hedberg 
2133ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
2134536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
2135ced5c338SAndrei Emeltchenko 
2136e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
213709b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
2138e59fda8dSJohan Hedberg 
21391da177e4SLinus Torvalds 	hci_req_unlock(hdev);
21401da177e4SLinus Torvalds 
21411da177e4SLinus Torvalds 	hci_dev_put(hdev);
21421da177e4SLinus Torvalds 	return 0;
21431da177e4SLinus Torvalds }
21441da177e4SLinus Torvalds 
21451da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
21461da177e4SLinus Torvalds {
21471da177e4SLinus Torvalds 	struct hci_dev *hdev;
21481da177e4SLinus Torvalds 	int err;
21491da177e4SLinus Torvalds 
215070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
215170f23020SAndrei Emeltchenko 	if (!hdev)
21521da177e4SLinus Torvalds 		return -ENODEV;
21538ee56540SMarcel Holtmann 
21540736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
21550736cfa8SMarcel Holtmann 		err = -EBUSY;
21560736cfa8SMarcel Holtmann 		goto done;
21570736cfa8SMarcel Holtmann 	}
21580736cfa8SMarcel Holtmann 
21598ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
21608ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
21618ee56540SMarcel Holtmann 
21621da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
21638ee56540SMarcel Holtmann 
21640736cfa8SMarcel Holtmann done:
21651da177e4SLinus Torvalds 	hci_dev_put(hdev);
21661da177e4SLinus Torvalds 	return err;
21671da177e4SLinus Torvalds }
21681da177e4SLinus Torvalds 
21691da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
21701da177e4SLinus Torvalds {
21711da177e4SLinus Torvalds 	struct hci_dev *hdev;
21721da177e4SLinus Torvalds 	int ret = 0;
21731da177e4SLinus Torvalds 
217470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
217570f23020SAndrei Emeltchenko 	if (!hdev)
21761da177e4SLinus Torvalds 		return -ENODEV;
21771da177e4SLinus Torvalds 
21781da177e4SLinus Torvalds 	hci_req_lock(hdev);
21791da177e4SLinus Torvalds 
2180808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
2181808a049eSMarcel Holtmann 		ret = -ENETDOWN;
21821da177e4SLinus Torvalds 		goto done;
2183808a049eSMarcel Holtmann 	}
21841da177e4SLinus Torvalds 
21850736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
21860736cfa8SMarcel Holtmann 		ret = -EBUSY;
21870736cfa8SMarcel Holtmann 		goto done;
21880736cfa8SMarcel Holtmann 	}
21890736cfa8SMarcel Holtmann 
21901da177e4SLinus Torvalds 	/* Drop queues */
21911da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
21921da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
21931da177e4SLinus Torvalds 
219409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
21951f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
21961da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
219709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
21981da177e4SLinus Torvalds 
21991da177e4SLinus Torvalds 	if (hdev->flush)
22001da177e4SLinus Torvalds 		hdev->flush(hdev);
22011da177e4SLinus Torvalds 
22021da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
22036ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
22041da177e4SLinus Torvalds 
22051da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
220601178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
22071da177e4SLinus Torvalds 
22081da177e4SLinus Torvalds done:
22091da177e4SLinus Torvalds 	hci_req_unlock(hdev);
22101da177e4SLinus Torvalds 	hci_dev_put(hdev);
22111da177e4SLinus Torvalds 	return ret;
22121da177e4SLinus Torvalds }
22131da177e4SLinus Torvalds 
22141da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
22151da177e4SLinus Torvalds {
22161da177e4SLinus Torvalds 	struct hci_dev *hdev;
22171da177e4SLinus Torvalds 	int ret = 0;
22181da177e4SLinus Torvalds 
221970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
222070f23020SAndrei Emeltchenko 	if (!hdev)
22211da177e4SLinus Torvalds 		return -ENODEV;
22221da177e4SLinus Torvalds 
22230736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22240736cfa8SMarcel Holtmann 		ret = -EBUSY;
22250736cfa8SMarcel Holtmann 		goto done;
22260736cfa8SMarcel Holtmann 	}
22270736cfa8SMarcel Holtmann 
22281da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
22291da177e4SLinus Torvalds 
22300736cfa8SMarcel Holtmann done:
22311da177e4SLinus Torvalds 	hci_dev_put(hdev);
22321da177e4SLinus Torvalds 	return ret;
22331da177e4SLinus Torvalds }
22341da177e4SLinus Torvalds 
22351da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
22361da177e4SLinus Torvalds {
22371da177e4SLinus Torvalds 	struct hci_dev *hdev;
22381da177e4SLinus Torvalds 	struct hci_dev_req dr;
22391da177e4SLinus Torvalds 	int err = 0;
22401da177e4SLinus Torvalds 
22411da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
22421da177e4SLinus Torvalds 		return -EFAULT;
22431da177e4SLinus Torvalds 
224470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
224570f23020SAndrei Emeltchenko 	if (!hdev)
22461da177e4SLinus Torvalds 		return -ENODEV;
22471da177e4SLinus Torvalds 
22480736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22490736cfa8SMarcel Holtmann 		err = -EBUSY;
22500736cfa8SMarcel Holtmann 		goto done;
22510736cfa8SMarcel Holtmann 	}
22520736cfa8SMarcel Holtmann 
22535b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
22545b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
22555b69bef5SMarcel Holtmann 		goto done;
22565b69bef5SMarcel Holtmann 	}
22575b69bef5SMarcel Holtmann 
225856f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
225956f87901SJohan Hedberg 		err = -EOPNOTSUPP;
226056f87901SJohan Hedberg 		goto done;
226156f87901SJohan Hedberg 	}
226256f87901SJohan Hedberg 
22631da177e4SLinus Torvalds 	switch (cmd) {
22641da177e4SLinus Torvalds 	case HCISETAUTH:
226501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
22665f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
22671da177e4SLinus Torvalds 		break;
22681da177e4SLinus Torvalds 
22691da177e4SLinus Torvalds 	case HCISETENCRYPT:
22701da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
22711da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
22721da177e4SLinus Torvalds 			break;
22731da177e4SLinus Torvalds 		}
22741da177e4SLinus Torvalds 
22751da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
22761da177e4SLinus Torvalds 			/* Auth must be enabled first */
227701178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
22785f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
22791da177e4SLinus Torvalds 			if (err)
22801da177e4SLinus Torvalds 				break;
22811da177e4SLinus Torvalds 		}
22821da177e4SLinus Torvalds 
228301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
22845f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
22851da177e4SLinus Torvalds 		break;
22861da177e4SLinus Torvalds 
22871da177e4SLinus Torvalds 	case HCISETSCAN:
228801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
22895f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
22901da177e4SLinus Torvalds 		break;
22911da177e4SLinus Torvalds 
22921da177e4SLinus Torvalds 	case HCISETLINKPOL:
229301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
22945f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
22951da177e4SLinus Torvalds 		break;
22961da177e4SLinus Torvalds 
22971da177e4SLinus Torvalds 	case HCISETLINKMODE:
2298e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2299e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2300e4e8e37cSMarcel Holtmann 		break;
2301e4e8e37cSMarcel Holtmann 
2302e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2303e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
23041da177e4SLinus Torvalds 		break;
23051da177e4SLinus Torvalds 
23061da177e4SLinus Torvalds 	case HCISETACLMTU:
23071da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
23081da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
23091da177e4SLinus Torvalds 		break;
23101da177e4SLinus Torvalds 
23111da177e4SLinus Torvalds 	case HCISETSCOMTU:
23121da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
23131da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
23141da177e4SLinus Torvalds 		break;
23151da177e4SLinus Torvalds 
23161da177e4SLinus Torvalds 	default:
23171da177e4SLinus Torvalds 		err = -EINVAL;
23181da177e4SLinus Torvalds 		break;
23191da177e4SLinus Torvalds 	}
2320e4e8e37cSMarcel Holtmann 
23210736cfa8SMarcel Holtmann done:
23221da177e4SLinus Torvalds 	hci_dev_put(hdev);
23231da177e4SLinus Torvalds 	return err;
23241da177e4SLinus Torvalds }
23251da177e4SLinus Torvalds 
23261da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
23271da177e4SLinus Torvalds {
23288035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
23291da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
23301da177e4SLinus Torvalds 	struct hci_dev_req *dr;
23311da177e4SLinus Torvalds 	int n = 0, size, err;
23321da177e4SLinus Torvalds 	__u16 dev_num;
23331da177e4SLinus Torvalds 
23341da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
23351da177e4SLinus Torvalds 		return -EFAULT;
23361da177e4SLinus Torvalds 
23371da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
23381da177e4SLinus Torvalds 		return -EINVAL;
23391da177e4SLinus Torvalds 
23401da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
23411da177e4SLinus Torvalds 
234270f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
234370f23020SAndrei Emeltchenko 	if (!dl)
23441da177e4SLinus Torvalds 		return -ENOMEM;
23451da177e4SLinus Torvalds 
23461da177e4SLinus Torvalds 	dr = dl->dev_req;
23471da177e4SLinus Torvalds 
2348f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
23498035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
2350a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2351e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
2352c542a06cSJohan Hedberg 
2353a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2354a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
2355c542a06cSJohan Hedberg 
23561da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
23571da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
2358c542a06cSJohan Hedberg 
23591da177e4SLinus Torvalds 		if (++n >= dev_num)
23601da177e4SLinus Torvalds 			break;
23611da177e4SLinus Torvalds 	}
2362f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
23631da177e4SLinus Torvalds 
23641da177e4SLinus Torvalds 	dl->dev_num = n;
23651da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
23661da177e4SLinus Torvalds 
23671da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
23681da177e4SLinus Torvalds 	kfree(dl);
23691da177e4SLinus Torvalds 
23701da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
23711da177e4SLinus Torvalds }
23721da177e4SLinus Torvalds 
23731da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
23741da177e4SLinus Torvalds {
23751da177e4SLinus Torvalds 	struct hci_dev *hdev;
23761da177e4SLinus Torvalds 	struct hci_dev_info di;
23771da177e4SLinus Torvalds 	int err = 0;
23781da177e4SLinus Torvalds 
23791da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
23801da177e4SLinus Torvalds 		return -EFAULT;
23811da177e4SLinus Torvalds 
238270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
238370f23020SAndrei Emeltchenko 	if (!hdev)
23841da177e4SLinus Torvalds 		return -ENODEV;
23851da177e4SLinus Torvalds 
2386a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
23873243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
2388ab81cbf9SJohan Hedberg 
2389a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2390a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
2391c542a06cSJohan Hedberg 
23921da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
23931da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
239460f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
23951da177e4SLinus Torvalds 	di.flags    = hdev->flags;
23961da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2397572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
23981da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
23991da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
24001da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
24011da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2402572c7f84SJohan Hedberg 	} else {
2403572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2404572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2405572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2406572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2407572c7f84SJohan Hedberg 	}
24081da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
24091da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
24101da177e4SLinus Torvalds 
24111da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
24121da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
24131da177e4SLinus Torvalds 
24141da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
24151da177e4SLinus Torvalds 		err = -EFAULT;
24161da177e4SLinus Torvalds 
24171da177e4SLinus Torvalds 	hci_dev_put(hdev);
24181da177e4SLinus Torvalds 
24191da177e4SLinus Torvalds 	return err;
24201da177e4SLinus Torvalds }
24211da177e4SLinus Torvalds 
24221da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
24231da177e4SLinus Torvalds 
2424611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2425611b30f7SMarcel Holtmann {
2426611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2427611b30f7SMarcel Holtmann 
2428611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2429611b30f7SMarcel Holtmann 
24300736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
24310736cfa8SMarcel Holtmann 		return -EBUSY;
24320736cfa8SMarcel Holtmann 
24335e130367SJohan Hedberg 	if (blocked) {
24345e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
2435bf543036SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags))
2436611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
24375e130367SJohan Hedberg 	} else {
24385e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
24395e130367SJohan Hedberg 	}
2440611b30f7SMarcel Holtmann 
2441611b30f7SMarcel Holtmann 	return 0;
2442611b30f7SMarcel Holtmann }
2443611b30f7SMarcel Holtmann 
2444611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2445611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2446611b30f7SMarcel Holtmann };
2447611b30f7SMarcel Holtmann 
2448ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2449ab81cbf9SJohan Hedberg {
2450ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
245196570ffcSJohan Hedberg 	int err;
2452ab81cbf9SJohan Hedberg 
2453ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2454ab81cbf9SJohan Hedberg 
2455cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
245696570ffcSJohan Hedberg 	if (err < 0) {
245796570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
2458ab81cbf9SJohan Hedberg 		return;
245996570ffcSJohan Hedberg 	}
2460ab81cbf9SJohan Hedberg 
2461a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2462a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2463a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2464a5c8f270SMarcel Holtmann 	 */
2465a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
2466a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
2467a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2468a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2469bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2470bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2471bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
247219202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
247319202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2474bf543036SJohan Hedberg 	}
2475ab81cbf9SJohan Hedberg 
2476a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
2477744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2478ab81cbf9SJohan Hedberg }
2479ab81cbf9SJohan Hedberg 
2480ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2481ab81cbf9SJohan Hedberg {
24823243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
24833243553fSJohan Hedberg 					    power_off.work);
2484ab81cbf9SJohan Hedberg 
2485ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2486ab81cbf9SJohan Hedberg 
24878ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2488ab81cbf9SJohan Hedberg }
2489ab81cbf9SJohan Hedberg 
249016ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
249116ab91abSJohan Hedberg {
249216ab91abSJohan Hedberg 	struct hci_dev *hdev;
249316ab91abSJohan Hedberg 
249416ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
249516ab91abSJohan Hedberg 
249616ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
249716ab91abSJohan Hedberg 
2498d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
249916ab91abSJohan Hedberg }
250016ab91abSJohan Hedberg 
25012aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
25022aeb9a1aSJohan Hedberg {
25034821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
25042aeb9a1aSJohan Hedberg 
25054821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
25064821002cSJohan Hedberg 		list_del(&uuid->list);
25072aeb9a1aSJohan Hedberg 		kfree(uuid);
25082aeb9a1aSJohan Hedberg 	}
25092aeb9a1aSJohan Hedberg 
25102aeb9a1aSJohan Hedberg 	return 0;
25112aeb9a1aSJohan Hedberg }
25122aeb9a1aSJohan Hedberg 
251355ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
251455ed8ca1SJohan Hedberg {
251555ed8ca1SJohan Hedberg 	struct list_head *p, *n;
251655ed8ca1SJohan Hedberg 
251755ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
251855ed8ca1SJohan Hedberg 		struct link_key *key;
251955ed8ca1SJohan Hedberg 
252055ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
252155ed8ca1SJohan Hedberg 
252255ed8ca1SJohan Hedberg 		list_del(p);
252355ed8ca1SJohan Hedberg 		kfree(key);
252455ed8ca1SJohan Hedberg 	}
252555ed8ca1SJohan Hedberg 
252655ed8ca1SJohan Hedberg 	return 0;
252755ed8ca1SJohan Hedberg }
252855ed8ca1SJohan Hedberg 
2529b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
2530b899efafSVinicius Costa Gomes {
2531b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2532b899efafSVinicius Costa Gomes 
2533b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2534b899efafSVinicius Costa Gomes 		list_del(&k->list);
2535b899efafSVinicius Costa Gomes 		kfree(k);
2536b899efafSVinicius Costa Gomes 	}
2537b899efafSVinicius Costa Gomes 
2538b899efafSVinicius Costa Gomes 	return 0;
2539b899efafSVinicius Costa Gomes }
2540b899efafSVinicius Costa Gomes 
254155ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
254255ed8ca1SJohan Hedberg {
254355ed8ca1SJohan Hedberg 	struct link_key *k;
254455ed8ca1SJohan Hedberg 
25458035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
254655ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
254755ed8ca1SJohan Hedberg 			return k;
254855ed8ca1SJohan Hedberg 
254955ed8ca1SJohan Hedberg 	return NULL;
255055ed8ca1SJohan Hedberg }
255155ed8ca1SJohan Hedberg 
2552745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2553d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2554d25e28abSJohan Hedberg {
2555d25e28abSJohan Hedberg 	/* Legacy key */
2556d25e28abSJohan Hedberg 	if (key_type < 0x03)
2557745c0ce3SVishal Agarwal 		return true;
2558d25e28abSJohan Hedberg 
2559d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2560d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2561745c0ce3SVishal Agarwal 		return false;
2562d25e28abSJohan Hedberg 
2563d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2564d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2565745c0ce3SVishal Agarwal 		return false;
2566d25e28abSJohan Hedberg 
2567d25e28abSJohan Hedberg 	/* Security mode 3 case */
2568d25e28abSJohan Hedberg 	if (!conn)
2569745c0ce3SVishal Agarwal 		return true;
2570d25e28abSJohan Hedberg 
2571d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2572d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2573745c0ce3SVishal Agarwal 		return true;
2574d25e28abSJohan Hedberg 
2575d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2576d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2577745c0ce3SVishal Agarwal 		return true;
2578d25e28abSJohan Hedberg 
2579d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2580d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2581745c0ce3SVishal Agarwal 		return true;
2582d25e28abSJohan Hedberg 
2583d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2584d25e28abSJohan Hedberg 	 * persistently */
2585745c0ce3SVishal Agarwal 	return false;
2586d25e28abSJohan Hedberg }
2587d25e28abSJohan Hedberg 
258898a0b845SJohan Hedberg static bool ltk_type_master(u8 type)
258998a0b845SJohan Hedberg {
259098a0b845SJohan Hedberg 	if (type == HCI_SMP_STK || type == HCI_SMP_LTK)
259198a0b845SJohan Hedberg 		return true;
259298a0b845SJohan Hedberg 
259398a0b845SJohan Hedberg 	return false;
259498a0b845SJohan Hedberg }
259598a0b845SJohan Hedberg 
259698a0b845SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8],
259798a0b845SJohan Hedberg 			     bool master)
259875d262c2SVinicius Costa Gomes {
2599c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
260075d262c2SVinicius Costa Gomes 
2601c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
2602c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
2603c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
260475d262c2SVinicius Costa Gomes 			continue;
260575d262c2SVinicius Costa Gomes 
260698a0b845SJohan Hedberg 		if (ltk_type_master(k->type) != master)
260798a0b845SJohan Hedberg 			continue;
260898a0b845SJohan Hedberg 
260975d262c2SVinicius Costa Gomes 		return k;
261075d262c2SVinicius Costa Gomes 	}
261175d262c2SVinicius Costa Gomes 
261275d262c2SVinicius Costa Gomes 	return NULL;
261375d262c2SVinicius Costa Gomes }
261475d262c2SVinicius Costa Gomes 
2615c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
261698a0b845SJohan Hedberg 				     u8 addr_type, bool master)
261775d262c2SVinicius Costa Gomes {
2618c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
261975d262c2SVinicius Costa Gomes 
2620c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
2621c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
262298a0b845SJohan Hedberg 		    bacmp(bdaddr, &k->bdaddr) == 0 &&
262398a0b845SJohan Hedberg 		    ltk_type_master(k->type) == master)
262475d262c2SVinicius Costa Gomes 			return k;
262575d262c2SVinicius Costa Gomes 
262675d262c2SVinicius Costa Gomes 	return NULL;
262775d262c2SVinicius Costa Gomes }
262875d262c2SVinicius Costa Gomes 
2629d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
2630d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
263155ed8ca1SJohan Hedberg {
263255ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2633745c0ce3SVishal Agarwal 	u8 old_key_type;
2634745c0ce3SVishal Agarwal 	bool persistent;
263555ed8ca1SJohan Hedberg 
263655ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
263755ed8ca1SJohan Hedberg 	if (old_key) {
263855ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
263955ed8ca1SJohan Hedberg 		key = old_key;
264055ed8ca1SJohan Hedberg 	} else {
264112adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
264255ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
264355ed8ca1SJohan Hedberg 		if (!key)
264455ed8ca1SJohan Hedberg 			return -ENOMEM;
264555ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
264655ed8ca1SJohan Hedberg 	}
264755ed8ca1SJohan Hedberg 
26486ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
264955ed8ca1SJohan Hedberg 
2650d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2651d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2652d25e28abSJohan Hedberg 	 * previous key */
2653d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2654a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2655d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2656655fe6ecSJohan Hedberg 		if (conn)
2657655fe6ecSJohan Hedberg 			conn->key_type = type;
2658655fe6ecSJohan Hedberg 	}
2659d25e28abSJohan Hedberg 
266055ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
26619b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
266255ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
266355ed8ca1SJohan Hedberg 
2664b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
266555ed8ca1SJohan Hedberg 		key->type = old_key_type;
26664748fed2SJohan Hedberg 	else
26674748fed2SJohan Hedberg 		key->type = type;
26684748fed2SJohan Hedberg 
26694df378a1SJohan Hedberg 	if (!new_key)
26704df378a1SJohan Hedberg 		return 0;
26714df378a1SJohan Hedberg 
26724df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
26734df378a1SJohan Hedberg 
2674744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
26754df378a1SJohan Hedberg 
26766ec5bcadSVishal Agarwal 	if (conn)
26776ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
267855ed8ca1SJohan Hedberg 
267955ed8ca1SJohan Hedberg 	return 0;
268055ed8ca1SJohan Hedberg }
268155ed8ca1SJohan Hedberg 
2682c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
26839a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
268404124681SGustavo F. Padovan 		ediv, u8 rand[8])
268575d262c2SVinicius Costa Gomes {
2686c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
268798a0b845SJohan Hedberg 	bool master = ltk_type_master(type);
268875d262c2SVinicius Costa Gomes 
268998a0b845SJohan Hedberg 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master);
2690c9839a11SVinicius Costa Gomes 	if (old_key)
269175d262c2SVinicius Costa Gomes 		key = old_key;
2692c9839a11SVinicius Costa Gomes 	else {
2693c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
269475d262c2SVinicius Costa Gomes 		if (!key)
269575d262c2SVinicius Costa Gomes 			return -ENOMEM;
2696c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
269775d262c2SVinicius Costa Gomes 	}
269875d262c2SVinicius Costa Gomes 
269975d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2700c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2701c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2702c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2703c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2704c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2705c9839a11SVinicius Costa Gomes 	key->type = type;
2706c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
270775d262c2SVinicius Costa Gomes 
2708c9839a11SVinicius Costa Gomes 	if (!new_key)
2709c9839a11SVinicius Costa Gomes 		return 0;
271075d262c2SVinicius Costa Gomes 
271121b93b75SJohan Hedberg 	if (type == HCI_SMP_LTK || type == HCI_SMP_LTK_SLAVE)
2712261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
2713261cc5aaSVinicius Costa Gomes 
271475d262c2SVinicius Costa Gomes 	return 0;
271575d262c2SVinicius Costa Gomes }
271675d262c2SVinicius Costa Gomes 
271755ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
271855ed8ca1SJohan Hedberg {
271955ed8ca1SJohan Hedberg 	struct link_key *key;
272055ed8ca1SJohan Hedberg 
272155ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
272255ed8ca1SJohan Hedberg 	if (!key)
272355ed8ca1SJohan Hedberg 		return -ENOENT;
272455ed8ca1SJohan Hedberg 
27256ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
272655ed8ca1SJohan Hedberg 
272755ed8ca1SJohan Hedberg 	list_del(&key->list);
272855ed8ca1SJohan Hedberg 	kfree(key);
272955ed8ca1SJohan Hedberg 
273055ed8ca1SJohan Hedberg 	return 0;
273155ed8ca1SJohan Hedberg }
273255ed8ca1SJohan Hedberg 
2733b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
2734b899efafSVinicius Costa Gomes {
2735b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2736b899efafSVinicius Costa Gomes 
2737b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2738b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
2739b899efafSVinicius Costa Gomes 			continue;
2740b899efafSVinicius Costa Gomes 
27416ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2742b899efafSVinicius Costa Gomes 
2743b899efafSVinicius Costa Gomes 		list_del(&k->list);
2744b899efafSVinicius Costa Gomes 		kfree(k);
2745b899efafSVinicius Costa Gomes 	}
2746b899efafSVinicius Costa Gomes 
2747b899efafSVinicius Costa Gomes 	return 0;
2748b899efafSVinicius Costa Gomes }
2749b899efafSVinicius Costa Gomes 
27506bd32326SVille Tervo /* HCI command timer function */
2751bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
27526bd32326SVille Tervo {
27536bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
27546bd32326SVille Tervo 
2755bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2756bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2757bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2758bda4f23aSAndrei Emeltchenko 
2759bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
2760bda4f23aSAndrei Emeltchenko 	} else {
27616bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
2762bda4f23aSAndrei Emeltchenko 	}
2763bda4f23aSAndrei Emeltchenko 
27646bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2765c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
27666bd32326SVille Tervo }
27676bd32326SVille Tervo 
27682763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
27692763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
27702763eda6SSzymon Janc {
27712763eda6SSzymon Janc 	struct oob_data *data;
27722763eda6SSzymon Janc 
27732763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
27742763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
27752763eda6SSzymon Janc 			return data;
27762763eda6SSzymon Janc 
27772763eda6SSzymon Janc 	return NULL;
27782763eda6SSzymon Janc }
27792763eda6SSzymon Janc 
27802763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
27812763eda6SSzymon Janc {
27822763eda6SSzymon Janc 	struct oob_data *data;
27832763eda6SSzymon Janc 
27842763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
27852763eda6SSzymon Janc 	if (!data)
27862763eda6SSzymon Janc 		return -ENOENT;
27872763eda6SSzymon Janc 
27886ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
27892763eda6SSzymon Janc 
27902763eda6SSzymon Janc 	list_del(&data->list);
27912763eda6SSzymon Janc 	kfree(data);
27922763eda6SSzymon Janc 
27932763eda6SSzymon Janc 	return 0;
27942763eda6SSzymon Janc }
27952763eda6SSzymon Janc 
27962763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
27972763eda6SSzymon Janc {
27982763eda6SSzymon Janc 	struct oob_data *data, *n;
27992763eda6SSzymon Janc 
28002763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
28012763eda6SSzymon Janc 		list_del(&data->list);
28022763eda6SSzymon Janc 		kfree(data);
28032763eda6SSzymon Janc 	}
28042763eda6SSzymon Janc 
28052763eda6SSzymon Janc 	return 0;
28062763eda6SSzymon Janc }
28072763eda6SSzymon Janc 
28080798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
28090798872eSMarcel Holtmann 			    u8 *hash, u8 *randomizer)
28102763eda6SSzymon Janc {
28112763eda6SSzymon Janc 	struct oob_data *data;
28122763eda6SSzymon Janc 
28132763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
28142763eda6SSzymon Janc 	if (!data) {
28150798872eSMarcel Holtmann 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
28162763eda6SSzymon Janc 		if (!data)
28172763eda6SSzymon Janc 			return -ENOMEM;
28182763eda6SSzymon Janc 
28192763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
28202763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
28212763eda6SSzymon Janc 	}
28222763eda6SSzymon Janc 
2823519ca9d0SMarcel Holtmann 	memcpy(data->hash192, hash, sizeof(data->hash192));
2824519ca9d0SMarcel Holtmann 	memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
28252763eda6SSzymon Janc 
28260798872eSMarcel Holtmann 	memset(data->hash256, 0, sizeof(data->hash256));
28270798872eSMarcel Holtmann 	memset(data->randomizer256, 0, sizeof(data->randomizer256));
28280798872eSMarcel Holtmann 
28290798872eSMarcel Holtmann 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
28300798872eSMarcel Holtmann 
28310798872eSMarcel Holtmann 	return 0;
28320798872eSMarcel Holtmann }
28330798872eSMarcel Holtmann 
28340798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
28350798872eSMarcel Holtmann 				u8 *hash192, u8 *randomizer192,
28360798872eSMarcel Holtmann 				u8 *hash256, u8 *randomizer256)
28370798872eSMarcel Holtmann {
28380798872eSMarcel Holtmann 	struct oob_data *data;
28390798872eSMarcel Holtmann 
28400798872eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, bdaddr);
28410798872eSMarcel Holtmann 	if (!data) {
28420798872eSMarcel Holtmann 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
28430798872eSMarcel Holtmann 		if (!data)
28440798872eSMarcel Holtmann 			return -ENOMEM;
28450798872eSMarcel Holtmann 
28460798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
28470798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
28480798872eSMarcel Holtmann 	}
28490798872eSMarcel Holtmann 
28500798872eSMarcel Holtmann 	memcpy(data->hash192, hash192, sizeof(data->hash192));
28510798872eSMarcel Holtmann 	memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192));
28520798872eSMarcel Holtmann 
28530798872eSMarcel Holtmann 	memcpy(data->hash256, hash256, sizeof(data->hash256));
28540798872eSMarcel Holtmann 	memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256));
28550798872eSMarcel Holtmann 
28566ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
28572763eda6SSzymon Janc 
28582763eda6SSzymon Janc 	return 0;
28592763eda6SSzymon Janc }
28602763eda6SSzymon Janc 
2861b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
2862b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
2863b2a66aadSAntti Julku {
2864b2a66aadSAntti Julku 	struct bdaddr_list *b;
2865b2a66aadSAntti Julku 
2866b9ee0a78SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list) {
2867b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2868b2a66aadSAntti Julku 			return b;
2869b9ee0a78SMarcel Holtmann 	}
2870b2a66aadSAntti Julku 
2871b2a66aadSAntti Julku 	return NULL;
2872b2a66aadSAntti Julku }
2873b2a66aadSAntti Julku 
2874b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
2875b2a66aadSAntti Julku {
2876b2a66aadSAntti Julku 	struct list_head *p, *n;
2877b2a66aadSAntti Julku 
2878b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
2879b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
2880b2a66aadSAntti Julku 
2881b2a66aadSAntti Julku 		list_del(p);
2882b2a66aadSAntti Julku 		kfree(b);
2883b2a66aadSAntti Julku 	}
2884b2a66aadSAntti Julku 
2885b2a66aadSAntti Julku 	return 0;
2886b2a66aadSAntti Julku }
2887b2a66aadSAntti Julku 
288888c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2889b2a66aadSAntti Julku {
2890b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2891b2a66aadSAntti Julku 
2892b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
2893b2a66aadSAntti Julku 		return -EBADF;
2894b2a66aadSAntti Julku 
2895b9ee0a78SMarcel Holtmann 	if (hci_blacklist_lookup(hdev, bdaddr, type))
28965e762444SAntti Julku 		return -EEXIST;
2897b2a66aadSAntti Julku 
2898b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
28995e762444SAntti Julku 	if (!entry)
29005e762444SAntti Julku 		return -ENOMEM;
2901b2a66aadSAntti Julku 
2902b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2903b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
2904b2a66aadSAntti Julku 
2905b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
2906b2a66aadSAntti Julku 
290788c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
2908b2a66aadSAntti Julku }
2909b2a66aadSAntti Julku 
291088c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2911b2a66aadSAntti Julku {
2912b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2913b2a66aadSAntti Julku 
2914b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
29155e762444SAntti Julku 		return hci_blacklist_clear(hdev);
2916b2a66aadSAntti Julku 
2917b9ee0a78SMarcel Holtmann 	entry = hci_blacklist_lookup(hdev, bdaddr, type);
29181ec918ceSSzymon Janc 	if (!entry)
29195e762444SAntti Julku 		return -ENOENT;
2920b2a66aadSAntti Julku 
2921b2a66aadSAntti Julku 	list_del(&entry->list);
2922b2a66aadSAntti Julku 	kfree(entry);
2923b2a66aadSAntti Julku 
292488c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
2925b2a66aadSAntti Julku }
2926b2a66aadSAntti Julku 
292715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
292815819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
292915819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
293015819a70SAndre Guedes {
293115819a70SAndre Guedes 	struct hci_conn_params *params;
293215819a70SAndre Guedes 
293315819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
293415819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
293515819a70SAndre Guedes 		    params->addr_type == addr_type) {
293615819a70SAndre Guedes 			return params;
293715819a70SAndre Guedes 		}
293815819a70SAndre Guedes 	}
293915819a70SAndre Guedes 
294015819a70SAndre Guedes 	return NULL;
294115819a70SAndre Guedes }
294215819a70SAndre Guedes 
294315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
294415819a70SAndre Guedes void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
294515819a70SAndre Guedes 			 u16 conn_min_interval, u16 conn_max_interval)
294615819a70SAndre Guedes {
294715819a70SAndre Guedes 	struct hci_conn_params *params;
294815819a70SAndre Guedes 
294915819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
295015819a70SAndre Guedes 	if (params) {
295115819a70SAndre Guedes 		params->conn_min_interval = conn_min_interval;
295215819a70SAndre Guedes 		params->conn_max_interval = conn_max_interval;
295315819a70SAndre Guedes 		return;
295415819a70SAndre Guedes 	}
295515819a70SAndre Guedes 
295615819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
295715819a70SAndre Guedes 	if (!params) {
295815819a70SAndre Guedes 		BT_ERR("Out of memory");
295915819a70SAndre Guedes 		return;
296015819a70SAndre Guedes 	}
296115819a70SAndre Guedes 
296215819a70SAndre Guedes 	bacpy(&params->addr, addr);
296315819a70SAndre Guedes 	params->addr_type = addr_type;
296415819a70SAndre Guedes 	params->conn_min_interval = conn_min_interval;
296515819a70SAndre Guedes 	params->conn_max_interval = conn_max_interval;
296615819a70SAndre Guedes 
296715819a70SAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
296815819a70SAndre Guedes 
296915819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u) conn_min_interval 0x%.4x "
297015819a70SAndre Guedes 	       "conn_max_interval 0x%.4x", addr, addr_type, conn_min_interval,
297115819a70SAndre Guedes 	       conn_max_interval);
297215819a70SAndre Guedes }
297315819a70SAndre Guedes 
297415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
297515819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
297615819a70SAndre Guedes {
297715819a70SAndre Guedes 	struct hci_conn_params *params;
297815819a70SAndre Guedes 
297915819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
298015819a70SAndre Guedes 	if (!params)
298115819a70SAndre Guedes 		return;
298215819a70SAndre Guedes 
298315819a70SAndre Guedes 	list_del(&params->list);
298415819a70SAndre Guedes 	kfree(params);
298515819a70SAndre Guedes 
298615819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
298715819a70SAndre Guedes }
298815819a70SAndre Guedes 
298915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
299015819a70SAndre Guedes void hci_conn_params_clear(struct hci_dev *hdev)
299115819a70SAndre Guedes {
299215819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
299315819a70SAndre Guedes 
299415819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
299515819a70SAndre Guedes 		list_del(&params->list);
299615819a70SAndre Guedes 		kfree(params);
299715819a70SAndre Guedes 	}
299815819a70SAndre Guedes 
299915819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
300015819a70SAndre Guedes }
300115819a70SAndre Guedes 
30024c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
30037ba8b4beSAndre Guedes {
30044c87eaabSAndre Guedes 	if (status) {
30054c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
30067ba8b4beSAndre Guedes 
30074c87eaabSAndre Guedes 		hci_dev_lock(hdev);
30084c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
30094c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
30104c87eaabSAndre Guedes 		return;
30114c87eaabSAndre Guedes 	}
30127ba8b4beSAndre Guedes }
30137ba8b4beSAndre Guedes 
30144c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
30157ba8b4beSAndre Guedes {
30164c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
30174c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
30184c87eaabSAndre Guedes 	struct hci_request req;
30194c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
30207ba8b4beSAndre Guedes 	int err;
30217ba8b4beSAndre Guedes 
30224c87eaabSAndre Guedes 	if (status) {
30234c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
30244c87eaabSAndre Guedes 		return;
30257ba8b4beSAndre Guedes 	}
30267ba8b4beSAndre Guedes 
30274c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
30284c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
30294c87eaabSAndre Guedes 		hci_dev_lock(hdev);
30304c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
30314c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
30324c87eaabSAndre Guedes 		break;
30337dbfac1dSAndre Guedes 
30344c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
30354c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
30367dbfac1dSAndre Guedes 
30377dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
30384c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
30394c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
30404c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
30414c87eaabSAndre Guedes 
30424c87eaabSAndre Guedes 		hci_dev_lock(hdev);
30434c87eaabSAndre Guedes 
30444c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
30454c87eaabSAndre Guedes 
30464c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
30474c87eaabSAndre Guedes 		if (err) {
30484c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
30494c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
30507dbfac1dSAndre Guedes 		}
30517dbfac1dSAndre Guedes 
30524c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
30534c87eaabSAndre Guedes 		break;
30544c87eaabSAndre Guedes 	}
30557dbfac1dSAndre Guedes }
30567dbfac1dSAndre Guedes 
30577ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
30587ba8b4beSAndre Guedes {
30597ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
30607ba8b4beSAndre Guedes 					    le_scan_disable.work);
30617ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
30624c87eaabSAndre Guedes 	struct hci_request req;
30634c87eaabSAndre Guedes 	int err;
30647ba8b4beSAndre Guedes 
30657ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
30667ba8b4beSAndre Guedes 
30674c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
30687ba8b4beSAndre Guedes 
30697ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
30704c87eaabSAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
30714c87eaabSAndre Guedes 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
30727ba8b4beSAndre Guedes 
30734c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
30744c87eaabSAndre Guedes 	if (err)
30754c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
307628b75a89SAndre Guedes }
307728b75a89SAndre Guedes 
30789be0dab7SDavid Herrmann /* Alloc HCI device */
30799be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
30809be0dab7SDavid Herrmann {
30819be0dab7SDavid Herrmann 	struct hci_dev *hdev;
30829be0dab7SDavid Herrmann 
30839be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
30849be0dab7SDavid Herrmann 	if (!hdev)
30859be0dab7SDavid Herrmann 		return NULL;
30869be0dab7SDavid Herrmann 
3087b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3088b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3089b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3090b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3091b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
3092bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3093bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3094b1b813d4SDavid Herrmann 
3095b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3096b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3097b1b813d4SDavid Herrmann 
3098bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3099bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
31004e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
31014e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
3102bef64738SMarcel Holtmann 
3103b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3104b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3105b1b813d4SDavid Herrmann 
3106b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3107b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
3108b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3109b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3110b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3111b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
311215819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
31136b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3114b1b813d4SDavid Herrmann 
3115b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3116b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3117b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3118b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3119b1b813d4SDavid Herrmann 
3120b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3121b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
3122b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
3123b1b813d4SDavid Herrmann 
3124b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3125b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3126b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3127b1b813d4SDavid Herrmann 
3128b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
3129b1b813d4SDavid Herrmann 
3130bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
3131b1b813d4SDavid Herrmann 
3132b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3133b1b813d4SDavid Herrmann 	discovery_init(hdev);
31349be0dab7SDavid Herrmann 
31359be0dab7SDavid Herrmann 	return hdev;
31369be0dab7SDavid Herrmann }
31379be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
31389be0dab7SDavid Herrmann 
31399be0dab7SDavid Herrmann /* Free HCI device */
31409be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
31419be0dab7SDavid Herrmann {
31429be0dab7SDavid Herrmann 	/* will free via device release */
31439be0dab7SDavid Herrmann 	put_device(&hdev->dev);
31449be0dab7SDavid Herrmann }
31459be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
31469be0dab7SDavid Herrmann 
31471da177e4SLinus Torvalds /* Register HCI device */
31481da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
31491da177e4SLinus Torvalds {
3150b1b813d4SDavid Herrmann 	int id, error;
31511da177e4SLinus Torvalds 
3152010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
31531da177e4SLinus Torvalds 		return -EINVAL;
31541da177e4SLinus Torvalds 
315508add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
315608add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
315708add513SMat Martineau 	 */
31583df92b31SSasha Levin 	switch (hdev->dev_type) {
31593df92b31SSasha Levin 	case HCI_BREDR:
31603df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
31611da177e4SLinus Torvalds 		break;
31623df92b31SSasha Levin 	case HCI_AMP:
31633df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
31643df92b31SSasha Levin 		break;
31653df92b31SSasha Levin 	default:
31663df92b31SSasha Levin 		return -EINVAL;
31671da177e4SLinus Torvalds 	}
31681da177e4SLinus Torvalds 
31693df92b31SSasha Levin 	if (id < 0)
31703df92b31SSasha Levin 		return id;
31713df92b31SSasha Levin 
31721da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
31731da177e4SLinus Torvalds 	hdev->id = id;
31742d8b3a11SAndrei Emeltchenko 
31752d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
31762d8b3a11SAndrei Emeltchenko 
3177d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3178d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
317933ca954dSDavid Herrmann 	if (!hdev->workqueue) {
318033ca954dSDavid Herrmann 		error = -ENOMEM;
318133ca954dSDavid Herrmann 		goto err;
318233ca954dSDavid Herrmann 	}
3183f48fd9c8SMarcel Holtmann 
3184d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3185d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
31866ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
31876ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
31886ead1bbcSJohan Hedberg 		error = -ENOMEM;
31896ead1bbcSJohan Hedberg 		goto err;
31906ead1bbcSJohan Hedberg 	}
31916ead1bbcSJohan Hedberg 
31920153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
31930153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
31940153e2ecSMarcel Holtmann 
3195bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3196bdc3e0f1SMarcel Holtmann 
3197bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
319833ca954dSDavid Herrmann 	if (error < 0)
319933ca954dSDavid Herrmann 		goto err_wqueue;
32001da177e4SLinus Torvalds 
3201611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3202a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3203a8c5fb1aSGustavo Padovan 				    hdev);
3204611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3205611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3206611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3207611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3208611b30f7SMarcel Holtmann 		}
3209611b30f7SMarcel Holtmann 	}
3210611b30f7SMarcel Holtmann 
32115e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
32125e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
32135e130367SJohan Hedberg 
3214a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
3215004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
3216ce2be9acSAndrei Emeltchenko 
321701cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
321856f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
321956f87901SJohan Hedberg 		 * through reading supported features during init.
322056f87901SJohan Hedberg 		 */
322156f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
322256f87901SJohan Hedberg 	}
3223ce2be9acSAndrei Emeltchenko 
3224fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3225fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3226fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3227fcee3377SGustavo Padovan 
32281da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
3229dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
32301da177e4SLinus Torvalds 
323119202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3232fbe96d6fSMarcel Holtmann 
32331da177e4SLinus Torvalds 	return id;
3234f48fd9c8SMarcel Holtmann 
323533ca954dSDavid Herrmann err_wqueue:
323633ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
32376ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
323833ca954dSDavid Herrmann err:
32393df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
3240f48fd9c8SMarcel Holtmann 
324133ca954dSDavid Herrmann 	return error;
32421da177e4SLinus Torvalds }
32431da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
32441da177e4SLinus Torvalds 
32451da177e4SLinus Torvalds /* Unregister HCI device */
324659735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
32471da177e4SLinus Torvalds {
32483df92b31SSasha Levin 	int i, id;
3249ef222013SMarcel Holtmann 
3250c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
32511da177e4SLinus Torvalds 
325294324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
325394324962SJohan Hovold 
32543df92b31SSasha Levin 	id = hdev->id;
32553df92b31SSasha Levin 
3256f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
32571da177e4SLinus Torvalds 	list_del(&hdev->list);
3258f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
32591da177e4SLinus Torvalds 
32601da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
32611da177e4SLinus Torvalds 
3262cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
3263ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
3264ef222013SMarcel Holtmann 
3265b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
3266b9b5ef18SGustavo Padovan 
3267ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
3268a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
326909fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
3270744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
327109fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
327256e5cb86SJohan Hedberg 	}
3273ab81cbf9SJohan Hedberg 
32742e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
32752e58ef3eSJohan Hedberg 	 * pending list */
32762e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
32772e58ef3eSJohan Hedberg 
32781da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
32791da177e4SLinus Torvalds 
3280611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3281611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
3282611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
3283611b30f7SMarcel Holtmann 	}
3284611b30f7SMarcel Holtmann 
3285bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
3286147e2d59SDave Young 
32870153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
32880153e2ecSMarcel Holtmann 
3289f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
32906ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
3291f48fd9c8SMarcel Holtmann 
329209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
3293e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
32942aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
329555ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
3296b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
32972763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
329815819a70SAndre Guedes 	hci_conn_params_clear(hdev);
329909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
3300e2e0cacbSJohan Hedberg 
3301dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
33023df92b31SSasha Levin 
33033df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
33041da177e4SLinus Torvalds }
33051da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
33061da177e4SLinus Torvalds 
33071da177e4SLinus Torvalds /* Suspend HCI device */
33081da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
33091da177e4SLinus Torvalds {
33101da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
33111da177e4SLinus Torvalds 	return 0;
33121da177e4SLinus Torvalds }
33131da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
33141da177e4SLinus Torvalds 
33151da177e4SLinus Torvalds /* Resume HCI device */
33161da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
33171da177e4SLinus Torvalds {
33181da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
33191da177e4SLinus Torvalds 	return 0;
33201da177e4SLinus Torvalds }
33211da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
33221da177e4SLinus Torvalds 
332376bca880SMarcel Holtmann /* Receive frame from HCI drivers */
3324e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
332576bca880SMarcel Holtmann {
332676bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
332776bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
332876bca880SMarcel Holtmann 		kfree_skb(skb);
332976bca880SMarcel Holtmann 		return -ENXIO;
333076bca880SMarcel Holtmann 	}
333176bca880SMarcel Holtmann 
3332d82603c6SJorrit Schippers 	/* Incoming skb */
333376bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
333476bca880SMarcel Holtmann 
333576bca880SMarcel Holtmann 	/* Time stamp */
333676bca880SMarcel Holtmann 	__net_timestamp(skb);
333776bca880SMarcel Holtmann 
333876bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3339b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3340c78ae283SMarcel Holtmann 
334176bca880SMarcel Holtmann 	return 0;
334276bca880SMarcel Holtmann }
334376bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
334476bca880SMarcel Holtmann 
334533e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
33461e429f38SGustavo F. Padovan 			  int count, __u8 index)
334733e882a5SSuraj Sumangala {
334833e882a5SSuraj Sumangala 	int len = 0;
334933e882a5SSuraj Sumangala 	int hlen = 0;
335033e882a5SSuraj Sumangala 	int remain = count;
335133e882a5SSuraj Sumangala 	struct sk_buff *skb;
335233e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
335333e882a5SSuraj Sumangala 
335433e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
335533e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
335633e882a5SSuraj Sumangala 		return -EILSEQ;
335733e882a5SSuraj Sumangala 
335833e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
335933e882a5SSuraj Sumangala 
336033e882a5SSuraj Sumangala 	if (!skb) {
336133e882a5SSuraj Sumangala 		switch (type) {
336233e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
336333e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
336433e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
336533e882a5SSuraj Sumangala 			break;
336633e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
336733e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
336833e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
336933e882a5SSuraj Sumangala 			break;
337033e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
337133e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
337233e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
337333e882a5SSuraj Sumangala 			break;
337433e882a5SSuraj Sumangala 		}
337533e882a5SSuraj Sumangala 
33761e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
337733e882a5SSuraj Sumangala 		if (!skb)
337833e882a5SSuraj Sumangala 			return -ENOMEM;
337933e882a5SSuraj Sumangala 
338033e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
338133e882a5SSuraj Sumangala 		scb->expect = hlen;
338233e882a5SSuraj Sumangala 		scb->pkt_type = type;
338333e882a5SSuraj Sumangala 
338433e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
338533e882a5SSuraj Sumangala 	}
338633e882a5SSuraj Sumangala 
338733e882a5SSuraj Sumangala 	while (count) {
338833e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
338989bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
339033e882a5SSuraj Sumangala 
339133e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
339233e882a5SSuraj Sumangala 
339333e882a5SSuraj Sumangala 		count -= len;
339433e882a5SSuraj Sumangala 		data += len;
339533e882a5SSuraj Sumangala 		scb->expect -= len;
339633e882a5SSuraj Sumangala 		remain = count;
339733e882a5SSuraj Sumangala 
339833e882a5SSuraj Sumangala 		switch (type) {
339933e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
340033e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
340133e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
340233e882a5SSuraj Sumangala 				scb->expect = h->plen;
340333e882a5SSuraj Sumangala 
340433e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
340533e882a5SSuraj Sumangala 					kfree_skb(skb);
340633e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
340733e882a5SSuraj Sumangala 					return -ENOMEM;
340833e882a5SSuraj Sumangala 				}
340933e882a5SSuraj Sumangala 			}
341033e882a5SSuraj Sumangala 			break;
341133e882a5SSuraj Sumangala 
341233e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
341333e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
341433e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
341533e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
341633e882a5SSuraj Sumangala 
341733e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
341833e882a5SSuraj Sumangala 					kfree_skb(skb);
341933e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
342033e882a5SSuraj Sumangala 					return -ENOMEM;
342133e882a5SSuraj Sumangala 				}
342233e882a5SSuraj Sumangala 			}
342333e882a5SSuraj Sumangala 			break;
342433e882a5SSuraj Sumangala 
342533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
342633e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
342733e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
342833e882a5SSuraj Sumangala 				scb->expect = h->dlen;
342933e882a5SSuraj Sumangala 
343033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
343133e882a5SSuraj Sumangala 					kfree_skb(skb);
343233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
343333e882a5SSuraj Sumangala 					return -ENOMEM;
343433e882a5SSuraj Sumangala 				}
343533e882a5SSuraj Sumangala 			}
343633e882a5SSuraj Sumangala 			break;
343733e882a5SSuraj Sumangala 		}
343833e882a5SSuraj Sumangala 
343933e882a5SSuraj Sumangala 		if (scb->expect == 0) {
344033e882a5SSuraj Sumangala 			/* Complete frame */
344133e882a5SSuraj Sumangala 
344233e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
3443e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
344433e882a5SSuraj Sumangala 
344533e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
344633e882a5SSuraj Sumangala 			return remain;
344733e882a5SSuraj Sumangala 		}
344833e882a5SSuraj Sumangala 	}
344933e882a5SSuraj Sumangala 
345033e882a5SSuraj Sumangala 	return remain;
345133e882a5SSuraj Sumangala }
345233e882a5SSuraj Sumangala 
3453ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
3454ef222013SMarcel Holtmann {
3455f39a3c06SSuraj Sumangala 	int rem = 0;
3456f39a3c06SSuraj Sumangala 
3457ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
3458ef222013SMarcel Holtmann 		return -EILSEQ;
3459ef222013SMarcel Holtmann 
3460da5f6c37SGustavo F. Padovan 	while (count) {
34611e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
3462f39a3c06SSuraj Sumangala 		if (rem < 0)
3463f39a3c06SSuraj Sumangala 			return rem;
3464ef222013SMarcel Holtmann 
3465f39a3c06SSuraj Sumangala 		data += (count - rem);
3466f39a3c06SSuraj Sumangala 		count = rem;
3467f81c6224SJoe Perches 	}
3468ef222013SMarcel Holtmann 
3469f39a3c06SSuraj Sumangala 	return rem;
3470ef222013SMarcel Holtmann }
3471ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
3472ef222013SMarcel Holtmann 
347399811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
347499811510SSuraj Sumangala 
347599811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
347699811510SSuraj Sumangala {
347799811510SSuraj Sumangala 	int type;
347899811510SSuraj Sumangala 	int rem = 0;
347999811510SSuraj Sumangala 
3480da5f6c37SGustavo F. Padovan 	while (count) {
348199811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
348299811510SSuraj Sumangala 
348399811510SSuraj Sumangala 		if (!skb) {
348499811510SSuraj Sumangala 			struct { char type; } *pkt;
348599811510SSuraj Sumangala 
348699811510SSuraj Sumangala 			/* Start of the frame */
348799811510SSuraj Sumangala 			pkt = data;
348899811510SSuraj Sumangala 			type = pkt->type;
348999811510SSuraj Sumangala 
349099811510SSuraj Sumangala 			data++;
349199811510SSuraj Sumangala 			count--;
349299811510SSuraj Sumangala 		} else
349399811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
349499811510SSuraj Sumangala 
34951e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
34961e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
349799811510SSuraj Sumangala 		if (rem < 0)
349899811510SSuraj Sumangala 			return rem;
349999811510SSuraj Sumangala 
350099811510SSuraj Sumangala 		data += (count - rem);
350199811510SSuraj Sumangala 		count = rem;
3502f81c6224SJoe Perches 	}
350399811510SSuraj Sumangala 
350499811510SSuraj Sumangala 	return rem;
350599811510SSuraj Sumangala }
350699811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
350799811510SSuraj Sumangala 
35081da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
35091da177e4SLinus Torvalds 
35101da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
35111da177e4SLinus Torvalds {
35121da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
35131da177e4SLinus Torvalds 
3514f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
35151da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
3516f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
35171da177e4SLinus Torvalds 
35181da177e4SLinus Torvalds 	return 0;
35191da177e4SLinus Torvalds }
35201da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
35211da177e4SLinus Torvalds 
35221da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
35231da177e4SLinus Torvalds {
35241da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
35251da177e4SLinus Torvalds 
3526f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
35271da177e4SLinus Torvalds 	list_del(&cb->list);
3528f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
35291da177e4SLinus Torvalds 
35301da177e4SLinus Torvalds 	return 0;
35311da177e4SLinus Torvalds }
35321da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
35331da177e4SLinus Torvalds 
353451086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
35351da177e4SLinus Torvalds {
35360d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
35371da177e4SLinus Torvalds 
35381da177e4SLinus Torvalds 	/* Time stamp */
3539a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
35401da177e4SLinus Torvalds 
3541cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3542cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3543cd82e61cSMarcel Holtmann 
3544cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3545cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3546470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
35471da177e4SLinus Torvalds 	}
35481da177e4SLinus Torvalds 
35491da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
35501da177e4SLinus Torvalds 	skb_orphan(skb);
35511da177e4SLinus Torvalds 
35527bd8f09fSMarcel Holtmann 	if (hdev->send(hdev, skb) < 0)
355351086991SMarcel Holtmann 		BT_ERR("%s sending frame failed", hdev->name);
35541da177e4SLinus Torvalds }
35551da177e4SLinus Torvalds 
35563119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
35573119ae95SJohan Hedberg {
35583119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
35593119ae95SJohan Hedberg 	req->hdev = hdev;
35605d73e034SAndre Guedes 	req->err = 0;
35613119ae95SJohan Hedberg }
35623119ae95SJohan Hedberg 
35633119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
35643119ae95SJohan Hedberg {
35653119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
35663119ae95SJohan Hedberg 	struct sk_buff *skb;
35673119ae95SJohan Hedberg 	unsigned long flags;
35683119ae95SJohan Hedberg 
35693119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
35703119ae95SJohan Hedberg 
35715d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
35725d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
35735d73e034SAndre Guedes 	 */
35745d73e034SAndre Guedes 	if (req->err) {
35755d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
35765d73e034SAndre Guedes 		return req->err;
35775d73e034SAndre Guedes 	}
35785d73e034SAndre Guedes 
35793119ae95SJohan Hedberg 	/* Do not allow empty requests */
35803119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
3581382b0c39SAndre Guedes 		return -ENODATA;
35823119ae95SJohan Hedberg 
35833119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
35843119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
35853119ae95SJohan Hedberg 
35863119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
35873119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
35883119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
35893119ae95SJohan Hedberg 
35903119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
35913119ae95SJohan Hedberg 
35923119ae95SJohan Hedberg 	return 0;
35933119ae95SJohan Hedberg }
35943119ae95SJohan Hedberg 
35951ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
359607dc93ddSJohan Hedberg 				       u32 plen, const void *param)
35971da177e4SLinus Torvalds {
35981da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
35991da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
36001da177e4SLinus Torvalds 	struct sk_buff *skb;
36011da177e4SLinus Torvalds 
36021da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
36031ca3a9d0SJohan Hedberg 	if (!skb)
36041ca3a9d0SJohan Hedberg 		return NULL;
36051da177e4SLinus Torvalds 
36061da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
3607a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
36081da177e4SLinus Torvalds 	hdr->plen   = plen;
36091da177e4SLinus Torvalds 
36101da177e4SLinus Torvalds 	if (plen)
36111da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
36121da177e4SLinus Torvalds 
36131da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
36141da177e4SLinus Torvalds 
36150d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
3616c78ae283SMarcel Holtmann 
36171ca3a9d0SJohan Hedberg 	return skb;
36181ca3a9d0SJohan Hedberg }
36191ca3a9d0SJohan Hedberg 
36201ca3a9d0SJohan Hedberg /* Send HCI command */
362107dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
362207dc93ddSJohan Hedberg 		 const void *param)
36231ca3a9d0SJohan Hedberg {
36241ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
36251ca3a9d0SJohan Hedberg 
36261ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
36271ca3a9d0SJohan Hedberg 
36281ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
36291ca3a9d0SJohan Hedberg 	if (!skb) {
36301ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
36311ca3a9d0SJohan Hedberg 		return -ENOMEM;
36321ca3a9d0SJohan Hedberg 	}
36331ca3a9d0SJohan Hedberg 
363411714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
363511714b3dSJohan Hedberg 	 * single-command requests.
363611714b3dSJohan Hedberg 	 */
363711714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
363811714b3dSJohan Hedberg 
36391da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3640c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
36411da177e4SLinus Torvalds 
36421da177e4SLinus Torvalds 	return 0;
36431da177e4SLinus Torvalds }
36441da177e4SLinus Torvalds 
364571c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
364607dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
364707dc93ddSJohan Hedberg 		    const void *param, u8 event)
364871c76a17SJohan Hedberg {
364971c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
365071c76a17SJohan Hedberg 	struct sk_buff *skb;
365171c76a17SJohan Hedberg 
365271c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
365371c76a17SJohan Hedberg 
365434739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
365534739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
365634739c1eSAndre Guedes 	 */
365734739c1eSAndre Guedes 	if (req->err)
365834739c1eSAndre Guedes 		return;
365934739c1eSAndre Guedes 
366071c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
366171c76a17SJohan Hedberg 	if (!skb) {
36625d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
36635d73e034SAndre Guedes 		       hdev->name, opcode);
36645d73e034SAndre Guedes 		req->err = -ENOMEM;
3665e348fe6bSAndre Guedes 		return;
366671c76a17SJohan Hedberg 	}
366771c76a17SJohan Hedberg 
366871c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
366971c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
367071c76a17SJohan Hedberg 
367102350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
367202350a72SJohan Hedberg 
367371c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
367471c76a17SJohan Hedberg }
367571c76a17SJohan Hedberg 
367607dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
367707dc93ddSJohan Hedberg 		 const void *param)
367802350a72SJohan Hedberg {
367902350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
368002350a72SJohan Hedberg }
368102350a72SJohan Hedberg 
36821da177e4SLinus Torvalds /* Get data from the previously sent command */
3683a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
36841da177e4SLinus Torvalds {
36851da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
36861da177e4SLinus Torvalds 
36871da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
36881da177e4SLinus Torvalds 		return NULL;
36891da177e4SLinus Torvalds 
36901da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
36911da177e4SLinus Torvalds 
3692a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
36931da177e4SLinus Torvalds 		return NULL;
36941da177e4SLinus Torvalds 
3695f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
36961da177e4SLinus Torvalds 
36971da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
36981da177e4SLinus Torvalds }
36991da177e4SLinus Torvalds 
37001da177e4SLinus Torvalds /* Send ACL data */
37011da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
37021da177e4SLinus Torvalds {
37031da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
37041da177e4SLinus Torvalds 	int len = skb->len;
37051da177e4SLinus Torvalds 
3706badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3707badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
37089c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3709aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3710aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
37111da177e4SLinus Torvalds }
37121da177e4SLinus Torvalds 
3713ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
371473d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
37151da177e4SLinus Torvalds {
3716ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
37171da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
37181da177e4SLinus Torvalds 	struct sk_buff *list;
37191da177e4SLinus Torvalds 
3720087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3721087bfd99SGustavo Padovan 	skb->data_len = 0;
3722087bfd99SGustavo Padovan 
3723087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3724204a6e54SAndrei Emeltchenko 
3725204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3726204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
3727087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3728204a6e54SAndrei Emeltchenko 		break;
3729204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3730204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3731204a6e54SAndrei Emeltchenko 		break;
3732204a6e54SAndrei Emeltchenko 	default:
3733204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
3734204a6e54SAndrei Emeltchenko 		return;
3735204a6e54SAndrei Emeltchenko 	}
3736087bfd99SGustavo Padovan 
373770f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
373870f23020SAndrei Emeltchenko 	if (!list) {
37391da177e4SLinus Torvalds 		/* Non fragmented */
37401da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
37411da177e4SLinus Torvalds 
374273d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
37431da177e4SLinus Torvalds 	} else {
37441da177e4SLinus Torvalds 		/* Fragmented */
37451da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
37461da177e4SLinus Torvalds 
37471da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
37481da177e4SLinus Torvalds 
37491da177e4SLinus Torvalds 		/* Queue all fragments atomically */
3750af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
37511da177e4SLinus Torvalds 
375273d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3753e702112fSAndrei Emeltchenko 
3754e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3755e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
37561da177e4SLinus Torvalds 		do {
37571da177e4SLinus Torvalds 			skb = list; list = list->next;
37581da177e4SLinus Torvalds 
37590d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3760e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
37611da177e4SLinus Torvalds 
37621da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
37631da177e4SLinus Torvalds 
376473d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
37651da177e4SLinus Torvalds 		} while (list);
37661da177e4SLinus Torvalds 
3767af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
37681da177e4SLinus Torvalds 	}
376973d80debSLuiz Augusto von Dentz }
377073d80debSLuiz Augusto von Dentz 
377173d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
377273d80debSLuiz Augusto von Dentz {
3773ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
377473d80debSLuiz Augusto von Dentz 
3775f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
377673d80debSLuiz Augusto von Dentz 
3777ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
37781da177e4SLinus Torvalds 
37793eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
37801da177e4SLinus Torvalds }
37811da177e4SLinus Torvalds 
37821da177e4SLinus Torvalds /* Send SCO data */
37830d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
37841da177e4SLinus Torvalds {
37851da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
37861da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
37871da177e4SLinus Torvalds 
37881da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
37891da177e4SLinus Torvalds 
3790aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
37911da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
37921da177e4SLinus Torvalds 
3793badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3794badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
37959c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
37961da177e4SLinus Torvalds 
37970d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
3798c78ae283SMarcel Holtmann 
37991da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
38003eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
38011da177e4SLinus Torvalds }
38021da177e4SLinus Torvalds 
38031da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
38041da177e4SLinus Torvalds 
38051da177e4SLinus Torvalds /* HCI Connection scheduler */
38066039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3807a8c5fb1aSGustavo Padovan 				     int *quote)
38081da177e4SLinus Torvalds {
38091da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
38108035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3811abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
38121da177e4SLinus Torvalds 
38131da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
38141da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3815bf4c6325SGustavo F. Padovan 
3816bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3817bf4c6325SGustavo F. Padovan 
3818bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3819769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
38201da177e4SLinus Torvalds 			continue;
3821769be974SMarcel Holtmann 
3822769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3823769be974SMarcel Holtmann 			continue;
3824769be974SMarcel Holtmann 
38251da177e4SLinus Torvalds 		num++;
38261da177e4SLinus Torvalds 
38271da177e4SLinus Torvalds 		if (c->sent < min) {
38281da177e4SLinus Torvalds 			min  = c->sent;
38291da177e4SLinus Torvalds 			conn = c;
38301da177e4SLinus Torvalds 		}
383152087a79SLuiz Augusto von Dentz 
383252087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
383352087a79SLuiz Augusto von Dentz 			break;
38341da177e4SLinus Torvalds 	}
38351da177e4SLinus Torvalds 
3836bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3837bf4c6325SGustavo F. Padovan 
38381da177e4SLinus Torvalds 	if (conn) {
38396ed58ec5SVille Tervo 		int cnt, q;
38406ed58ec5SVille Tervo 
38416ed58ec5SVille Tervo 		switch (conn->type) {
38426ed58ec5SVille Tervo 		case ACL_LINK:
38436ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
38446ed58ec5SVille Tervo 			break;
38456ed58ec5SVille Tervo 		case SCO_LINK:
38466ed58ec5SVille Tervo 		case ESCO_LINK:
38476ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
38486ed58ec5SVille Tervo 			break;
38496ed58ec5SVille Tervo 		case LE_LINK:
38506ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
38516ed58ec5SVille Tervo 			break;
38526ed58ec5SVille Tervo 		default:
38536ed58ec5SVille Tervo 			cnt = 0;
38546ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
38556ed58ec5SVille Tervo 		}
38566ed58ec5SVille Tervo 
38576ed58ec5SVille Tervo 		q = cnt / num;
38581da177e4SLinus Torvalds 		*quote = q ? q : 1;
38591da177e4SLinus Torvalds 	} else
38601da177e4SLinus Torvalds 		*quote = 0;
38611da177e4SLinus Torvalds 
38621da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
38631da177e4SLinus Torvalds 	return conn;
38641da177e4SLinus Torvalds }
38651da177e4SLinus Torvalds 
38666039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
38671da177e4SLinus Torvalds {
38681da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
38691da177e4SLinus Torvalds 	struct hci_conn *c;
38701da177e4SLinus Torvalds 
3871bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
38721da177e4SLinus Torvalds 
3873bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3874bf4c6325SGustavo F. Padovan 
38751da177e4SLinus Torvalds 	/* Kill stalled connections */
3876bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3877bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
38786ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
38796ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
3880bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
38811da177e4SLinus Torvalds 		}
38821da177e4SLinus Torvalds 	}
3883bf4c6325SGustavo F. Padovan 
3884bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
38851da177e4SLinus Torvalds }
38861da177e4SLinus Torvalds 
38876039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
388873d80debSLuiz Augusto von Dentz 				      int *quote)
388973d80debSLuiz Augusto von Dentz {
389073d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
389173d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3892abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
389373d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
389473d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
389573d80debSLuiz Augusto von Dentz 
389673d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
389773d80debSLuiz Augusto von Dentz 
3898bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3899bf4c6325SGustavo F. Padovan 
3900bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
390173d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
390273d80debSLuiz Augusto von Dentz 
390373d80debSLuiz Augusto von Dentz 		if (conn->type != type)
390473d80debSLuiz Augusto von Dentz 			continue;
390573d80debSLuiz Augusto von Dentz 
390673d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
390773d80debSLuiz Augusto von Dentz 			continue;
390873d80debSLuiz Augusto von Dentz 
390973d80debSLuiz Augusto von Dentz 		conn_num++;
391073d80debSLuiz Augusto von Dentz 
39118192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
391273d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
391373d80debSLuiz Augusto von Dentz 
391473d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
391573d80debSLuiz Augusto von Dentz 				continue;
391673d80debSLuiz Augusto von Dentz 
391773d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
391873d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
391973d80debSLuiz Augusto von Dentz 				continue;
392073d80debSLuiz Augusto von Dentz 
392173d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
392273d80debSLuiz Augusto von Dentz 				num = 0;
392373d80debSLuiz Augusto von Dentz 				min = ~0;
392473d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
392573d80debSLuiz Augusto von Dentz 			}
392673d80debSLuiz Augusto von Dentz 
392773d80debSLuiz Augusto von Dentz 			num++;
392873d80debSLuiz Augusto von Dentz 
392973d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
393073d80debSLuiz Augusto von Dentz 				min  = conn->sent;
393173d80debSLuiz Augusto von Dentz 				chan = tmp;
393273d80debSLuiz Augusto von Dentz 			}
393373d80debSLuiz Augusto von Dentz 		}
393473d80debSLuiz Augusto von Dentz 
393573d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
393673d80debSLuiz Augusto von Dentz 			break;
393773d80debSLuiz Augusto von Dentz 	}
393873d80debSLuiz Augusto von Dentz 
3939bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3940bf4c6325SGustavo F. Padovan 
394173d80debSLuiz Augusto von Dentz 	if (!chan)
394273d80debSLuiz Augusto von Dentz 		return NULL;
394373d80debSLuiz Augusto von Dentz 
394473d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
394573d80debSLuiz Augusto von Dentz 	case ACL_LINK:
394673d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
394773d80debSLuiz Augusto von Dentz 		break;
3948bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3949bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3950bd1eb66bSAndrei Emeltchenko 		break;
395173d80debSLuiz Augusto von Dentz 	case SCO_LINK:
395273d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
395373d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
395473d80debSLuiz Augusto von Dentz 		break;
395573d80debSLuiz Augusto von Dentz 	case LE_LINK:
395673d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
395773d80debSLuiz Augusto von Dentz 		break;
395873d80debSLuiz Augusto von Dentz 	default:
395973d80debSLuiz Augusto von Dentz 		cnt = 0;
396073d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
396173d80debSLuiz Augusto von Dentz 	}
396273d80debSLuiz Augusto von Dentz 
396373d80debSLuiz Augusto von Dentz 	q = cnt / num;
396473d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
396573d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
396673d80debSLuiz Augusto von Dentz 	return chan;
396773d80debSLuiz Augusto von Dentz }
396873d80debSLuiz Augusto von Dentz 
396902b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
397002b20f0bSLuiz Augusto von Dentz {
397102b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
397202b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
397302b20f0bSLuiz Augusto von Dentz 	int num = 0;
397402b20f0bSLuiz Augusto von Dentz 
397502b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
397602b20f0bSLuiz Augusto von Dentz 
3977bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3978bf4c6325SGustavo F. Padovan 
3979bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
398002b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
398102b20f0bSLuiz Augusto von Dentz 
398202b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
398302b20f0bSLuiz Augusto von Dentz 			continue;
398402b20f0bSLuiz Augusto von Dentz 
398502b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
398602b20f0bSLuiz Augusto von Dentz 			continue;
398702b20f0bSLuiz Augusto von Dentz 
398802b20f0bSLuiz Augusto von Dentz 		num++;
398902b20f0bSLuiz Augusto von Dentz 
39908192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
399102b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
399202b20f0bSLuiz Augusto von Dentz 
399302b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
399402b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
399502b20f0bSLuiz Augusto von Dentz 				continue;
399602b20f0bSLuiz Augusto von Dentz 			}
399702b20f0bSLuiz Augusto von Dentz 
399802b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
399902b20f0bSLuiz Augusto von Dentz 				continue;
400002b20f0bSLuiz Augusto von Dentz 
400102b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
400202b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
400302b20f0bSLuiz Augusto von Dentz 				continue;
400402b20f0bSLuiz Augusto von Dentz 
400502b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
400602b20f0bSLuiz Augusto von Dentz 
400702b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
400802b20f0bSLuiz Augusto von Dentz 			       skb->priority);
400902b20f0bSLuiz Augusto von Dentz 		}
401002b20f0bSLuiz Augusto von Dentz 
401102b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
401202b20f0bSLuiz Augusto von Dentz 			break;
401302b20f0bSLuiz Augusto von Dentz 	}
4014bf4c6325SGustavo F. Padovan 
4015bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4016bf4c6325SGustavo F. Padovan 
401702b20f0bSLuiz Augusto von Dentz }
401802b20f0bSLuiz Augusto von Dentz 
4019b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4020b71d385aSAndrei Emeltchenko {
4021b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4022b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4023b71d385aSAndrei Emeltchenko }
4024b71d385aSAndrei Emeltchenko 
40256039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
40261da177e4SLinus Torvalds {
40271da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
40281da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
40291da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
403063d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
40315f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4032bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
40331da177e4SLinus Torvalds 	}
403463d2bc1bSAndrei Emeltchenko }
40351da177e4SLinus Torvalds 
40366039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
403763d2bc1bSAndrei Emeltchenko {
403863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
403963d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
404063d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
404163d2bc1bSAndrei Emeltchenko 	int quote;
404263d2bc1bSAndrei Emeltchenko 
404363d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
404404837f64SMarcel Holtmann 
404573d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
404673d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4047ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4048ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
404973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
405073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
405173d80debSLuiz Augusto von Dentz 
4052ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4053ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4054ec1cce24SLuiz Augusto von Dentz 				break;
4055ec1cce24SLuiz Augusto von Dentz 
4056ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4057ec1cce24SLuiz Augusto von Dentz 
405873d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
405973d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
406004837f64SMarcel Holtmann 
406157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
40621da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
40631da177e4SLinus Torvalds 
40641da177e4SLinus Torvalds 			hdev->acl_cnt--;
406573d80debSLuiz Augusto von Dentz 			chan->sent++;
406673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
40671da177e4SLinus Torvalds 		}
40681da177e4SLinus Torvalds 	}
406902b20f0bSLuiz Augusto von Dentz 
407002b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
407102b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
40721da177e4SLinus Torvalds }
40731da177e4SLinus Torvalds 
40746039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4075b71d385aSAndrei Emeltchenko {
407663d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4077b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4078b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4079b71d385aSAndrei Emeltchenko 	int quote;
4080bd1eb66bSAndrei Emeltchenko 	u8 type;
4081b71d385aSAndrei Emeltchenko 
408263d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
4083b71d385aSAndrei Emeltchenko 
4084bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4085bd1eb66bSAndrei Emeltchenko 
4086bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
4087bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
4088bd1eb66bSAndrei Emeltchenko 	else
4089bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
4090bd1eb66bSAndrei Emeltchenko 
4091b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
4092bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
4093b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
4094b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
4095b71d385aSAndrei Emeltchenko 			int blocks;
4096b71d385aSAndrei Emeltchenko 
4097b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
4098b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
4099b71d385aSAndrei Emeltchenko 
4100b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
4101b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
4102b71d385aSAndrei Emeltchenko 				break;
4103b71d385aSAndrei Emeltchenko 
4104b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
4105b71d385aSAndrei Emeltchenko 
4106b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
4107b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
4108b71d385aSAndrei Emeltchenko 				return;
4109b71d385aSAndrei Emeltchenko 
4110b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
4111b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
4112b71d385aSAndrei Emeltchenko 
411357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4114b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4115b71d385aSAndrei Emeltchenko 
4116b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4117b71d385aSAndrei Emeltchenko 			quote -= blocks;
4118b71d385aSAndrei Emeltchenko 
4119b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4120b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4121b71d385aSAndrei Emeltchenko 		}
4122b71d385aSAndrei Emeltchenko 	}
4123b71d385aSAndrei Emeltchenko 
4124b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4125bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4126b71d385aSAndrei Emeltchenko }
4127b71d385aSAndrei Emeltchenko 
41286039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4129b71d385aSAndrei Emeltchenko {
4130b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4131b71d385aSAndrei Emeltchenko 
4132bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4133bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
4134bd1eb66bSAndrei Emeltchenko 		return;
4135bd1eb66bSAndrei Emeltchenko 
4136bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4137bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4138b71d385aSAndrei Emeltchenko 		return;
4139b71d385aSAndrei Emeltchenko 
4140b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4141b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4142b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4143b71d385aSAndrei Emeltchenko 		break;
4144b71d385aSAndrei Emeltchenko 
4145b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4146b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4147b71d385aSAndrei Emeltchenko 		break;
4148b71d385aSAndrei Emeltchenko 	}
4149b71d385aSAndrei Emeltchenko }
4150b71d385aSAndrei Emeltchenko 
41511da177e4SLinus Torvalds /* Schedule SCO */
41526039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
41531da177e4SLinus Torvalds {
41541da177e4SLinus Torvalds 	struct hci_conn *conn;
41551da177e4SLinus Torvalds 	struct sk_buff *skb;
41561da177e4SLinus Torvalds 	int quote;
41571da177e4SLinus Torvalds 
41581da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
41591da177e4SLinus Torvalds 
416052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
416152087a79SLuiz Augusto von Dentz 		return;
416252087a79SLuiz Augusto von Dentz 
41631da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
41641da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
41651da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
416657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
41671da177e4SLinus Torvalds 
41681da177e4SLinus Torvalds 			conn->sent++;
41691da177e4SLinus Torvalds 			if (conn->sent == ~0)
41701da177e4SLinus Torvalds 				conn->sent = 0;
41711da177e4SLinus Torvalds 		}
41721da177e4SLinus Torvalds 	}
41731da177e4SLinus Torvalds }
41741da177e4SLinus Torvalds 
41756039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
4176b6a0dc82SMarcel Holtmann {
4177b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4178b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
4179b6a0dc82SMarcel Holtmann 	int quote;
4180b6a0dc82SMarcel Holtmann 
4181b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
4182b6a0dc82SMarcel Holtmann 
418352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
418452087a79SLuiz Augusto von Dentz 		return;
418552087a79SLuiz Augusto von Dentz 
41868fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
41878fc9ced3SGustavo Padovan 						     &quote))) {
4188b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
4189b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
419057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4191b6a0dc82SMarcel Holtmann 
4192b6a0dc82SMarcel Holtmann 			conn->sent++;
4193b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
4194b6a0dc82SMarcel Holtmann 				conn->sent = 0;
4195b6a0dc82SMarcel Holtmann 		}
4196b6a0dc82SMarcel Holtmann 	}
4197b6a0dc82SMarcel Holtmann }
4198b6a0dc82SMarcel Holtmann 
41996039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
42006ed58ec5SVille Tervo {
420173d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
42026ed58ec5SVille Tervo 	struct sk_buff *skb;
420302b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
42046ed58ec5SVille Tervo 
42056ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
42066ed58ec5SVille Tervo 
420752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
420852087a79SLuiz Augusto von Dentz 		return;
420952087a79SLuiz Augusto von Dentz 
42106ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
42116ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
42126ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
4213bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
42146ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
4215bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
42166ed58ec5SVille Tervo 	}
42176ed58ec5SVille Tervo 
42186ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
421902b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
422073d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4221ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4222ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
422373d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
422473d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
42256ed58ec5SVille Tervo 
4226ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4227ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4228ec1cce24SLuiz Augusto von Dentz 				break;
4229ec1cce24SLuiz Augusto von Dentz 
4230ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4231ec1cce24SLuiz Augusto von Dentz 
423257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
42336ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
42346ed58ec5SVille Tervo 
42356ed58ec5SVille Tervo 			cnt--;
423673d80debSLuiz Augusto von Dentz 			chan->sent++;
423773d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
42386ed58ec5SVille Tervo 		}
42396ed58ec5SVille Tervo 	}
424073d80debSLuiz Augusto von Dentz 
42416ed58ec5SVille Tervo 	if (hdev->le_pkts)
42426ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
42436ed58ec5SVille Tervo 	else
42446ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
424502b20f0bSLuiz Augusto von Dentz 
424602b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
424702b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
42486ed58ec5SVille Tervo }
42496ed58ec5SVille Tervo 
42503eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
42511da177e4SLinus Torvalds {
42523eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
42531da177e4SLinus Torvalds 	struct sk_buff *skb;
42541da177e4SLinus Torvalds 
42556ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
42566ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
42571da177e4SLinus Torvalds 
425852de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
42591da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
42601da177e4SLinus Torvalds 		hci_sched_acl(hdev);
42611da177e4SLinus Torvalds 		hci_sched_sco(hdev);
4262b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
42636ed58ec5SVille Tervo 		hci_sched_le(hdev);
426452de599eSMarcel Holtmann 	}
42656ed58ec5SVille Tervo 
42661da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
42671da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
426857d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
42691da177e4SLinus Torvalds }
42701da177e4SLinus Torvalds 
427125985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
42721da177e4SLinus Torvalds 
42731da177e4SLinus Torvalds /* ACL data packet */
42746039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
42751da177e4SLinus Torvalds {
42761da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
42771da177e4SLinus Torvalds 	struct hci_conn *conn;
42781da177e4SLinus Torvalds 	__u16 handle, flags;
42791da177e4SLinus Torvalds 
42801da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
42811da177e4SLinus Torvalds 
42821da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
42831da177e4SLinus Torvalds 	flags  = hci_flags(handle);
42841da177e4SLinus Torvalds 	handle = hci_handle(handle);
42851da177e4SLinus Torvalds 
4286f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4287a8c5fb1aSGustavo Padovan 	       handle, flags);
42881da177e4SLinus Torvalds 
42891da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
42901da177e4SLinus Torvalds 
42911da177e4SLinus Torvalds 	hci_dev_lock(hdev);
42921da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
42931da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
42941da177e4SLinus Torvalds 
42951da177e4SLinus Torvalds 	if (conn) {
429665983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
429704837f64SMarcel Holtmann 
42981da177e4SLinus Torvalds 		/* Send to upper protocol */
4299686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
43001da177e4SLinus Torvalds 		return;
43011da177e4SLinus Torvalds 	} else {
43021da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
43031da177e4SLinus Torvalds 		       hdev->name, handle);
43041da177e4SLinus Torvalds 	}
43051da177e4SLinus Torvalds 
43061da177e4SLinus Torvalds 	kfree_skb(skb);
43071da177e4SLinus Torvalds }
43081da177e4SLinus Torvalds 
43091da177e4SLinus Torvalds /* SCO data packet */
43106039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
43111da177e4SLinus Torvalds {
43121da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
43131da177e4SLinus Torvalds 	struct hci_conn *conn;
43141da177e4SLinus Torvalds 	__u16 handle;
43151da177e4SLinus Torvalds 
43161da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
43171da177e4SLinus Torvalds 
43181da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
43191da177e4SLinus Torvalds 
4320f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
43211da177e4SLinus Torvalds 
43221da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
43231da177e4SLinus Torvalds 
43241da177e4SLinus Torvalds 	hci_dev_lock(hdev);
43251da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
43261da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
43271da177e4SLinus Torvalds 
43281da177e4SLinus Torvalds 	if (conn) {
43291da177e4SLinus Torvalds 		/* Send to upper protocol */
4330686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
43311da177e4SLinus Torvalds 		return;
43321da177e4SLinus Torvalds 	} else {
43331da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
43341da177e4SLinus Torvalds 		       hdev->name, handle);
43351da177e4SLinus Torvalds 	}
43361da177e4SLinus Torvalds 
43371da177e4SLinus Torvalds 	kfree_skb(skb);
43381da177e4SLinus Torvalds }
43391da177e4SLinus Torvalds 
43409238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
43419238f36aSJohan Hedberg {
43429238f36aSJohan Hedberg 	struct sk_buff *skb;
43439238f36aSJohan Hedberg 
43449238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
43459238f36aSJohan Hedberg 	if (!skb)
43469238f36aSJohan Hedberg 		return true;
43479238f36aSJohan Hedberg 
43489238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
43499238f36aSJohan Hedberg }
43509238f36aSJohan Hedberg 
435142c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
435242c6b129SJohan Hedberg {
435342c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
435442c6b129SJohan Hedberg 	struct sk_buff *skb;
435542c6b129SJohan Hedberg 	u16 opcode;
435642c6b129SJohan Hedberg 
435742c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
435842c6b129SJohan Hedberg 		return;
435942c6b129SJohan Hedberg 
436042c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
436142c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
436242c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
436342c6b129SJohan Hedberg 		return;
436442c6b129SJohan Hedberg 
436542c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
436642c6b129SJohan Hedberg 	if (!skb)
436742c6b129SJohan Hedberg 		return;
436842c6b129SJohan Hedberg 
436942c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
437042c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
437142c6b129SJohan Hedberg }
437242c6b129SJohan Hedberg 
43739238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
43749238f36aSJohan Hedberg {
43759238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
43769238f36aSJohan Hedberg 	struct sk_buff *skb;
43779238f36aSJohan Hedberg 	unsigned long flags;
43789238f36aSJohan Hedberg 
43799238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
43809238f36aSJohan Hedberg 
438142c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
438242c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
43839238f36aSJohan Hedberg 	 */
438442c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
438542c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
438642c6b129SJohan Hedberg 		 * reset complete event during init and any pending
438742c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
438842c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
438942c6b129SJohan Hedberg 		 * command.
439042c6b129SJohan Hedberg 		 */
439142c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
439242c6b129SJohan Hedberg 			hci_resend_last(hdev);
439342c6b129SJohan Hedberg 
43949238f36aSJohan Hedberg 		return;
439542c6b129SJohan Hedberg 	}
43969238f36aSJohan Hedberg 
43979238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
43989238f36aSJohan Hedberg 	 * this request the request is not yet complete.
43999238f36aSJohan Hedberg 	 */
44009238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
44019238f36aSJohan Hedberg 		return;
44029238f36aSJohan Hedberg 
44039238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
44049238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
44059238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
44069238f36aSJohan Hedberg 	 */
44079238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
44089238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
440953e21fbcSJohan Hedberg 
441053e21fbcSJohan Hedberg 		if (req_complete) {
441153e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
441253e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
441353e21fbcSJohan Hedberg 			 * this function gets called again.
441453e21fbcSJohan Hedberg 			 */
441553e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
441653e21fbcSJohan Hedberg 
44179238f36aSJohan Hedberg 			goto call_complete;
44189238f36aSJohan Hedberg 		}
441953e21fbcSJohan Hedberg 	}
44209238f36aSJohan Hedberg 
44219238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
44229238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
44239238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
44249238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
44259238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
44269238f36aSJohan Hedberg 			break;
44279238f36aSJohan Hedberg 		}
44289238f36aSJohan Hedberg 
44299238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
44309238f36aSJohan Hedberg 		kfree_skb(skb);
44319238f36aSJohan Hedberg 	}
44329238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
44339238f36aSJohan Hedberg 
44349238f36aSJohan Hedberg call_complete:
44359238f36aSJohan Hedberg 	if (req_complete)
44369238f36aSJohan Hedberg 		req_complete(hdev, status);
44379238f36aSJohan Hedberg }
44389238f36aSJohan Hedberg 
4439b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
44401da177e4SLinus Torvalds {
4441b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
44421da177e4SLinus Torvalds 	struct sk_buff *skb;
44431da177e4SLinus Torvalds 
44441da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
44451da177e4SLinus Torvalds 
44461da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
4447cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4448cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4449cd82e61cSMarcel Holtmann 
44501da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
44511da177e4SLinus Torvalds 			/* Send copy to the sockets */
4452470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
44531da177e4SLinus Torvalds 		}
44541da177e4SLinus Torvalds 
44550736cfa8SMarcel Holtmann 		if (test_bit(HCI_RAW, &hdev->flags) ||
44560736cfa8SMarcel Holtmann 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
44571da177e4SLinus Torvalds 			kfree_skb(skb);
44581da177e4SLinus Torvalds 			continue;
44591da177e4SLinus Torvalds 		}
44601da177e4SLinus Torvalds 
44611da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
44621da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
44630d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
44641da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
44651da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
44661da177e4SLinus Torvalds 				kfree_skb(skb);
44671da177e4SLinus Torvalds 				continue;
44683ff50b79SStephen Hemminger 			}
44691da177e4SLinus Torvalds 		}
44701da177e4SLinus Torvalds 
44711da177e4SLinus Torvalds 		/* Process frame */
44720d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
44731da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4474b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
44751da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
44761da177e4SLinus Torvalds 			break;
44771da177e4SLinus Torvalds 
44781da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
44791da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
44801da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
44811da177e4SLinus Torvalds 			break;
44821da177e4SLinus Torvalds 
44831da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
44841da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
44851da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
44861da177e4SLinus Torvalds 			break;
44871da177e4SLinus Torvalds 
44881da177e4SLinus Torvalds 		default:
44891da177e4SLinus Torvalds 			kfree_skb(skb);
44901da177e4SLinus Torvalds 			break;
44911da177e4SLinus Torvalds 		}
44921da177e4SLinus Torvalds 	}
44931da177e4SLinus Torvalds }
44941da177e4SLinus Torvalds 
4495c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
44961da177e4SLinus Torvalds {
4497c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
44981da177e4SLinus Torvalds 	struct sk_buff *skb;
44991da177e4SLinus Torvalds 
45002104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
45012104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
45021da177e4SLinus Torvalds 
45031da177e4SLinus Torvalds 	/* Send queued commands */
45045a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
45055a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
45065a08ecceSAndrei Emeltchenko 		if (!skb)
45075a08ecceSAndrei Emeltchenko 			return;
45085a08ecceSAndrei Emeltchenko 
45091da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
45101da177e4SLinus Torvalds 
4511a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
451270f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
45131da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
451457d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
45157bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
45167bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
45177bdb8a5cSSzymon Janc 			else
45186bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
45195f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
45201da177e4SLinus Torvalds 		} else {
45211da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
4522c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
45231da177e4SLinus Torvalds 		}
45241da177e4SLinus Torvalds 	}
45251da177e4SLinus Torvalds }
4526