xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 111902f7)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
288c520a59SGustavo Padovan #include <linux/export.h>
293df92b31SSasha Levin #include <linux/idr.h>
30611b30f7SMarcel Holtmann #include <linux/rfkill.h>
31baf27f6eSMarcel Holtmann #include <linux/debugfs.h>
3299780a7bSJohan Hedberg #include <linux/crypto.h>
3347219839SMarcel Holtmann #include <asm/unaligned.h>
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
361da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
374bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
381da177e4SLinus Torvalds 
39970c4e46SJohan Hedberg #include "smp.h"
40970c4e46SJohan Hedberg 
41b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
42c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
433eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds /* HCI device list */
461da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
471da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds /* HCI callback list */
501da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
511da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
521da177e4SLinus Torvalds 
533df92b31SSasha Levin /* HCI ID Numbering */
543df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
553df92b31SSasha Levin 
561da177e4SLinus Torvalds /* ---- HCI notifications ---- */
571da177e4SLinus Torvalds 
586516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
591da177e4SLinus Torvalds {
60040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
611da177e4SLinus Torvalds }
621da177e4SLinus Torvalds 
63baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
64baf27f6eSMarcel Holtmann 
654b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
664b4148e9SMarcel Holtmann 			     size_t count, loff_t *ppos)
674b4148e9SMarcel Holtmann {
684b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
694b4148e9SMarcel Holtmann 	char buf[3];
704b4148e9SMarcel Holtmann 
71111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_DUT_MODE, &hdev->dbg_flags) ? 'Y': 'N';
724b4148e9SMarcel Holtmann 	buf[1] = '\n';
734b4148e9SMarcel Holtmann 	buf[2] = '\0';
744b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
754b4148e9SMarcel Holtmann }
764b4148e9SMarcel Holtmann 
774b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
784b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
794b4148e9SMarcel Holtmann {
804b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
814b4148e9SMarcel Holtmann 	struct sk_buff *skb;
824b4148e9SMarcel Holtmann 	char buf[32];
834b4148e9SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
844b4148e9SMarcel Holtmann 	bool enable;
854b4148e9SMarcel Holtmann 	int err;
864b4148e9SMarcel Holtmann 
874b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
884b4148e9SMarcel Holtmann 		return -ENETDOWN;
894b4148e9SMarcel Holtmann 
904b4148e9SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
914b4148e9SMarcel Holtmann 		return -EFAULT;
924b4148e9SMarcel Holtmann 
934b4148e9SMarcel Holtmann 	buf[buf_size] = '\0';
944b4148e9SMarcel Holtmann 	if (strtobool(buf, &enable))
954b4148e9SMarcel Holtmann 		return -EINVAL;
964b4148e9SMarcel Holtmann 
97111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_DUT_MODE, &hdev->dbg_flags))
984b4148e9SMarcel Holtmann 		return -EALREADY;
994b4148e9SMarcel Holtmann 
1004b4148e9SMarcel Holtmann 	hci_req_lock(hdev);
1014b4148e9SMarcel Holtmann 	if (enable)
1024b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
1034b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1044b4148e9SMarcel Holtmann 	else
1054b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1064b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1074b4148e9SMarcel Holtmann 	hci_req_unlock(hdev);
1084b4148e9SMarcel Holtmann 
1094b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1104b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1114b4148e9SMarcel Holtmann 
1124b4148e9SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
1134b4148e9SMarcel Holtmann 	kfree_skb(skb);
1144b4148e9SMarcel Holtmann 
1154b4148e9SMarcel Holtmann 	if (err < 0)
1164b4148e9SMarcel Holtmann 		return err;
1174b4148e9SMarcel Holtmann 
118111902f7SMarcel Holtmann 	change_bit(HCI_DUT_MODE, &hdev->dbg_flags);
1194b4148e9SMarcel Holtmann 
1204b4148e9SMarcel Holtmann 	return count;
1214b4148e9SMarcel Holtmann }
1224b4148e9SMarcel Holtmann 
1234b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1244b4148e9SMarcel Holtmann 	.open		= simple_open,
1254b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1264b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1274b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1284b4148e9SMarcel Holtmann };
1294b4148e9SMarcel Holtmann 
130dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr)
131dfb826a8SMarcel Holtmann {
132dfb826a8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
133dfb826a8SMarcel Holtmann 	u8 p;
134dfb826a8SMarcel Holtmann 
135dfb826a8SMarcel Holtmann 	hci_dev_lock(hdev);
136dfb826a8SMarcel Holtmann 	for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
137cfbb2b5bSMarcel Holtmann 		seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
138dfb826a8SMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p,
139dfb826a8SMarcel Holtmann 			   hdev->features[p][0], hdev->features[p][1],
140dfb826a8SMarcel Holtmann 			   hdev->features[p][2], hdev->features[p][3],
141dfb826a8SMarcel Holtmann 			   hdev->features[p][4], hdev->features[p][5],
142dfb826a8SMarcel Holtmann 			   hdev->features[p][6], hdev->features[p][7]);
143dfb826a8SMarcel Holtmann 	}
144cfbb2b5bSMarcel Holtmann 	if (lmp_le_capable(hdev))
145cfbb2b5bSMarcel Holtmann 		seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
146cfbb2b5bSMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
147cfbb2b5bSMarcel Holtmann 			   hdev->le_features[0], hdev->le_features[1],
148cfbb2b5bSMarcel Holtmann 			   hdev->le_features[2], hdev->le_features[3],
149cfbb2b5bSMarcel Holtmann 			   hdev->le_features[4], hdev->le_features[5],
150cfbb2b5bSMarcel Holtmann 			   hdev->le_features[6], hdev->le_features[7]);
151dfb826a8SMarcel Holtmann 	hci_dev_unlock(hdev);
152dfb826a8SMarcel Holtmann 
153dfb826a8SMarcel Holtmann 	return 0;
154dfb826a8SMarcel Holtmann }
155dfb826a8SMarcel Holtmann 
156dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file)
157dfb826a8SMarcel Holtmann {
158dfb826a8SMarcel Holtmann 	return single_open(file, features_show, inode->i_private);
159dfb826a8SMarcel Holtmann }
160dfb826a8SMarcel Holtmann 
161dfb826a8SMarcel Holtmann static const struct file_operations features_fops = {
162dfb826a8SMarcel Holtmann 	.open		= features_open,
163dfb826a8SMarcel Holtmann 	.read		= seq_read,
164dfb826a8SMarcel Holtmann 	.llseek		= seq_lseek,
165dfb826a8SMarcel Holtmann 	.release	= single_release,
166dfb826a8SMarcel Holtmann };
167dfb826a8SMarcel Holtmann 
16870afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p)
16970afe0b8SMarcel Holtmann {
17070afe0b8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
17170afe0b8SMarcel Holtmann 	struct bdaddr_list *b;
17270afe0b8SMarcel Holtmann 
17370afe0b8SMarcel Holtmann 	hci_dev_lock(hdev);
17470afe0b8SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list)
175b25f0785SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
17670afe0b8SMarcel Holtmann 	hci_dev_unlock(hdev);
17770afe0b8SMarcel Holtmann 
17870afe0b8SMarcel Holtmann 	return 0;
17970afe0b8SMarcel Holtmann }
18070afe0b8SMarcel Holtmann 
18170afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file)
18270afe0b8SMarcel Holtmann {
18370afe0b8SMarcel Holtmann 	return single_open(file, blacklist_show, inode->i_private);
18470afe0b8SMarcel Holtmann }
18570afe0b8SMarcel Holtmann 
18670afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = {
18770afe0b8SMarcel Holtmann 	.open		= blacklist_open,
18870afe0b8SMarcel Holtmann 	.read		= seq_read,
18970afe0b8SMarcel Holtmann 	.llseek		= seq_lseek,
19070afe0b8SMarcel Holtmann 	.release	= single_release,
19170afe0b8SMarcel Holtmann };
19270afe0b8SMarcel Holtmann 
19347219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p)
19447219839SMarcel Holtmann {
19547219839SMarcel Holtmann 	struct hci_dev *hdev = f->private;
19647219839SMarcel Holtmann 	struct bt_uuid *uuid;
19747219839SMarcel Holtmann 
19847219839SMarcel Holtmann 	hci_dev_lock(hdev);
19947219839SMarcel Holtmann 	list_for_each_entry(uuid, &hdev->uuids, list) {
20058f01aa9SMarcel Holtmann 		u8 i, val[16];
20147219839SMarcel Holtmann 
20258f01aa9SMarcel Holtmann 		/* The Bluetooth UUID values are stored in big endian,
20358f01aa9SMarcel Holtmann 		 * but with reversed byte order. So convert them into
20458f01aa9SMarcel Holtmann 		 * the right order for the %pUb modifier.
20558f01aa9SMarcel Holtmann 		 */
20658f01aa9SMarcel Holtmann 		for (i = 0; i < 16; i++)
20758f01aa9SMarcel Holtmann 			val[i] = uuid->uuid[15 - i];
20847219839SMarcel Holtmann 
20958f01aa9SMarcel Holtmann 		seq_printf(f, "%pUb\n", val);
21047219839SMarcel Holtmann 	}
21147219839SMarcel Holtmann 	hci_dev_unlock(hdev);
21247219839SMarcel Holtmann 
21347219839SMarcel Holtmann 	return 0;
21447219839SMarcel Holtmann }
21547219839SMarcel Holtmann 
21647219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file)
21747219839SMarcel Holtmann {
21847219839SMarcel Holtmann 	return single_open(file, uuids_show, inode->i_private);
21947219839SMarcel Holtmann }
22047219839SMarcel Holtmann 
22147219839SMarcel Holtmann static const struct file_operations uuids_fops = {
22247219839SMarcel Holtmann 	.open		= uuids_open,
22347219839SMarcel Holtmann 	.read		= seq_read,
22447219839SMarcel Holtmann 	.llseek		= seq_lseek,
22547219839SMarcel Holtmann 	.release	= single_release,
22647219839SMarcel Holtmann };
22747219839SMarcel Holtmann 
228baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p)
229baf27f6eSMarcel Holtmann {
230baf27f6eSMarcel Holtmann 	struct hci_dev *hdev = f->private;
231baf27f6eSMarcel Holtmann 	struct discovery_state *cache = &hdev->discovery;
232baf27f6eSMarcel Holtmann 	struct inquiry_entry *e;
233baf27f6eSMarcel Holtmann 
234baf27f6eSMarcel Holtmann 	hci_dev_lock(hdev);
235baf27f6eSMarcel Holtmann 
236baf27f6eSMarcel Holtmann 	list_for_each_entry(e, &cache->all, all) {
237baf27f6eSMarcel Holtmann 		struct inquiry_data *data = &e->data;
238baf27f6eSMarcel Holtmann 		seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
239baf27f6eSMarcel Holtmann 			   &data->bdaddr,
240baf27f6eSMarcel Holtmann 			   data->pscan_rep_mode, data->pscan_period_mode,
241baf27f6eSMarcel Holtmann 			   data->pscan_mode, data->dev_class[2],
242baf27f6eSMarcel Holtmann 			   data->dev_class[1], data->dev_class[0],
243baf27f6eSMarcel Holtmann 			   __le16_to_cpu(data->clock_offset),
244baf27f6eSMarcel Holtmann 			   data->rssi, data->ssp_mode, e->timestamp);
245baf27f6eSMarcel Holtmann 	}
246baf27f6eSMarcel Holtmann 
247baf27f6eSMarcel Holtmann 	hci_dev_unlock(hdev);
248baf27f6eSMarcel Holtmann 
249baf27f6eSMarcel Holtmann 	return 0;
250baf27f6eSMarcel Holtmann }
251baf27f6eSMarcel Holtmann 
252baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file)
253baf27f6eSMarcel Holtmann {
254baf27f6eSMarcel Holtmann 	return single_open(file, inquiry_cache_show, inode->i_private);
255baf27f6eSMarcel Holtmann }
256baf27f6eSMarcel Holtmann 
257baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = {
258baf27f6eSMarcel Holtmann 	.open		= inquiry_cache_open,
259baf27f6eSMarcel Holtmann 	.read		= seq_read,
260baf27f6eSMarcel Holtmann 	.llseek		= seq_lseek,
261baf27f6eSMarcel Holtmann 	.release	= single_release,
262baf27f6eSMarcel Holtmann };
263baf27f6eSMarcel Holtmann 
26402d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr)
26502d08d15SMarcel Holtmann {
26602d08d15SMarcel Holtmann 	struct hci_dev *hdev = f->private;
26702d08d15SMarcel Holtmann 	struct list_head *p, *n;
26802d08d15SMarcel Holtmann 
26902d08d15SMarcel Holtmann 	hci_dev_lock(hdev);
27002d08d15SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->link_keys) {
27102d08d15SMarcel Holtmann 		struct link_key *key = list_entry(p, struct link_key, list);
27202d08d15SMarcel Holtmann 		seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
27302d08d15SMarcel Holtmann 			   HCI_LINK_KEY_SIZE, key->val, key->pin_len);
27402d08d15SMarcel Holtmann 	}
27502d08d15SMarcel Holtmann 	hci_dev_unlock(hdev);
27602d08d15SMarcel Holtmann 
27702d08d15SMarcel Holtmann 	return 0;
27802d08d15SMarcel Holtmann }
27902d08d15SMarcel Holtmann 
28002d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file)
28102d08d15SMarcel Holtmann {
28202d08d15SMarcel Holtmann 	return single_open(file, link_keys_show, inode->i_private);
28302d08d15SMarcel Holtmann }
28402d08d15SMarcel Holtmann 
28502d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = {
28602d08d15SMarcel Holtmann 	.open		= link_keys_open,
28702d08d15SMarcel Holtmann 	.read		= seq_read,
28802d08d15SMarcel Holtmann 	.llseek		= seq_lseek,
28902d08d15SMarcel Holtmann 	.release	= single_release,
29002d08d15SMarcel Holtmann };
29102d08d15SMarcel Holtmann 
292babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr)
293babdbb3cSMarcel Holtmann {
294babdbb3cSMarcel Holtmann 	struct hci_dev *hdev = f->private;
295babdbb3cSMarcel Holtmann 
296babdbb3cSMarcel Holtmann 	hci_dev_lock(hdev);
297babdbb3cSMarcel Holtmann 	seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
298babdbb3cSMarcel Holtmann 		   hdev->dev_class[1], hdev->dev_class[0]);
299babdbb3cSMarcel Holtmann 	hci_dev_unlock(hdev);
300babdbb3cSMarcel Holtmann 
301babdbb3cSMarcel Holtmann 	return 0;
302babdbb3cSMarcel Holtmann }
303babdbb3cSMarcel Holtmann 
304babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file)
305babdbb3cSMarcel Holtmann {
306babdbb3cSMarcel Holtmann 	return single_open(file, dev_class_show, inode->i_private);
307babdbb3cSMarcel Holtmann }
308babdbb3cSMarcel Holtmann 
309babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = {
310babdbb3cSMarcel Holtmann 	.open		= dev_class_open,
311babdbb3cSMarcel Holtmann 	.read		= seq_read,
312babdbb3cSMarcel Holtmann 	.llseek		= seq_lseek,
313babdbb3cSMarcel Holtmann 	.release	= single_release,
314babdbb3cSMarcel Holtmann };
315babdbb3cSMarcel Holtmann 
316041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val)
317041000b9SMarcel Holtmann {
318041000b9SMarcel Holtmann 	struct hci_dev *hdev = data;
319041000b9SMarcel Holtmann 
320041000b9SMarcel Holtmann 	hci_dev_lock(hdev);
321041000b9SMarcel Holtmann 	*val = hdev->voice_setting;
322041000b9SMarcel Holtmann 	hci_dev_unlock(hdev);
323041000b9SMarcel Holtmann 
324041000b9SMarcel Holtmann 	return 0;
325041000b9SMarcel Holtmann }
326041000b9SMarcel Holtmann 
327041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
328041000b9SMarcel Holtmann 			NULL, "0x%4.4llx\n");
329041000b9SMarcel Holtmann 
330ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val)
331ebd1e33bSMarcel Holtmann {
332ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
333ebd1e33bSMarcel Holtmann 
334ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
335ebd1e33bSMarcel Holtmann 	hdev->auto_accept_delay = val;
336ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
337ebd1e33bSMarcel Holtmann 
338ebd1e33bSMarcel Holtmann 	return 0;
339ebd1e33bSMarcel Holtmann }
340ebd1e33bSMarcel Holtmann 
341ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val)
342ebd1e33bSMarcel Holtmann {
343ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
344ebd1e33bSMarcel Holtmann 
345ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
346ebd1e33bSMarcel Holtmann 	*val = hdev->auto_accept_delay;
347ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
348ebd1e33bSMarcel Holtmann 
349ebd1e33bSMarcel Holtmann 	return 0;
350ebd1e33bSMarcel Holtmann }
351ebd1e33bSMarcel Holtmann 
352ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
353ebd1e33bSMarcel Holtmann 			auto_accept_delay_set, "%llu\n");
354ebd1e33bSMarcel Holtmann 
35506f5b778SMarcel Holtmann static int ssp_debug_mode_set(void *data, u64 val)
35606f5b778SMarcel Holtmann {
35706f5b778SMarcel Holtmann 	struct hci_dev *hdev = data;
35806f5b778SMarcel Holtmann 	struct sk_buff *skb;
35906f5b778SMarcel Holtmann 	__u8 mode;
36006f5b778SMarcel Holtmann 	int err;
36106f5b778SMarcel Holtmann 
36206f5b778SMarcel Holtmann 	if (val != 0 && val != 1)
36306f5b778SMarcel Holtmann 		return -EINVAL;
36406f5b778SMarcel Holtmann 
36506f5b778SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
36606f5b778SMarcel Holtmann 		return -ENETDOWN;
36706f5b778SMarcel Holtmann 
36806f5b778SMarcel Holtmann 	hci_req_lock(hdev);
36906f5b778SMarcel Holtmann 	mode = val;
37006f5b778SMarcel Holtmann 	skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
37106f5b778SMarcel Holtmann 			     &mode, HCI_CMD_TIMEOUT);
37206f5b778SMarcel Holtmann 	hci_req_unlock(hdev);
37306f5b778SMarcel Holtmann 
37406f5b778SMarcel Holtmann 	if (IS_ERR(skb))
37506f5b778SMarcel Holtmann 		return PTR_ERR(skb);
37606f5b778SMarcel Holtmann 
37706f5b778SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
37806f5b778SMarcel Holtmann 	kfree_skb(skb);
37906f5b778SMarcel Holtmann 
38006f5b778SMarcel Holtmann 	if (err < 0)
38106f5b778SMarcel Holtmann 		return err;
38206f5b778SMarcel Holtmann 
38306f5b778SMarcel Holtmann 	hci_dev_lock(hdev);
38406f5b778SMarcel Holtmann 	hdev->ssp_debug_mode = val;
38506f5b778SMarcel Holtmann 	hci_dev_unlock(hdev);
38606f5b778SMarcel Holtmann 
38706f5b778SMarcel Holtmann 	return 0;
38806f5b778SMarcel Holtmann }
38906f5b778SMarcel Holtmann 
39006f5b778SMarcel Holtmann static int ssp_debug_mode_get(void *data, u64 *val)
39106f5b778SMarcel Holtmann {
39206f5b778SMarcel Holtmann 	struct hci_dev *hdev = data;
39306f5b778SMarcel Holtmann 
39406f5b778SMarcel Holtmann 	hci_dev_lock(hdev);
39506f5b778SMarcel Holtmann 	*val = hdev->ssp_debug_mode;
39606f5b778SMarcel Holtmann 	hci_dev_unlock(hdev);
39706f5b778SMarcel Holtmann 
39806f5b778SMarcel Holtmann 	return 0;
39906f5b778SMarcel Holtmann }
40006f5b778SMarcel Holtmann 
40106f5b778SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
40206f5b778SMarcel Holtmann 			ssp_debug_mode_set, "%llu\n");
40306f5b778SMarcel Holtmann 
4045afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
4055afeac14SMarcel Holtmann 				     size_t count, loff_t *ppos)
4065afeac14SMarcel Holtmann {
4075afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
4085afeac14SMarcel Holtmann 	char buf[3];
4095afeac14SMarcel Holtmann 
410111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_SC, &hdev->dbg_flags) ? 'Y': 'N';
4115afeac14SMarcel Holtmann 	buf[1] = '\n';
4125afeac14SMarcel Holtmann 	buf[2] = '\0';
4135afeac14SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
4145afeac14SMarcel Holtmann }
4155afeac14SMarcel Holtmann 
4165afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file,
4175afeac14SMarcel Holtmann 				      const char __user *user_buf,
4185afeac14SMarcel Holtmann 				      size_t count, loff_t *ppos)
4195afeac14SMarcel Holtmann {
4205afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
4215afeac14SMarcel Holtmann 	char buf[32];
4225afeac14SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
4235afeac14SMarcel Holtmann 	bool enable;
4245afeac14SMarcel Holtmann 
4255afeac14SMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
4265afeac14SMarcel Holtmann 		return -EBUSY;
4275afeac14SMarcel Holtmann 
4285afeac14SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
4295afeac14SMarcel Holtmann 		return -EFAULT;
4305afeac14SMarcel Holtmann 
4315afeac14SMarcel Holtmann 	buf[buf_size] = '\0';
4325afeac14SMarcel Holtmann 	if (strtobool(buf, &enable))
4335afeac14SMarcel Holtmann 		return -EINVAL;
4345afeac14SMarcel Holtmann 
435111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_SC, &hdev->dbg_flags))
4365afeac14SMarcel Holtmann 		return -EALREADY;
4375afeac14SMarcel Holtmann 
438111902f7SMarcel Holtmann 	change_bit(HCI_FORCE_SC, &hdev->dbg_flags);
4395afeac14SMarcel Holtmann 
4405afeac14SMarcel Holtmann 	return count;
4415afeac14SMarcel Holtmann }
4425afeac14SMarcel Holtmann 
4435afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = {
4445afeac14SMarcel Holtmann 	.open		= simple_open,
4455afeac14SMarcel Holtmann 	.read		= force_sc_support_read,
4465afeac14SMarcel Holtmann 	.write		= force_sc_support_write,
4475afeac14SMarcel Holtmann 	.llseek		= default_llseek,
4485afeac14SMarcel Holtmann };
4495afeac14SMarcel Holtmann 
450134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
451134c2a89SMarcel Holtmann 				 size_t count, loff_t *ppos)
452134c2a89SMarcel Holtmann {
453134c2a89SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
454134c2a89SMarcel Holtmann 	char buf[3];
455134c2a89SMarcel Holtmann 
456134c2a89SMarcel Holtmann 	buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N';
457134c2a89SMarcel Holtmann 	buf[1] = '\n';
458134c2a89SMarcel Holtmann 	buf[2] = '\0';
459134c2a89SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
460134c2a89SMarcel Holtmann }
461134c2a89SMarcel Holtmann 
462134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = {
463134c2a89SMarcel Holtmann 	.open		= simple_open,
464134c2a89SMarcel Holtmann 	.read		= sc_only_mode_read,
465134c2a89SMarcel Holtmann 	.llseek		= default_llseek,
466134c2a89SMarcel Holtmann };
467134c2a89SMarcel Holtmann 
4682bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val)
4692bfa3531SMarcel Holtmann {
4702bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4712bfa3531SMarcel Holtmann 
4722bfa3531SMarcel Holtmann 	if (val != 0 && (val < 500 || val > 3600000))
4732bfa3531SMarcel Holtmann 		return -EINVAL;
4742bfa3531SMarcel Holtmann 
4752bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4762bfa3531SMarcel Holtmann 	hdev->idle_timeout = val;
4772bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4782bfa3531SMarcel Holtmann 
4792bfa3531SMarcel Holtmann 	return 0;
4802bfa3531SMarcel Holtmann }
4812bfa3531SMarcel Holtmann 
4822bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val)
4832bfa3531SMarcel Holtmann {
4842bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4852bfa3531SMarcel Holtmann 
4862bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4872bfa3531SMarcel Holtmann 	*val = hdev->idle_timeout;
4882bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4892bfa3531SMarcel Holtmann 
4902bfa3531SMarcel Holtmann 	return 0;
4912bfa3531SMarcel Holtmann }
4922bfa3531SMarcel Holtmann 
4932bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
4942bfa3531SMarcel Holtmann 			idle_timeout_set, "%llu\n");
4952bfa3531SMarcel Holtmann 
496c982b2eaSJohan Hedberg static int rpa_timeout_set(void *data, u64 val)
497c982b2eaSJohan Hedberg {
498c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
499c982b2eaSJohan Hedberg 
500c982b2eaSJohan Hedberg 	/* Require the RPA timeout to be at least 30 seconds and at most
501c982b2eaSJohan Hedberg 	 * 24 hours.
502c982b2eaSJohan Hedberg 	 */
503c982b2eaSJohan Hedberg 	if (val < 30 || val > (60 * 60 * 24))
504c982b2eaSJohan Hedberg 		return -EINVAL;
505c982b2eaSJohan Hedberg 
506c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
507c982b2eaSJohan Hedberg 	hdev->rpa_timeout = val;
508c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
509c982b2eaSJohan Hedberg 
510c982b2eaSJohan Hedberg 	return 0;
511c982b2eaSJohan Hedberg }
512c982b2eaSJohan Hedberg 
513c982b2eaSJohan Hedberg static int rpa_timeout_get(void *data, u64 *val)
514c982b2eaSJohan Hedberg {
515c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
516c982b2eaSJohan Hedberg 
517c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
518c982b2eaSJohan Hedberg 	*val = hdev->rpa_timeout;
519c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
520c982b2eaSJohan Hedberg 
521c982b2eaSJohan Hedberg 	return 0;
522c982b2eaSJohan Hedberg }
523c982b2eaSJohan Hedberg 
524c982b2eaSJohan Hedberg DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get,
525c982b2eaSJohan Hedberg 			rpa_timeout_set, "%llu\n");
526c982b2eaSJohan Hedberg 
5272bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val)
5282bfa3531SMarcel Holtmann {
5292bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5302bfa3531SMarcel Holtmann 
5312bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
5322bfa3531SMarcel Holtmann 		return -EINVAL;
5332bfa3531SMarcel Holtmann 
5342bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5352bfa3531SMarcel Holtmann 	hdev->sniff_min_interval = val;
5362bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5372bfa3531SMarcel Holtmann 
5382bfa3531SMarcel Holtmann 	return 0;
5392bfa3531SMarcel Holtmann }
5402bfa3531SMarcel Holtmann 
5412bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val)
5422bfa3531SMarcel Holtmann {
5432bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5442bfa3531SMarcel Holtmann 
5452bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5462bfa3531SMarcel Holtmann 	*val = hdev->sniff_min_interval;
5472bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5482bfa3531SMarcel Holtmann 
5492bfa3531SMarcel Holtmann 	return 0;
5502bfa3531SMarcel Holtmann }
5512bfa3531SMarcel Holtmann 
5522bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get,
5532bfa3531SMarcel Holtmann 			sniff_min_interval_set, "%llu\n");
5542bfa3531SMarcel Holtmann 
5552bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val)
5562bfa3531SMarcel Holtmann {
5572bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5582bfa3531SMarcel Holtmann 
5592bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
5602bfa3531SMarcel Holtmann 		return -EINVAL;
5612bfa3531SMarcel Holtmann 
5622bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5632bfa3531SMarcel Holtmann 	hdev->sniff_max_interval = val;
5642bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5652bfa3531SMarcel Holtmann 
5662bfa3531SMarcel Holtmann 	return 0;
5672bfa3531SMarcel Holtmann }
5682bfa3531SMarcel Holtmann 
5692bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val)
5702bfa3531SMarcel Holtmann {
5712bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5722bfa3531SMarcel Holtmann 
5732bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5742bfa3531SMarcel Holtmann 	*val = hdev->sniff_max_interval;
5752bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5762bfa3531SMarcel Holtmann 
5772bfa3531SMarcel Holtmann 	return 0;
5782bfa3531SMarcel Holtmann }
5792bfa3531SMarcel Holtmann 
5802bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
5812bfa3531SMarcel Holtmann 			sniff_max_interval_set, "%llu\n");
5822bfa3531SMarcel Holtmann 
58331ad1691SAndrzej Kaczmarek static int conn_info_min_age_set(void *data, u64 val)
58431ad1691SAndrzej Kaczmarek {
58531ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
58631ad1691SAndrzej Kaczmarek 
58731ad1691SAndrzej Kaczmarek 	if (val == 0 || val > hdev->conn_info_max_age)
58831ad1691SAndrzej Kaczmarek 		return -EINVAL;
58931ad1691SAndrzej Kaczmarek 
59031ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
59131ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = val;
59231ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
59331ad1691SAndrzej Kaczmarek 
59431ad1691SAndrzej Kaczmarek 	return 0;
59531ad1691SAndrzej Kaczmarek }
59631ad1691SAndrzej Kaczmarek 
59731ad1691SAndrzej Kaczmarek static int conn_info_min_age_get(void *data, u64 *val)
59831ad1691SAndrzej Kaczmarek {
59931ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
60031ad1691SAndrzej Kaczmarek 
60131ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
60231ad1691SAndrzej Kaczmarek 	*val = hdev->conn_info_min_age;
60331ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
60431ad1691SAndrzej Kaczmarek 
60531ad1691SAndrzej Kaczmarek 	return 0;
60631ad1691SAndrzej Kaczmarek }
60731ad1691SAndrzej Kaczmarek 
60831ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_min_age_fops, conn_info_min_age_get,
60931ad1691SAndrzej Kaczmarek 			conn_info_min_age_set, "%llu\n");
61031ad1691SAndrzej Kaczmarek 
61131ad1691SAndrzej Kaczmarek static int conn_info_max_age_set(void *data, u64 val)
61231ad1691SAndrzej Kaczmarek {
61331ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
61431ad1691SAndrzej Kaczmarek 
61531ad1691SAndrzej Kaczmarek 	if (val == 0 || val < hdev->conn_info_min_age)
61631ad1691SAndrzej Kaczmarek 		return -EINVAL;
61731ad1691SAndrzej Kaczmarek 
61831ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
61931ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = val;
62031ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
62131ad1691SAndrzej Kaczmarek 
62231ad1691SAndrzej Kaczmarek 	return 0;
62331ad1691SAndrzej Kaczmarek }
62431ad1691SAndrzej Kaczmarek 
62531ad1691SAndrzej Kaczmarek static int conn_info_max_age_get(void *data, u64 *val)
62631ad1691SAndrzej Kaczmarek {
62731ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
62831ad1691SAndrzej Kaczmarek 
62931ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
63031ad1691SAndrzej Kaczmarek 	*val = hdev->conn_info_max_age;
63131ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
63231ad1691SAndrzej Kaczmarek 
63331ad1691SAndrzej Kaczmarek 	return 0;
63431ad1691SAndrzej Kaczmarek }
63531ad1691SAndrzej Kaczmarek 
63631ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get,
63731ad1691SAndrzej Kaczmarek 			conn_info_max_age_set, "%llu\n");
63831ad1691SAndrzej Kaczmarek 
639ac345813SMarcel Holtmann static int identity_show(struct seq_file *f, void *p)
640ac345813SMarcel Holtmann {
641ac345813SMarcel Holtmann 	struct hci_dev *hdev = f->private;
642a1f4c318SJohan Hedberg 	bdaddr_t addr;
643ac345813SMarcel Holtmann 	u8 addr_type;
644ac345813SMarcel Holtmann 
645ac345813SMarcel Holtmann 	hci_dev_lock(hdev);
646ac345813SMarcel Holtmann 
647a1f4c318SJohan Hedberg 	hci_copy_identity_address(hdev, &addr, &addr_type);
648ac345813SMarcel Holtmann 
649a1f4c318SJohan Hedberg 	seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type,
650473deef2SMarcel Holtmann 		   16, hdev->irk, &hdev->rpa);
651ac345813SMarcel Holtmann 
652ac345813SMarcel Holtmann 	hci_dev_unlock(hdev);
653ac345813SMarcel Holtmann 
654ac345813SMarcel Holtmann 	return 0;
655ac345813SMarcel Holtmann }
656ac345813SMarcel Holtmann 
657ac345813SMarcel Holtmann static int identity_open(struct inode *inode, struct file *file)
658ac345813SMarcel Holtmann {
659ac345813SMarcel Holtmann 	return single_open(file, identity_show, inode->i_private);
660ac345813SMarcel Holtmann }
661ac345813SMarcel Holtmann 
662ac345813SMarcel Holtmann static const struct file_operations identity_fops = {
663ac345813SMarcel Holtmann 	.open		= identity_open,
664ac345813SMarcel Holtmann 	.read		= seq_read,
665ac345813SMarcel Holtmann 	.llseek		= seq_lseek,
666ac345813SMarcel Holtmann 	.release	= single_release,
667ac345813SMarcel Holtmann };
668ac345813SMarcel Holtmann 
6697a4cd51dSMarcel Holtmann static int random_address_show(struct seq_file *f, void *p)
6707a4cd51dSMarcel Holtmann {
6717a4cd51dSMarcel Holtmann 	struct hci_dev *hdev = f->private;
6727a4cd51dSMarcel Holtmann 
6737a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
6747a4cd51dSMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->random_addr);
6757a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
6767a4cd51dSMarcel Holtmann 
6777a4cd51dSMarcel Holtmann 	return 0;
6787a4cd51dSMarcel Holtmann }
6797a4cd51dSMarcel Holtmann 
6807a4cd51dSMarcel Holtmann static int random_address_open(struct inode *inode, struct file *file)
6817a4cd51dSMarcel Holtmann {
6827a4cd51dSMarcel Holtmann 	return single_open(file, random_address_show, inode->i_private);
6837a4cd51dSMarcel Holtmann }
6847a4cd51dSMarcel Holtmann 
6857a4cd51dSMarcel Holtmann static const struct file_operations random_address_fops = {
6867a4cd51dSMarcel Holtmann 	.open		= random_address_open,
6877a4cd51dSMarcel Holtmann 	.read		= seq_read,
6887a4cd51dSMarcel Holtmann 	.llseek		= seq_lseek,
6897a4cd51dSMarcel Holtmann 	.release	= single_release,
6907a4cd51dSMarcel Holtmann };
6917a4cd51dSMarcel Holtmann 
692e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p)
693e7b8fc92SMarcel Holtmann {
694e7b8fc92SMarcel Holtmann 	struct hci_dev *hdev = f->private;
695e7b8fc92SMarcel Holtmann 
696e7b8fc92SMarcel Holtmann 	hci_dev_lock(hdev);
697e7b8fc92SMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->static_addr);
698e7b8fc92SMarcel Holtmann 	hci_dev_unlock(hdev);
699e7b8fc92SMarcel Holtmann 
700e7b8fc92SMarcel Holtmann 	return 0;
701e7b8fc92SMarcel Holtmann }
702e7b8fc92SMarcel Holtmann 
703e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file)
704e7b8fc92SMarcel Holtmann {
705e7b8fc92SMarcel Holtmann 	return single_open(file, static_address_show, inode->i_private);
706e7b8fc92SMarcel Holtmann }
707e7b8fc92SMarcel Holtmann 
708e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = {
709e7b8fc92SMarcel Holtmann 	.open		= static_address_open,
710e7b8fc92SMarcel Holtmann 	.read		= seq_read,
711e7b8fc92SMarcel Holtmann 	.llseek		= seq_lseek,
712e7b8fc92SMarcel Holtmann 	.release	= single_release,
713e7b8fc92SMarcel Holtmann };
714e7b8fc92SMarcel Holtmann 
715b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file,
716b32bba6cSMarcel Holtmann 					 char __user *user_buf,
717b32bba6cSMarcel Holtmann 					 size_t count, loff_t *ppos)
71892202185SMarcel Holtmann {
719b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
720b32bba6cSMarcel Holtmann 	char buf[3];
72192202185SMarcel Holtmann 
722111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N';
723b32bba6cSMarcel Holtmann 	buf[1] = '\n';
724b32bba6cSMarcel Holtmann 	buf[2] = '\0';
725b32bba6cSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
726b32bba6cSMarcel Holtmann }
727b32bba6cSMarcel Holtmann 
728b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file,
729b32bba6cSMarcel Holtmann 					  const char __user *user_buf,
730b32bba6cSMarcel Holtmann 					  size_t count, loff_t *ppos)
731b32bba6cSMarcel Holtmann {
732b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
733b32bba6cSMarcel Holtmann 	char buf[32];
734b32bba6cSMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
735b32bba6cSMarcel Holtmann 	bool enable;
736b32bba6cSMarcel Holtmann 
737b32bba6cSMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
738b32bba6cSMarcel Holtmann 		return -EBUSY;
739b32bba6cSMarcel Holtmann 
740b32bba6cSMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
741b32bba6cSMarcel Holtmann 		return -EFAULT;
742b32bba6cSMarcel Holtmann 
743b32bba6cSMarcel Holtmann 	buf[buf_size] = '\0';
744b32bba6cSMarcel Holtmann 	if (strtobool(buf, &enable))
74592202185SMarcel Holtmann 		return -EINVAL;
74692202185SMarcel Holtmann 
747111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags))
748b32bba6cSMarcel Holtmann 		return -EALREADY;
74992202185SMarcel Holtmann 
750111902f7SMarcel Holtmann 	change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags);
751b32bba6cSMarcel Holtmann 
752b32bba6cSMarcel Holtmann 	return count;
75392202185SMarcel Holtmann }
75492202185SMarcel Holtmann 
755b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = {
756b32bba6cSMarcel Holtmann 	.open		= simple_open,
757b32bba6cSMarcel Holtmann 	.read		= force_static_address_read,
758b32bba6cSMarcel Holtmann 	.write		= force_static_address_write,
759b32bba6cSMarcel Holtmann 	.llseek		= default_llseek,
760b32bba6cSMarcel Holtmann };
76192202185SMarcel Holtmann 
762d2ab0ac1SMarcel Holtmann static int white_list_show(struct seq_file *f, void *ptr)
763d2ab0ac1SMarcel Holtmann {
764d2ab0ac1SMarcel Holtmann 	struct hci_dev *hdev = f->private;
765d2ab0ac1SMarcel Holtmann 	struct bdaddr_list *b;
766d2ab0ac1SMarcel Holtmann 
767d2ab0ac1SMarcel Holtmann 	hci_dev_lock(hdev);
768d2ab0ac1SMarcel Holtmann 	list_for_each_entry(b, &hdev->le_white_list, list)
769d2ab0ac1SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
770d2ab0ac1SMarcel Holtmann 	hci_dev_unlock(hdev);
771d2ab0ac1SMarcel Holtmann 
772d2ab0ac1SMarcel Holtmann 	return 0;
773d2ab0ac1SMarcel Holtmann }
774d2ab0ac1SMarcel Holtmann 
775d2ab0ac1SMarcel Holtmann static int white_list_open(struct inode *inode, struct file *file)
776d2ab0ac1SMarcel Holtmann {
777d2ab0ac1SMarcel Holtmann 	return single_open(file, white_list_show, inode->i_private);
778d2ab0ac1SMarcel Holtmann }
779d2ab0ac1SMarcel Holtmann 
780d2ab0ac1SMarcel Holtmann static const struct file_operations white_list_fops = {
781d2ab0ac1SMarcel Holtmann 	.open		= white_list_open,
782d2ab0ac1SMarcel Holtmann 	.read		= seq_read,
783d2ab0ac1SMarcel Holtmann 	.llseek		= seq_lseek,
784d2ab0ac1SMarcel Holtmann 	.release	= single_release,
785d2ab0ac1SMarcel Holtmann };
786d2ab0ac1SMarcel Holtmann 
7873698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
7883698d704SMarcel Holtmann {
7893698d704SMarcel Holtmann 	struct hci_dev *hdev = f->private;
7903698d704SMarcel Holtmann 	struct list_head *p, *n;
7913698d704SMarcel Holtmann 
7923698d704SMarcel Holtmann 	hci_dev_lock(hdev);
7933698d704SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->identity_resolving_keys) {
7943698d704SMarcel Holtmann 		struct smp_irk *irk = list_entry(p, struct smp_irk, list);
7953698d704SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
7963698d704SMarcel Holtmann 			   &irk->bdaddr, irk->addr_type,
7973698d704SMarcel Holtmann 			   16, irk->val, &irk->rpa);
7983698d704SMarcel Holtmann 	}
7993698d704SMarcel Holtmann 	hci_dev_unlock(hdev);
8003698d704SMarcel Holtmann 
8013698d704SMarcel Holtmann 	return 0;
8023698d704SMarcel Holtmann }
8033698d704SMarcel Holtmann 
8043698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file)
8053698d704SMarcel Holtmann {
8063698d704SMarcel Holtmann 	return single_open(file, identity_resolving_keys_show,
8073698d704SMarcel Holtmann 			   inode->i_private);
8083698d704SMarcel Holtmann }
8093698d704SMarcel Holtmann 
8103698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = {
8113698d704SMarcel Holtmann 	.open		= identity_resolving_keys_open,
8123698d704SMarcel Holtmann 	.read		= seq_read,
8133698d704SMarcel Holtmann 	.llseek		= seq_lseek,
8143698d704SMarcel Holtmann 	.release	= single_release,
8153698d704SMarcel Holtmann };
8163698d704SMarcel Holtmann 
8178f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr)
8188f8625cdSMarcel Holtmann {
8198f8625cdSMarcel Holtmann 	struct hci_dev *hdev = f->private;
8208f8625cdSMarcel Holtmann 	struct list_head *p, *n;
8218f8625cdSMarcel Holtmann 
8228f8625cdSMarcel Holtmann 	hci_dev_lock(hdev);
823f813f1beSJohan Hedberg 	list_for_each_safe(p, n, &hdev->long_term_keys) {
8248f8625cdSMarcel Holtmann 		struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list);
825fe39c7b2SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n",
8268f8625cdSMarcel Holtmann 			   &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
8278f8625cdSMarcel Holtmann 			   ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
828fe39c7b2SMarcel Holtmann 			   __le64_to_cpu(ltk->rand), 16, ltk->val);
8298f8625cdSMarcel Holtmann 	}
8308f8625cdSMarcel Holtmann 	hci_dev_unlock(hdev);
8318f8625cdSMarcel Holtmann 
8328f8625cdSMarcel Holtmann 	return 0;
8338f8625cdSMarcel Holtmann }
8348f8625cdSMarcel Holtmann 
8358f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file)
8368f8625cdSMarcel Holtmann {
8378f8625cdSMarcel Holtmann 	return single_open(file, long_term_keys_show, inode->i_private);
8388f8625cdSMarcel Holtmann }
8398f8625cdSMarcel Holtmann 
8408f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = {
8418f8625cdSMarcel Holtmann 	.open		= long_term_keys_open,
8428f8625cdSMarcel Holtmann 	.read		= seq_read,
8438f8625cdSMarcel Holtmann 	.llseek		= seq_lseek,
8448f8625cdSMarcel Holtmann 	.release	= single_release,
8458f8625cdSMarcel Holtmann };
8468f8625cdSMarcel Holtmann 
8474e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val)
8484e70c7e7SMarcel Holtmann {
8494e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8504e70c7e7SMarcel Holtmann 
8514e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
8524e70c7e7SMarcel Holtmann 		return -EINVAL;
8534e70c7e7SMarcel Holtmann 
8544e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8554e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = val;
8564e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8574e70c7e7SMarcel Holtmann 
8584e70c7e7SMarcel Holtmann 	return 0;
8594e70c7e7SMarcel Holtmann }
8604e70c7e7SMarcel Holtmann 
8614e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val)
8624e70c7e7SMarcel Holtmann {
8634e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8644e70c7e7SMarcel Holtmann 
8654e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8664e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_min_interval;
8674e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8684e70c7e7SMarcel Holtmann 
8694e70c7e7SMarcel Holtmann 	return 0;
8704e70c7e7SMarcel Holtmann }
8714e70c7e7SMarcel Holtmann 
8724e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
8734e70c7e7SMarcel Holtmann 			conn_min_interval_set, "%llu\n");
8744e70c7e7SMarcel Holtmann 
8754e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val)
8764e70c7e7SMarcel Holtmann {
8774e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8784e70c7e7SMarcel Holtmann 
8794e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
8804e70c7e7SMarcel Holtmann 		return -EINVAL;
8814e70c7e7SMarcel Holtmann 
8824e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8834e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = val;
8844e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8854e70c7e7SMarcel Holtmann 
8864e70c7e7SMarcel Holtmann 	return 0;
8874e70c7e7SMarcel Holtmann }
8884e70c7e7SMarcel Holtmann 
8894e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val)
8904e70c7e7SMarcel Holtmann {
8914e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8924e70c7e7SMarcel Holtmann 
8934e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8944e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_max_interval;
8954e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8964e70c7e7SMarcel Holtmann 
8974e70c7e7SMarcel Holtmann 	return 0;
8984e70c7e7SMarcel Holtmann }
8994e70c7e7SMarcel Holtmann 
9004e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
9014e70c7e7SMarcel Holtmann 			conn_max_interval_set, "%llu\n");
9024e70c7e7SMarcel Holtmann 
9033f959d46SMarcel Holtmann static int adv_channel_map_set(void *data, u64 val)
9043f959d46SMarcel Holtmann {
9053f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
9063f959d46SMarcel Holtmann 
9073f959d46SMarcel Holtmann 	if (val < 0x01 || val > 0x07)
9083f959d46SMarcel Holtmann 		return -EINVAL;
9093f959d46SMarcel Holtmann 
9103f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
9113f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = val;
9123f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
9133f959d46SMarcel Holtmann 
9143f959d46SMarcel Holtmann 	return 0;
9153f959d46SMarcel Holtmann }
9163f959d46SMarcel Holtmann 
9173f959d46SMarcel Holtmann static int adv_channel_map_get(void *data, u64 *val)
9183f959d46SMarcel Holtmann {
9193f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
9203f959d46SMarcel Holtmann 
9213f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
9223f959d46SMarcel Holtmann 	*val = hdev->le_adv_channel_map;
9233f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
9243f959d46SMarcel Holtmann 
9253f959d46SMarcel Holtmann 	return 0;
9263f959d46SMarcel Holtmann }
9273f959d46SMarcel Holtmann 
9283f959d46SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
9293f959d46SMarcel Holtmann 			adv_channel_map_set, "%llu\n");
9303f959d46SMarcel Holtmann 
93189863109SJukka Rissanen static ssize_t lowpan_read(struct file *file, char __user *user_buf,
93289863109SJukka Rissanen 			   size_t count, loff_t *ppos)
93389863109SJukka Rissanen {
93489863109SJukka Rissanen 	struct hci_dev *hdev = file->private_data;
93589863109SJukka Rissanen 	char buf[3];
93689863109SJukka Rissanen 
93789863109SJukka Rissanen 	buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N';
93889863109SJukka Rissanen 	buf[1] = '\n';
93989863109SJukka Rissanen 	buf[2] = '\0';
94089863109SJukka Rissanen 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
94189863109SJukka Rissanen }
94289863109SJukka Rissanen 
94389863109SJukka Rissanen static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer,
94489863109SJukka Rissanen 			    size_t count, loff_t *position)
94589863109SJukka Rissanen {
94689863109SJukka Rissanen 	struct hci_dev *hdev = fp->private_data;
94789863109SJukka Rissanen 	bool enable;
94889863109SJukka Rissanen 	char buf[32];
94989863109SJukka Rissanen 	size_t buf_size = min(count, (sizeof(buf)-1));
95089863109SJukka Rissanen 
95189863109SJukka Rissanen 	if (copy_from_user(buf, user_buffer, buf_size))
95289863109SJukka Rissanen 		return -EFAULT;
95389863109SJukka Rissanen 
95489863109SJukka Rissanen 	buf[buf_size] = '\0';
95589863109SJukka Rissanen 
95689863109SJukka Rissanen 	if (strtobool(buf, &enable) < 0)
95789863109SJukka Rissanen 		return -EINVAL;
95889863109SJukka Rissanen 
95989863109SJukka Rissanen 	if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
96089863109SJukka Rissanen 		return -EALREADY;
96189863109SJukka Rissanen 
96289863109SJukka Rissanen 	change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags);
96389863109SJukka Rissanen 
96489863109SJukka Rissanen 	return count;
96589863109SJukka Rissanen }
96689863109SJukka Rissanen 
96789863109SJukka Rissanen static const struct file_operations lowpan_debugfs_fops = {
96889863109SJukka Rissanen 	.open		= simple_open,
96989863109SJukka Rissanen 	.read		= lowpan_read,
97089863109SJukka Rissanen 	.write		= lowpan_write,
97189863109SJukka Rissanen 	.llseek		= default_llseek,
97289863109SJukka Rissanen };
97389863109SJukka Rissanen 
9747d474e06SAndre Guedes static int le_auto_conn_show(struct seq_file *sf, void *ptr)
9757d474e06SAndre Guedes {
9767d474e06SAndre Guedes 	struct hci_dev *hdev = sf->private;
9777d474e06SAndre Guedes 	struct hci_conn_params *p;
9787d474e06SAndre Guedes 
9797d474e06SAndre Guedes 	hci_dev_lock(hdev);
9807d474e06SAndre Guedes 
9817d474e06SAndre Guedes 	list_for_each_entry(p, &hdev->le_conn_params, list) {
9827d474e06SAndre Guedes 		seq_printf(sf, "%pMR %u %u\n", &p->addr, p->addr_type,
9837d474e06SAndre Guedes 			   p->auto_connect);
9847d474e06SAndre Guedes 	}
9857d474e06SAndre Guedes 
9867d474e06SAndre Guedes 	hci_dev_unlock(hdev);
9877d474e06SAndre Guedes 
9887d474e06SAndre Guedes 	return 0;
9897d474e06SAndre Guedes }
9907d474e06SAndre Guedes 
9917d474e06SAndre Guedes static int le_auto_conn_open(struct inode *inode, struct file *file)
9927d474e06SAndre Guedes {
9937d474e06SAndre Guedes 	return single_open(file, le_auto_conn_show, inode->i_private);
9947d474e06SAndre Guedes }
9957d474e06SAndre Guedes 
9967d474e06SAndre Guedes static ssize_t le_auto_conn_write(struct file *file, const char __user *data,
9977d474e06SAndre Guedes 				  size_t count, loff_t *offset)
9987d474e06SAndre Guedes {
9997d474e06SAndre Guedes 	struct seq_file *sf = file->private_data;
10007d474e06SAndre Guedes 	struct hci_dev *hdev = sf->private;
10017d474e06SAndre Guedes 	u8 auto_connect = 0;
10027d474e06SAndre Guedes 	bdaddr_t addr;
10037d474e06SAndre Guedes 	u8 addr_type;
10047d474e06SAndre Guedes 	char *buf;
10057d474e06SAndre Guedes 	int err = 0;
10067d474e06SAndre Guedes 	int n;
10077d474e06SAndre Guedes 
10087d474e06SAndre Guedes 	/* Don't allow partial write */
10097d474e06SAndre Guedes 	if (*offset != 0)
10107d474e06SAndre Guedes 		return -EINVAL;
10117d474e06SAndre Guedes 
10127d474e06SAndre Guedes 	if (count < 3)
10137d474e06SAndre Guedes 		return -EINVAL;
10147d474e06SAndre Guedes 
10154408dd15SAndre Guedes 	buf = memdup_user(data, count);
10164408dd15SAndre Guedes 	if (IS_ERR(buf))
10174408dd15SAndre Guedes 		return PTR_ERR(buf);
10187d474e06SAndre Guedes 
10197d474e06SAndre Guedes 	if (memcmp(buf, "add", 3) == 0) {
10207d474e06SAndre Guedes 		n = sscanf(&buf[4], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu %hhu",
10217d474e06SAndre Guedes 			   &addr.b[5], &addr.b[4], &addr.b[3], &addr.b[2],
10227d474e06SAndre Guedes 			   &addr.b[1], &addr.b[0], &addr_type,
10237d474e06SAndre Guedes 			   &auto_connect);
10247d474e06SAndre Guedes 
10257d474e06SAndre Guedes 		if (n < 7) {
10267d474e06SAndre Guedes 			err = -EINVAL;
10277d474e06SAndre Guedes 			goto done;
10287d474e06SAndre Guedes 		}
10297d474e06SAndre Guedes 
10307d474e06SAndre Guedes 		hci_dev_lock(hdev);
10317d474e06SAndre Guedes 		err = hci_conn_params_add(hdev, &addr, addr_type, auto_connect,
10327d474e06SAndre Guedes 					  hdev->le_conn_min_interval,
10337d474e06SAndre Guedes 					  hdev->le_conn_max_interval);
10347d474e06SAndre Guedes 		hci_dev_unlock(hdev);
10357d474e06SAndre Guedes 
10367d474e06SAndre Guedes 		if (err)
10377d474e06SAndre Guedes 			goto done;
10387d474e06SAndre Guedes 	} else if (memcmp(buf, "del", 3) == 0) {
10397d474e06SAndre Guedes 		n = sscanf(&buf[4], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
10407d474e06SAndre Guedes 			   &addr.b[5], &addr.b[4], &addr.b[3], &addr.b[2],
10417d474e06SAndre Guedes 			   &addr.b[1], &addr.b[0], &addr_type);
10427d474e06SAndre Guedes 
10437d474e06SAndre Guedes 		if (n < 7) {
10447d474e06SAndre Guedes 			err = -EINVAL;
10457d474e06SAndre Guedes 			goto done;
10467d474e06SAndre Guedes 		}
10477d474e06SAndre Guedes 
10487d474e06SAndre Guedes 		hci_dev_lock(hdev);
10497d474e06SAndre Guedes 		hci_conn_params_del(hdev, &addr, addr_type);
10507d474e06SAndre Guedes 		hci_dev_unlock(hdev);
10517d474e06SAndre Guedes 	} else if (memcmp(buf, "clr", 3) == 0) {
10527d474e06SAndre Guedes 		hci_dev_lock(hdev);
10537d474e06SAndre Guedes 		hci_conn_params_clear(hdev);
10547d474e06SAndre Guedes 		hci_pend_le_conns_clear(hdev);
10557d474e06SAndre Guedes 		hci_update_background_scan(hdev);
10567d474e06SAndre Guedes 		hci_dev_unlock(hdev);
10577d474e06SAndre Guedes 	} else {
10587d474e06SAndre Guedes 		err = -EINVAL;
10597d474e06SAndre Guedes 	}
10607d474e06SAndre Guedes 
10617d474e06SAndre Guedes done:
10627d474e06SAndre Guedes 	kfree(buf);
10637d474e06SAndre Guedes 
10647d474e06SAndre Guedes 	if (err)
10657d474e06SAndre Guedes 		return err;
10667d474e06SAndre Guedes 	else
10677d474e06SAndre Guedes 		return count;
10687d474e06SAndre Guedes }
10697d474e06SAndre Guedes 
10707d474e06SAndre Guedes static const struct file_operations le_auto_conn_fops = {
10717d474e06SAndre Guedes 	.open		= le_auto_conn_open,
10727d474e06SAndre Guedes 	.read		= seq_read,
10737d474e06SAndre Guedes 	.write		= le_auto_conn_write,
10747d474e06SAndre Guedes 	.llseek		= seq_lseek,
10757d474e06SAndre Guedes 	.release	= single_release,
10767d474e06SAndre Guedes };
10777d474e06SAndre Guedes 
10781da177e4SLinus Torvalds /* ---- HCI requests ---- */
10791da177e4SLinus Torvalds 
108042c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
10811da177e4SLinus Torvalds {
108242c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
108375fb0e32SJohan Hedberg 
10841da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
10851da177e4SLinus Torvalds 		hdev->req_result = result;
10861da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
10871da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
10881da177e4SLinus Torvalds 	}
10891da177e4SLinus Torvalds }
10901da177e4SLinus Torvalds 
10911da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
10921da177e4SLinus Torvalds {
10931da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
10941da177e4SLinus Torvalds 
10951da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
10961da177e4SLinus Torvalds 		hdev->req_result = err;
10971da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
10981da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
10991da177e4SLinus Torvalds 	}
11001da177e4SLinus Torvalds }
11011da177e4SLinus Torvalds 
110277a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
110377a63e0aSFengguang Wu 					    u8 event)
110475e84b7cSJohan Hedberg {
110575e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
110675e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
110775e84b7cSJohan Hedberg 	struct sk_buff *skb;
110875e84b7cSJohan Hedberg 
110975e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
111075e84b7cSJohan Hedberg 
111175e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
111275e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
111375e84b7cSJohan Hedberg 
111475e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
111575e84b7cSJohan Hedberg 
111675e84b7cSJohan Hedberg 	if (!skb)
111775e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
111875e84b7cSJohan Hedberg 
111975e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
112075e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
112175e84b7cSJohan Hedberg 		goto failed;
112275e84b7cSJohan Hedberg 	}
112375e84b7cSJohan Hedberg 
112475e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
112575e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
112675e84b7cSJohan Hedberg 
11277b1abbbeSJohan Hedberg 	if (event) {
11287b1abbbeSJohan Hedberg 		if (hdr->evt != event)
11297b1abbbeSJohan Hedberg 			goto failed;
11307b1abbbeSJohan Hedberg 		return skb;
11317b1abbbeSJohan Hedberg 	}
11327b1abbbeSJohan Hedberg 
113375e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
113475e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
113575e84b7cSJohan Hedberg 		goto failed;
113675e84b7cSJohan Hedberg 	}
113775e84b7cSJohan Hedberg 
113875e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
113975e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
114075e84b7cSJohan Hedberg 		goto failed;
114175e84b7cSJohan Hedberg 	}
114275e84b7cSJohan Hedberg 
114375e84b7cSJohan Hedberg 	ev = (void *) skb->data;
114475e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
114575e84b7cSJohan Hedberg 
114675e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
114775e84b7cSJohan Hedberg 		return skb;
114875e84b7cSJohan Hedberg 
114975e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
115075e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
115175e84b7cSJohan Hedberg 
115275e84b7cSJohan Hedberg failed:
115375e84b7cSJohan Hedberg 	kfree_skb(skb);
115475e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
115575e84b7cSJohan Hedberg }
115675e84b7cSJohan Hedberg 
11577b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
115807dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
115975e84b7cSJohan Hedberg {
116075e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
116175e84b7cSJohan Hedberg 	struct hci_request req;
116275e84b7cSJohan Hedberg 	int err = 0;
116375e84b7cSJohan Hedberg 
116475e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
116575e84b7cSJohan Hedberg 
116675e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
116775e84b7cSJohan Hedberg 
11687b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
116975e84b7cSJohan Hedberg 
117075e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
117175e84b7cSJohan Hedberg 
117275e84b7cSJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
117375e84b7cSJohan Hedberg 	if (err < 0)
117475e84b7cSJohan Hedberg 		return ERR_PTR(err);
117575e84b7cSJohan Hedberg 
117675e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
117775e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
117875e84b7cSJohan Hedberg 
117975e84b7cSJohan Hedberg 	schedule_timeout(timeout);
118075e84b7cSJohan Hedberg 
118175e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
118275e84b7cSJohan Hedberg 
118375e84b7cSJohan Hedberg 	if (signal_pending(current))
118475e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
118575e84b7cSJohan Hedberg 
118675e84b7cSJohan Hedberg 	switch (hdev->req_status) {
118775e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
118875e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
118975e84b7cSJohan Hedberg 		break;
119075e84b7cSJohan Hedberg 
119175e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
119275e84b7cSJohan Hedberg 		err = -hdev->req_result;
119375e84b7cSJohan Hedberg 		break;
119475e84b7cSJohan Hedberg 
119575e84b7cSJohan Hedberg 	default:
119675e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
119775e84b7cSJohan Hedberg 		break;
119875e84b7cSJohan Hedberg 	}
119975e84b7cSJohan Hedberg 
120075e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
120175e84b7cSJohan Hedberg 
120275e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
120375e84b7cSJohan Hedberg 
120475e84b7cSJohan Hedberg 	if (err < 0)
120575e84b7cSJohan Hedberg 		return ERR_PTR(err);
120675e84b7cSJohan Hedberg 
12077b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
12087b1abbbeSJohan Hedberg }
12097b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
12107b1abbbeSJohan Hedberg 
12117b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
121207dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
12137b1abbbeSJohan Hedberg {
12147b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
121575e84b7cSJohan Hedberg }
121675e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
121775e84b7cSJohan Hedberg 
12181da177e4SLinus Torvalds /* Execute request and wait for completion. */
121901178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
122042c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
122142c6b129SJohan Hedberg 				      unsigned long opt),
12221da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
12231da177e4SLinus Torvalds {
122442c6b129SJohan Hedberg 	struct hci_request req;
12251da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
12261da177e4SLinus Torvalds 	int err = 0;
12271da177e4SLinus Torvalds 
12281da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
12291da177e4SLinus Torvalds 
123042c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
123142c6b129SJohan Hedberg 
12321da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
12331da177e4SLinus Torvalds 
123442c6b129SJohan Hedberg 	func(&req, opt);
123553cce22dSJohan Hedberg 
123642c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
123742c6b129SJohan Hedberg 	if (err < 0) {
123853cce22dSJohan Hedberg 		hdev->req_status = 0;
1239920c8300SAndre Guedes 
1240920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
1241920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
1242920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
1243920c8300SAndre Guedes 		 * and should not trigger an error return.
124442c6b129SJohan Hedberg 		 */
1245920c8300SAndre Guedes 		if (err == -ENODATA)
124642c6b129SJohan Hedberg 			return 0;
1247920c8300SAndre Guedes 
1248920c8300SAndre Guedes 		return err;
124953cce22dSJohan Hedberg 	}
125053cce22dSJohan Hedberg 
1251bc4445c7SAndre Guedes 	add_wait_queue(&hdev->req_wait_q, &wait);
1252bc4445c7SAndre Guedes 	set_current_state(TASK_INTERRUPTIBLE);
1253bc4445c7SAndre Guedes 
12541da177e4SLinus Torvalds 	schedule_timeout(timeout);
12551da177e4SLinus Torvalds 
12561da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
12571da177e4SLinus Torvalds 
12581da177e4SLinus Torvalds 	if (signal_pending(current))
12591da177e4SLinus Torvalds 		return -EINTR;
12601da177e4SLinus Torvalds 
12611da177e4SLinus Torvalds 	switch (hdev->req_status) {
12621da177e4SLinus Torvalds 	case HCI_REQ_DONE:
1263e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
12641da177e4SLinus Torvalds 		break;
12651da177e4SLinus Torvalds 
12661da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
12671da177e4SLinus Torvalds 		err = -hdev->req_result;
12681da177e4SLinus Torvalds 		break;
12691da177e4SLinus Torvalds 
12701da177e4SLinus Torvalds 	default:
12711da177e4SLinus Torvalds 		err = -ETIMEDOUT;
12721da177e4SLinus Torvalds 		break;
12733ff50b79SStephen Hemminger 	}
12741da177e4SLinus Torvalds 
1275a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
12761da177e4SLinus Torvalds 
12771da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
12781da177e4SLinus Torvalds 
12791da177e4SLinus Torvalds 	return err;
12801da177e4SLinus Torvalds }
12811da177e4SLinus Torvalds 
128201178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
128342c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
128442c6b129SJohan Hedberg 				    unsigned long opt),
12851da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
12861da177e4SLinus Torvalds {
12871da177e4SLinus Torvalds 	int ret;
12881da177e4SLinus Torvalds 
12897c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
12907c6a329eSMarcel Holtmann 		return -ENETDOWN;
12917c6a329eSMarcel Holtmann 
12921da177e4SLinus Torvalds 	/* Serialize all requests */
12931da177e4SLinus Torvalds 	hci_req_lock(hdev);
129401178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
12951da177e4SLinus Torvalds 	hci_req_unlock(hdev);
12961da177e4SLinus Torvalds 
12971da177e4SLinus Torvalds 	return ret;
12981da177e4SLinus Torvalds }
12991da177e4SLinus Torvalds 
130042c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
13011da177e4SLinus Torvalds {
130242c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
13031da177e4SLinus Torvalds 
13041da177e4SLinus Torvalds 	/* Reset device */
130542c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
130642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
13071da177e4SLinus Torvalds }
13081da177e4SLinus Torvalds 
130942c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
13101da177e4SLinus Torvalds {
131142c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
13122455a3eaSAndrei Emeltchenko 
13131da177e4SLinus Torvalds 	/* Read Local Supported Features */
131442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
13151da177e4SLinus Torvalds 
13161143e5a6SMarcel Holtmann 	/* Read Local Version */
131742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
13182177bab5SJohan Hedberg 
13192177bab5SJohan Hedberg 	/* Read BD Address */
132042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
13211da177e4SLinus Torvalds }
13221da177e4SLinus Torvalds 
132342c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
1324e61ef499SAndrei Emeltchenko {
132542c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
13262455a3eaSAndrei Emeltchenko 
1327e61ef499SAndrei Emeltchenko 	/* Read Local Version */
132842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
13296bcbc489SAndrei Emeltchenko 
1330f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
1331f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
1332f6996cfeSMarcel Holtmann 
1333f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
1334f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1335f6996cfeSMarcel Holtmann 
13366bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
133742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
1338e71dfabaSAndrei Emeltchenko 
1339e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
134042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
13417528ca1cSMarcel Holtmann 
1342f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
1343f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
1344f38ba941SMarcel Holtmann 
13457528ca1cSMarcel Holtmann 	/* Read Location Data */
13467528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
1347e61ef499SAndrei Emeltchenko }
1348e61ef499SAndrei Emeltchenko 
134942c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
1350e61ef499SAndrei Emeltchenko {
135142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1352e61ef499SAndrei Emeltchenko 
1353e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
1354e61ef499SAndrei Emeltchenko 
135511778716SAndrei Emeltchenko 	/* Reset */
135611778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
135742c6b129SJohan Hedberg 		hci_reset_req(req, 0);
135811778716SAndrei Emeltchenko 
1359e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
1360e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
136142c6b129SJohan Hedberg 		bredr_init(req);
1362e61ef499SAndrei Emeltchenko 		break;
1363e61ef499SAndrei Emeltchenko 
1364e61ef499SAndrei Emeltchenko 	case HCI_AMP:
136542c6b129SJohan Hedberg 		amp_init(req);
1366e61ef499SAndrei Emeltchenko 		break;
1367e61ef499SAndrei Emeltchenko 
1368e61ef499SAndrei Emeltchenko 	default:
1369e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
1370e61ef499SAndrei Emeltchenko 		break;
1371e61ef499SAndrei Emeltchenko 	}
1372e61ef499SAndrei Emeltchenko }
1373e61ef499SAndrei Emeltchenko 
137442c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
13752177bab5SJohan Hedberg {
13764ca048e3SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
13774ca048e3SMarcel Holtmann 
13782177bab5SJohan Hedberg 	__le16 param;
13792177bab5SJohan Hedberg 	__u8 flt_type;
13802177bab5SJohan Hedberg 
13812177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
138242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
13832177bab5SJohan Hedberg 
13842177bab5SJohan Hedberg 	/* Read Class of Device */
138542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
13862177bab5SJohan Hedberg 
13872177bab5SJohan Hedberg 	/* Read Local Name */
138842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
13892177bab5SJohan Hedberg 
13902177bab5SJohan Hedberg 	/* Read Voice Setting */
139142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
13922177bab5SJohan Hedberg 
1393b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
1394b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
1395b4cb9fb2SMarcel Holtmann 
13964b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
13974b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
13984b836f39SMarcel Holtmann 
13992177bab5SJohan Hedberg 	/* Clear Event Filters */
14002177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
140142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
14022177bab5SJohan Hedberg 
14032177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
1404dcf4adbfSJoe Perches 	param = cpu_to_le16(0x7d00);
140542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
14062177bab5SJohan Hedberg 
14074ca048e3SMarcel Holtmann 	/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
14084ca048e3SMarcel Holtmann 	 * but it does not support page scan related HCI commands.
14094ca048e3SMarcel Holtmann 	 */
14104ca048e3SMarcel Holtmann 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
1411f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
1412f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
1413f332ec66SJohan Hedberg 	}
14142177bab5SJohan Hedberg }
14152177bab5SJohan Hedberg 
141642c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
14172177bab5SJohan Hedberg {
1418c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1419c73eee91SJohan Hedberg 
14202177bab5SJohan Hedberg 	/* Read LE Buffer Size */
142142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
14222177bab5SJohan Hedberg 
14232177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
142442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
14252177bab5SJohan Hedberg 
1426747d3f03SMarcel Holtmann 	/* Read LE Supported States */
1427747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
1428747d3f03SMarcel Holtmann 
14292177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
143042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
14312177bab5SJohan Hedberg 
14322177bab5SJohan Hedberg 	/* Read LE White List Size */
143342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
14342177bab5SJohan Hedberg 
1435747d3f03SMarcel Holtmann 	/* Clear LE White List */
1436747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
1437c73eee91SJohan Hedberg 
1438c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
1439c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1440c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
14412177bab5SJohan Hedberg }
14422177bab5SJohan Hedberg 
14432177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
14442177bab5SJohan Hedberg {
14452177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
14462177bab5SJohan Hedberg 		return 0x02;
14472177bab5SJohan Hedberg 
14482177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
14492177bab5SJohan Hedberg 		return 0x01;
14502177bab5SJohan Hedberg 
14512177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
14522177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
14532177bab5SJohan Hedberg 		return 0x01;
14542177bab5SJohan Hedberg 
14552177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
14562177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
14572177bab5SJohan Hedberg 			return 0x01;
14582177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
14592177bab5SJohan Hedberg 			return 0x01;
14602177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
14612177bab5SJohan Hedberg 			return 0x01;
14622177bab5SJohan Hedberg 	}
14632177bab5SJohan Hedberg 
14642177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
14652177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
14662177bab5SJohan Hedberg 		return 0x01;
14672177bab5SJohan Hedberg 
14682177bab5SJohan Hedberg 	return 0x00;
14692177bab5SJohan Hedberg }
14702177bab5SJohan Hedberg 
147142c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
14722177bab5SJohan Hedberg {
14732177bab5SJohan Hedberg 	u8 mode;
14742177bab5SJohan Hedberg 
147542c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
14762177bab5SJohan Hedberg 
147742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
14782177bab5SJohan Hedberg }
14792177bab5SJohan Hedberg 
148042c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
14812177bab5SJohan Hedberg {
148242c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
148342c6b129SJohan Hedberg 
14842177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
14852177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
14862177bab5SJohan Hedberg 	 * command otherwise.
14872177bab5SJohan Hedberg 	 */
14882177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
14892177bab5SJohan Hedberg 
14902177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
14912177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
14922177bab5SJohan Hedberg 	 */
14932177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
14942177bab5SJohan Hedberg 		return;
14952177bab5SJohan Hedberg 
14962177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
14972177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
14982177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
14992177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
15002177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
15012177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
1502c7882cbdSMarcel Holtmann 	} else {
1503c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
1504c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
1505c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
1506c7882cbdSMarcel Holtmann 		events[0] |= 0x80; /* Encryption Change */
1507c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
1508c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
1509c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
1510c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
1511c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
1512c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
1513c7882cbdSMarcel Holtmann 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
15142177bab5SJohan Hedberg 	}
15152177bab5SJohan Hedberg 
15162177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
15172177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
15182177bab5SJohan Hedberg 
15192177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
15202177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
15212177bab5SJohan Hedberg 
15222177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
15232177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
15242177bab5SJohan Hedberg 
15252177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
15262177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
15272177bab5SJohan Hedberg 
15282177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
15292177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
15302177bab5SJohan Hedberg 
15312177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
15322177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
15332177bab5SJohan Hedberg 
15342177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
15352177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
15362177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
15372177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
15382177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
15392177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
15402177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
15412177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
15422177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
15432177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
15442177bab5SJohan Hedberg 					 * Features Notification
15452177bab5SJohan Hedberg 					 */
15462177bab5SJohan Hedberg 	}
15472177bab5SJohan Hedberg 
15482177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
15492177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
15502177bab5SJohan Hedberg 
155142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
15522177bab5SJohan Hedberg 
15532177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
15542177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
15552177bab5SJohan Hedberg 		events[0] = 0x1f;
155642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
15572177bab5SJohan Hedberg 			    sizeof(events), events);
15582177bab5SJohan Hedberg 	}
15592177bab5SJohan Hedberg }
15602177bab5SJohan Hedberg 
156142c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
15622177bab5SJohan Hedberg {
156342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
156442c6b129SJohan Hedberg 
15652177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
156642c6b129SJohan Hedberg 		bredr_setup(req);
156756f87901SJohan Hedberg 	else
156856f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
15692177bab5SJohan Hedberg 
15702177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
157142c6b129SJohan Hedberg 		le_setup(req);
15722177bab5SJohan Hedberg 
157342c6b129SJohan Hedberg 	hci_setup_event_mask(req);
15742177bab5SJohan Hedberg 
15753f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
15763f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
15773f8e2d75SJohan Hedberg 	 */
15783f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
157942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
15802177bab5SJohan Hedberg 
15812177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
158257af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
158357af75a8SMarcel Holtmann 		 * should also be available as well. However some
158457af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
158557af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
158657af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
158757af75a8SMarcel Holtmann 		 */
158857af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
158957af75a8SMarcel Holtmann 
15902177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
15912177bab5SJohan Hedberg 			u8 mode = 0x01;
159242c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
15932177bab5SJohan Hedberg 				    sizeof(mode), &mode);
15942177bab5SJohan Hedberg 		} else {
15952177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
15962177bab5SJohan Hedberg 
15972177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
15982177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
15992177bab5SJohan Hedberg 
160042c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
16012177bab5SJohan Hedberg 		}
16022177bab5SJohan Hedberg 	}
16032177bab5SJohan Hedberg 
16042177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
160542c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
16062177bab5SJohan Hedberg 
16072177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
160842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
16092177bab5SJohan Hedberg 
16102177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
16112177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
16122177bab5SJohan Hedberg 
16132177bab5SJohan Hedberg 		cp.page = 0x01;
161442c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
161542c6b129SJohan Hedberg 			    sizeof(cp), &cp);
16162177bab5SJohan Hedberg 	}
16172177bab5SJohan Hedberg 
16182177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
16192177bab5SJohan Hedberg 		u8 enable = 1;
162042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
16212177bab5SJohan Hedberg 			    &enable);
16222177bab5SJohan Hedberg 	}
16232177bab5SJohan Hedberg }
16242177bab5SJohan Hedberg 
162542c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
16262177bab5SJohan Hedberg {
162742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
16282177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
16292177bab5SJohan Hedberg 	u16 link_policy = 0;
16302177bab5SJohan Hedberg 
16312177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
16322177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
16332177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
16342177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
16352177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
16362177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
16372177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
16382177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
16392177bab5SJohan Hedberg 
16402177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
164142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
16422177bab5SJohan Hedberg }
16432177bab5SJohan Hedberg 
164442c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
16452177bab5SJohan Hedberg {
164642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
16472177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
16482177bab5SJohan Hedberg 
1649c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
1650c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1651c73eee91SJohan Hedberg 		return;
1652c73eee91SJohan Hedberg 
16532177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
16542177bab5SJohan Hedberg 
16552177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
16562177bab5SJohan Hedberg 		cp.le = 0x01;
16572177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
16582177bab5SJohan Hedberg 	}
16592177bab5SJohan Hedberg 
16602177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
166142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
16622177bab5SJohan Hedberg 			    &cp);
16632177bab5SJohan Hedberg }
16642177bab5SJohan Hedberg 
1665d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
1666d62e6d67SJohan Hedberg {
1667d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1668d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1669d62e6d67SJohan Hedberg 
1670d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
1671d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1672d62e6d67SJohan Hedberg 	 */
167353b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
1674d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
1675d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
1676d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
1677d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
1678d62e6d67SJohan Hedberg 	}
1679d62e6d67SJohan Hedberg 
1680d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
1681d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1682d62e6d67SJohan Hedberg 	 */
168353b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
1684d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
1685d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
1686d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
1687d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
1688d62e6d67SJohan Hedberg 	}
1689d62e6d67SJohan Hedberg 
169040c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
169140c59fcbSMarcel Holtmann 	if (lmp_ping_capable(hdev))
169240c59fcbSMarcel Holtmann 		events[2] |= 0x80;
169340c59fcbSMarcel Holtmann 
1694d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
1695d62e6d67SJohan Hedberg }
1696d62e6d67SJohan Hedberg 
169742c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
16982177bab5SJohan Hedberg {
169942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1700d2c5d77fSJohan Hedberg 	u8 p;
170142c6b129SJohan Hedberg 
1702b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
1703b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
1704b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
1705b8f4e068SGustavo Padovan 	 *
1706b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
1707b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
1708b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
1709b8f4e068SGustavo Padovan 	 * command redundant anyway.
1710f9f462faSMarcel Holtmann 	 *
1711f9f462faSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
1712f9f462faSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
1713f9f462faSMarcel Holtmann 	 * just disable this command.
1714b8f4e068SGustavo Padovan 	 */
1715f9f462faSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
1716f9f462faSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
171759f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
171859f45d57SJohan Hedberg 
171959f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
172059f45d57SJohan Hedberg 		cp.delete_all = 0x01;
172159f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
172259f45d57SJohan Hedberg 			    sizeof(cp), &cp);
172359f45d57SJohan Hedberg 	}
172459f45d57SJohan Hedberg 
17252177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
172642c6b129SJohan Hedberg 		hci_setup_link_policy(req);
17272177bab5SJohan Hedberg 
17287bf32048SJohan Hedberg 	if (lmp_le_capable(hdev))
172942c6b129SJohan Hedberg 		hci_set_le_support(req);
1730d2c5d77fSJohan Hedberg 
1731d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
1732d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
1733d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
1734d2c5d77fSJohan Hedberg 
1735d2c5d77fSJohan Hedberg 		cp.page = p;
1736d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
1737d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
1738d2c5d77fSJohan Hedberg 	}
17392177bab5SJohan Hedberg }
17402177bab5SJohan Hedberg 
17415d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
17425d4e7e8dSJohan Hedberg {
17435d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
17445d4e7e8dSJohan Hedberg 
1745d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
1746d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
1747d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
1748d62e6d67SJohan Hedberg 
17495d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
175053b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
17515d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
1752a6d0d690SMarcel Holtmann 
1753a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
17545afeac14SMarcel Holtmann 	if ((lmp_sc_capable(hdev) ||
1755111902f7SMarcel Holtmann 	     test_bit(HCI_FORCE_SC, &hdev->dbg_flags)) &&
1756a6d0d690SMarcel Holtmann 	    test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
1757a6d0d690SMarcel Holtmann 		u8 support = 0x01;
1758a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
1759a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
1760a6d0d690SMarcel Holtmann 	}
17615d4e7e8dSJohan Hedberg }
17625d4e7e8dSJohan Hedberg 
17632177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
17642177bab5SJohan Hedberg {
17652177bab5SJohan Hedberg 	int err;
17662177bab5SJohan Hedberg 
17672177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
17682177bab5SJohan Hedberg 	if (err < 0)
17692177bab5SJohan Hedberg 		return err;
17702177bab5SJohan Hedberg 
17714b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
17724b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
17734b4148e9SMarcel Holtmann 	 */
17744b4148e9SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
17754b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
17764b4148e9SMarcel Holtmann 				    &dut_mode_fops);
17774b4148e9SMarcel Holtmann 	}
17784b4148e9SMarcel Holtmann 
17792177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
17802177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
17812177bab5SJohan Hedberg 	 * first stage init.
17822177bab5SJohan Hedberg 	 */
17832177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
17842177bab5SJohan Hedberg 		return 0;
17852177bab5SJohan Hedberg 
17862177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
17872177bab5SJohan Hedberg 	if (err < 0)
17882177bab5SJohan Hedberg 		return err;
17892177bab5SJohan Hedberg 
17905d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
17915d4e7e8dSJohan Hedberg 	if (err < 0)
17925d4e7e8dSJohan Hedberg 		return err;
17935d4e7e8dSJohan Hedberg 
1794baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
1795baf27f6eSMarcel Holtmann 	if (err < 0)
1796baf27f6eSMarcel Holtmann 		return err;
1797baf27f6eSMarcel Holtmann 
1798baf27f6eSMarcel Holtmann 	/* Only create debugfs entries during the initial setup
1799baf27f6eSMarcel Holtmann 	 * phase and not every time the controller gets powered on.
1800baf27f6eSMarcel Holtmann 	 */
1801baf27f6eSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1802baf27f6eSMarcel Holtmann 		return 0;
1803baf27f6eSMarcel Holtmann 
1804dfb826a8SMarcel Holtmann 	debugfs_create_file("features", 0444, hdev->debugfs, hdev,
1805dfb826a8SMarcel Holtmann 			    &features_fops);
1806ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
1807ceeb3bc0SMarcel Holtmann 			   &hdev->manufacturer);
1808ceeb3bc0SMarcel Holtmann 	debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
1809ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
181070afe0b8SMarcel Holtmann 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
181170afe0b8SMarcel Holtmann 			    &blacklist_fops);
181247219839SMarcel Holtmann 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
181347219839SMarcel Holtmann 
181431ad1691SAndrzej Kaczmarek 	debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
181531ad1691SAndrzej Kaczmarek 			    &conn_info_min_age_fops);
181631ad1691SAndrzej Kaczmarek 	debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev,
181731ad1691SAndrzej Kaczmarek 			    &conn_info_max_age_fops);
181831ad1691SAndrzej Kaczmarek 
1819baf27f6eSMarcel Holtmann 	if (lmp_bredr_capable(hdev)) {
1820baf27f6eSMarcel Holtmann 		debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
1821baf27f6eSMarcel Holtmann 				    hdev, &inquiry_cache_fops);
182202d08d15SMarcel Holtmann 		debugfs_create_file("link_keys", 0400, hdev->debugfs,
182302d08d15SMarcel Holtmann 				    hdev, &link_keys_fops);
1824babdbb3cSMarcel Holtmann 		debugfs_create_file("dev_class", 0444, hdev->debugfs,
1825babdbb3cSMarcel Holtmann 				    hdev, &dev_class_fops);
1826041000b9SMarcel Holtmann 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
1827041000b9SMarcel Holtmann 				    hdev, &voice_setting_fops);
1828baf27f6eSMarcel Holtmann 	}
1829baf27f6eSMarcel Holtmann 
183006f5b778SMarcel Holtmann 	if (lmp_ssp_capable(hdev)) {
1831ebd1e33bSMarcel Holtmann 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
1832ebd1e33bSMarcel Holtmann 				    hdev, &auto_accept_delay_fops);
183306f5b778SMarcel Holtmann 		debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
183406f5b778SMarcel Holtmann 				    hdev, &ssp_debug_mode_fops);
18355afeac14SMarcel Holtmann 		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
18365afeac14SMarcel Holtmann 				    hdev, &force_sc_support_fops);
1837134c2a89SMarcel Holtmann 		debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
1838134c2a89SMarcel Holtmann 				    hdev, &sc_only_mode_fops);
183906f5b778SMarcel Holtmann 	}
1840ebd1e33bSMarcel Holtmann 
18412bfa3531SMarcel Holtmann 	if (lmp_sniff_capable(hdev)) {
18422bfa3531SMarcel Holtmann 		debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
18432bfa3531SMarcel Holtmann 				    hdev, &idle_timeout_fops);
18442bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
18452bfa3531SMarcel Holtmann 				    hdev, &sniff_min_interval_fops);
18462bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
18472bfa3531SMarcel Holtmann 				    hdev, &sniff_max_interval_fops);
18482bfa3531SMarcel Holtmann 	}
18492bfa3531SMarcel Holtmann 
1850d0f729b8SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1851ac345813SMarcel Holtmann 		debugfs_create_file("identity", 0400, hdev->debugfs,
1852ac345813SMarcel Holtmann 				    hdev, &identity_fops);
1853ac345813SMarcel Holtmann 		debugfs_create_file("rpa_timeout", 0644, hdev->debugfs,
1854ac345813SMarcel Holtmann 				    hdev, &rpa_timeout_fops);
18557a4cd51dSMarcel Holtmann 		debugfs_create_file("random_address", 0444, hdev->debugfs,
18567a4cd51dSMarcel Holtmann 				    hdev, &random_address_fops);
1857e7b8fc92SMarcel Holtmann 		debugfs_create_file("static_address", 0444, hdev->debugfs,
1858e7b8fc92SMarcel Holtmann 				    hdev, &static_address_fops);
1859b32bba6cSMarcel Holtmann 
1860b32bba6cSMarcel Holtmann 		/* For controllers with a public address, provide a debug
1861b32bba6cSMarcel Holtmann 		 * option to force the usage of the configured static
1862b32bba6cSMarcel Holtmann 		 * address. By default the public address is used.
1863b32bba6cSMarcel Holtmann 		 */
1864b32bba6cSMarcel Holtmann 		if (bacmp(&hdev->bdaddr, BDADDR_ANY))
1865b32bba6cSMarcel Holtmann 			debugfs_create_file("force_static_address", 0644,
1866b32bba6cSMarcel Holtmann 					    hdev->debugfs, hdev,
1867b32bba6cSMarcel Holtmann 					    &force_static_address_fops);
1868b32bba6cSMarcel Holtmann 
1869b32bba6cSMarcel Holtmann 		debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1870b32bba6cSMarcel Holtmann 				  &hdev->le_white_list_size);
1871d2ab0ac1SMarcel Holtmann 		debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
1872d2ab0ac1SMarcel Holtmann 				    &white_list_fops);
18733698d704SMarcel Holtmann 		debugfs_create_file("identity_resolving_keys", 0400,
18743698d704SMarcel Holtmann 				    hdev->debugfs, hdev,
18753698d704SMarcel Holtmann 				    &identity_resolving_keys_fops);
18768f8625cdSMarcel Holtmann 		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
18778f8625cdSMarcel Holtmann 				    hdev, &long_term_keys_fops);
18784e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
18794e70c7e7SMarcel Holtmann 				    hdev, &conn_min_interval_fops);
18804e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
18814e70c7e7SMarcel Holtmann 				    hdev, &conn_max_interval_fops);
18823f959d46SMarcel Holtmann 		debugfs_create_file("adv_channel_map", 0644, hdev->debugfs,
18833f959d46SMarcel Holtmann 				    hdev, &adv_channel_map_fops);
188489863109SJukka Rissanen 		debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
188589863109SJukka Rissanen 				    &lowpan_debugfs_fops);
18867d474e06SAndre Guedes 		debugfs_create_file("le_auto_conn", 0644, hdev->debugfs, hdev,
18877d474e06SAndre Guedes 				    &le_auto_conn_fops);
1888b9a7a61eSLukasz Rymanowski 		debugfs_create_u16("discov_interleaved_timeout", 0644,
1889b9a7a61eSLukasz Rymanowski 				   hdev->debugfs,
1890b9a7a61eSLukasz Rymanowski 				   &hdev->discov_interleaved_timeout);
1891d0f729b8SMarcel Holtmann 	}
1892e7b8fc92SMarcel Holtmann 
1893baf27f6eSMarcel Holtmann 	return 0;
18942177bab5SJohan Hedberg }
18952177bab5SJohan Hedberg 
189642c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
18971da177e4SLinus Torvalds {
18981da177e4SLinus Torvalds 	__u8 scan = opt;
18991da177e4SLinus Torvalds 
190042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
19011da177e4SLinus Torvalds 
19021da177e4SLinus Torvalds 	/* Inquiry and Page scans */
190342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
19041da177e4SLinus Torvalds }
19051da177e4SLinus Torvalds 
190642c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
19071da177e4SLinus Torvalds {
19081da177e4SLinus Torvalds 	__u8 auth = opt;
19091da177e4SLinus Torvalds 
191042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
19111da177e4SLinus Torvalds 
19121da177e4SLinus Torvalds 	/* Authentication */
191342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
19141da177e4SLinus Torvalds }
19151da177e4SLinus Torvalds 
191642c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
19171da177e4SLinus Torvalds {
19181da177e4SLinus Torvalds 	__u8 encrypt = opt;
19191da177e4SLinus Torvalds 
192042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
19211da177e4SLinus Torvalds 
1922e4e8e37cSMarcel Holtmann 	/* Encryption */
192342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
19241da177e4SLinus Torvalds }
19251da177e4SLinus Torvalds 
192642c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
1927e4e8e37cSMarcel Holtmann {
1928e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
1929e4e8e37cSMarcel Holtmann 
193042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
1931e4e8e37cSMarcel Holtmann 
1932e4e8e37cSMarcel Holtmann 	/* Default link policy */
193342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
1934e4e8e37cSMarcel Holtmann }
1935e4e8e37cSMarcel Holtmann 
19361da177e4SLinus Torvalds /* Get HCI device by index.
19371da177e4SLinus Torvalds  * Device is held on return. */
19381da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
19391da177e4SLinus Torvalds {
19408035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
19411da177e4SLinus Torvalds 
19421da177e4SLinus Torvalds 	BT_DBG("%d", index);
19431da177e4SLinus Torvalds 
19441da177e4SLinus Torvalds 	if (index < 0)
19451da177e4SLinus Torvalds 		return NULL;
19461da177e4SLinus Torvalds 
19471da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
19488035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
19491da177e4SLinus Torvalds 		if (d->id == index) {
19501da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
19511da177e4SLinus Torvalds 			break;
19521da177e4SLinus Torvalds 		}
19531da177e4SLinus Torvalds 	}
19541da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
19551da177e4SLinus Torvalds 	return hdev;
19561da177e4SLinus Torvalds }
19571da177e4SLinus Torvalds 
19581da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1959ff9ef578SJohan Hedberg 
196030dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
196130dc78e1SJohan Hedberg {
196230dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
196330dc78e1SJohan Hedberg 
19646fbe195dSAndre Guedes 	switch (discov->state) {
1965343f935bSAndre Guedes 	case DISCOVERY_FINDING:
19666fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
196730dc78e1SJohan Hedberg 		return true;
196830dc78e1SJohan Hedberg 
19696fbe195dSAndre Guedes 	default:
197030dc78e1SJohan Hedberg 		return false;
197130dc78e1SJohan Hedberg 	}
19726fbe195dSAndre Guedes }
197330dc78e1SJohan Hedberg 
1974ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1975ff9ef578SJohan Hedberg {
1976ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1977ff9ef578SJohan Hedberg 
1978ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
1979ff9ef578SJohan Hedberg 		return;
1980ff9ef578SJohan Hedberg 
1981ff9ef578SJohan Hedberg 	switch (state) {
1982ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1983c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
1984c54c3860SAndre Guedes 
19857b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
1986ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1987ff9ef578SJohan Hedberg 		break;
1988ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1989ff9ef578SJohan Hedberg 		break;
1990343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1991ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1992ff9ef578SJohan Hedberg 		break;
199330dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
199430dc78e1SJohan Hedberg 		break;
1995ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1996ff9ef578SJohan Hedberg 		break;
1997ff9ef578SJohan Hedberg 	}
1998ff9ef578SJohan Hedberg 
1999ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
2000ff9ef578SJohan Hedberg }
2001ff9ef578SJohan Hedberg 
20021f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
20031da177e4SLinus Torvalds {
200430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2005b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
20061da177e4SLinus Torvalds 
2007561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
2008561aafbcSJohan Hedberg 		list_del(&p->all);
2009b57c1a56SJohan Hedberg 		kfree(p);
20101da177e4SLinus Torvalds 	}
2011561aafbcSJohan Hedberg 
2012561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
2013561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
20141da177e4SLinus Torvalds }
20151da177e4SLinus Torvalds 
2016a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
2017a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
20181da177e4SLinus Torvalds {
201930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
20201da177e4SLinus Torvalds 	struct inquiry_entry *e;
20211da177e4SLinus Torvalds 
20226ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
20231da177e4SLinus Torvalds 
2024561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
20251da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
20261da177e4SLinus Torvalds 			return e;
20271da177e4SLinus Torvalds 	}
20281da177e4SLinus Torvalds 
2029b57c1a56SJohan Hedberg 	return NULL;
2030b57c1a56SJohan Hedberg }
2031b57c1a56SJohan Hedberg 
2032561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
2033561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
2034561aafbcSJohan Hedberg {
203530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2036561aafbcSJohan Hedberg 	struct inquiry_entry *e;
2037561aafbcSJohan Hedberg 
20386ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
2039561aafbcSJohan Hedberg 
2040561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
2041561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
2042561aafbcSJohan Hedberg 			return e;
2043561aafbcSJohan Hedberg 	}
2044561aafbcSJohan Hedberg 
2045561aafbcSJohan Hedberg 	return NULL;
2046561aafbcSJohan Hedberg }
2047561aafbcSJohan Hedberg 
204830dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
204930dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
205030dc78e1SJohan Hedberg 						       int state)
205130dc78e1SJohan Hedberg {
205230dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
205330dc78e1SJohan Hedberg 	struct inquiry_entry *e;
205430dc78e1SJohan Hedberg 
20556ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
205630dc78e1SJohan Hedberg 
205730dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
205830dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
205930dc78e1SJohan Hedberg 			return e;
206030dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
206130dc78e1SJohan Hedberg 			return e;
206230dc78e1SJohan Hedberg 	}
206330dc78e1SJohan Hedberg 
206430dc78e1SJohan Hedberg 	return NULL;
206530dc78e1SJohan Hedberg }
206630dc78e1SJohan Hedberg 
2067a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
2068a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
2069a3d4e20aSJohan Hedberg {
2070a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2071a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
2072a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
2073a3d4e20aSJohan Hedberg 
2074a3d4e20aSJohan Hedberg 	list_del(&ie->list);
2075a3d4e20aSJohan Hedberg 
2076a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
2077a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
2078a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
2079a3d4e20aSJohan Hedberg 			break;
2080a3d4e20aSJohan Hedberg 		pos = &p->list;
2081a3d4e20aSJohan Hedberg 	}
2082a3d4e20aSJohan Hedberg 
2083a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
2084a3d4e20aSJohan Hedberg }
2085a3d4e20aSJohan Hedberg 
20863175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
2087388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
20881da177e4SLinus Torvalds {
208930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
209070f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
20911da177e4SLinus Torvalds 
20926ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
20931da177e4SLinus Torvalds 
20942b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
20952b2fec4dSSzymon Janc 
2096388fc8faSJohan Hedberg 	*ssp = data->ssp_mode;
2097388fc8faSJohan Hedberg 
209870f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
2099a3d4e20aSJohan Hedberg 	if (ie) {
21008002d77cSJohan Hedberg 		if (ie->data.ssp_mode)
2101388fc8faSJohan Hedberg 			*ssp = true;
2102388fc8faSJohan Hedberg 
2103a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
2104a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
2105a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
2106a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
2107a3d4e20aSJohan Hedberg 		}
2108a3d4e20aSJohan Hedberg 
2109561aafbcSJohan Hedberg 		goto update;
2110a3d4e20aSJohan Hedberg 	}
2111561aafbcSJohan Hedberg 
21121da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
211370f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
211470f23020SAndrei Emeltchenko 	if (!ie)
21153175405bSJohan Hedberg 		return false;
211670f23020SAndrei Emeltchenko 
2117561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
2118561aafbcSJohan Hedberg 
2119561aafbcSJohan Hedberg 	if (name_known) {
2120561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
2121561aafbcSJohan Hedberg 	} else {
2122561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
2123561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
2124561aafbcSJohan Hedberg 	}
2125561aafbcSJohan Hedberg 
2126561aafbcSJohan Hedberg update:
2127561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
2128561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
2129561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
2130561aafbcSJohan Hedberg 		list_del(&ie->list);
21311da177e4SLinus Torvalds 	}
21321da177e4SLinus Torvalds 
213370f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
213470f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
21351da177e4SLinus Torvalds 	cache->timestamp = jiffies;
21363175405bSJohan Hedberg 
21373175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
21383175405bSJohan Hedberg 		return false;
21393175405bSJohan Hedberg 
21403175405bSJohan Hedberg 	return true;
21411da177e4SLinus Torvalds }
21421da177e4SLinus Torvalds 
21431da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
21441da177e4SLinus Torvalds {
214530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
21461da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
21471da177e4SLinus Torvalds 	struct inquiry_entry *e;
21481da177e4SLinus Torvalds 	int copied = 0;
21491da177e4SLinus Torvalds 
2150561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
21511da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
2152b57c1a56SJohan Hedberg 
2153b57c1a56SJohan Hedberg 		if (copied >= num)
2154b57c1a56SJohan Hedberg 			break;
2155b57c1a56SJohan Hedberg 
21561da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
21571da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
21581da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
21591da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
21601da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
21611da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
2162b57c1a56SJohan Hedberg 
21631da177e4SLinus Torvalds 		info++;
2164b57c1a56SJohan Hedberg 		copied++;
21651da177e4SLinus Torvalds 	}
21661da177e4SLinus Torvalds 
21671da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
21681da177e4SLinus Torvalds 	return copied;
21691da177e4SLinus Torvalds }
21701da177e4SLinus Torvalds 
217142c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
21721da177e4SLinus Torvalds {
21731da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
217442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
21751da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
21761da177e4SLinus Torvalds 
21771da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
21781da177e4SLinus Torvalds 
21791da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
21801da177e4SLinus Torvalds 		return;
21811da177e4SLinus Torvalds 
21821da177e4SLinus Torvalds 	/* Start Inquiry */
21831da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
21841da177e4SLinus Torvalds 	cp.length  = ir->length;
21851da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
218642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
21871da177e4SLinus Torvalds }
21881da177e4SLinus Torvalds 
21893e13fa1eSAndre Guedes static int wait_inquiry(void *word)
21903e13fa1eSAndre Guedes {
21913e13fa1eSAndre Guedes 	schedule();
21923e13fa1eSAndre Guedes 	return signal_pending(current);
21933e13fa1eSAndre Guedes }
21943e13fa1eSAndre Guedes 
21951da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
21961da177e4SLinus Torvalds {
21971da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
21981da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
21991da177e4SLinus Torvalds 	struct hci_dev *hdev;
22001da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
22011da177e4SLinus Torvalds 	long timeo;
22021da177e4SLinus Torvalds 	__u8 *buf;
22031da177e4SLinus Torvalds 
22041da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
22051da177e4SLinus Torvalds 		return -EFAULT;
22061da177e4SLinus Torvalds 
22075a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
22085a08ecceSAndrei Emeltchenko 	if (!hdev)
22091da177e4SLinus Torvalds 		return -ENODEV;
22101da177e4SLinus Torvalds 
22110736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22120736cfa8SMarcel Holtmann 		err = -EBUSY;
22130736cfa8SMarcel Holtmann 		goto done;
22140736cfa8SMarcel Holtmann 	}
22150736cfa8SMarcel Holtmann 
22165b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
22175b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
22185b69bef5SMarcel Holtmann 		goto done;
22195b69bef5SMarcel Holtmann 	}
22205b69bef5SMarcel Holtmann 
222156f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
222256f87901SJohan Hedberg 		err = -EOPNOTSUPP;
222356f87901SJohan Hedberg 		goto done;
222456f87901SJohan Hedberg 	}
222556f87901SJohan Hedberg 
222609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
22271da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
2228a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
22291f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
22301da177e4SLinus Torvalds 		do_inquiry = 1;
22311da177e4SLinus Torvalds 	}
223209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
22331da177e4SLinus Torvalds 
223404837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
223570f23020SAndrei Emeltchenko 
223670f23020SAndrei Emeltchenko 	if (do_inquiry) {
223701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
223801178cd4SJohan Hedberg 				   timeo);
223970f23020SAndrei Emeltchenko 		if (err < 0)
22401da177e4SLinus Torvalds 			goto done;
22413e13fa1eSAndre Guedes 
22423e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
22433e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
22443e13fa1eSAndre Guedes 		 */
22453e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
22463e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
22473e13fa1eSAndre Guedes 			return -EINTR;
224870f23020SAndrei Emeltchenko 	}
22491da177e4SLinus Torvalds 
22508fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
22518fc9ced3SGustavo Padovan 	 * 255 entries
22528fc9ced3SGustavo Padovan 	 */
22531da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
22541da177e4SLinus Torvalds 
22551da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
22561da177e4SLinus Torvalds 	 * copy it to the user space.
22571da177e4SLinus Torvalds 	 */
225870f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
225970f23020SAndrei Emeltchenko 	if (!buf) {
22601da177e4SLinus Torvalds 		err = -ENOMEM;
22611da177e4SLinus Torvalds 		goto done;
22621da177e4SLinus Torvalds 	}
22631da177e4SLinus Torvalds 
226409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
22651da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
226609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
22671da177e4SLinus Torvalds 
22681da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
22691da177e4SLinus Torvalds 
22701da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
22711da177e4SLinus Torvalds 		ptr += sizeof(ir);
22721da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
22731da177e4SLinus Torvalds 				 ir.num_rsp))
22741da177e4SLinus Torvalds 			err = -EFAULT;
22751da177e4SLinus Torvalds 	} else
22761da177e4SLinus Torvalds 		err = -EFAULT;
22771da177e4SLinus Torvalds 
22781da177e4SLinus Torvalds 	kfree(buf);
22791da177e4SLinus Torvalds 
22801da177e4SLinus Torvalds done:
22811da177e4SLinus Torvalds 	hci_dev_put(hdev);
22821da177e4SLinus Torvalds 	return err;
22831da177e4SLinus Torvalds }
22841da177e4SLinus Torvalds 
2285cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
22861da177e4SLinus Torvalds {
22871da177e4SLinus Torvalds 	int ret = 0;
22881da177e4SLinus Torvalds 
22891da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
22901da177e4SLinus Torvalds 
22911da177e4SLinus Torvalds 	hci_req_lock(hdev);
22921da177e4SLinus Torvalds 
229394324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
229494324962SJohan Hovold 		ret = -ENODEV;
229594324962SJohan Hovold 		goto done;
229694324962SJohan Hovold 	}
229794324962SJohan Hovold 
2298a5c8f270SMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
2299a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
2300a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
2301bf543036SJohan Hedberg 		 */
2302a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
2303611b30f7SMarcel Holtmann 			ret = -ERFKILL;
2304611b30f7SMarcel Holtmann 			goto done;
2305611b30f7SMarcel Holtmann 		}
2306611b30f7SMarcel Holtmann 
2307a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
2308a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
2309a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
2310a5c8f270SMarcel Holtmann 		 * or not.
2311a5c8f270SMarcel Holtmann 		 *
2312c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
2313c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
2314c6beca0eSMarcel Holtmann 		 * available.
2315c6beca0eSMarcel Holtmann 		 *
2316a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
2317a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
2318a5c8f270SMarcel Holtmann 		 */
2319c6beca0eSMarcel Holtmann 		if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
2320c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
2321a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2322a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
2323a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
2324a5c8f270SMarcel Holtmann 			goto done;
2325a5c8f270SMarcel Holtmann 		}
2326a5c8f270SMarcel Holtmann 	}
2327a5c8f270SMarcel Holtmann 
23281da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
23291da177e4SLinus Torvalds 		ret = -EALREADY;
23301da177e4SLinus Torvalds 		goto done;
23311da177e4SLinus Torvalds 	}
23321da177e4SLinus Torvalds 
23331da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
23341da177e4SLinus Torvalds 		ret = -EIO;
23351da177e4SLinus Torvalds 		goto done;
23361da177e4SLinus Torvalds 	}
23371da177e4SLinus Torvalds 
23381da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
23391da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
2340f41c70c4SMarcel Holtmann 
2341f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
2342f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
2343f41c70c4SMarcel Holtmann 
2344f41c70c4SMarcel Holtmann 	if (!ret) {
2345f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
2346f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
2347f41c70c4SMarcel Holtmann 
23480736cfa8SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags) &&
23490736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
23502177bab5SJohan Hedberg 			ret = __hci_init(hdev);
23511da177e4SLinus Torvalds 	}
23521da177e4SLinus Torvalds 
2353f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
2354f41c70c4SMarcel Holtmann 
23551da177e4SLinus Torvalds 	if (!ret) {
23561da177e4SLinus Torvalds 		hci_dev_hold(hdev);
2357d6bfd59cSJohan Hedberg 		set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
23581da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
23591da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
2360bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
23610736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
23621514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
236309fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2364744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
236509fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
236656e5cb86SJohan Hedberg 		}
23671da177e4SLinus Torvalds 	} else {
23681da177e4SLinus Torvalds 		/* Init failed, cleanup */
23693eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
2370c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
2371b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
23721da177e4SLinus Torvalds 
23731da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
23741da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
23751da177e4SLinus Torvalds 
23761da177e4SLinus Torvalds 		if (hdev->flush)
23771da177e4SLinus Torvalds 			hdev->flush(hdev);
23781da177e4SLinus Torvalds 
23791da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
23801da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
23811da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
23821da177e4SLinus Torvalds 		}
23831da177e4SLinus Torvalds 
23841da177e4SLinus Torvalds 		hdev->close(hdev);
23851da177e4SLinus Torvalds 		hdev->flags = 0;
23861da177e4SLinus Torvalds 	}
23871da177e4SLinus Torvalds 
23881da177e4SLinus Torvalds done:
23891da177e4SLinus Torvalds 	hci_req_unlock(hdev);
23901da177e4SLinus Torvalds 	return ret;
23911da177e4SLinus Torvalds }
23921da177e4SLinus Torvalds 
2393cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
2394cbed0ca1SJohan Hedberg 
2395cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
2396cbed0ca1SJohan Hedberg {
2397cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
2398cbed0ca1SJohan Hedberg 	int err;
2399cbed0ca1SJohan Hedberg 
2400cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
2401cbed0ca1SJohan Hedberg 	if (!hdev)
2402cbed0ca1SJohan Hedberg 		return -ENODEV;
2403cbed0ca1SJohan Hedberg 
2404e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
2405e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
2406e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
2407e1d08f40SJohan Hedberg 	 * completed.
2408e1d08f40SJohan Hedberg 	 */
2409e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2410e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
2411e1d08f40SJohan Hedberg 
2412a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
2413a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
2414a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
2415a5c8f270SMarcel Holtmann 	 */
2416e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
2417e1d08f40SJohan Hedberg 
2418cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
2419cbed0ca1SJohan Hedberg 
2420cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
2421cbed0ca1SJohan Hedberg 
2422cbed0ca1SJohan Hedberg 	return err;
2423cbed0ca1SJohan Hedberg }
2424cbed0ca1SJohan Hedberg 
24251da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
24261da177e4SLinus Torvalds {
24271da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
24281da177e4SLinus Torvalds 
242978c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
243078c04c0bSVinicius Costa Gomes 
24311da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
24321da177e4SLinus Torvalds 	hci_req_lock(hdev);
24331da177e4SLinus Torvalds 
24341da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
243565cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
24361da177e4SLinus Torvalds 		hci_req_unlock(hdev);
24371da177e4SLinus Torvalds 		return 0;
24381da177e4SLinus Torvalds 	}
24391da177e4SLinus Torvalds 
24403eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
24413eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
2442b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
24431da177e4SLinus Torvalds 
244416ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
2445e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
244616ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
24475e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
2448310a3d48SMarcel Holtmann 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
244916ab91abSJohan Hedberg 	}
245016ab91abSJohan Hedberg 
2451a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
24527d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
24537d78525dSJohan Hedberg 
24547ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
24554518bb0fSJohan Hedberg 
24564518bb0fSJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
2457d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
24587ba8b4beSAndre Guedes 
245909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
24601f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
24611da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
24626046dc3eSAndre Guedes 	hci_pend_le_conns_clear(hdev);
246309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
24641da177e4SLinus Torvalds 
24651da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
24661da177e4SLinus Torvalds 
24671da177e4SLinus Torvalds 	if (hdev->flush)
24681da177e4SLinus Torvalds 		hdev->flush(hdev);
24691da177e4SLinus Torvalds 
24701da177e4SLinus Torvalds 	/* Reset device */
24711da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
24721da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
24738af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
24743a6afbd2SMarcel Holtmann 	    !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
2475a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
24761da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
247701178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
24781da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
24791da177e4SLinus Torvalds 	}
24801da177e4SLinus Torvalds 
2481c347b765SGustavo F. Padovan 	/* flush cmd  work */
2482c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
24831da177e4SLinus Torvalds 
24841da177e4SLinus Torvalds 	/* Drop queues */
24851da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
24861da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
24871da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
24881da177e4SLinus Torvalds 
24891da177e4SLinus Torvalds 	/* Drop last sent command */
24901da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
249165cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
24921da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
24931da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
24941da177e4SLinus Torvalds 	}
24951da177e4SLinus Torvalds 
2496b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
2497b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
2498b6ddb638SJohan Hedberg 
24991da177e4SLinus Torvalds 	/* After this point our queues are empty
25001da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
25011da177e4SLinus Torvalds 	hdev->close(hdev);
25021da177e4SLinus Torvalds 
250335b973c9SJohan Hedberg 	/* Clear flags */
250435b973c9SJohan Hedberg 	hdev->flags = 0;
250535b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
250635b973c9SJohan Hedberg 
250793c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
250893c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
250909fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2510744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
251109fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
25128ee56540SMarcel Holtmann 		}
251393c311a0SMarcel Holtmann 	}
25145add6af8SJohan Hedberg 
2515ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
2516536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
2517ced5c338SAndrei Emeltchenko 
2518e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
251909b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
25207a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
2521e59fda8dSJohan Hedberg 
25221da177e4SLinus Torvalds 	hci_req_unlock(hdev);
25231da177e4SLinus Torvalds 
25241da177e4SLinus Torvalds 	hci_dev_put(hdev);
25251da177e4SLinus Torvalds 	return 0;
25261da177e4SLinus Torvalds }
25271da177e4SLinus Torvalds 
25281da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
25291da177e4SLinus Torvalds {
25301da177e4SLinus Torvalds 	struct hci_dev *hdev;
25311da177e4SLinus Torvalds 	int err;
25321da177e4SLinus Torvalds 
253370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
253470f23020SAndrei Emeltchenko 	if (!hdev)
25351da177e4SLinus Torvalds 		return -ENODEV;
25368ee56540SMarcel Holtmann 
25370736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
25380736cfa8SMarcel Holtmann 		err = -EBUSY;
25390736cfa8SMarcel Holtmann 		goto done;
25400736cfa8SMarcel Holtmann 	}
25410736cfa8SMarcel Holtmann 
25428ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
25438ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
25448ee56540SMarcel Holtmann 
25451da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
25468ee56540SMarcel Holtmann 
25470736cfa8SMarcel Holtmann done:
25481da177e4SLinus Torvalds 	hci_dev_put(hdev);
25491da177e4SLinus Torvalds 	return err;
25501da177e4SLinus Torvalds }
25511da177e4SLinus Torvalds 
25521da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
25531da177e4SLinus Torvalds {
25541da177e4SLinus Torvalds 	struct hci_dev *hdev;
25551da177e4SLinus Torvalds 	int ret = 0;
25561da177e4SLinus Torvalds 
255770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
255870f23020SAndrei Emeltchenko 	if (!hdev)
25591da177e4SLinus Torvalds 		return -ENODEV;
25601da177e4SLinus Torvalds 
25611da177e4SLinus Torvalds 	hci_req_lock(hdev);
25621da177e4SLinus Torvalds 
2563808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
2564808a049eSMarcel Holtmann 		ret = -ENETDOWN;
25651da177e4SLinus Torvalds 		goto done;
2566808a049eSMarcel Holtmann 	}
25671da177e4SLinus Torvalds 
25680736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
25690736cfa8SMarcel Holtmann 		ret = -EBUSY;
25700736cfa8SMarcel Holtmann 		goto done;
25710736cfa8SMarcel Holtmann 	}
25720736cfa8SMarcel Holtmann 
25731da177e4SLinus Torvalds 	/* Drop queues */
25741da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
25751da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
25761da177e4SLinus Torvalds 
257709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
25781f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
25791da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
258009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
25811da177e4SLinus Torvalds 
25821da177e4SLinus Torvalds 	if (hdev->flush)
25831da177e4SLinus Torvalds 		hdev->flush(hdev);
25841da177e4SLinus Torvalds 
25851da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
25866ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
25871da177e4SLinus Torvalds 
25881da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
258901178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
25901da177e4SLinus Torvalds 
25911da177e4SLinus Torvalds done:
25921da177e4SLinus Torvalds 	hci_req_unlock(hdev);
25931da177e4SLinus Torvalds 	hci_dev_put(hdev);
25941da177e4SLinus Torvalds 	return ret;
25951da177e4SLinus Torvalds }
25961da177e4SLinus Torvalds 
25971da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
25981da177e4SLinus Torvalds {
25991da177e4SLinus Torvalds 	struct hci_dev *hdev;
26001da177e4SLinus Torvalds 	int ret = 0;
26011da177e4SLinus Torvalds 
260270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
260370f23020SAndrei Emeltchenko 	if (!hdev)
26041da177e4SLinus Torvalds 		return -ENODEV;
26051da177e4SLinus Torvalds 
26060736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
26070736cfa8SMarcel Holtmann 		ret = -EBUSY;
26080736cfa8SMarcel Holtmann 		goto done;
26090736cfa8SMarcel Holtmann 	}
26100736cfa8SMarcel Holtmann 
26111da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
26121da177e4SLinus Torvalds 
26130736cfa8SMarcel Holtmann done:
26141da177e4SLinus Torvalds 	hci_dev_put(hdev);
26151da177e4SLinus Torvalds 	return ret;
26161da177e4SLinus Torvalds }
26171da177e4SLinus Torvalds 
26181da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
26191da177e4SLinus Torvalds {
26201da177e4SLinus Torvalds 	struct hci_dev *hdev;
26211da177e4SLinus Torvalds 	struct hci_dev_req dr;
26221da177e4SLinus Torvalds 	int err = 0;
26231da177e4SLinus Torvalds 
26241da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
26251da177e4SLinus Torvalds 		return -EFAULT;
26261da177e4SLinus Torvalds 
262770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
262870f23020SAndrei Emeltchenko 	if (!hdev)
26291da177e4SLinus Torvalds 		return -ENODEV;
26301da177e4SLinus Torvalds 
26310736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
26320736cfa8SMarcel Holtmann 		err = -EBUSY;
26330736cfa8SMarcel Holtmann 		goto done;
26340736cfa8SMarcel Holtmann 	}
26350736cfa8SMarcel Holtmann 
26365b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
26375b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
26385b69bef5SMarcel Holtmann 		goto done;
26395b69bef5SMarcel Holtmann 	}
26405b69bef5SMarcel Holtmann 
264156f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
264256f87901SJohan Hedberg 		err = -EOPNOTSUPP;
264356f87901SJohan Hedberg 		goto done;
264456f87901SJohan Hedberg 	}
264556f87901SJohan Hedberg 
26461da177e4SLinus Torvalds 	switch (cmd) {
26471da177e4SLinus Torvalds 	case HCISETAUTH:
264801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
26495f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
26501da177e4SLinus Torvalds 		break;
26511da177e4SLinus Torvalds 
26521da177e4SLinus Torvalds 	case HCISETENCRYPT:
26531da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
26541da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
26551da177e4SLinus Torvalds 			break;
26561da177e4SLinus Torvalds 		}
26571da177e4SLinus Torvalds 
26581da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
26591da177e4SLinus Torvalds 			/* Auth must be enabled first */
266001178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
26615f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
26621da177e4SLinus Torvalds 			if (err)
26631da177e4SLinus Torvalds 				break;
26641da177e4SLinus Torvalds 		}
26651da177e4SLinus Torvalds 
266601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
26675f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
26681da177e4SLinus Torvalds 		break;
26691da177e4SLinus Torvalds 
26701da177e4SLinus Torvalds 	case HCISETSCAN:
267101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
26725f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
26731da177e4SLinus Torvalds 		break;
26741da177e4SLinus Torvalds 
26751da177e4SLinus Torvalds 	case HCISETLINKPOL:
267601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
26775f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
26781da177e4SLinus Torvalds 		break;
26791da177e4SLinus Torvalds 
26801da177e4SLinus Torvalds 	case HCISETLINKMODE:
2681e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2682e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2683e4e8e37cSMarcel Holtmann 		break;
2684e4e8e37cSMarcel Holtmann 
2685e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2686e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
26871da177e4SLinus Torvalds 		break;
26881da177e4SLinus Torvalds 
26891da177e4SLinus Torvalds 	case HCISETACLMTU:
26901da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
26911da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
26921da177e4SLinus Torvalds 		break;
26931da177e4SLinus Torvalds 
26941da177e4SLinus Torvalds 	case HCISETSCOMTU:
26951da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
26961da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
26971da177e4SLinus Torvalds 		break;
26981da177e4SLinus Torvalds 
26991da177e4SLinus Torvalds 	default:
27001da177e4SLinus Torvalds 		err = -EINVAL;
27011da177e4SLinus Torvalds 		break;
27021da177e4SLinus Torvalds 	}
2703e4e8e37cSMarcel Holtmann 
27040736cfa8SMarcel Holtmann done:
27051da177e4SLinus Torvalds 	hci_dev_put(hdev);
27061da177e4SLinus Torvalds 	return err;
27071da177e4SLinus Torvalds }
27081da177e4SLinus Torvalds 
27091da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
27101da177e4SLinus Torvalds {
27118035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
27121da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
27131da177e4SLinus Torvalds 	struct hci_dev_req *dr;
27141da177e4SLinus Torvalds 	int n = 0, size, err;
27151da177e4SLinus Torvalds 	__u16 dev_num;
27161da177e4SLinus Torvalds 
27171da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
27181da177e4SLinus Torvalds 		return -EFAULT;
27191da177e4SLinus Torvalds 
27201da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
27211da177e4SLinus Torvalds 		return -EINVAL;
27221da177e4SLinus Torvalds 
27231da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
27241da177e4SLinus Torvalds 
272570f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
272670f23020SAndrei Emeltchenko 	if (!dl)
27271da177e4SLinus Torvalds 		return -ENOMEM;
27281da177e4SLinus Torvalds 
27291da177e4SLinus Torvalds 	dr = dl->dev_req;
27301da177e4SLinus Torvalds 
2731f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
27328035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
2733a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2734e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
2735c542a06cSJohan Hedberg 
2736a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2737a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
2738c542a06cSJohan Hedberg 
27391da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
27401da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
2741c542a06cSJohan Hedberg 
27421da177e4SLinus Torvalds 		if (++n >= dev_num)
27431da177e4SLinus Torvalds 			break;
27441da177e4SLinus Torvalds 	}
2745f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
27461da177e4SLinus Torvalds 
27471da177e4SLinus Torvalds 	dl->dev_num = n;
27481da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
27491da177e4SLinus Torvalds 
27501da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
27511da177e4SLinus Torvalds 	kfree(dl);
27521da177e4SLinus Torvalds 
27531da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
27541da177e4SLinus Torvalds }
27551da177e4SLinus Torvalds 
27561da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
27571da177e4SLinus Torvalds {
27581da177e4SLinus Torvalds 	struct hci_dev *hdev;
27591da177e4SLinus Torvalds 	struct hci_dev_info di;
27601da177e4SLinus Torvalds 	int err = 0;
27611da177e4SLinus Torvalds 
27621da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
27631da177e4SLinus Torvalds 		return -EFAULT;
27641da177e4SLinus Torvalds 
276570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
276670f23020SAndrei Emeltchenko 	if (!hdev)
27671da177e4SLinus Torvalds 		return -ENODEV;
27681da177e4SLinus Torvalds 
2769a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
27703243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
2771ab81cbf9SJohan Hedberg 
2772a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2773a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
2774c542a06cSJohan Hedberg 
27751da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
27761da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
277760f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
27781da177e4SLinus Torvalds 	di.flags    = hdev->flags;
27791da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2780572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
27811da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
27821da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
27831da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
27841da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2785572c7f84SJohan Hedberg 	} else {
2786572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2787572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2788572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2789572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2790572c7f84SJohan Hedberg 	}
27911da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
27921da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
27931da177e4SLinus Torvalds 
27941da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
27951da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
27961da177e4SLinus Torvalds 
27971da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
27981da177e4SLinus Torvalds 		err = -EFAULT;
27991da177e4SLinus Torvalds 
28001da177e4SLinus Torvalds 	hci_dev_put(hdev);
28011da177e4SLinus Torvalds 
28021da177e4SLinus Torvalds 	return err;
28031da177e4SLinus Torvalds }
28041da177e4SLinus Torvalds 
28051da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
28061da177e4SLinus Torvalds 
2807611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2808611b30f7SMarcel Holtmann {
2809611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2810611b30f7SMarcel Holtmann 
2811611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2812611b30f7SMarcel Holtmann 
28130736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
28140736cfa8SMarcel Holtmann 		return -EBUSY;
28150736cfa8SMarcel Holtmann 
28165e130367SJohan Hedberg 	if (blocked) {
28175e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
2818bf543036SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags))
2819611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
28205e130367SJohan Hedberg 	} else {
28215e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
28225e130367SJohan Hedberg 	}
2823611b30f7SMarcel Holtmann 
2824611b30f7SMarcel Holtmann 	return 0;
2825611b30f7SMarcel Holtmann }
2826611b30f7SMarcel Holtmann 
2827611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2828611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2829611b30f7SMarcel Holtmann };
2830611b30f7SMarcel Holtmann 
2831ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2832ab81cbf9SJohan Hedberg {
2833ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
283496570ffcSJohan Hedberg 	int err;
2835ab81cbf9SJohan Hedberg 
2836ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2837ab81cbf9SJohan Hedberg 
2838cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
283996570ffcSJohan Hedberg 	if (err < 0) {
284096570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
2841ab81cbf9SJohan Hedberg 		return;
284296570ffcSJohan Hedberg 	}
2843ab81cbf9SJohan Hedberg 
2844a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2845a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2846a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2847a5c8f270SMarcel Holtmann 	 */
2848a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
2849a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
2850a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2851a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2852bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2853bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2854bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
285519202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
285619202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2857bf543036SJohan Hedberg 	}
2858ab81cbf9SJohan Hedberg 
2859a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
2860744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2861ab81cbf9SJohan Hedberg }
2862ab81cbf9SJohan Hedberg 
2863ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2864ab81cbf9SJohan Hedberg {
28653243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
28663243553fSJohan Hedberg 					    power_off.work);
2867ab81cbf9SJohan Hedberg 
2868ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2869ab81cbf9SJohan Hedberg 
28708ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2871ab81cbf9SJohan Hedberg }
2872ab81cbf9SJohan Hedberg 
287316ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
287416ab91abSJohan Hedberg {
287516ab91abSJohan Hedberg 	struct hci_dev *hdev;
287616ab91abSJohan Hedberg 
287716ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
287816ab91abSJohan Hedberg 
287916ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
288016ab91abSJohan Hedberg 
2881d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
288216ab91abSJohan Hedberg }
288316ab91abSJohan Hedberg 
288435f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
28852aeb9a1aSJohan Hedberg {
28864821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
28872aeb9a1aSJohan Hedberg 
28884821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
28894821002cSJohan Hedberg 		list_del(&uuid->list);
28902aeb9a1aSJohan Hedberg 		kfree(uuid);
28912aeb9a1aSJohan Hedberg 	}
28922aeb9a1aSJohan Hedberg }
28932aeb9a1aSJohan Hedberg 
289435f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
289555ed8ca1SJohan Hedberg {
289655ed8ca1SJohan Hedberg 	struct list_head *p, *n;
289755ed8ca1SJohan Hedberg 
289855ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
289955ed8ca1SJohan Hedberg 		struct link_key *key;
290055ed8ca1SJohan Hedberg 
290155ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
290255ed8ca1SJohan Hedberg 
290355ed8ca1SJohan Hedberg 		list_del(p);
290455ed8ca1SJohan Hedberg 		kfree(key);
290555ed8ca1SJohan Hedberg 	}
290655ed8ca1SJohan Hedberg }
290755ed8ca1SJohan Hedberg 
290835f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2909b899efafSVinicius Costa Gomes {
2910b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2911b899efafSVinicius Costa Gomes 
2912b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2913b899efafSVinicius Costa Gomes 		list_del(&k->list);
2914b899efafSVinicius Costa Gomes 		kfree(k);
2915b899efafSVinicius Costa Gomes 	}
2916b899efafSVinicius Costa Gomes }
2917b899efafSVinicius Costa Gomes 
2918970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2919970c4e46SJohan Hedberg {
2920970c4e46SJohan Hedberg 	struct smp_irk *k, *tmp;
2921970c4e46SJohan Hedberg 
2922970c4e46SJohan Hedberg 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
2923970c4e46SJohan Hedberg 		list_del(&k->list);
2924970c4e46SJohan Hedberg 		kfree(k);
2925970c4e46SJohan Hedberg 	}
2926970c4e46SJohan Hedberg }
2927970c4e46SJohan Hedberg 
292855ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
292955ed8ca1SJohan Hedberg {
293055ed8ca1SJohan Hedberg 	struct link_key *k;
293155ed8ca1SJohan Hedberg 
29328035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
293355ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
293455ed8ca1SJohan Hedberg 			return k;
293555ed8ca1SJohan Hedberg 
293655ed8ca1SJohan Hedberg 	return NULL;
293755ed8ca1SJohan Hedberg }
293855ed8ca1SJohan Hedberg 
2939745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2940d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2941d25e28abSJohan Hedberg {
2942d25e28abSJohan Hedberg 	/* Legacy key */
2943d25e28abSJohan Hedberg 	if (key_type < 0x03)
2944745c0ce3SVishal Agarwal 		return true;
2945d25e28abSJohan Hedberg 
2946d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2947d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2948745c0ce3SVishal Agarwal 		return false;
2949d25e28abSJohan Hedberg 
2950d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2951d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2952745c0ce3SVishal Agarwal 		return false;
2953d25e28abSJohan Hedberg 
2954d25e28abSJohan Hedberg 	/* Security mode 3 case */
2955d25e28abSJohan Hedberg 	if (!conn)
2956745c0ce3SVishal Agarwal 		return true;
2957d25e28abSJohan Hedberg 
2958d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2959d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2960745c0ce3SVishal Agarwal 		return true;
2961d25e28abSJohan Hedberg 
2962d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2963d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2964745c0ce3SVishal Agarwal 		return true;
2965d25e28abSJohan Hedberg 
2966d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2967d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2968745c0ce3SVishal Agarwal 		return true;
2969d25e28abSJohan Hedberg 
2970d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2971d25e28abSJohan Hedberg 	 * persistently */
2972745c0ce3SVishal Agarwal 	return false;
2973d25e28abSJohan Hedberg }
2974d25e28abSJohan Hedberg 
297598a0b845SJohan Hedberg static bool ltk_type_master(u8 type)
297698a0b845SJohan Hedberg {
2977d97c9fb0SJohan Hedberg 	return (type == SMP_LTK);
297898a0b845SJohan Hedberg }
297998a0b845SJohan Hedberg 
2980fe39c7b2SMarcel Holtmann struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
298198a0b845SJohan Hedberg 			     bool master)
298275d262c2SVinicius Costa Gomes {
2983c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
298475d262c2SVinicius Costa Gomes 
2985c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
2986fe39c7b2SMarcel Holtmann 		if (k->ediv != ediv || k->rand != rand)
298775d262c2SVinicius Costa Gomes 			continue;
298875d262c2SVinicius Costa Gomes 
298998a0b845SJohan Hedberg 		if (ltk_type_master(k->type) != master)
299098a0b845SJohan Hedberg 			continue;
299198a0b845SJohan Hedberg 
299275d262c2SVinicius Costa Gomes 		return k;
299375d262c2SVinicius Costa Gomes 	}
299475d262c2SVinicius Costa Gomes 
299575d262c2SVinicius Costa Gomes 	return NULL;
299675d262c2SVinicius Costa Gomes }
299775d262c2SVinicius Costa Gomes 
2998c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
299998a0b845SJohan Hedberg 				     u8 addr_type, bool master)
300075d262c2SVinicius Costa Gomes {
3001c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
300275d262c2SVinicius Costa Gomes 
3003c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
3004c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
300598a0b845SJohan Hedberg 		    bacmp(bdaddr, &k->bdaddr) == 0 &&
300698a0b845SJohan Hedberg 		    ltk_type_master(k->type) == master)
300775d262c2SVinicius Costa Gomes 			return k;
300875d262c2SVinicius Costa Gomes 
300975d262c2SVinicius Costa Gomes 	return NULL;
301075d262c2SVinicius Costa Gomes }
301175d262c2SVinicius Costa Gomes 
3012970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
3013970c4e46SJohan Hedberg {
3014970c4e46SJohan Hedberg 	struct smp_irk *irk;
3015970c4e46SJohan Hedberg 
3016970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
3017970c4e46SJohan Hedberg 		if (!bacmp(&irk->rpa, rpa))
3018970c4e46SJohan Hedberg 			return irk;
3019970c4e46SJohan Hedberg 	}
3020970c4e46SJohan Hedberg 
3021970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
3022970c4e46SJohan Hedberg 		if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) {
3023970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
3024970c4e46SJohan Hedberg 			return irk;
3025970c4e46SJohan Hedberg 		}
3026970c4e46SJohan Hedberg 	}
3027970c4e46SJohan Hedberg 
3028970c4e46SJohan Hedberg 	return NULL;
3029970c4e46SJohan Hedberg }
3030970c4e46SJohan Hedberg 
3031970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
3032970c4e46SJohan Hedberg 				     u8 addr_type)
3033970c4e46SJohan Hedberg {
3034970c4e46SJohan Hedberg 	struct smp_irk *irk;
3035970c4e46SJohan Hedberg 
30366cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
30376cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
30386cfc9988SJohan Hedberg 		return NULL;
30396cfc9988SJohan Hedberg 
3040970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
3041970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
3042970c4e46SJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0)
3043970c4e46SJohan Hedberg 			return irk;
3044970c4e46SJohan Hedberg 	}
3045970c4e46SJohan Hedberg 
3046970c4e46SJohan Hedberg 	return NULL;
3047970c4e46SJohan Hedberg }
3048970c4e46SJohan Hedberg 
3049d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
3050d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
305155ed8ca1SJohan Hedberg {
305255ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
3053745c0ce3SVishal Agarwal 	u8 old_key_type;
3054745c0ce3SVishal Agarwal 	bool persistent;
305555ed8ca1SJohan Hedberg 
305655ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
305755ed8ca1SJohan Hedberg 	if (old_key) {
305855ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
305955ed8ca1SJohan Hedberg 		key = old_key;
306055ed8ca1SJohan Hedberg 	} else {
306112adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
30620a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
306355ed8ca1SJohan Hedberg 		if (!key)
306455ed8ca1SJohan Hedberg 			return -ENOMEM;
306555ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
306655ed8ca1SJohan Hedberg 	}
306755ed8ca1SJohan Hedberg 
30686ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
306955ed8ca1SJohan Hedberg 
3070d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
3071d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
3072d25e28abSJohan Hedberg 	 * previous key */
3073d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
3074a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
3075d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
3076655fe6ecSJohan Hedberg 		if (conn)
3077655fe6ecSJohan Hedberg 			conn->key_type = type;
3078655fe6ecSJohan Hedberg 	}
3079d25e28abSJohan Hedberg 
308055ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
30819b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
308255ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
308355ed8ca1SJohan Hedberg 
3084b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
308555ed8ca1SJohan Hedberg 		key->type = old_key_type;
30864748fed2SJohan Hedberg 	else
30874748fed2SJohan Hedberg 		key->type = type;
30884748fed2SJohan Hedberg 
30894df378a1SJohan Hedberg 	if (!new_key)
30904df378a1SJohan Hedberg 		return 0;
30914df378a1SJohan Hedberg 
30924df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
30934df378a1SJohan Hedberg 
3094744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
30954df378a1SJohan Hedberg 
30966ec5bcadSVishal Agarwal 	if (conn)
30976ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
309855ed8ca1SJohan Hedberg 
309955ed8ca1SJohan Hedberg 	return 0;
310055ed8ca1SJohan Hedberg }
310155ed8ca1SJohan Hedberg 
3102ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
310335d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
3104fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
310575d262c2SVinicius Costa Gomes {
3106c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
310798a0b845SJohan Hedberg 	bool master = ltk_type_master(type);
310875d262c2SVinicius Costa Gomes 
310998a0b845SJohan Hedberg 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master);
3110c9839a11SVinicius Costa Gomes 	if (old_key)
311175d262c2SVinicius Costa Gomes 		key = old_key;
3112c9839a11SVinicius Costa Gomes 	else {
31130a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
311475d262c2SVinicius Costa Gomes 		if (!key)
3115ca9142b8SJohan Hedberg 			return NULL;
3116c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
311775d262c2SVinicius Costa Gomes 	}
311875d262c2SVinicius Costa Gomes 
311975d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
3120c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
3121c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
3122c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
3123c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
3124fe39c7b2SMarcel Holtmann 	key->rand = rand;
3125c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
3126c9839a11SVinicius Costa Gomes 	key->type = type;
312775d262c2SVinicius Costa Gomes 
3128ca9142b8SJohan Hedberg 	return key;
312975d262c2SVinicius Costa Gomes }
313075d262c2SVinicius Costa Gomes 
3131ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
3132ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
3133970c4e46SJohan Hedberg {
3134970c4e46SJohan Hedberg 	struct smp_irk *irk;
3135970c4e46SJohan Hedberg 
3136970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
3137970c4e46SJohan Hedberg 	if (!irk) {
3138970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
3139970c4e46SJohan Hedberg 		if (!irk)
3140ca9142b8SJohan Hedberg 			return NULL;
3141970c4e46SJohan Hedberg 
3142970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
3143970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
3144970c4e46SJohan Hedberg 
3145970c4e46SJohan Hedberg 		list_add(&irk->list, &hdev->identity_resolving_keys);
3146970c4e46SJohan Hedberg 	}
3147970c4e46SJohan Hedberg 
3148970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
3149970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
3150970c4e46SJohan Hedberg 
3151ca9142b8SJohan Hedberg 	return irk;
3152970c4e46SJohan Hedberg }
3153970c4e46SJohan Hedberg 
315455ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
315555ed8ca1SJohan Hedberg {
315655ed8ca1SJohan Hedberg 	struct link_key *key;
315755ed8ca1SJohan Hedberg 
315855ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
315955ed8ca1SJohan Hedberg 	if (!key)
316055ed8ca1SJohan Hedberg 		return -ENOENT;
316155ed8ca1SJohan Hedberg 
31626ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
316355ed8ca1SJohan Hedberg 
316455ed8ca1SJohan Hedberg 	list_del(&key->list);
316555ed8ca1SJohan Hedberg 	kfree(key);
316655ed8ca1SJohan Hedberg 
316755ed8ca1SJohan Hedberg 	return 0;
316855ed8ca1SJohan Hedberg }
316955ed8ca1SJohan Hedberg 
3170e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
3171b899efafSVinicius Costa Gomes {
3172b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
3173c51ffa0bSJohan Hedberg 	int removed = 0;
3174b899efafSVinicius Costa Gomes 
3175b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
3176e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
3177b899efafSVinicius Costa Gomes 			continue;
3178b899efafSVinicius Costa Gomes 
31796ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
3180b899efafSVinicius Costa Gomes 
3181b899efafSVinicius Costa Gomes 		list_del(&k->list);
3182b899efafSVinicius Costa Gomes 		kfree(k);
3183c51ffa0bSJohan Hedberg 		removed++;
3184b899efafSVinicius Costa Gomes 	}
3185b899efafSVinicius Costa Gomes 
3186c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
3187b899efafSVinicius Costa Gomes }
3188b899efafSVinicius Costa Gomes 
3189a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
3190a7ec7338SJohan Hedberg {
3191a7ec7338SJohan Hedberg 	struct smp_irk *k, *tmp;
3192a7ec7338SJohan Hedberg 
3193668b7b19SJohan Hedberg 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
3194a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
3195a7ec7338SJohan Hedberg 			continue;
3196a7ec7338SJohan Hedberg 
3197a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
3198a7ec7338SJohan Hedberg 
3199a7ec7338SJohan Hedberg 		list_del(&k->list);
3200a7ec7338SJohan Hedberg 		kfree(k);
3201a7ec7338SJohan Hedberg 	}
3202a7ec7338SJohan Hedberg }
3203a7ec7338SJohan Hedberg 
32046bd32326SVille Tervo /* HCI command timer function */
320565cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
32066bd32326SVille Tervo {
320765cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
320865cc2b49SMarcel Holtmann 					    cmd_timer.work);
32096bd32326SVille Tervo 
3210bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
3211bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
3212bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
3213bda4f23aSAndrei Emeltchenko 
3214bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
3215bda4f23aSAndrei Emeltchenko 	} else {
32166bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
3217bda4f23aSAndrei Emeltchenko 	}
3218bda4f23aSAndrei Emeltchenko 
32196bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
3220c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
32216bd32326SVille Tervo }
32226bd32326SVille Tervo 
32232763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
32242763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
32252763eda6SSzymon Janc {
32262763eda6SSzymon Janc 	struct oob_data *data;
32272763eda6SSzymon Janc 
32282763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
32292763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
32302763eda6SSzymon Janc 			return data;
32312763eda6SSzymon Janc 
32322763eda6SSzymon Janc 	return NULL;
32332763eda6SSzymon Janc }
32342763eda6SSzymon Janc 
32352763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
32362763eda6SSzymon Janc {
32372763eda6SSzymon Janc 	struct oob_data *data;
32382763eda6SSzymon Janc 
32392763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
32402763eda6SSzymon Janc 	if (!data)
32412763eda6SSzymon Janc 		return -ENOENT;
32422763eda6SSzymon Janc 
32436ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
32442763eda6SSzymon Janc 
32452763eda6SSzymon Janc 	list_del(&data->list);
32462763eda6SSzymon Janc 	kfree(data);
32472763eda6SSzymon Janc 
32482763eda6SSzymon Janc 	return 0;
32492763eda6SSzymon Janc }
32502763eda6SSzymon Janc 
325135f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
32522763eda6SSzymon Janc {
32532763eda6SSzymon Janc 	struct oob_data *data, *n;
32542763eda6SSzymon Janc 
32552763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
32562763eda6SSzymon Janc 		list_del(&data->list);
32572763eda6SSzymon Janc 		kfree(data);
32582763eda6SSzymon Janc 	}
32592763eda6SSzymon Janc }
32602763eda6SSzymon Janc 
32610798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
32620798872eSMarcel Holtmann 			    u8 *hash, u8 *randomizer)
32632763eda6SSzymon Janc {
32642763eda6SSzymon Janc 	struct oob_data *data;
32652763eda6SSzymon Janc 
32662763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
32672763eda6SSzymon Janc 	if (!data) {
32680a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
32692763eda6SSzymon Janc 		if (!data)
32702763eda6SSzymon Janc 			return -ENOMEM;
32712763eda6SSzymon Janc 
32722763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
32732763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
32742763eda6SSzymon Janc 	}
32752763eda6SSzymon Janc 
3276519ca9d0SMarcel Holtmann 	memcpy(data->hash192, hash, sizeof(data->hash192));
3277519ca9d0SMarcel Holtmann 	memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
32782763eda6SSzymon Janc 
32790798872eSMarcel Holtmann 	memset(data->hash256, 0, sizeof(data->hash256));
32800798872eSMarcel Holtmann 	memset(data->randomizer256, 0, sizeof(data->randomizer256));
32810798872eSMarcel Holtmann 
32820798872eSMarcel Holtmann 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
32830798872eSMarcel Holtmann 
32840798872eSMarcel Holtmann 	return 0;
32850798872eSMarcel Holtmann }
32860798872eSMarcel Holtmann 
32870798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
32880798872eSMarcel Holtmann 				u8 *hash192, u8 *randomizer192,
32890798872eSMarcel Holtmann 				u8 *hash256, u8 *randomizer256)
32900798872eSMarcel Holtmann {
32910798872eSMarcel Holtmann 	struct oob_data *data;
32920798872eSMarcel Holtmann 
32930798872eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, bdaddr);
32940798872eSMarcel Holtmann 	if (!data) {
32950a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
32960798872eSMarcel Holtmann 		if (!data)
32970798872eSMarcel Holtmann 			return -ENOMEM;
32980798872eSMarcel Holtmann 
32990798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
33000798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
33010798872eSMarcel Holtmann 	}
33020798872eSMarcel Holtmann 
33030798872eSMarcel Holtmann 	memcpy(data->hash192, hash192, sizeof(data->hash192));
33040798872eSMarcel Holtmann 	memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192));
33050798872eSMarcel Holtmann 
33060798872eSMarcel Holtmann 	memcpy(data->hash256, hash256, sizeof(data->hash256));
33070798872eSMarcel Holtmann 	memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256));
33080798872eSMarcel Holtmann 
33096ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
33102763eda6SSzymon Janc 
33112763eda6SSzymon Janc 	return 0;
33122763eda6SSzymon Janc }
33132763eda6SSzymon Janc 
3314b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
3315b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
3316b2a66aadSAntti Julku {
3317b2a66aadSAntti Julku 	struct bdaddr_list *b;
3318b2a66aadSAntti Julku 
3319b9ee0a78SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list) {
3320b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3321b2a66aadSAntti Julku 			return b;
3322b9ee0a78SMarcel Holtmann 	}
3323b2a66aadSAntti Julku 
3324b2a66aadSAntti Julku 	return NULL;
3325b2a66aadSAntti Julku }
3326b2a66aadSAntti Julku 
3327c9507490SMarcel Holtmann static void hci_blacklist_clear(struct hci_dev *hdev)
3328b2a66aadSAntti Julku {
3329b2a66aadSAntti Julku 	struct list_head *p, *n;
3330b2a66aadSAntti Julku 
3331b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
3332b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
3333b2a66aadSAntti Julku 
3334b2a66aadSAntti Julku 		list_del(p);
3335b2a66aadSAntti Julku 		kfree(b);
3336b2a66aadSAntti Julku 	}
3337b2a66aadSAntti Julku }
3338b2a66aadSAntti Julku 
333988c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3340b2a66aadSAntti Julku {
3341b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3342b2a66aadSAntti Julku 
3343b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3344b2a66aadSAntti Julku 		return -EBADF;
3345b2a66aadSAntti Julku 
3346b9ee0a78SMarcel Holtmann 	if (hci_blacklist_lookup(hdev, bdaddr, type))
33475e762444SAntti Julku 		return -EEXIST;
3348b2a66aadSAntti Julku 
3349b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
33505e762444SAntti Julku 	if (!entry)
33515e762444SAntti Julku 		return -ENOMEM;
3352b2a66aadSAntti Julku 
3353b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3354b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3355b2a66aadSAntti Julku 
3356b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
3357b2a66aadSAntti Julku 
335888c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
3359b2a66aadSAntti Julku }
3360b2a66aadSAntti Julku 
336188c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3362b2a66aadSAntti Julku {
3363b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3364b2a66aadSAntti Julku 
336535f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
336635f7498aSJohan Hedberg 		hci_blacklist_clear(hdev);
336735f7498aSJohan Hedberg 		return 0;
336835f7498aSJohan Hedberg 	}
3369b2a66aadSAntti Julku 
3370b9ee0a78SMarcel Holtmann 	entry = hci_blacklist_lookup(hdev, bdaddr, type);
33711ec918ceSSzymon Janc 	if (!entry)
33725e762444SAntti Julku 		return -ENOENT;
3373b2a66aadSAntti Julku 
3374b2a66aadSAntti Julku 	list_del(&entry->list);
3375b2a66aadSAntti Julku 	kfree(entry);
3376b2a66aadSAntti Julku 
337788c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
3378b2a66aadSAntti Julku }
3379b2a66aadSAntti Julku 
3380d2ab0ac1SMarcel Holtmann struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev,
3381d2ab0ac1SMarcel Holtmann 					  bdaddr_t *bdaddr, u8 type)
3382d2ab0ac1SMarcel Holtmann {
3383d2ab0ac1SMarcel Holtmann 	struct bdaddr_list *b;
3384d2ab0ac1SMarcel Holtmann 
3385d2ab0ac1SMarcel Holtmann 	list_for_each_entry(b, &hdev->le_white_list, list) {
3386d2ab0ac1SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3387d2ab0ac1SMarcel Holtmann 			return b;
3388d2ab0ac1SMarcel Holtmann 	}
3389d2ab0ac1SMarcel Holtmann 
3390d2ab0ac1SMarcel Holtmann 	return NULL;
3391d2ab0ac1SMarcel Holtmann }
3392d2ab0ac1SMarcel Holtmann 
3393d2ab0ac1SMarcel Holtmann void hci_white_list_clear(struct hci_dev *hdev)
3394d2ab0ac1SMarcel Holtmann {
3395d2ab0ac1SMarcel Holtmann 	struct list_head *p, *n;
3396d2ab0ac1SMarcel Holtmann 
3397d2ab0ac1SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->le_white_list) {
3398d2ab0ac1SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
3399d2ab0ac1SMarcel Holtmann 
3400d2ab0ac1SMarcel Holtmann 		list_del(p);
3401d2ab0ac1SMarcel Holtmann 		kfree(b);
3402d2ab0ac1SMarcel Holtmann 	}
3403d2ab0ac1SMarcel Holtmann }
3404d2ab0ac1SMarcel Holtmann 
3405d2ab0ac1SMarcel Holtmann int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3406d2ab0ac1SMarcel Holtmann {
3407d2ab0ac1SMarcel Holtmann 	struct bdaddr_list *entry;
3408d2ab0ac1SMarcel Holtmann 
3409d2ab0ac1SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3410d2ab0ac1SMarcel Holtmann 		return -EBADF;
3411d2ab0ac1SMarcel Holtmann 
3412d2ab0ac1SMarcel Holtmann 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
3413d2ab0ac1SMarcel Holtmann 	if (!entry)
3414d2ab0ac1SMarcel Holtmann 		return -ENOMEM;
3415d2ab0ac1SMarcel Holtmann 
3416d2ab0ac1SMarcel Holtmann 	bacpy(&entry->bdaddr, bdaddr);
3417d2ab0ac1SMarcel Holtmann 	entry->bdaddr_type = type;
3418d2ab0ac1SMarcel Holtmann 
3419d2ab0ac1SMarcel Holtmann 	list_add(&entry->list, &hdev->le_white_list);
3420d2ab0ac1SMarcel Holtmann 
3421d2ab0ac1SMarcel Holtmann 	return 0;
3422d2ab0ac1SMarcel Holtmann }
3423d2ab0ac1SMarcel Holtmann 
3424d2ab0ac1SMarcel Holtmann int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3425d2ab0ac1SMarcel Holtmann {
3426d2ab0ac1SMarcel Holtmann 	struct bdaddr_list *entry;
3427d2ab0ac1SMarcel Holtmann 
3428d2ab0ac1SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3429d2ab0ac1SMarcel Holtmann 		return -EBADF;
3430d2ab0ac1SMarcel Holtmann 
3431d2ab0ac1SMarcel Holtmann 	entry = hci_white_list_lookup(hdev, bdaddr, type);
3432d2ab0ac1SMarcel Holtmann 	if (!entry)
3433d2ab0ac1SMarcel Holtmann 		return -ENOENT;
3434d2ab0ac1SMarcel Holtmann 
3435d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
3436d2ab0ac1SMarcel Holtmann 	kfree(entry);
3437d2ab0ac1SMarcel Holtmann 
3438d2ab0ac1SMarcel Holtmann 	return 0;
3439d2ab0ac1SMarcel Holtmann }
3440d2ab0ac1SMarcel Holtmann 
344115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
344215819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
344315819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
344415819a70SAndre Guedes {
344515819a70SAndre Guedes 	struct hci_conn_params *params;
344615819a70SAndre Guedes 
344715819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
344815819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
344915819a70SAndre Guedes 		    params->addr_type == addr_type) {
345015819a70SAndre Guedes 			return params;
345115819a70SAndre Guedes 		}
345215819a70SAndre Guedes 	}
345315819a70SAndre Guedes 
345415819a70SAndre Guedes 	return NULL;
345515819a70SAndre Guedes }
345615819a70SAndre Guedes 
3457cef952ceSAndre Guedes static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
3458cef952ceSAndre Guedes {
3459cef952ceSAndre Guedes 	struct hci_conn *conn;
3460cef952ceSAndre Guedes 
3461cef952ceSAndre Guedes 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr);
3462cef952ceSAndre Guedes 	if (!conn)
3463cef952ceSAndre Guedes 		return false;
3464cef952ceSAndre Guedes 
3465cef952ceSAndre Guedes 	if (conn->dst_type != type)
3466cef952ceSAndre Guedes 		return false;
3467cef952ceSAndre Guedes 
3468cef952ceSAndre Guedes 	if (conn->state != BT_CONNECTED)
3469cef952ceSAndre Guedes 		return false;
3470cef952ceSAndre Guedes 
3471cef952ceSAndre Guedes 	return true;
3472cef952ceSAndre Guedes }
3473cef952ceSAndre Guedes 
3474a9b0a04cSAndre Guedes static bool is_identity_address(bdaddr_t *addr, u8 addr_type)
3475a9b0a04cSAndre Guedes {
3476a9b0a04cSAndre Guedes 	if (addr_type == ADDR_LE_DEV_PUBLIC)
3477a9b0a04cSAndre Guedes 		return true;
3478a9b0a04cSAndre Guedes 
3479a9b0a04cSAndre Guedes 	/* Check for Random Static address type */
3480a9b0a04cSAndre Guedes 	if ((addr->b[5] & 0xc0) == 0xc0)
3481a9b0a04cSAndre Guedes 		return true;
3482a9b0a04cSAndre Guedes 
3483a9b0a04cSAndre Guedes 	return false;
3484a9b0a04cSAndre Guedes }
3485a9b0a04cSAndre Guedes 
348615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
3487a9b0a04cSAndre Guedes int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
34889fcb18efSAndre Guedes 			u8 auto_connect, u16 conn_min_interval,
34899fcb18efSAndre Guedes 			u16 conn_max_interval)
349015819a70SAndre Guedes {
349115819a70SAndre Guedes 	struct hci_conn_params *params;
349215819a70SAndre Guedes 
3493a9b0a04cSAndre Guedes 	if (!is_identity_address(addr, addr_type))
3494a9b0a04cSAndre Guedes 		return -EINVAL;
3495a9b0a04cSAndre Guedes 
349615819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
3497cef952ceSAndre Guedes 	if (params)
3498cef952ceSAndre Guedes 		goto update;
349915819a70SAndre Guedes 
350015819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
350115819a70SAndre Guedes 	if (!params) {
350215819a70SAndre Guedes 		BT_ERR("Out of memory");
3503a9b0a04cSAndre Guedes 		return -ENOMEM;
350415819a70SAndre Guedes 	}
350515819a70SAndre Guedes 
350615819a70SAndre Guedes 	bacpy(&params->addr, addr);
350715819a70SAndre Guedes 	params->addr_type = addr_type;
3508cef952ceSAndre Guedes 
3509cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
3510cef952ceSAndre Guedes 
3511cef952ceSAndre Guedes update:
351215819a70SAndre Guedes 	params->conn_min_interval = conn_min_interval;
351315819a70SAndre Guedes 	params->conn_max_interval = conn_max_interval;
35149fcb18efSAndre Guedes 	params->auto_connect = auto_connect;
351515819a70SAndre Guedes 
3516cef952ceSAndre Guedes 	switch (auto_connect) {
3517cef952ceSAndre Guedes 	case HCI_AUTO_CONN_DISABLED:
3518cef952ceSAndre Guedes 	case HCI_AUTO_CONN_LINK_LOSS:
3519cef952ceSAndre Guedes 		hci_pend_le_conn_del(hdev, addr, addr_type);
3520cef952ceSAndre Guedes 		break;
3521cef952ceSAndre Guedes 	case HCI_AUTO_CONN_ALWAYS:
3522cef952ceSAndre Guedes 		if (!is_connected(hdev, addr, addr_type))
3523cef952ceSAndre Guedes 			hci_pend_le_conn_add(hdev, addr, addr_type);
3524cef952ceSAndre Guedes 		break;
3525cef952ceSAndre Guedes 	}
352615819a70SAndre Guedes 
35279fcb18efSAndre Guedes 	BT_DBG("addr %pMR (type %u) auto_connect %u conn_min_interval 0x%.4x "
35289fcb18efSAndre Guedes 	       "conn_max_interval 0x%.4x", addr, addr_type, auto_connect,
35299fcb18efSAndre Guedes 	       conn_min_interval, conn_max_interval);
3530a9b0a04cSAndre Guedes 
3531a9b0a04cSAndre Guedes 	return 0;
353215819a70SAndre Guedes }
353315819a70SAndre Guedes 
353415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
353515819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
353615819a70SAndre Guedes {
353715819a70SAndre Guedes 	struct hci_conn_params *params;
353815819a70SAndre Guedes 
353915819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
354015819a70SAndre Guedes 	if (!params)
354115819a70SAndre Guedes 		return;
354215819a70SAndre Guedes 
3543cef952ceSAndre Guedes 	hci_pend_le_conn_del(hdev, addr, addr_type);
3544cef952ceSAndre Guedes 
354515819a70SAndre Guedes 	list_del(&params->list);
354615819a70SAndre Guedes 	kfree(params);
354715819a70SAndre Guedes 
354815819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
354915819a70SAndre Guedes }
355015819a70SAndre Guedes 
355115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
355215819a70SAndre Guedes void hci_conn_params_clear(struct hci_dev *hdev)
355315819a70SAndre Guedes {
355415819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
355515819a70SAndre Guedes 
355615819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
355715819a70SAndre Guedes 		list_del(&params->list);
355815819a70SAndre Guedes 		kfree(params);
355915819a70SAndre Guedes 	}
356015819a70SAndre Guedes 
356115819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
356215819a70SAndre Guedes }
356315819a70SAndre Guedes 
356477a77a30SAndre Guedes /* This function requires the caller holds hdev->lock */
356577a77a30SAndre Guedes struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
356677a77a30SAndre Guedes 					    bdaddr_t *addr, u8 addr_type)
356777a77a30SAndre Guedes {
356877a77a30SAndre Guedes 	struct bdaddr_list *entry;
356977a77a30SAndre Guedes 
357077a77a30SAndre Guedes 	list_for_each_entry(entry, &hdev->pend_le_conns, list) {
357177a77a30SAndre Guedes 		if (bacmp(&entry->bdaddr, addr) == 0 &&
357277a77a30SAndre Guedes 		    entry->bdaddr_type == addr_type)
357377a77a30SAndre Guedes 			return entry;
357477a77a30SAndre Guedes 	}
357577a77a30SAndre Guedes 
357677a77a30SAndre Guedes 	return NULL;
357777a77a30SAndre Guedes }
357877a77a30SAndre Guedes 
357977a77a30SAndre Guedes /* This function requires the caller holds hdev->lock */
358077a77a30SAndre Guedes void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
358177a77a30SAndre Guedes {
358277a77a30SAndre Guedes 	struct bdaddr_list *entry;
358377a77a30SAndre Guedes 
358477a77a30SAndre Guedes 	entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
358577a77a30SAndre Guedes 	if (entry)
3586a4790dbdSAndre Guedes 		goto done;
358777a77a30SAndre Guedes 
358877a77a30SAndre Guedes 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
358977a77a30SAndre Guedes 	if (!entry) {
359077a77a30SAndre Guedes 		BT_ERR("Out of memory");
359177a77a30SAndre Guedes 		return;
359277a77a30SAndre Guedes 	}
359377a77a30SAndre Guedes 
359477a77a30SAndre Guedes 	bacpy(&entry->bdaddr, addr);
359577a77a30SAndre Guedes 	entry->bdaddr_type = addr_type;
359677a77a30SAndre Guedes 
359777a77a30SAndre Guedes 	list_add(&entry->list, &hdev->pend_le_conns);
359877a77a30SAndre Guedes 
359977a77a30SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
3600a4790dbdSAndre Guedes 
3601a4790dbdSAndre Guedes done:
3602a4790dbdSAndre Guedes 	hci_update_background_scan(hdev);
360377a77a30SAndre Guedes }
360477a77a30SAndre Guedes 
360577a77a30SAndre Guedes /* This function requires the caller holds hdev->lock */
360677a77a30SAndre Guedes void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
360777a77a30SAndre Guedes {
360877a77a30SAndre Guedes 	struct bdaddr_list *entry;
360977a77a30SAndre Guedes 
361077a77a30SAndre Guedes 	entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
361177a77a30SAndre Guedes 	if (!entry)
3612a4790dbdSAndre Guedes 		goto done;
361377a77a30SAndre Guedes 
361477a77a30SAndre Guedes 	list_del(&entry->list);
361577a77a30SAndre Guedes 	kfree(entry);
361677a77a30SAndre Guedes 
361777a77a30SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
3618a4790dbdSAndre Guedes 
3619a4790dbdSAndre Guedes done:
3620a4790dbdSAndre Guedes 	hci_update_background_scan(hdev);
362177a77a30SAndre Guedes }
362277a77a30SAndre Guedes 
362377a77a30SAndre Guedes /* This function requires the caller holds hdev->lock */
362477a77a30SAndre Guedes void hci_pend_le_conns_clear(struct hci_dev *hdev)
362577a77a30SAndre Guedes {
362677a77a30SAndre Guedes 	struct bdaddr_list *entry, *tmp;
362777a77a30SAndre Guedes 
362877a77a30SAndre Guedes 	list_for_each_entry_safe(entry, tmp, &hdev->pend_le_conns, list) {
362977a77a30SAndre Guedes 		list_del(&entry->list);
363077a77a30SAndre Guedes 		kfree(entry);
363177a77a30SAndre Guedes 	}
363277a77a30SAndre Guedes 
363377a77a30SAndre Guedes 	BT_DBG("All LE pending connections cleared");
363477a77a30SAndre Guedes }
363577a77a30SAndre Guedes 
36364c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
36377ba8b4beSAndre Guedes {
36384c87eaabSAndre Guedes 	if (status) {
36394c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
36407ba8b4beSAndre Guedes 
36414c87eaabSAndre Guedes 		hci_dev_lock(hdev);
36424c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
36434c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
36444c87eaabSAndre Guedes 		return;
36454c87eaabSAndre Guedes 	}
36467ba8b4beSAndre Guedes }
36477ba8b4beSAndre Guedes 
36484c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
36497ba8b4beSAndre Guedes {
36504c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
36514c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
36524c87eaabSAndre Guedes 	struct hci_request req;
36534c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
36547ba8b4beSAndre Guedes 	int err;
36557ba8b4beSAndre Guedes 
36564c87eaabSAndre Guedes 	if (status) {
36574c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
36584c87eaabSAndre Guedes 		return;
36597ba8b4beSAndre Guedes 	}
36607ba8b4beSAndre Guedes 
36614c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
36624c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
36634c87eaabSAndre Guedes 		hci_dev_lock(hdev);
36644c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
36654c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
36664c87eaabSAndre Guedes 		break;
36677dbfac1dSAndre Guedes 
36684c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
36694c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
36707dbfac1dSAndre Guedes 
36717dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
36724c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
36734c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
36744c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
36754c87eaabSAndre Guedes 
36764c87eaabSAndre Guedes 		hci_dev_lock(hdev);
36774c87eaabSAndre Guedes 
36784c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
36794c87eaabSAndre Guedes 
36804c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
36814c87eaabSAndre Guedes 		if (err) {
36824c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
36834c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
36847dbfac1dSAndre Guedes 		}
36857dbfac1dSAndre Guedes 
36864c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
36874c87eaabSAndre Guedes 		break;
36884c87eaabSAndre Guedes 	}
36897dbfac1dSAndre Guedes }
36907dbfac1dSAndre Guedes 
36917ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
36927ba8b4beSAndre Guedes {
36937ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
36947ba8b4beSAndre Guedes 					    le_scan_disable.work);
36954c87eaabSAndre Guedes 	struct hci_request req;
36964c87eaabSAndre Guedes 	int err;
36977ba8b4beSAndre Guedes 
36987ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
36997ba8b4beSAndre Guedes 
37004c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
37017ba8b4beSAndre Guedes 
3702b1efcc28SAndre Guedes 	hci_req_add_le_scan_disable(&req);
37037ba8b4beSAndre Guedes 
37044c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
37054c87eaabSAndre Guedes 	if (err)
37064c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
370728b75a89SAndre Guedes }
370828b75a89SAndre Guedes 
37098d97250eSJohan Hedberg static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
37108d97250eSJohan Hedberg {
37118d97250eSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
37128d97250eSJohan Hedberg 
37138d97250eSJohan Hedberg 	/* If we're advertising or initiating an LE connection we can't
37148d97250eSJohan Hedberg 	 * go ahead and change the random address at this time. This is
37158d97250eSJohan Hedberg 	 * because the eventual initiator address used for the
37168d97250eSJohan Hedberg 	 * subsequently created connection will be undefined (some
37178d97250eSJohan Hedberg 	 * controllers use the new address and others the one we had
37188d97250eSJohan Hedberg 	 * when the operation started).
37198d97250eSJohan Hedberg 	 *
37208d97250eSJohan Hedberg 	 * In this kind of scenario skip the update and let the random
37218d97250eSJohan Hedberg 	 * address be updated at the next cycle.
37228d97250eSJohan Hedberg 	 */
37238d97250eSJohan Hedberg 	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) ||
37248d97250eSJohan Hedberg 	    hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
37258d97250eSJohan Hedberg 		BT_DBG("Deferring random address update");
37268d97250eSJohan Hedberg 		return;
37278d97250eSJohan Hedberg 	}
37288d97250eSJohan Hedberg 
37298d97250eSJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa);
37308d97250eSJohan Hedberg }
37318d97250eSJohan Hedberg 
373294b1fc92SMarcel Holtmann int hci_update_random_address(struct hci_request *req, bool require_privacy,
373394b1fc92SMarcel Holtmann 			      u8 *own_addr_type)
3734ebd3a747SJohan Hedberg {
3735ebd3a747SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
3736ebd3a747SJohan Hedberg 	int err;
3737ebd3a747SJohan Hedberg 
3738ebd3a747SJohan Hedberg 	/* If privacy is enabled use a resolvable private address. If
37392b5224dcSMarcel Holtmann 	 * current RPA has expired or there is something else than
37402b5224dcSMarcel Holtmann 	 * the current RPA in use, then generate a new one.
3741ebd3a747SJohan Hedberg 	 */
3742ebd3a747SJohan Hedberg 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3743ebd3a747SJohan Hedberg 		int to;
3744ebd3a747SJohan Hedberg 
3745ebd3a747SJohan Hedberg 		*own_addr_type = ADDR_LE_DEV_RANDOM;
3746ebd3a747SJohan Hedberg 
3747ebd3a747SJohan Hedberg 		if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) &&
37482b5224dcSMarcel Holtmann 		    !bacmp(&hdev->random_addr, &hdev->rpa))
3749ebd3a747SJohan Hedberg 			return 0;
3750ebd3a747SJohan Hedberg 
37512b5224dcSMarcel Holtmann 		err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa);
3752ebd3a747SJohan Hedberg 		if (err < 0) {
3753ebd3a747SJohan Hedberg 			BT_ERR("%s failed to generate new RPA", hdev->name);
3754ebd3a747SJohan Hedberg 			return err;
3755ebd3a747SJohan Hedberg 		}
3756ebd3a747SJohan Hedberg 
37578d97250eSJohan Hedberg 		set_random_addr(req, &hdev->rpa);
3758ebd3a747SJohan Hedberg 
3759ebd3a747SJohan Hedberg 		to = msecs_to_jiffies(hdev->rpa_timeout * 1000);
3760ebd3a747SJohan Hedberg 		queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to);
3761ebd3a747SJohan Hedberg 
3762ebd3a747SJohan Hedberg 		return 0;
3763ebd3a747SJohan Hedberg 	}
3764ebd3a747SJohan Hedberg 
376594b1fc92SMarcel Holtmann 	/* In case of required privacy without resolvable private address,
376694b1fc92SMarcel Holtmann 	 * use an unresolvable private address. This is useful for active
376794b1fc92SMarcel Holtmann 	 * scanning and non-connectable advertising.
376894b1fc92SMarcel Holtmann 	 */
376994b1fc92SMarcel Holtmann 	if (require_privacy) {
377094b1fc92SMarcel Holtmann 		bdaddr_t urpa;
377194b1fc92SMarcel Holtmann 
377294b1fc92SMarcel Holtmann 		get_random_bytes(&urpa, 6);
377394b1fc92SMarcel Holtmann 		urpa.b[5] &= 0x3f;	/* Clear two most significant bits */
377494b1fc92SMarcel Holtmann 
377594b1fc92SMarcel Holtmann 		*own_addr_type = ADDR_LE_DEV_RANDOM;
37768d97250eSJohan Hedberg 		set_random_addr(req, &urpa);
377794b1fc92SMarcel Holtmann 		return 0;
377894b1fc92SMarcel Holtmann 	}
377994b1fc92SMarcel Holtmann 
3780ebd3a747SJohan Hedberg 	/* If forcing static address is in use or there is no public
3781ebd3a747SJohan Hedberg 	 * address use the static address as random address (but skip
3782ebd3a747SJohan Hedberg 	 * the HCI command if the current random address is already the
3783ebd3a747SJohan Hedberg 	 * static one.
3784ebd3a747SJohan Hedberg 	 */
3785111902f7SMarcel Holtmann 	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
3786ebd3a747SJohan Hedberg 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3787ebd3a747SJohan Hedberg 		*own_addr_type = ADDR_LE_DEV_RANDOM;
3788ebd3a747SJohan Hedberg 		if (bacmp(&hdev->static_addr, &hdev->random_addr))
3789ebd3a747SJohan Hedberg 			hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6,
3790ebd3a747SJohan Hedberg 				    &hdev->static_addr);
3791ebd3a747SJohan Hedberg 		return 0;
3792ebd3a747SJohan Hedberg 	}
3793ebd3a747SJohan Hedberg 
3794ebd3a747SJohan Hedberg 	/* Neither privacy nor static address is being used so use a
3795ebd3a747SJohan Hedberg 	 * public address.
3796ebd3a747SJohan Hedberg 	 */
3797ebd3a747SJohan Hedberg 	*own_addr_type = ADDR_LE_DEV_PUBLIC;
3798ebd3a747SJohan Hedberg 
3799ebd3a747SJohan Hedberg 	return 0;
3800ebd3a747SJohan Hedberg }
3801ebd3a747SJohan Hedberg 
3802a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
3803a1f4c318SJohan Hedberg  *
3804a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
3805a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
3806a1f4c318SJohan Hedberg  * the static random address.
3807a1f4c318SJohan Hedberg  *
3808a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
3809a1f4c318SJohan Hedberg  * public address to use the static random address instead.
3810a1f4c318SJohan Hedberg  */
3811a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3812a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
3813a1f4c318SJohan Hedberg {
3814111902f7SMarcel Holtmann 	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
3815a1f4c318SJohan Hedberg 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3816a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
3817a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
3818a1f4c318SJohan Hedberg 	} else {
3819a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
3820a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
3821a1f4c318SJohan Hedberg 	}
3822a1f4c318SJohan Hedberg }
3823a1f4c318SJohan Hedberg 
38249be0dab7SDavid Herrmann /* Alloc HCI device */
38259be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
38269be0dab7SDavid Herrmann {
38279be0dab7SDavid Herrmann 	struct hci_dev *hdev;
38289be0dab7SDavid Herrmann 
38299be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
38309be0dab7SDavid Herrmann 	if (!hdev)
38319be0dab7SDavid Herrmann 		return NULL;
38329be0dab7SDavid Herrmann 
3833b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3834b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3835b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3836b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3837b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
3838bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3839bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3840b1b813d4SDavid Herrmann 
3841b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3842b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3843b1b813d4SDavid Herrmann 
38443f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3845bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3846bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
38474e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
38484e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
3849bef64738SMarcel Holtmann 
3850d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3851b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
385231ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
385331ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
3854d6bfd59cSJohan Hedberg 
3855b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3856b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3857b1b813d4SDavid Herrmann 
3858b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3859b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
3860b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3861b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3862b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3863970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3864b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
3865d2ab0ac1SMarcel Holtmann 	INIT_LIST_HEAD(&hdev->le_white_list);
386615819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
386777a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
38686b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3869b1b813d4SDavid Herrmann 
3870b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3871b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3872b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3873b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3874b1b813d4SDavid Herrmann 
3875b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3876b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
3877b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
3878b1b813d4SDavid Herrmann 
3879b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3880b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3881b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3882b1b813d4SDavid Herrmann 
3883b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
3884b1b813d4SDavid Herrmann 
388565cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
3886b1b813d4SDavid Herrmann 
3887b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3888b1b813d4SDavid Herrmann 	discovery_init(hdev);
38899be0dab7SDavid Herrmann 
38909be0dab7SDavid Herrmann 	return hdev;
38919be0dab7SDavid Herrmann }
38929be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
38939be0dab7SDavid Herrmann 
38949be0dab7SDavid Herrmann /* Free HCI device */
38959be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
38969be0dab7SDavid Herrmann {
38979be0dab7SDavid Herrmann 	/* will free via device release */
38989be0dab7SDavid Herrmann 	put_device(&hdev->dev);
38999be0dab7SDavid Herrmann }
39009be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
39019be0dab7SDavid Herrmann 
39021da177e4SLinus Torvalds /* Register HCI device */
39031da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
39041da177e4SLinus Torvalds {
3905b1b813d4SDavid Herrmann 	int id, error;
39061da177e4SLinus Torvalds 
3907010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
39081da177e4SLinus Torvalds 		return -EINVAL;
39091da177e4SLinus Torvalds 
391008add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
391108add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
391208add513SMat Martineau 	 */
39133df92b31SSasha Levin 	switch (hdev->dev_type) {
39143df92b31SSasha Levin 	case HCI_BREDR:
39153df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
39161da177e4SLinus Torvalds 		break;
39173df92b31SSasha Levin 	case HCI_AMP:
39183df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
39193df92b31SSasha Levin 		break;
39203df92b31SSasha Levin 	default:
39213df92b31SSasha Levin 		return -EINVAL;
39221da177e4SLinus Torvalds 	}
39231da177e4SLinus Torvalds 
39243df92b31SSasha Levin 	if (id < 0)
39253df92b31SSasha Levin 		return id;
39263df92b31SSasha Levin 
39271da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
39281da177e4SLinus Torvalds 	hdev->id = id;
39292d8b3a11SAndrei Emeltchenko 
39302d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
39312d8b3a11SAndrei Emeltchenko 
3932d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3933d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
393433ca954dSDavid Herrmann 	if (!hdev->workqueue) {
393533ca954dSDavid Herrmann 		error = -ENOMEM;
393633ca954dSDavid Herrmann 		goto err;
393733ca954dSDavid Herrmann 	}
3938f48fd9c8SMarcel Holtmann 
3939d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3940d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
39416ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
39426ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
39436ead1bbcSJohan Hedberg 		error = -ENOMEM;
39446ead1bbcSJohan Hedberg 		goto err;
39456ead1bbcSJohan Hedberg 	}
39466ead1bbcSJohan Hedberg 
39470153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
39480153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
39490153e2ecSMarcel Holtmann 
3950bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3951bdc3e0f1SMarcel Holtmann 
395299780a7bSJohan Hedberg 	hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0,
395399780a7bSJohan Hedberg 					       CRYPTO_ALG_ASYNC);
395499780a7bSJohan Hedberg 	if (IS_ERR(hdev->tfm_aes)) {
395599780a7bSJohan Hedberg 		BT_ERR("Unable to create crypto context");
395699780a7bSJohan Hedberg 		error = PTR_ERR(hdev->tfm_aes);
395799780a7bSJohan Hedberg 		hdev->tfm_aes = NULL;
395899780a7bSJohan Hedberg 		goto err_wqueue;
395999780a7bSJohan Hedberg 	}
396099780a7bSJohan Hedberg 
3961bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
396233ca954dSDavid Herrmann 	if (error < 0)
396399780a7bSJohan Hedberg 		goto err_tfm;
39641da177e4SLinus Torvalds 
3965611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3966a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3967a8c5fb1aSGustavo Padovan 				    hdev);
3968611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3969611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3970611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3971611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3972611b30f7SMarcel Holtmann 		}
3973611b30f7SMarcel Holtmann 	}
3974611b30f7SMarcel Holtmann 
39755e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
39765e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
39775e130367SJohan Hedberg 
3978a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
3979004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
3980ce2be9acSAndrei Emeltchenko 
398101cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
398256f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
398356f87901SJohan Hedberg 		 * through reading supported features during init.
398456f87901SJohan Hedberg 		 */
398556f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
398656f87901SJohan Hedberg 	}
3987ce2be9acSAndrei Emeltchenko 
3988fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3989fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3990fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3991fcee3377SGustavo Padovan 
39921da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
3993dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
39941da177e4SLinus Torvalds 
399519202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3996fbe96d6fSMarcel Holtmann 
39971da177e4SLinus Torvalds 	return id;
3998f48fd9c8SMarcel Holtmann 
399999780a7bSJohan Hedberg err_tfm:
400099780a7bSJohan Hedberg 	crypto_free_blkcipher(hdev->tfm_aes);
400133ca954dSDavid Herrmann err_wqueue:
400233ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
40036ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
400433ca954dSDavid Herrmann err:
40053df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
4006f48fd9c8SMarcel Holtmann 
400733ca954dSDavid Herrmann 	return error;
40081da177e4SLinus Torvalds }
40091da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
40101da177e4SLinus Torvalds 
40111da177e4SLinus Torvalds /* Unregister HCI device */
401259735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
40131da177e4SLinus Torvalds {
40143df92b31SSasha Levin 	int i, id;
4015ef222013SMarcel Holtmann 
4016c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
40171da177e4SLinus Torvalds 
401894324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
401994324962SJohan Hovold 
40203df92b31SSasha Levin 	id = hdev->id;
40213df92b31SSasha Levin 
4022f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
40231da177e4SLinus Torvalds 	list_del(&hdev->list);
4024f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
40251da177e4SLinus Torvalds 
40261da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
40271da177e4SLinus Torvalds 
4028cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
4029ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
4030ef222013SMarcel Holtmann 
4031b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
4032b9b5ef18SGustavo Padovan 
4033ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
4034a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
403509fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
4036744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
403709fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
403856e5cb86SJohan Hedberg 	}
4039ab81cbf9SJohan Hedberg 
40402e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
40412e58ef3eSJohan Hedberg 	 * pending list */
40422e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
40432e58ef3eSJohan Hedberg 
40441da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
40451da177e4SLinus Torvalds 
4046611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
4047611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
4048611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
4049611b30f7SMarcel Holtmann 	}
4050611b30f7SMarcel Holtmann 
405199780a7bSJohan Hedberg 	if (hdev->tfm_aes)
405299780a7bSJohan Hedberg 		crypto_free_blkcipher(hdev->tfm_aes);
405399780a7bSJohan Hedberg 
4054bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
4055147e2d59SDave Young 
40560153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
40570153e2ecSMarcel Holtmann 
4058f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
40596ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
4060f48fd9c8SMarcel Holtmann 
406109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4062e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
40632aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
406455ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
4065b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
4066970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
40672763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
4068d2ab0ac1SMarcel Holtmann 	hci_white_list_clear(hdev);
406915819a70SAndre Guedes 	hci_conn_params_clear(hdev);
407077a77a30SAndre Guedes 	hci_pend_le_conns_clear(hdev);
407109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4072e2e0cacbSJohan Hedberg 
4073dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
40743df92b31SSasha Levin 
40753df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
40761da177e4SLinus Torvalds }
40771da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
40781da177e4SLinus Torvalds 
40791da177e4SLinus Torvalds /* Suspend HCI device */
40801da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
40811da177e4SLinus Torvalds {
40821da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
40831da177e4SLinus Torvalds 	return 0;
40841da177e4SLinus Torvalds }
40851da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
40861da177e4SLinus Torvalds 
40871da177e4SLinus Torvalds /* Resume HCI device */
40881da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
40891da177e4SLinus Torvalds {
40901da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
40911da177e4SLinus Torvalds 	return 0;
40921da177e4SLinus Torvalds }
40931da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
40941da177e4SLinus Torvalds 
409576bca880SMarcel Holtmann /* Receive frame from HCI drivers */
4096e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
409776bca880SMarcel Holtmann {
409876bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
409976bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
410076bca880SMarcel Holtmann 		kfree_skb(skb);
410176bca880SMarcel Holtmann 		return -ENXIO;
410276bca880SMarcel Holtmann 	}
410376bca880SMarcel Holtmann 
4104d82603c6SJorrit Schippers 	/* Incoming skb */
410576bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
410676bca880SMarcel Holtmann 
410776bca880SMarcel Holtmann 	/* Time stamp */
410876bca880SMarcel Holtmann 	__net_timestamp(skb);
410976bca880SMarcel Holtmann 
411076bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
4111b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
4112c78ae283SMarcel Holtmann 
411376bca880SMarcel Holtmann 	return 0;
411476bca880SMarcel Holtmann }
411576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
411676bca880SMarcel Holtmann 
411733e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
41181e429f38SGustavo F. Padovan 			  int count, __u8 index)
411933e882a5SSuraj Sumangala {
412033e882a5SSuraj Sumangala 	int len = 0;
412133e882a5SSuraj Sumangala 	int hlen = 0;
412233e882a5SSuraj Sumangala 	int remain = count;
412333e882a5SSuraj Sumangala 	struct sk_buff *skb;
412433e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
412533e882a5SSuraj Sumangala 
412633e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
412733e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
412833e882a5SSuraj Sumangala 		return -EILSEQ;
412933e882a5SSuraj Sumangala 
413033e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
413133e882a5SSuraj Sumangala 
413233e882a5SSuraj Sumangala 	if (!skb) {
413333e882a5SSuraj Sumangala 		switch (type) {
413433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
413533e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
413633e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
413733e882a5SSuraj Sumangala 			break;
413833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
413933e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
414033e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
414133e882a5SSuraj Sumangala 			break;
414233e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
414333e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
414433e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
414533e882a5SSuraj Sumangala 			break;
414633e882a5SSuraj Sumangala 		}
414733e882a5SSuraj Sumangala 
41481e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
414933e882a5SSuraj Sumangala 		if (!skb)
415033e882a5SSuraj Sumangala 			return -ENOMEM;
415133e882a5SSuraj Sumangala 
415233e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
415333e882a5SSuraj Sumangala 		scb->expect = hlen;
415433e882a5SSuraj Sumangala 		scb->pkt_type = type;
415533e882a5SSuraj Sumangala 
415633e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
415733e882a5SSuraj Sumangala 	}
415833e882a5SSuraj Sumangala 
415933e882a5SSuraj Sumangala 	while (count) {
416033e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
416189bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
416233e882a5SSuraj Sumangala 
416333e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
416433e882a5SSuraj Sumangala 
416533e882a5SSuraj Sumangala 		count -= len;
416633e882a5SSuraj Sumangala 		data += len;
416733e882a5SSuraj Sumangala 		scb->expect -= len;
416833e882a5SSuraj Sumangala 		remain = count;
416933e882a5SSuraj Sumangala 
417033e882a5SSuraj Sumangala 		switch (type) {
417133e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
417233e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
417333e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
417433e882a5SSuraj Sumangala 				scb->expect = h->plen;
417533e882a5SSuraj Sumangala 
417633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
417733e882a5SSuraj Sumangala 					kfree_skb(skb);
417833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
417933e882a5SSuraj Sumangala 					return -ENOMEM;
418033e882a5SSuraj Sumangala 				}
418133e882a5SSuraj Sumangala 			}
418233e882a5SSuraj Sumangala 			break;
418333e882a5SSuraj Sumangala 
418433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
418533e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
418633e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
418733e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
418833e882a5SSuraj Sumangala 
418933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
419033e882a5SSuraj Sumangala 					kfree_skb(skb);
419133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
419233e882a5SSuraj Sumangala 					return -ENOMEM;
419333e882a5SSuraj Sumangala 				}
419433e882a5SSuraj Sumangala 			}
419533e882a5SSuraj Sumangala 			break;
419633e882a5SSuraj Sumangala 
419733e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
419833e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
419933e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
420033e882a5SSuraj Sumangala 				scb->expect = h->dlen;
420133e882a5SSuraj Sumangala 
420233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
420333e882a5SSuraj Sumangala 					kfree_skb(skb);
420433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
420533e882a5SSuraj Sumangala 					return -ENOMEM;
420633e882a5SSuraj Sumangala 				}
420733e882a5SSuraj Sumangala 			}
420833e882a5SSuraj Sumangala 			break;
420933e882a5SSuraj Sumangala 		}
421033e882a5SSuraj Sumangala 
421133e882a5SSuraj Sumangala 		if (scb->expect == 0) {
421233e882a5SSuraj Sumangala 			/* Complete frame */
421333e882a5SSuraj Sumangala 
421433e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
4215e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
421633e882a5SSuraj Sumangala 
421733e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
421833e882a5SSuraj Sumangala 			return remain;
421933e882a5SSuraj Sumangala 		}
422033e882a5SSuraj Sumangala 	}
422133e882a5SSuraj Sumangala 
422233e882a5SSuraj Sumangala 	return remain;
422333e882a5SSuraj Sumangala }
422433e882a5SSuraj Sumangala 
4225ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
4226ef222013SMarcel Holtmann {
4227f39a3c06SSuraj Sumangala 	int rem = 0;
4228f39a3c06SSuraj Sumangala 
4229ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
4230ef222013SMarcel Holtmann 		return -EILSEQ;
4231ef222013SMarcel Holtmann 
4232da5f6c37SGustavo F. Padovan 	while (count) {
42331e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
4234f39a3c06SSuraj Sumangala 		if (rem < 0)
4235f39a3c06SSuraj Sumangala 			return rem;
4236ef222013SMarcel Holtmann 
4237f39a3c06SSuraj Sumangala 		data += (count - rem);
4238f39a3c06SSuraj Sumangala 		count = rem;
4239f81c6224SJoe Perches 	}
4240ef222013SMarcel Holtmann 
4241f39a3c06SSuraj Sumangala 	return rem;
4242ef222013SMarcel Holtmann }
4243ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
4244ef222013SMarcel Holtmann 
424599811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
424699811510SSuraj Sumangala 
424799811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
424899811510SSuraj Sumangala {
424999811510SSuraj Sumangala 	int type;
425099811510SSuraj Sumangala 	int rem = 0;
425199811510SSuraj Sumangala 
4252da5f6c37SGustavo F. Padovan 	while (count) {
425399811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
425499811510SSuraj Sumangala 
425599811510SSuraj Sumangala 		if (!skb) {
425699811510SSuraj Sumangala 			struct { char type; } *pkt;
425799811510SSuraj Sumangala 
425899811510SSuraj Sumangala 			/* Start of the frame */
425999811510SSuraj Sumangala 			pkt = data;
426099811510SSuraj Sumangala 			type = pkt->type;
426199811510SSuraj Sumangala 
426299811510SSuraj Sumangala 			data++;
426399811510SSuraj Sumangala 			count--;
426499811510SSuraj Sumangala 		} else
426599811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
426699811510SSuraj Sumangala 
42671e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
42681e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
426999811510SSuraj Sumangala 		if (rem < 0)
427099811510SSuraj Sumangala 			return rem;
427199811510SSuraj Sumangala 
427299811510SSuraj Sumangala 		data += (count - rem);
427399811510SSuraj Sumangala 		count = rem;
4274f81c6224SJoe Perches 	}
427599811510SSuraj Sumangala 
427699811510SSuraj Sumangala 	return rem;
427799811510SSuraj Sumangala }
427899811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
427999811510SSuraj Sumangala 
42801da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
42811da177e4SLinus Torvalds 
42821da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
42831da177e4SLinus Torvalds {
42841da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
42851da177e4SLinus Torvalds 
4286f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
42871da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
4288f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
42891da177e4SLinus Torvalds 
42901da177e4SLinus Torvalds 	return 0;
42911da177e4SLinus Torvalds }
42921da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
42931da177e4SLinus Torvalds 
42941da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
42951da177e4SLinus Torvalds {
42961da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
42971da177e4SLinus Torvalds 
4298f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
42991da177e4SLinus Torvalds 	list_del(&cb->list);
4300f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
43011da177e4SLinus Torvalds 
43021da177e4SLinus Torvalds 	return 0;
43031da177e4SLinus Torvalds }
43041da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
43051da177e4SLinus Torvalds 
430651086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
43071da177e4SLinus Torvalds {
43080d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
43091da177e4SLinus Torvalds 
43101da177e4SLinus Torvalds 	/* Time stamp */
4311a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
43121da177e4SLinus Torvalds 
4313cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
4314cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
4315cd82e61cSMarcel Holtmann 
4316cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
4317cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
4318470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
43191da177e4SLinus Torvalds 	}
43201da177e4SLinus Torvalds 
43211da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
43221da177e4SLinus Torvalds 	skb_orphan(skb);
43231da177e4SLinus Torvalds 
43247bd8f09fSMarcel Holtmann 	if (hdev->send(hdev, skb) < 0)
432551086991SMarcel Holtmann 		BT_ERR("%s sending frame failed", hdev->name);
43261da177e4SLinus Torvalds }
43271da177e4SLinus Torvalds 
43283119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
43293119ae95SJohan Hedberg {
43303119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
43313119ae95SJohan Hedberg 	req->hdev = hdev;
43325d73e034SAndre Guedes 	req->err = 0;
43333119ae95SJohan Hedberg }
43343119ae95SJohan Hedberg 
43353119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
43363119ae95SJohan Hedberg {
43373119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
43383119ae95SJohan Hedberg 	struct sk_buff *skb;
43393119ae95SJohan Hedberg 	unsigned long flags;
43403119ae95SJohan Hedberg 
43413119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
43423119ae95SJohan Hedberg 
43435d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
43445d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
43455d73e034SAndre Guedes 	 */
43465d73e034SAndre Guedes 	if (req->err) {
43475d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
43485d73e034SAndre Guedes 		return req->err;
43495d73e034SAndre Guedes 	}
43505d73e034SAndre Guedes 
43513119ae95SJohan Hedberg 	/* Do not allow empty requests */
43523119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
4353382b0c39SAndre Guedes 		return -ENODATA;
43543119ae95SJohan Hedberg 
43553119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
43563119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
43573119ae95SJohan Hedberg 
43583119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
43593119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
43603119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
43613119ae95SJohan Hedberg 
43623119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
43633119ae95SJohan Hedberg 
43643119ae95SJohan Hedberg 	return 0;
43653119ae95SJohan Hedberg }
43663119ae95SJohan Hedberg 
43671ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
436807dc93ddSJohan Hedberg 				       u32 plen, const void *param)
43691da177e4SLinus Torvalds {
43701da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
43711da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
43721da177e4SLinus Torvalds 	struct sk_buff *skb;
43731da177e4SLinus Torvalds 
43741da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
43751ca3a9d0SJohan Hedberg 	if (!skb)
43761ca3a9d0SJohan Hedberg 		return NULL;
43771da177e4SLinus Torvalds 
43781da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
4379a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
43801da177e4SLinus Torvalds 	hdr->plen   = plen;
43811da177e4SLinus Torvalds 
43821da177e4SLinus Torvalds 	if (plen)
43831da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
43841da177e4SLinus Torvalds 
43851da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
43861da177e4SLinus Torvalds 
43870d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
4388c78ae283SMarcel Holtmann 
43891ca3a9d0SJohan Hedberg 	return skb;
43901ca3a9d0SJohan Hedberg }
43911ca3a9d0SJohan Hedberg 
43921ca3a9d0SJohan Hedberg /* Send HCI command */
439307dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
439407dc93ddSJohan Hedberg 		 const void *param)
43951ca3a9d0SJohan Hedberg {
43961ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
43971ca3a9d0SJohan Hedberg 
43981ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
43991ca3a9d0SJohan Hedberg 
44001ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
44011ca3a9d0SJohan Hedberg 	if (!skb) {
44021ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
44031ca3a9d0SJohan Hedberg 		return -ENOMEM;
44041ca3a9d0SJohan Hedberg 	}
44051ca3a9d0SJohan Hedberg 
440611714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
440711714b3dSJohan Hedberg 	 * single-command requests.
440811714b3dSJohan Hedberg 	 */
440911714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
441011714b3dSJohan Hedberg 
44111da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
4412c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
44131da177e4SLinus Torvalds 
44141da177e4SLinus Torvalds 	return 0;
44151da177e4SLinus Torvalds }
44161da177e4SLinus Torvalds 
441771c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
441807dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
441907dc93ddSJohan Hedberg 		    const void *param, u8 event)
442071c76a17SJohan Hedberg {
442171c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
442271c76a17SJohan Hedberg 	struct sk_buff *skb;
442371c76a17SJohan Hedberg 
442471c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
442571c76a17SJohan Hedberg 
442634739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
442734739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
442834739c1eSAndre Guedes 	 */
442934739c1eSAndre Guedes 	if (req->err)
443034739c1eSAndre Guedes 		return;
443134739c1eSAndre Guedes 
443271c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
443371c76a17SJohan Hedberg 	if (!skb) {
44345d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
44355d73e034SAndre Guedes 		       hdev->name, opcode);
44365d73e034SAndre Guedes 		req->err = -ENOMEM;
4437e348fe6bSAndre Guedes 		return;
443871c76a17SJohan Hedberg 	}
443971c76a17SJohan Hedberg 
444071c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
444171c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
444271c76a17SJohan Hedberg 
444302350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
444402350a72SJohan Hedberg 
444571c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
444671c76a17SJohan Hedberg }
444771c76a17SJohan Hedberg 
444807dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
444907dc93ddSJohan Hedberg 		 const void *param)
445002350a72SJohan Hedberg {
445102350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
445202350a72SJohan Hedberg }
445302350a72SJohan Hedberg 
44541da177e4SLinus Torvalds /* Get data from the previously sent command */
4455a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
44561da177e4SLinus Torvalds {
44571da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
44581da177e4SLinus Torvalds 
44591da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
44601da177e4SLinus Torvalds 		return NULL;
44611da177e4SLinus Torvalds 
44621da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
44631da177e4SLinus Torvalds 
4464a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
44651da177e4SLinus Torvalds 		return NULL;
44661da177e4SLinus Torvalds 
4467f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
44681da177e4SLinus Torvalds 
44691da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
44701da177e4SLinus Torvalds }
44711da177e4SLinus Torvalds 
44721da177e4SLinus Torvalds /* Send ACL data */
44731da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
44741da177e4SLinus Torvalds {
44751da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
44761da177e4SLinus Torvalds 	int len = skb->len;
44771da177e4SLinus Torvalds 
4478badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
4479badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
44809c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
4481aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
4482aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
44831da177e4SLinus Torvalds }
44841da177e4SLinus Torvalds 
4485ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
448673d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
44871da177e4SLinus Torvalds {
4488ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
44891da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
44901da177e4SLinus Torvalds 	struct sk_buff *list;
44911da177e4SLinus Torvalds 
4492087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
4493087bfd99SGustavo Padovan 	skb->data_len = 0;
4494087bfd99SGustavo Padovan 
4495087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
4496204a6e54SAndrei Emeltchenko 
4497204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
4498204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
4499087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
4500204a6e54SAndrei Emeltchenko 		break;
4501204a6e54SAndrei Emeltchenko 	case HCI_AMP:
4502204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
4503204a6e54SAndrei Emeltchenko 		break;
4504204a6e54SAndrei Emeltchenko 	default:
4505204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
4506204a6e54SAndrei Emeltchenko 		return;
4507204a6e54SAndrei Emeltchenko 	}
4508087bfd99SGustavo Padovan 
450970f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
451070f23020SAndrei Emeltchenko 	if (!list) {
45111da177e4SLinus Torvalds 		/* Non fragmented */
45121da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
45131da177e4SLinus Torvalds 
451473d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
45151da177e4SLinus Torvalds 	} else {
45161da177e4SLinus Torvalds 		/* Fragmented */
45171da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
45181da177e4SLinus Torvalds 
45191da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
45201da177e4SLinus Torvalds 
45211da177e4SLinus Torvalds 		/* Queue all fragments atomically */
4522af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
45231da177e4SLinus Torvalds 
452473d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
4525e702112fSAndrei Emeltchenko 
4526e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
4527e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
45281da177e4SLinus Torvalds 		do {
45291da177e4SLinus Torvalds 			skb = list; list = list->next;
45301da177e4SLinus Torvalds 
45310d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
4532e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
45331da177e4SLinus Torvalds 
45341da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
45351da177e4SLinus Torvalds 
453673d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
45371da177e4SLinus Torvalds 		} while (list);
45381da177e4SLinus Torvalds 
4539af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
45401da177e4SLinus Torvalds 	}
454173d80debSLuiz Augusto von Dentz }
454273d80debSLuiz Augusto von Dentz 
454373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
454473d80debSLuiz Augusto von Dentz {
4545ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
454673d80debSLuiz Augusto von Dentz 
4547f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
454873d80debSLuiz Augusto von Dentz 
4549ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
45501da177e4SLinus Torvalds 
45513eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
45521da177e4SLinus Torvalds }
45531da177e4SLinus Torvalds 
45541da177e4SLinus Torvalds /* Send SCO data */
45550d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
45561da177e4SLinus Torvalds {
45571da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
45581da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
45591da177e4SLinus Torvalds 
45601da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
45611da177e4SLinus Torvalds 
4562aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
45631da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
45641da177e4SLinus Torvalds 
4565badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
4566badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
45679c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
45681da177e4SLinus Torvalds 
45690d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
4570c78ae283SMarcel Holtmann 
45711da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
45723eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
45731da177e4SLinus Torvalds }
45741da177e4SLinus Torvalds 
45751da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
45761da177e4SLinus Torvalds 
45771da177e4SLinus Torvalds /* HCI Connection scheduler */
45786039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
4579a8c5fb1aSGustavo Padovan 				     int *quote)
45801da177e4SLinus Torvalds {
45811da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
45828035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
4583abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
45841da177e4SLinus Torvalds 
45851da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
45861da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
4587bf4c6325SGustavo F. Padovan 
4588bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4589bf4c6325SGustavo F. Padovan 
4590bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4591769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
45921da177e4SLinus Torvalds 			continue;
4593769be974SMarcel Holtmann 
4594769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
4595769be974SMarcel Holtmann 			continue;
4596769be974SMarcel Holtmann 
45971da177e4SLinus Torvalds 		num++;
45981da177e4SLinus Torvalds 
45991da177e4SLinus Torvalds 		if (c->sent < min) {
46001da177e4SLinus Torvalds 			min  = c->sent;
46011da177e4SLinus Torvalds 			conn = c;
46021da177e4SLinus Torvalds 		}
460352087a79SLuiz Augusto von Dentz 
460452087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
460552087a79SLuiz Augusto von Dentz 			break;
46061da177e4SLinus Torvalds 	}
46071da177e4SLinus Torvalds 
4608bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4609bf4c6325SGustavo F. Padovan 
46101da177e4SLinus Torvalds 	if (conn) {
46116ed58ec5SVille Tervo 		int cnt, q;
46126ed58ec5SVille Tervo 
46136ed58ec5SVille Tervo 		switch (conn->type) {
46146ed58ec5SVille Tervo 		case ACL_LINK:
46156ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
46166ed58ec5SVille Tervo 			break;
46176ed58ec5SVille Tervo 		case SCO_LINK:
46186ed58ec5SVille Tervo 		case ESCO_LINK:
46196ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
46206ed58ec5SVille Tervo 			break;
46216ed58ec5SVille Tervo 		case LE_LINK:
46226ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
46236ed58ec5SVille Tervo 			break;
46246ed58ec5SVille Tervo 		default:
46256ed58ec5SVille Tervo 			cnt = 0;
46266ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
46276ed58ec5SVille Tervo 		}
46286ed58ec5SVille Tervo 
46296ed58ec5SVille Tervo 		q = cnt / num;
46301da177e4SLinus Torvalds 		*quote = q ? q : 1;
46311da177e4SLinus Torvalds 	} else
46321da177e4SLinus Torvalds 		*quote = 0;
46331da177e4SLinus Torvalds 
46341da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
46351da177e4SLinus Torvalds 	return conn;
46361da177e4SLinus Torvalds }
46371da177e4SLinus Torvalds 
46386039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
46391da177e4SLinus Torvalds {
46401da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
46411da177e4SLinus Torvalds 	struct hci_conn *c;
46421da177e4SLinus Torvalds 
4643bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
46441da177e4SLinus Torvalds 
4645bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4646bf4c6325SGustavo F. Padovan 
46471da177e4SLinus Torvalds 	/* Kill stalled connections */
4648bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4649bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
46506ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
46516ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
4652bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
46531da177e4SLinus Torvalds 		}
46541da177e4SLinus Torvalds 	}
4655bf4c6325SGustavo F. Padovan 
4656bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
46571da177e4SLinus Torvalds }
46581da177e4SLinus Torvalds 
46596039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
466073d80debSLuiz Augusto von Dentz 				      int *quote)
466173d80debSLuiz Augusto von Dentz {
466273d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
466373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4664abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
466573d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
466673d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
466773d80debSLuiz Augusto von Dentz 
466873d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
466973d80debSLuiz Augusto von Dentz 
4670bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4671bf4c6325SGustavo F. Padovan 
4672bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
467373d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
467473d80debSLuiz Augusto von Dentz 
467573d80debSLuiz Augusto von Dentz 		if (conn->type != type)
467673d80debSLuiz Augusto von Dentz 			continue;
467773d80debSLuiz Augusto von Dentz 
467873d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
467973d80debSLuiz Augusto von Dentz 			continue;
468073d80debSLuiz Augusto von Dentz 
468173d80debSLuiz Augusto von Dentz 		conn_num++;
468273d80debSLuiz Augusto von Dentz 
46838192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
468473d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
468573d80debSLuiz Augusto von Dentz 
468673d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
468773d80debSLuiz Augusto von Dentz 				continue;
468873d80debSLuiz Augusto von Dentz 
468973d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
469073d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
469173d80debSLuiz Augusto von Dentz 				continue;
469273d80debSLuiz Augusto von Dentz 
469373d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
469473d80debSLuiz Augusto von Dentz 				num = 0;
469573d80debSLuiz Augusto von Dentz 				min = ~0;
469673d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
469773d80debSLuiz Augusto von Dentz 			}
469873d80debSLuiz Augusto von Dentz 
469973d80debSLuiz Augusto von Dentz 			num++;
470073d80debSLuiz Augusto von Dentz 
470173d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
470273d80debSLuiz Augusto von Dentz 				min  = conn->sent;
470373d80debSLuiz Augusto von Dentz 				chan = tmp;
470473d80debSLuiz Augusto von Dentz 			}
470573d80debSLuiz Augusto von Dentz 		}
470673d80debSLuiz Augusto von Dentz 
470773d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
470873d80debSLuiz Augusto von Dentz 			break;
470973d80debSLuiz Augusto von Dentz 	}
471073d80debSLuiz Augusto von Dentz 
4711bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4712bf4c6325SGustavo F. Padovan 
471373d80debSLuiz Augusto von Dentz 	if (!chan)
471473d80debSLuiz Augusto von Dentz 		return NULL;
471573d80debSLuiz Augusto von Dentz 
471673d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
471773d80debSLuiz Augusto von Dentz 	case ACL_LINK:
471873d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
471973d80debSLuiz Augusto von Dentz 		break;
4720bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4721bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4722bd1eb66bSAndrei Emeltchenko 		break;
472373d80debSLuiz Augusto von Dentz 	case SCO_LINK:
472473d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
472573d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
472673d80debSLuiz Augusto von Dentz 		break;
472773d80debSLuiz Augusto von Dentz 	case LE_LINK:
472873d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
472973d80debSLuiz Augusto von Dentz 		break;
473073d80debSLuiz Augusto von Dentz 	default:
473173d80debSLuiz Augusto von Dentz 		cnt = 0;
473273d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
473373d80debSLuiz Augusto von Dentz 	}
473473d80debSLuiz Augusto von Dentz 
473573d80debSLuiz Augusto von Dentz 	q = cnt / num;
473673d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
473773d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
473873d80debSLuiz Augusto von Dentz 	return chan;
473973d80debSLuiz Augusto von Dentz }
474073d80debSLuiz Augusto von Dentz 
474102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
474202b20f0bSLuiz Augusto von Dentz {
474302b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
474402b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
474502b20f0bSLuiz Augusto von Dentz 	int num = 0;
474602b20f0bSLuiz Augusto von Dentz 
474702b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
474802b20f0bSLuiz Augusto von Dentz 
4749bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4750bf4c6325SGustavo F. Padovan 
4751bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
475202b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
475302b20f0bSLuiz Augusto von Dentz 
475402b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
475502b20f0bSLuiz Augusto von Dentz 			continue;
475602b20f0bSLuiz Augusto von Dentz 
475702b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
475802b20f0bSLuiz Augusto von Dentz 			continue;
475902b20f0bSLuiz Augusto von Dentz 
476002b20f0bSLuiz Augusto von Dentz 		num++;
476102b20f0bSLuiz Augusto von Dentz 
47628192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
476302b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
476402b20f0bSLuiz Augusto von Dentz 
476502b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
476602b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
476702b20f0bSLuiz Augusto von Dentz 				continue;
476802b20f0bSLuiz Augusto von Dentz 			}
476902b20f0bSLuiz Augusto von Dentz 
477002b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
477102b20f0bSLuiz Augusto von Dentz 				continue;
477202b20f0bSLuiz Augusto von Dentz 
477302b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
477402b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
477502b20f0bSLuiz Augusto von Dentz 				continue;
477602b20f0bSLuiz Augusto von Dentz 
477702b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
477802b20f0bSLuiz Augusto von Dentz 
477902b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
478002b20f0bSLuiz Augusto von Dentz 			       skb->priority);
478102b20f0bSLuiz Augusto von Dentz 		}
478202b20f0bSLuiz Augusto von Dentz 
478302b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
478402b20f0bSLuiz Augusto von Dentz 			break;
478502b20f0bSLuiz Augusto von Dentz 	}
4786bf4c6325SGustavo F. Padovan 
4787bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4788bf4c6325SGustavo F. Padovan 
478902b20f0bSLuiz Augusto von Dentz }
479002b20f0bSLuiz Augusto von Dentz 
4791b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4792b71d385aSAndrei Emeltchenko {
4793b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4794b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4795b71d385aSAndrei Emeltchenko }
4796b71d385aSAndrei Emeltchenko 
47976039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
47981da177e4SLinus Torvalds {
47991da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
48001da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
48011da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
480263d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
48035f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4804bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
48051da177e4SLinus Torvalds 	}
480663d2bc1bSAndrei Emeltchenko }
48071da177e4SLinus Torvalds 
48086039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
480963d2bc1bSAndrei Emeltchenko {
481063d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
481163d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
481263d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
481363d2bc1bSAndrei Emeltchenko 	int quote;
481463d2bc1bSAndrei Emeltchenko 
481563d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
481604837f64SMarcel Holtmann 
481773d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
481873d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4819ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4820ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
482173d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
482273d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
482373d80debSLuiz Augusto von Dentz 
4824ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4825ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4826ec1cce24SLuiz Augusto von Dentz 				break;
4827ec1cce24SLuiz Augusto von Dentz 
4828ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4829ec1cce24SLuiz Augusto von Dentz 
483073d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
483173d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
483204837f64SMarcel Holtmann 
483357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
48341da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
48351da177e4SLinus Torvalds 
48361da177e4SLinus Torvalds 			hdev->acl_cnt--;
483773d80debSLuiz Augusto von Dentz 			chan->sent++;
483873d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
48391da177e4SLinus Torvalds 		}
48401da177e4SLinus Torvalds 	}
484102b20f0bSLuiz Augusto von Dentz 
484202b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
484302b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
48441da177e4SLinus Torvalds }
48451da177e4SLinus Torvalds 
48466039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4847b71d385aSAndrei Emeltchenko {
484863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4849b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4850b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4851b71d385aSAndrei Emeltchenko 	int quote;
4852bd1eb66bSAndrei Emeltchenko 	u8 type;
4853b71d385aSAndrei Emeltchenko 
485463d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
4855b71d385aSAndrei Emeltchenko 
4856bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4857bd1eb66bSAndrei Emeltchenko 
4858bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
4859bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
4860bd1eb66bSAndrei Emeltchenko 	else
4861bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
4862bd1eb66bSAndrei Emeltchenko 
4863b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
4864bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
4865b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
4866b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
4867b71d385aSAndrei Emeltchenko 			int blocks;
4868b71d385aSAndrei Emeltchenko 
4869b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
4870b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
4871b71d385aSAndrei Emeltchenko 
4872b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
4873b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
4874b71d385aSAndrei Emeltchenko 				break;
4875b71d385aSAndrei Emeltchenko 
4876b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
4877b71d385aSAndrei Emeltchenko 
4878b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
4879b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
4880b71d385aSAndrei Emeltchenko 				return;
4881b71d385aSAndrei Emeltchenko 
4882b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
4883b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
4884b71d385aSAndrei Emeltchenko 
488557d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4886b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4887b71d385aSAndrei Emeltchenko 
4888b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4889b71d385aSAndrei Emeltchenko 			quote -= blocks;
4890b71d385aSAndrei Emeltchenko 
4891b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4892b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4893b71d385aSAndrei Emeltchenko 		}
4894b71d385aSAndrei Emeltchenko 	}
4895b71d385aSAndrei Emeltchenko 
4896b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4897bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4898b71d385aSAndrei Emeltchenko }
4899b71d385aSAndrei Emeltchenko 
49006039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4901b71d385aSAndrei Emeltchenko {
4902b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4903b71d385aSAndrei Emeltchenko 
4904bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4905bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
4906bd1eb66bSAndrei Emeltchenko 		return;
4907bd1eb66bSAndrei Emeltchenko 
4908bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4909bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4910b71d385aSAndrei Emeltchenko 		return;
4911b71d385aSAndrei Emeltchenko 
4912b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4913b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4914b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4915b71d385aSAndrei Emeltchenko 		break;
4916b71d385aSAndrei Emeltchenko 
4917b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4918b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4919b71d385aSAndrei Emeltchenko 		break;
4920b71d385aSAndrei Emeltchenko 	}
4921b71d385aSAndrei Emeltchenko }
4922b71d385aSAndrei Emeltchenko 
49231da177e4SLinus Torvalds /* Schedule SCO */
49246039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
49251da177e4SLinus Torvalds {
49261da177e4SLinus Torvalds 	struct hci_conn *conn;
49271da177e4SLinus Torvalds 	struct sk_buff *skb;
49281da177e4SLinus Torvalds 	int quote;
49291da177e4SLinus Torvalds 
49301da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
49311da177e4SLinus Torvalds 
493252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
493352087a79SLuiz Augusto von Dentz 		return;
493452087a79SLuiz Augusto von Dentz 
49351da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
49361da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
49371da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
493857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
49391da177e4SLinus Torvalds 
49401da177e4SLinus Torvalds 			conn->sent++;
49411da177e4SLinus Torvalds 			if (conn->sent == ~0)
49421da177e4SLinus Torvalds 				conn->sent = 0;
49431da177e4SLinus Torvalds 		}
49441da177e4SLinus Torvalds 	}
49451da177e4SLinus Torvalds }
49461da177e4SLinus Torvalds 
49476039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
4948b6a0dc82SMarcel Holtmann {
4949b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4950b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
4951b6a0dc82SMarcel Holtmann 	int quote;
4952b6a0dc82SMarcel Holtmann 
4953b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
4954b6a0dc82SMarcel Holtmann 
495552087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
495652087a79SLuiz Augusto von Dentz 		return;
495752087a79SLuiz Augusto von Dentz 
49588fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
49598fc9ced3SGustavo Padovan 						     &quote))) {
4960b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
4961b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
496257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4963b6a0dc82SMarcel Holtmann 
4964b6a0dc82SMarcel Holtmann 			conn->sent++;
4965b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
4966b6a0dc82SMarcel Holtmann 				conn->sent = 0;
4967b6a0dc82SMarcel Holtmann 		}
4968b6a0dc82SMarcel Holtmann 	}
4969b6a0dc82SMarcel Holtmann }
4970b6a0dc82SMarcel Holtmann 
49716039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
49726ed58ec5SVille Tervo {
497373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
49746ed58ec5SVille Tervo 	struct sk_buff *skb;
497502b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
49766ed58ec5SVille Tervo 
49776ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
49786ed58ec5SVille Tervo 
497952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
498052087a79SLuiz Augusto von Dentz 		return;
498152087a79SLuiz Augusto von Dentz 
49826ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
49836ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
49846ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
4985bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
49866ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
4987bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
49886ed58ec5SVille Tervo 	}
49896ed58ec5SVille Tervo 
49906ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
499102b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
499273d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4993ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4994ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
499573d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
499673d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
49976ed58ec5SVille Tervo 
4998ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4999ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
5000ec1cce24SLuiz Augusto von Dentz 				break;
5001ec1cce24SLuiz Augusto von Dentz 
5002ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
5003ec1cce24SLuiz Augusto von Dentz 
500457d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
50056ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
50066ed58ec5SVille Tervo 
50076ed58ec5SVille Tervo 			cnt--;
500873d80debSLuiz Augusto von Dentz 			chan->sent++;
500973d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
50106ed58ec5SVille Tervo 		}
50116ed58ec5SVille Tervo 	}
501273d80debSLuiz Augusto von Dentz 
50136ed58ec5SVille Tervo 	if (hdev->le_pkts)
50146ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
50156ed58ec5SVille Tervo 	else
50166ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
501702b20f0bSLuiz Augusto von Dentz 
501802b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
501902b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
50206ed58ec5SVille Tervo }
50216ed58ec5SVille Tervo 
50223eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
50231da177e4SLinus Torvalds {
50243eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
50251da177e4SLinus Torvalds 	struct sk_buff *skb;
50261da177e4SLinus Torvalds 
50276ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
50286ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
50291da177e4SLinus Torvalds 
503052de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
50311da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
50321da177e4SLinus Torvalds 		hci_sched_acl(hdev);
50331da177e4SLinus Torvalds 		hci_sched_sco(hdev);
5034b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
50356ed58ec5SVille Tervo 		hci_sched_le(hdev);
503652de599eSMarcel Holtmann 	}
50376ed58ec5SVille Tervo 
50381da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
50391da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
504057d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
50411da177e4SLinus Torvalds }
50421da177e4SLinus Torvalds 
504325985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
50441da177e4SLinus Torvalds 
50451da177e4SLinus Torvalds /* ACL data packet */
50466039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
50471da177e4SLinus Torvalds {
50481da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
50491da177e4SLinus Torvalds 	struct hci_conn *conn;
50501da177e4SLinus Torvalds 	__u16 handle, flags;
50511da177e4SLinus Torvalds 
50521da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
50531da177e4SLinus Torvalds 
50541da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
50551da177e4SLinus Torvalds 	flags  = hci_flags(handle);
50561da177e4SLinus Torvalds 	handle = hci_handle(handle);
50571da177e4SLinus Torvalds 
5058f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
5059a8c5fb1aSGustavo Padovan 	       handle, flags);
50601da177e4SLinus Torvalds 
50611da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
50621da177e4SLinus Torvalds 
50631da177e4SLinus Torvalds 	hci_dev_lock(hdev);
50641da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
50651da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
50661da177e4SLinus Torvalds 
50671da177e4SLinus Torvalds 	if (conn) {
506865983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
506904837f64SMarcel Holtmann 
50701da177e4SLinus Torvalds 		/* Send to upper protocol */
5071686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
50721da177e4SLinus Torvalds 		return;
50731da177e4SLinus Torvalds 	} else {
50741da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
50751da177e4SLinus Torvalds 		       hdev->name, handle);
50761da177e4SLinus Torvalds 	}
50771da177e4SLinus Torvalds 
50781da177e4SLinus Torvalds 	kfree_skb(skb);
50791da177e4SLinus Torvalds }
50801da177e4SLinus Torvalds 
50811da177e4SLinus Torvalds /* SCO data packet */
50826039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
50831da177e4SLinus Torvalds {
50841da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
50851da177e4SLinus Torvalds 	struct hci_conn *conn;
50861da177e4SLinus Torvalds 	__u16 handle;
50871da177e4SLinus Torvalds 
50881da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
50891da177e4SLinus Torvalds 
50901da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
50911da177e4SLinus Torvalds 
5092f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
50931da177e4SLinus Torvalds 
50941da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
50951da177e4SLinus Torvalds 
50961da177e4SLinus Torvalds 	hci_dev_lock(hdev);
50971da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
50981da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
50991da177e4SLinus Torvalds 
51001da177e4SLinus Torvalds 	if (conn) {
51011da177e4SLinus Torvalds 		/* Send to upper protocol */
5102686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
51031da177e4SLinus Torvalds 		return;
51041da177e4SLinus Torvalds 	} else {
51051da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
51061da177e4SLinus Torvalds 		       hdev->name, handle);
51071da177e4SLinus Torvalds 	}
51081da177e4SLinus Torvalds 
51091da177e4SLinus Torvalds 	kfree_skb(skb);
51101da177e4SLinus Torvalds }
51111da177e4SLinus Torvalds 
51129238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
51139238f36aSJohan Hedberg {
51149238f36aSJohan Hedberg 	struct sk_buff *skb;
51159238f36aSJohan Hedberg 
51169238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
51179238f36aSJohan Hedberg 	if (!skb)
51189238f36aSJohan Hedberg 		return true;
51199238f36aSJohan Hedberg 
51209238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
51219238f36aSJohan Hedberg }
51229238f36aSJohan Hedberg 
512342c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
512442c6b129SJohan Hedberg {
512542c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
512642c6b129SJohan Hedberg 	struct sk_buff *skb;
512742c6b129SJohan Hedberg 	u16 opcode;
512842c6b129SJohan Hedberg 
512942c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
513042c6b129SJohan Hedberg 		return;
513142c6b129SJohan Hedberg 
513242c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
513342c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
513442c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
513542c6b129SJohan Hedberg 		return;
513642c6b129SJohan Hedberg 
513742c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
513842c6b129SJohan Hedberg 	if (!skb)
513942c6b129SJohan Hedberg 		return;
514042c6b129SJohan Hedberg 
514142c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
514242c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
514342c6b129SJohan Hedberg }
514442c6b129SJohan Hedberg 
51459238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
51469238f36aSJohan Hedberg {
51479238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
51489238f36aSJohan Hedberg 	struct sk_buff *skb;
51499238f36aSJohan Hedberg 	unsigned long flags;
51509238f36aSJohan Hedberg 
51519238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
51529238f36aSJohan Hedberg 
515342c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
515442c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
51559238f36aSJohan Hedberg 	 */
515642c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
515742c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
515842c6b129SJohan Hedberg 		 * reset complete event during init and any pending
515942c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
516042c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
516142c6b129SJohan Hedberg 		 * command.
516242c6b129SJohan Hedberg 		 */
516342c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
516442c6b129SJohan Hedberg 			hci_resend_last(hdev);
516542c6b129SJohan Hedberg 
51669238f36aSJohan Hedberg 		return;
516742c6b129SJohan Hedberg 	}
51689238f36aSJohan Hedberg 
51699238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
51709238f36aSJohan Hedberg 	 * this request the request is not yet complete.
51719238f36aSJohan Hedberg 	 */
51729238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
51739238f36aSJohan Hedberg 		return;
51749238f36aSJohan Hedberg 
51759238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
51769238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
51779238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
51789238f36aSJohan Hedberg 	 */
51799238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
51809238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
518153e21fbcSJohan Hedberg 
518253e21fbcSJohan Hedberg 		if (req_complete) {
518353e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
518453e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
518553e21fbcSJohan Hedberg 			 * this function gets called again.
518653e21fbcSJohan Hedberg 			 */
518753e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
518853e21fbcSJohan Hedberg 
51899238f36aSJohan Hedberg 			goto call_complete;
51909238f36aSJohan Hedberg 		}
519153e21fbcSJohan Hedberg 	}
51929238f36aSJohan Hedberg 
51939238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
51949238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
51959238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
51969238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
51979238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
51989238f36aSJohan Hedberg 			break;
51999238f36aSJohan Hedberg 		}
52009238f36aSJohan Hedberg 
52019238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
52029238f36aSJohan Hedberg 		kfree_skb(skb);
52039238f36aSJohan Hedberg 	}
52049238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
52059238f36aSJohan Hedberg 
52069238f36aSJohan Hedberg call_complete:
52079238f36aSJohan Hedberg 	if (req_complete)
52089238f36aSJohan Hedberg 		req_complete(hdev, status);
52099238f36aSJohan Hedberg }
52109238f36aSJohan Hedberg 
5211b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
52121da177e4SLinus Torvalds {
5213b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
52141da177e4SLinus Torvalds 	struct sk_buff *skb;
52151da177e4SLinus Torvalds 
52161da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
52171da177e4SLinus Torvalds 
52181da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
5219cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
5220cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
5221cd82e61cSMarcel Holtmann 
52221da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
52231da177e4SLinus Torvalds 			/* Send copy to the sockets */
5224470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
52251da177e4SLinus Torvalds 		}
52261da177e4SLinus Torvalds 
52270736cfa8SMarcel Holtmann 		if (test_bit(HCI_RAW, &hdev->flags) ||
52280736cfa8SMarcel Holtmann 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
52291da177e4SLinus Torvalds 			kfree_skb(skb);
52301da177e4SLinus Torvalds 			continue;
52311da177e4SLinus Torvalds 		}
52321da177e4SLinus Torvalds 
52331da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
52341da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
52350d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
52361da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
52371da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
52381da177e4SLinus Torvalds 				kfree_skb(skb);
52391da177e4SLinus Torvalds 				continue;
52403ff50b79SStephen Hemminger 			}
52411da177e4SLinus Torvalds 		}
52421da177e4SLinus Torvalds 
52431da177e4SLinus Torvalds 		/* Process frame */
52440d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
52451da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
5246b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
52471da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
52481da177e4SLinus Torvalds 			break;
52491da177e4SLinus Torvalds 
52501da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
52511da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
52521da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
52531da177e4SLinus Torvalds 			break;
52541da177e4SLinus Torvalds 
52551da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
52561da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
52571da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
52581da177e4SLinus Torvalds 			break;
52591da177e4SLinus Torvalds 
52601da177e4SLinus Torvalds 		default:
52611da177e4SLinus Torvalds 			kfree_skb(skb);
52621da177e4SLinus Torvalds 			break;
52631da177e4SLinus Torvalds 		}
52641da177e4SLinus Torvalds 	}
52651da177e4SLinus Torvalds }
52661da177e4SLinus Torvalds 
5267c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
52681da177e4SLinus Torvalds {
5269c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
52701da177e4SLinus Torvalds 	struct sk_buff *skb;
52711da177e4SLinus Torvalds 
52722104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
52732104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
52741da177e4SLinus Torvalds 
52751da177e4SLinus Torvalds 	/* Send queued commands */
52765a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
52775a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
52785a08ecceSAndrei Emeltchenko 		if (!skb)
52795a08ecceSAndrei Emeltchenko 			return;
52805a08ecceSAndrei Emeltchenko 
52811da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
52821da177e4SLinus Torvalds 
5283a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
528470f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
52851da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
528657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
52877bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
528865cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
52897bdb8a5cSSzymon Janc 			else
529065cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
529165cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
52921da177e4SLinus Torvalds 		} else {
52931da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
5294c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
52951da177e4SLinus Torvalds 		}
52961da177e4SLinus Torvalds 	}
52971da177e4SLinus Torvalds }
5298b1efcc28SAndre Guedes 
5299b1efcc28SAndre Guedes void hci_req_add_le_scan_disable(struct hci_request *req)
5300b1efcc28SAndre Guedes {
5301b1efcc28SAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
5302b1efcc28SAndre Guedes 
5303b1efcc28SAndre Guedes 	memset(&cp, 0, sizeof(cp));
5304b1efcc28SAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
5305b1efcc28SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
5306b1efcc28SAndre Guedes }
5307a4790dbdSAndre Guedes 
53088ef30fd3SAndre Guedes void hci_req_add_le_passive_scan(struct hci_request *req)
53098ef30fd3SAndre Guedes {
53108ef30fd3SAndre Guedes 	struct hci_cp_le_set_scan_param param_cp;
53118ef30fd3SAndre Guedes 	struct hci_cp_le_set_scan_enable enable_cp;
53128ef30fd3SAndre Guedes 	struct hci_dev *hdev = req->hdev;
53138ef30fd3SAndre Guedes 	u8 own_addr_type;
53148ef30fd3SAndre Guedes 
53158ef30fd3SAndre Guedes 	/* Set require_privacy to true to avoid identification from
53168ef30fd3SAndre Guedes 	 * unknown peer devices. Since this is passive scanning, no
53178ef30fd3SAndre Guedes 	 * SCAN_REQ using the local identity should be sent. Mandating
53188ef30fd3SAndre Guedes 	 * privacy is just an extra precaution.
53198ef30fd3SAndre Guedes 	 */
53208ef30fd3SAndre Guedes 	if (hci_update_random_address(req, true, &own_addr_type))
53218ef30fd3SAndre Guedes 		return;
53228ef30fd3SAndre Guedes 
53238ef30fd3SAndre Guedes 	memset(&param_cp, 0, sizeof(param_cp));
53248ef30fd3SAndre Guedes 	param_cp.type = LE_SCAN_PASSIVE;
53258ef30fd3SAndre Guedes 	param_cp.interval = cpu_to_le16(hdev->le_scan_interval);
53268ef30fd3SAndre Guedes 	param_cp.window = cpu_to_le16(hdev->le_scan_window);
53278ef30fd3SAndre Guedes 	param_cp.own_address_type = own_addr_type;
53288ef30fd3SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
53298ef30fd3SAndre Guedes 		    &param_cp);
53308ef30fd3SAndre Guedes 
53318ef30fd3SAndre Guedes 	memset(&enable_cp, 0, sizeof(enable_cp));
53328ef30fd3SAndre Guedes 	enable_cp.enable = LE_SCAN_ENABLE;
53334340a124SAndre Guedes 	enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
53348ef30fd3SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
53358ef30fd3SAndre Guedes 		    &enable_cp);
53368ef30fd3SAndre Guedes }
53378ef30fd3SAndre Guedes 
5338a4790dbdSAndre Guedes static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
5339a4790dbdSAndre Guedes {
5340a4790dbdSAndre Guedes 	if (status)
5341a4790dbdSAndre Guedes 		BT_DBG("HCI request failed to update background scanning: "
5342a4790dbdSAndre Guedes 		       "status 0x%2.2x", status);
5343a4790dbdSAndre Guedes }
5344a4790dbdSAndre Guedes 
5345a4790dbdSAndre Guedes /* This function controls the background scanning based on hdev->pend_le_conns
5346a4790dbdSAndre Guedes  * list. If there are pending LE connection we start the background scanning,
5347a4790dbdSAndre Guedes  * otherwise we stop it.
5348a4790dbdSAndre Guedes  *
5349a4790dbdSAndre Guedes  * This function requires the caller holds hdev->lock.
5350a4790dbdSAndre Guedes  */
5351a4790dbdSAndre Guedes void hci_update_background_scan(struct hci_dev *hdev)
5352a4790dbdSAndre Guedes {
5353a4790dbdSAndre Guedes 	struct hci_request req;
5354a4790dbdSAndre Guedes 	struct hci_conn *conn;
5355a4790dbdSAndre Guedes 	int err;
5356a4790dbdSAndre Guedes 
5357a4790dbdSAndre Guedes 	hci_req_init(&req, hdev);
5358a4790dbdSAndre Guedes 
5359a4790dbdSAndre Guedes 	if (list_empty(&hdev->pend_le_conns)) {
5360a4790dbdSAndre Guedes 		/* If there is no pending LE connections, we should stop
5361a4790dbdSAndre Guedes 		 * the background scanning.
5362a4790dbdSAndre Guedes 		 */
5363a4790dbdSAndre Guedes 
5364a4790dbdSAndre Guedes 		/* If controller is not scanning we are done. */
5365a4790dbdSAndre Guedes 		if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
5366a4790dbdSAndre Guedes 			return;
5367a4790dbdSAndre Guedes 
5368a4790dbdSAndre Guedes 		hci_req_add_le_scan_disable(&req);
5369a4790dbdSAndre Guedes 
5370a4790dbdSAndre Guedes 		BT_DBG("%s stopping background scanning", hdev->name);
5371a4790dbdSAndre Guedes 	} else {
5372a4790dbdSAndre Guedes 		/* If there is at least one pending LE connection, we should
5373a4790dbdSAndre Guedes 		 * keep the background scan running.
5374a4790dbdSAndre Guedes 		 */
5375a4790dbdSAndre Guedes 
5376a4790dbdSAndre Guedes 		/* If controller is connecting, we should not start scanning
5377a4790dbdSAndre Guedes 		 * since some controllers are not able to scan and connect at
5378a4790dbdSAndre Guedes 		 * the same time.
5379a4790dbdSAndre Guedes 		 */
5380a4790dbdSAndre Guedes 		conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
5381a4790dbdSAndre Guedes 		if (conn)
5382a4790dbdSAndre Guedes 			return;
5383a4790dbdSAndre Guedes 
53844340a124SAndre Guedes 		/* If controller is currently scanning, we stop it to ensure we
53854340a124SAndre Guedes 		 * don't miss any advertising (due to duplicates filter).
53864340a124SAndre Guedes 		 */
53874340a124SAndre Guedes 		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
53884340a124SAndre Guedes 			hci_req_add_le_scan_disable(&req);
53894340a124SAndre Guedes 
53908ef30fd3SAndre Guedes 		hci_req_add_le_passive_scan(&req);
5391a4790dbdSAndre Guedes 
5392a4790dbdSAndre Guedes 		BT_DBG("%s starting background scanning", hdev->name);
5393a4790dbdSAndre Guedes 	}
5394a4790dbdSAndre Guedes 
5395a4790dbdSAndre Guedes 	err = hci_req_run(&req, update_background_scan_complete);
5396a4790dbdSAndre Guedes 	if (err)
5397a4790dbdSAndre Guedes 		BT_ERR("Failed to run HCI request: err %d", err);
5398a4790dbdSAndre Guedes }
5399