xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 71c3b60e)
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>
38af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h>
391da177e4SLinus Torvalds 
400857dd3bSJohan Hedberg #include "hci_request.h"
4160c5f5fbSMarcel Holtmann #include "hci_debugfs.h"
42970c4e46SJohan Hedberg #include "smp.h"
43970c4e46SJohan Hedberg 
44b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
45c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
463eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds /* HCI device list */
491da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
501da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds /* HCI callback list */
531da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
541da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
551da177e4SLinus Torvalds 
563df92b31SSasha Levin /* HCI ID Numbering */
573df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
583df92b31SSasha Levin 
59899de765SMarcel Holtmann /* ----- HCI requests ----- */
60899de765SMarcel Holtmann 
61899de765SMarcel Holtmann #define HCI_REQ_DONE	  0
62899de765SMarcel Holtmann #define HCI_REQ_PEND	  1
63899de765SMarcel Holtmann #define HCI_REQ_CANCELED  2
64899de765SMarcel Holtmann 
65899de765SMarcel Holtmann #define hci_req_lock(d)		mutex_lock(&d->req_lock)
66899de765SMarcel Holtmann #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
67899de765SMarcel Holtmann 
681da177e4SLinus Torvalds /* ---- HCI notifications ---- */
691da177e4SLinus Torvalds 
706516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
711da177e4SLinus Torvalds {
72040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
731da177e4SLinus Torvalds }
741da177e4SLinus Torvalds 
75baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
76baf27f6eSMarcel Holtmann 
774b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, 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 	char buf[3];
824b4148e9SMarcel Holtmann 
83111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_DUT_MODE, &hdev->dbg_flags) ? 'Y': 'N';
844b4148e9SMarcel Holtmann 	buf[1] = '\n';
854b4148e9SMarcel Holtmann 	buf[2] = '\0';
864b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
874b4148e9SMarcel Holtmann }
884b4148e9SMarcel Holtmann 
894b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
904b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
914b4148e9SMarcel Holtmann {
924b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
934b4148e9SMarcel Holtmann 	struct sk_buff *skb;
944b4148e9SMarcel Holtmann 	char buf[32];
954b4148e9SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
964b4148e9SMarcel Holtmann 	bool enable;
974b4148e9SMarcel Holtmann 	int err;
984b4148e9SMarcel Holtmann 
994b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1004b4148e9SMarcel Holtmann 		return -ENETDOWN;
1014b4148e9SMarcel Holtmann 
1024b4148e9SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
1034b4148e9SMarcel Holtmann 		return -EFAULT;
1044b4148e9SMarcel Holtmann 
1054b4148e9SMarcel Holtmann 	buf[buf_size] = '\0';
1064b4148e9SMarcel Holtmann 	if (strtobool(buf, &enable))
1074b4148e9SMarcel Holtmann 		return -EINVAL;
1084b4148e9SMarcel Holtmann 
109111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_DUT_MODE, &hdev->dbg_flags))
1104b4148e9SMarcel Holtmann 		return -EALREADY;
1114b4148e9SMarcel Holtmann 
1124b4148e9SMarcel Holtmann 	hci_req_lock(hdev);
1134b4148e9SMarcel Holtmann 	if (enable)
1144b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
1154b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1164b4148e9SMarcel Holtmann 	else
1174b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1184b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1194b4148e9SMarcel Holtmann 	hci_req_unlock(hdev);
1204b4148e9SMarcel Holtmann 
1214b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1224b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1234b4148e9SMarcel Holtmann 
1244b4148e9SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
1254b4148e9SMarcel Holtmann 	kfree_skb(skb);
1264b4148e9SMarcel Holtmann 
1274b4148e9SMarcel Holtmann 	if (err < 0)
1284b4148e9SMarcel Holtmann 		return err;
1294b4148e9SMarcel Holtmann 
130111902f7SMarcel Holtmann 	change_bit(HCI_DUT_MODE, &hdev->dbg_flags);
1314b4148e9SMarcel Holtmann 
1324b4148e9SMarcel Holtmann 	return count;
1334b4148e9SMarcel Holtmann }
1344b4148e9SMarcel Holtmann 
1354b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1364b4148e9SMarcel Holtmann 	.open		= simple_open,
1374b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1384b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1394b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1404b4148e9SMarcel Holtmann };
1414b4148e9SMarcel Holtmann 
142c982b2eaSJohan Hedberg static int rpa_timeout_set(void *data, u64 val)
143c982b2eaSJohan Hedberg {
144c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
145c982b2eaSJohan Hedberg 
146c982b2eaSJohan Hedberg 	/* Require the RPA timeout to be at least 30 seconds and at most
147c982b2eaSJohan Hedberg 	 * 24 hours.
148c982b2eaSJohan Hedberg 	 */
149c982b2eaSJohan Hedberg 	if (val < 30 || val > (60 * 60 * 24))
150c982b2eaSJohan Hedberg 		return -EINVAL;
151c982b2eaSJohan Hedberg 
152c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
153c982b2eaSJohan Hedberg 	hdev->rpa_timeout = val;
154c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
155c982b2eaSJohan Hedberg 
156c982b2eaSJohan Hedberg 	return 0;
157c982b2eaSJohan Hedberg }
158c982b2eaSJohan Hedberg 
159c982b2eaSJohan Hedberg static int rpa_timeout_get(void *data, u64 *val)
160c982b2eaSJohan Hedberg {
161c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
162c982b2eaSJohan Hedberg 
163c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
164c982b2eaSJohan Hedberg 	*val = hdev->rpa_timeout;
165c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
166c982b2eaSJohan Hedberg 
167c982b2eaSJohan Hedberg 	return 0;
168c982b2eaSJohan Hedberg }
169c982b2eaSJohan Hedberg 
170c982b2eaSJohan Hedberg DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get,
171c982b2eaSJohan Hedberg 			rpa_timeout_set, "%llu\n");
172c982b2eaSJohan Hedberg 
173ac345813SMarcel Holtmann static int identity_show(struct seq_file *f, void *p)
174ac345813SMarcel Holtmann {
175ac345813SMarcel Holtmann 	struct hci_dev *hdev = f->private;
176a1f4c318SJohan Hedberg 	bdaddr_t addr;
177ac345813SMarcel Holtmann 	u8 addr_type;
178ac345813SMarcel Holtmann 
179ac345813SMarcel Holtmann 	hci_dev_lock(hdev);
180ac345813SMarcel Holtmann 
181a1f4c318SJohan Hedberg 	hci_copy_identity_address(hdev, &addr, &addr_type);
182ac345813SMarcel Holtmann 
183a1f4c318SJohan Hedberg 	seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type,
184473deef2SMarcel Holtmann 		   16, hdev->irk, &hdev->rpa);
185ac345813SMarcel Holtmann 
186ac345813SMarcel Holtmann 	hci_dev_unlock(hdev);
187ac345813SMarcel Holtmann 
188ac345813SMarcel Holtmann 	return 0;
189ac345813SMarcel Holtmann }
190ac345813SMarcel Holtmann 
191ac345813SMarcel Holtmann static int identity_open(struct inode *inode, struct file *file)
192ac345813SMarcel Holtmann {
193ac345813SMarcel Holtmann 	return single_open(file, identity_show, inode->i_private);
194ac345813SMarcel Holtmann }
195ac345813SMarcel Holtmann 
196ac345813SMarcel Holtmann static const struct file_operations identity_fops = {
197ac345813SMarcel Holtmann 	.open		= identity_open,
198ac345813SMarcel Holtmann 	.read		= seq_read,
199ac345813SMarcel Holtmann 	.llseek		= seq_lseek,
200ac345813SMarcel Holtmann 	.release	= single_release,
201ac345813SMarcel Holtmann };
202ac345813SMarcel Holtmann 
2037a4cd51dSMarcel Holtmann static int random_address_show(struct seq_file *f, void *p)
2047a4cd51dSMarcel Holtmann {
2057a4cd51dSMarcel Holtmann 	struct hci_dev *hdev = f->private;
2067a4cd51dSMarcel Holtmann 
2077a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
2087a4cd51dSMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->random_addr);
2097a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
2107a4cd51dSMarcel Holtmann 
2117a4cd51dSMarcel Holtmann 	return 0;
2127a4cd51dSMarcel Holtmann }
2137a4cd51dSMarcel Holtmann 
2147a4cd51dSMarcel Holtmann static int random_address_open(struct inode *inode, struct file *file)
2157a4cd51dSMarcel Holtmann {
2167a4cd51dSMarcel Holtmann 	return single_open(file, random_address_show, inode->i_private);
2177a4cd51dSMarcel Holtmann }
2187a4cd51dSMarcel Holtmann 
2197a4cd51dSMarcel Holtmann static const struct file_operations random_address_fops = {
2207a4cd51dSMarcel Holtmann 	.open		= random_address_open,
2217a4cd51dSMarcel Holtmann 	.read		= seq_read,
2227a4cd51dSMarcel Holtmann 	.llseek		= seq_lseek,
2237a4cd51dSMarcel Holtmann 	.release	= single_release,
2247a4cd51dSMarcel Holtmann };
2257a4cd51dSMarcel Holtmann 
226e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p)
227e7b8fc92SMarcel Holtmann {
228e7b8fc92SMarcel Holtmann 	struct hci_dev *hdev = f->private;
229e7b8fc92SMarcel Holtmann 
230e7b8fc92SMarcel Holtmann 	hci_dev_lock(hdev);
231e7b8fc92SMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->static_addr);
232e7b8fc92SMarcel Holtmann 	hci_dev_unlock(hdev);
233e7b8fc92SMarcel Holtmann 
234e7b8fc92SMarcel Holtmann 	return 0;
235e7b8fc92SMarcel Holtmann }
236e7b8fc92SMarcel Holtmann 
237e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file)
238e7b8fc92SMarcel Holtmann {
239e7b8fc92SMarcel Holtmann 	return single_open(file, static_address_show, inode->i_private);
240e7b8fc92SMarcel Holtmann }
241e7b8fc92SMarcel Holtmann 
242e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = {
243e7b8fc92SMarcel Holtmann 	.open		= static_address_open,
244e7b8fc92SMarcel Holtmann 	.read		= seq_read,
245e7b8fc92SMarcel Holtmann 	.llseek		= seq_lseek,
246e7b8fc92SMarcel Holtmann 	.release	= single_release,
247e7b8fc92SMarcel Holtmann };
248e7b8fc92SMarcel Holtmann 
249b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file,
250b32bba6cSMarcel Holtmann 					 char __user *user_buf,
251b32bba6cSMarcel Holtmann 					 size_t count, loff_t *ppos)
25292202185SMarcel Holtmann {
253b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
254b32bba6cSMarcel Holtmann 	char buf[3];
25592202185SMarcel Holtmann 
256111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N';
257b32bba6cSMarcel Holtmann 	buf[1] = '\n';
258b32bba6cSMarcel Holtmann 	buf[2] = '\0';
259b32bba6cSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
260b32bba6cSMarcel Holtmann }
261b32bba6cSMarcel Holtmann 
262b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file,
263b32bba6cSMarcel Holtmann 					  const char __user *user_buf,
264b32bba6cSMarcel Holtmann 					  size_t count, loff_t *ppos)
265b32bba6cSMarcel Holtmann {
266b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
267b32bba6cSMarcel Holtmann 	char buf[32];
268b32bba6cSMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
269b32bba6cSMarcel Holtmann 	bool enable;
270b32bba6cSMarcel Holtmann 
271b32bba6cSMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
272b32bba6cSMarcel Holtmann 		return -EBUSY;
273b32bba6cSMarcel Holtmann 
274b32bba6cSMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
275b32bba6cSMarcel Holtmann 		return -EFAULT;
276b32bba6cSMarcel Holtmann 
277b32bba6cSMarcel Holtmann 	buf[buf_size] = '\0';
278b32bba6cSMarcel Holtmann 	if (strtobool(buf, &enable))
27992202185SMarcel Holtmann 		return -EINVAL;
28092202185SMarcel Holtmann 
281111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags))
282b32bba6cSMarcel Holtmann 		return -EALREADY;
28392202185SMarcel Holtmann 
284111902f7SMarcel Holtmann 	change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags);
285b32bba6cSMarcel Holtmann 
286b32bba6cSMarcel Holtmann 	return count;
28792202185SMarcel Holtmann }
28892202185SMarcel Holtmann 
289b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = {
290b32bba6cSMarcel Holtmann 	.open		= simple_open,
291b32bba6cSMarcel Holtmann 	.read		= force_static_address_read,
292b32bba6cSMarcel Holtmann 	.write		= force_static_address_write,
293b32bba6cSMarcel Holtmann 	.llseek		= default_llseek,
294b32bba6cSMarcel Holtmann };
29592202185SMarcel Holtmann 
296d2ab0ac1SMarcel Holtmann static int white_list_show(struct seq_file *f, void *ptr)
297d2ab0ac1SMarcel Holtmann {
298d2ab0ac1SMarcel Holtmann 	struct hci_dev *hdev = f->private;
299d2ab0ac1SMarcel Holtmann 	struct bdaddr_list *b;
300d2ab0ac1SMarcel Holtmann 
301d2ab0ac1SMarcel Holtmann 	hci_dev_lock(hdev);
302d2ab0ac1SMarcel Holtmann 	list_for_each_entry(b, &hdev->le_white_list, list)
303d2ab0ac1SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
304d2ab0ac1SMarcel Holtmann 	hci_dev_unlock(hdev);
305d2ab0ac1SMarcel Holtmann 
306d2ab0ac1SMarcel Holtmann 	return 0;
307d2ab0ac1SMarcel Holtmann }
308d2ab0ac1SMarcel Holtmann 
309d2ab0ac1SMarcel Holtmann static int white_list_open(struct inode *inode, struct file *file)
310d2ab0ac1SMarcel Holtmann {
311d2ab0ac1SMarcel Holtmann 	return single_open(file, white_list_show, inode->i_private);
312d2ab0ac1SMarcel Holtmann }
313d2ab0ac1SMarcel Holtmann 
314d2ab0ac1SMarcel Holtmann static const struct file_operations white_list_fops = {
315d2ab0ac1SMarcel Holtmann 	.open		= white_list_open,
316d2ab0ac1SMarcel Holtmann 	.read		= seq_read,
317d2ab0ac1SMarcel Holtmann 	.llseek		= seq_lseek,
318d2ab0ac1SMarcel Holtmann 	.release	= single_release,
319d2ab0ac1SMarcel Holtmann };
320d2ab0ac1SMarcel Holtmann 
3213698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
3223698d704SMarcel Holtmann {
3233698d704SMarcel Holtmann 	struct hci_dev *hdev = f->private;
324adae20cbSJohan Hedberg 	struct smp_irk *irk;
3253698d704SMarcel Holtmann 
326adae20cbSJohan Hedberg 	rcu_read_lock();
327adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
3283698d704SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
3293698d704SMarcel Holtmann 			   &irk->bdaddr, irk->addr_type,
3303698d704SMarcel Holtmann 			   16, irk->val, &irk->rpa);
3313698d704SMarcel Holtmann 	}
332adae20cbSJohan Hedberg 	rcu_read_unlock();
3333698d704SMarcel Holtmann 
3343698d704SMarcel Holtmann 	return 0;
3353698d704SMarcel Holtmann }
3363698d704SMarcel Holtmann 
3373698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file)
3383698d704SMarcel Holtmann {
3393698d704SMarcel Holtmann 	return single_open(file, identity_resolving_keys_show,
3403698d704SMarcel Holtmann 			   inode->i_private);
3413698d704SMarcel Holtmann }
3423698d704SMarcel Holtmann 
3433698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = {
3443698d704SMarcel Holtmann 	.open		= identity_resolving_keys_open,
3453698d704SMarcel Holtmann 	.read		= seq_read,
3463698d704SMarcel Holtmann 	.llseek		= seq_lseek,
3473698d704SMarcel Holtmann 	.release	= single_release,
3483698d704SMarcel Holtmann };
3493698d704SMarcel Holtmann 
3508f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr)
3518f8625cdSMarcel Holtmann {
3528f8625cdSMarcel Holtmann 	struct hci_dev *hdev = f->private;
353970d0f1bSJohan Hedberg 	struct smp_ltk *ltk;
3548f8625cdSMarcel Holtmann 
355970d0f1bSJohan Hedberg 	rcu_read_lock();
356970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(ltk, &hdev->long_term_keys, list)
357fe39c7b2SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n",
3588f8625cdSMarcel Holtmann 			   &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
3598f8625cdSMarcel Holtmann 			   ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
360fe39c7b2SMarcel Holtmann 			   __le64_to_cpu(ltk->rand), 16, ltk->val);
361970d0f1bSJohan Hedberg 	rcu_read_unlock();
3628f8625cdSMarcel Holtmann 
3638f8625cdSMarcel Holtmann 	return 0;
3648f8625cdSMarcel Holtmann }
3658f8625cdSMarcel Holtmann 
3668f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file)
3678f8625cdSMarcel Holtmann {
3688f8625cdSMarcel Holtmann 	return single_open(file, long_term_keys_show, inode->i_private);
3698f8625cdSMarcel Holtmann }
3708f8625cdSMarcel Holtmann 
3718f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = {
3728f8625cdSMarcel Holtmann 	.open		= long_term_keys_open,
3738f8625cdSMarcel Holtmann 	.read		= seq_read,
3748f8625cdSMarcel Holtmann 	.llseek		= seq_lseek,
3758f8625cdSMarcel Holtmann 	.release	= single_release,
3768f8625cdSMarcel Holtmann };
3778f8625cdSMarcel Holtmann 
3784e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val)
3794e70c7e7SMarcel Holtmann {
3804e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
3814e70c7e7SMarcel Holtmann 
3824e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
3834e70c7e7SMarcel Holtmann 		return -EINVAL;
3844e70c7e7SMarcel Holtmann 
3854e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
3864e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = val;
3874e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
3884e70c7e7SMarcel Holtmann 
3894e70c7e7SMarcel Holtmann 	return 0;
3904e70c7e7SMarcel Holtmann }
3914e70c7e7SMarcel Holtmann 
3924e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val)
3934e70c7e7SMarcel Holtmann {
3944e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
3954e70c7e7SMarcel Holtmann 
3964e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
3974e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_min_interval;
3984e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
3994e70c7e7SMarcel Holtmann 
4004e70c7e7SMarcel Holtmann 	return 0;
4014e70c7e7SMarcel Holtmann }
4024e70c7e7SMarcel Holtmann 
4034e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
4044e70c7e7SMarcel Holtmann 			conn_min_interval_set, "%llu\n");
4054e70c7e7SMarcel Holtmann 
4064e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val)
4074e70c7e7SMarcel Holtmann {
4084e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
4094e70c7e7SMarcel Holtmann 
4104e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
4114e70c7e7SMarcel Holtmann 		return -EINVAL;
4124e70c7e7SMarcel Holtmann 
4134e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
4144e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = val;
4154e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
4164e70c7e7SMarcel Holtmann 
4174e70c7e7SMarcel Holtmann 	return 0;
4184e70c7e7SMarcel Holtmann }
4194e70c7e7SMarcel Holtmann 
4204e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val)
4214e70c7e7SMarcel Holtmann {
4224e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
4234e70c7e7SMarcel Holtmann 
4244e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
4254e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_max_interval;
4264e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
4274e70c7e7SMarcel Holtmann 
4284e70c7e7SMarcel Holtmann 	return 0;
4294e70c7e7SMarcel Holtmann }
4304e70c7e7SMarcel Holtmann 
4314e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
4324e70c7e7SMarcel Holtmann 			conn_max_interval_set, "%llu\n");
4334e70c7e7SMarcel Holtmann 
434816a93d1SMarcel Holtmann static int conn_latency_set(void *data, u64 val)
435816a93d1SMarcel Holtmann {
436816a93d1SMarcel Holtmann 	struct hci_dev *hdev = data;
437816a93d1SMarcel Holtmann 
438816a93d1SMarcel Holtmann 	if (val > 0x01f3)
439816a93d1SMarcel Holtmann 		return -EINVAL;
440816a93d1SMarcel Holtmann 
441816a93d1SMarcel Holtmann 	hci_dev_lock(hdev);
442816a93d1SMarcel Holtmann 	hdev->le_conn_latency = val;
443816a93d1SMarcel Holtmann 	hci_dev_unlock(hdev);
444816a93d1SMarcel Holtmann 
445816a93d1SMarcel Holtmann 	return 0;
446816a93d1SMarcel Holtmann }
447816a93d1SMarcel Holtmann 
448816a93d1SMarcel Holtmann static int conn_latency_get(void *data, u64 *val)
449816a93d1SMarcel Holtmann {
450816a93d1SMarcel Holtmann 	struct hci_dev *hdev = data;
451816a93d1SMarcel Holtmann 
452816a93d1SMarcel Holtmann 	hci_dev_lock(hdev);
453816a93d1SMarcel Holtmann 	*val = hdev->le_conn_latency;
454816a93d1SMarcel Holtmann 	hci_dev_unlock(hdev);
455816a93d1SMarcel Holtmann 
456816a93d1SMarcel Holtmann 	return 0;
457816a93d1SMarcel Holtmann }
458816a93d1SMarcel Holtmann 
459816a93d1SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get,
460816a93d1SMarcel Holtmann 			conn_latency_set, "%llu\n");
461816a93d1SMarcel Holtmann 
462f1649577SMarcel Holtmann static int supervision_timeout_set(void *data, u64 val)
463f1649577SMarcel Holtmann {
464f1649577SMarcel Holtmann 	struct hci_dev *hdev = data;
465f1649577SMarcel Holtmann 
466f1649577SMarcel Holtmann 	if (val < 0x000a || val > 0x0c80)
467f1649577SMarcel Holtmann 		return -EINVAL;
468f1649577SMarcel Holtmann 
469f1649577SMarcel Holtmann 	hci_dev_lock(hdev);
470f1649577SMarcel Holtmann 	hdev->le_supv_timeout = val;
471f1649577SMarcel Holtmann 	hci_dev_unlock(hdev);
472f1649577SMarcel Holtmann 
473f1649577SMarcel Holtmann 	return 0;
474f1649577SMarcel Holtmann }
475f1649577SMarcel Holtmann 
476f1649577SMarcel Holtmann static int supervision_timeout_get(void *data, u64 *val)
477f1649577SMarcel Holtmann {
478f1649577SMarcel Holtmann 	struct hci_dev *hdev = data;
479f1649577SMarcel Holtmann 
480f1649577SMarcel Holtmann 	hci_dev_lock(hdev);
481f1649577SMarcel Holtmann 	*val = hdev->le_supv_timeout;
482f1649577SMarcel Holtmann 	hci_dev_unlock(hdev);
483f1649577SMarcel Holtmann 
484f1649577SMarcel Holtmann 	return 0;
485f1649577SMarcel Holtmann }
486f1649577SMarcel Holtmann 
487f1649577SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get,
488f1649577SMarcel Holtmann 			supervision_timeout_set, "%llu\n");
489f1649577SMarcel Holtmann 
4903f959d46SMarcel Holtmann static int adv_channel_map_set(void *data, u64 val)
4913f959d46SMarcel Holtmann {
4923f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
4933f959d46SMarcel Holtmann 
4943f959d46SMarcel Holtmann 	if (val < 0x01 || val > 0x07)
4953f959d46SMarcel Holtmann 		return -EINVAL;
4963f959d46SMarcel Holtmann 
4973f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
4983f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = val;
4993f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
5003f959d46SMarcel Holtmann 
5013f959d46SMarcel Holtmann 	return 0;
5023f959d46SMarcel Holtmann }
5033f959d46SMarcel Holtmann 
5043f959d46SMarcel Holtmann static int adv_channel_map_get(void *data, u64 *val)
5053f959d46SMarcel Holtmann {
5063f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
5073f959d46SMarcel Holtmann 
5083f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
5093f959d46SMarcel Holtmann 	*val = hdev->le_adv_channel_map;
5103f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
5113f959d46SMarcel Holtmann 
5123f959d46SMarcel Holtmann 	return 0;
5133f959d46SMarcel Holtmann }
5143f959d46SMarcel Holtmann 
5153f959d46SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
5163f959d46SMarcel Holtmann 			adv_channel_map_set, "%llu\n");
5173f959d46SMarcel Holtmann 
518729a1051SGeorg Lukas static int adv_min_interval_set(void *data, u64 val)
51989863109SJukka Rissanen {
520729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
52189863109SJukka Rissanen 
522729a1051SGeorg Lukas 	if (val < 0x0020 || val > 0x4000 || val > hdev->le_adv_max_interval)
52389863109SJukka Rissanen 		return -EINVAL;
52489863109SJukka Rissanen 
5257d474e06SAndre Guedes 	hci_dev_lock(hdev);
526729a1051SGeorg Lukas 	hdev->le_adv_min_interval = val;
5277d474e06SAndre Guedes 	hci_dev_unlock(hdev);
5287d474e06SAndre Guedes 
5297d474e06SAndre Guedes 	return 0;
5307d474e06SAndre Guedes }
5317d474e06SAndre Guedes 
532729a1051SGeorg Lukas static int adv_min_interval_get(void *data, u64 *val)
5337d474e06SAndre Guedes {
534729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
535729a1051SGeorg Lukas 
536729a1051SGeorg Lukas 	hci_dev_lock(hdev);
537729a1051SGeorg Lukas 	*val = hdev->le_adv_min_interval;
538729a1051SGeorg Lukas 	hci_dev_unlock(hdev);
539729a1051SGeorg Lukas 
540729a1051SGeorg Lukas 	return 0;
5417d474e06SAndre Guedes }
5427d474e06SAndre Guedes 
543729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_min_interval_fops, adv_min_interval_get,
544729a1051SGeorg Lukas 			adv_min_interval_set, "%llu\n");
5457d474e06SAndre Guedes 
546729a1051SGeorg Lukas static int adv_max_interval_set(void *data, u64 val)
547729a1051SGeorg Lukas {
548729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
549729a1051SGeorg Lukas 
550729a1051SGeorg Lukas 	if (val < 0x0020 || val > 0x4000 || val < hdev->le_adv_min_interval)
5517d474e06SAndre Guedes 		return -EINVAL;
5527d474e06SAndre Guedes 
5537d474e06SAndre Guedes 	hci_dev_lock(hdev);
554729a1051SGeorg Lukas 	hdev->le_adv_max_interval = val;
5557d474e06SAndre Guedes 	hci_dev_unlock(hdev);
5567d474e06SAndre Guedes 
557729a1051SGeorg Lukas 	return 0;
5587d474e06SAndre Guedes }
5597d474e06SAndre Guedes 
560729a1051SGeorg Lukas static int adv_max_interval_get(void *data, u64 *val)
561729a1051SGeorg Lukas {
562729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
563729a1051SGeorg Lukas 
5647d474e06SAndre Guedes 	hci_dev_lock(hdev);
565729a1051SGeorg Lukas 	*val = hdev->le_adv_max_interval;
5667d474e06SAndre Guedes 	hci_dev_unlock(hdev);
567729a1051SGeorg Lukas 
568729a1051SGeorg Lukas 	return 0;
569729a1051SGeorg Lukas }
570729a1051SGeorg Lukas 
571729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get,
572729a1051SGeorg Lukas 			adv_max_interval_set, "%llu\n");
573729a1051SGeorg Lukas 
5741da177e4SLinus Torvalds /* ---- HCI requests ---- */
5751da177e4SLinus Torvalds 
57642c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
5771da177e4SLinus Torvalds {
57842c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
57975fb0e32SJohan Hedberg 
5801da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
5811da177e4SLinus Torvalds 		hdev->req_result = result;
5821da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
5831da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
5841da177e4SLinus Torvalds 	}
5851da177e4SLinus Torvalds }
5861da177e4SLinus Torvalds 
5871da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
5881da177e4SLinus Torvalds {
5891da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
5901da177e4SLinus Torvalds 
5911da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
5921da177e4SLinus Torvalds 		hdev->req_result = err;
5931da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
5941da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
5951da177e4SLinus Torvalds 	}
5961da177e4SLinus Torvalds }
5971da177e4SLinus Torvalds 
59877a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
59977a63e0aSFengguang Wu 					    u8 event)
60075e84b7cSJohan Hedberg {
60175e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
60275e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
60375e84b7cSJohan Hedberg 	struct sk_buff *skb;
60475e84b7cSJohan Hedberg 
60575e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
60675e84b7cSJohan Hedberg 
60775e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
60875e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
60975e84b7cSJohan Hedberg 
61075e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
61175e84b7cSJohan Hedberg 
61275e84b7cSJohan Hedberg 	if (!skb)
61375e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
61475e84b7cSJohan Hedberg 
61575e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
61675e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
61775e84b7cSJohan Hedberg 		goto failed;
61875e84b7cSJohan Hedberg 	}
61975e84b7cSJohan Hedberg 
62075e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
62175e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
62275e84b7cSJohan Hedberg 
6237b1abbbeSJohan Hedberg 	if (event) {
6247b1abbbeSJohan Hedberg 		if (hdr->evt != event)
6257b1abbbeSJohan Hedberg 			goto failed;
6267b1abbbeSJohan Hedberg 		return skb;
6277b1abbbeSJohan Hedberg 	}
6287b1abbbeSJohan Hedberg 
62975e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
63075e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
63175e84b7cSJohan Hedberg 		goto failed;
63275e84b7cSJohan Hedberg 	}
63375e84b7cSJohan Hedberg 
63475e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
63575e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
63675e84b7cSJohan Hedberg 		goto failed;
63775e84b7cSJohan Hedberg 	}
63875e84b7cSJohan Hedberg 
63975e84b7cSJohan Hedberg 	ev = (void *) skb->data;
64075e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
64175e84b7cSJohan Hedberg 
64275e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
64375e84b7cSJohan Hedberg 		return skb;
64475e84b7cSJohan Hedberg 
64575e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
64675e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
64775e84b7cSJohan Hedberg 
64875e84b7cSJohan Hedberg failed:
64975e84b7cSJohan Hedberg 	kfree_skb(skb);
65075e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
65175e84b7cSJohan Hedberg }
65275e84b7cSJohan Hedberg 
6537b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
65407dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
65575e84b7cSJohan Hedberg {
65675e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
65775e84b7cSJohan Hedberg 	struct hci_request req;
65875e84b7cSJohan Hedberg 	int err = 0;
65975e84b7cSJohan Hedberg 
66075e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
66175e84b7cSJohan Hedberg 
66275e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
66375e84b7cSJohan Hedberg 
6647b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
66575e84b7cSJohan Hedberg 
66675e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
66775e84b7cSJohan Hedberg 
66875e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
66975e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
67075e84b7cSJohan Hedberg 
671039fada5SChan-yeol Park 	err = hci_req_run(&req, hci_req_sync_complete);
672039fada5SChan-yeol Park 	if (err < 0) {
673039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
67422a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
675039fada5SChan-yeol Park 		return ERR_PTR(err);
676039fada5SChan-yeol Park 	}
677039fada5SChan-yeol Park 
67875e84b7cSJohan Hedberg 	schedule_timeout(timeout);
67975e84b7cSJohan Hedberg 
68075e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
68175e84b7cSJohan Hedberg 
68275e84b7cSJohan Hedberg 	if (signal_pending(current))
68375e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
68475e84b7cSJohan Hedberg 
68575e84b7cSJohan Hedberg 	switch (hdev->req_status) {
68675e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
68775e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
68875e84b7cSJohan Hedberg 		break;
68975e84b7cSJohan Hedberg 
69075e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
69175e84b7cSJohan Hedberg 		err = -hdev->req_result;
69275e84b7cSJohan Hedberg 		break;
69375e84b7cSJohan Hedberg 
69475e84b7cSJohan Hedberg 	default:
69575e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
69675e84b7cSJohan Hedberg 		break;
69775e84b7cSJohan Hedberg 	}
69875e84b7cSJohan Hedberg 
69975e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
70075e84b7cSJohan Hedberg 
70175e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
70275e84b7cSJohan Hedberg 
70375e84b7cSJohan Hedberg 	if (err < 0)
70475e84b7cSJohan Hedberg 		return ERR_PTR(err);
70575e84b7cSJohan Hedberg 
7067b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
7077b1abbbeSJohan Hedberg }
7087b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
7097b1abbbeSJohan Hedberg 
7107b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
71107dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
7127b1abbbeSJohan Hedberg {
7137b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
71475e84b7cSJohan Hedberg }
71575e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
71675e84b7cSJohan Hedberg 
7171da177e4SLinus Torvalds /* Execute request and wait for completion. */
71801178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
71942c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
72042c6b129SJohan Hedberg 				      unsigned long opt),
7211da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
7221da177e4SLinus Torvalds {
72342c6b129SJohan Hedberg 	struct hci_request req;
7241da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
7251da177e4SLinus Torvalds 	int err = 0;
7261da177e4SLinus Torvalds 
7271da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
7281da177e4SLinus Torvalds 
72942c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
73042c6b129SJohan Hedberg 
7311da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
7321da177e4SLinus Torvalds 
73342c6b129SJohan Hedberg 	func(&req, opt);
73453cce22dSJohan Hedberg 
735039fada5SChan-yeol Park 	add_wait_queue(&hdev->req_wait_q, &wait);
736039fada5SChan-yeol Park 	set_current_state(TASK_INTERRUPTIBLE);
737039fada5SChan-yeol Park 
73842c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
73942c6b129SJohan Hedberg 	if (err < 0) {
74053cce22dSJohan Hedberg 		hdev->req_status = 0;
741920c8300SAndre Guedes 
742039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
74322a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
744039fada5SChan-yeol Park 
745920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
746920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
747920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
748920c8300SAndre Guedes 		 * and should not trigger an error return.
74942c6b129SJohan Hedberg 		 */
750920c8300SAndre Guedes 		if (err == -ENODATA)
75142c6b129SJohan Hedberg 			return 0;
752920c8300SAndre Guedes 
753920c8300SAndre Guedes 		return err;
75453cce22dSJohan Hedberg 	}
75553cce22dSJohan Hedberg 
7561da177e4SLinus Torvalds 	schedule_timeout(timeout);
7571da177e4SLinus Torvalds 
7581da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
7591da177e4SLinus Torvalds 
7601da177e4SLinus Torvalds 	if (signal_pending(current))
7611da177e4SLinus Torvalds 		return -EINTR;
7621da177e4SLinus Torvalds 
7631da177e4SLinus Torvalds 	switch (hdev->req_status) {
7641da177e4SLinus Torvalds 	case HCI_REQ_DONE:
765e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
7661da177e4SLinus Torvalds 		break;
7671da177e4SLinus Torvalds 
7681da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
7691da177e4SLinus Torvalds 		err = -hdev->req_result;
7701da177e4SLinus Torvalds 		break;
7711da177e4SLinus Torvalds 
7721da177e4SLinus Torvalds 	default:
7731da177e4SLinus Torvalds 		err = -ETIMEDOUT;
7741da177e4SLinus Torvalds 		break;
7753ff50b79SStephen Hemminger 	}
7761da177e4SLinus Torvalds 
777a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
7781da177e4SLinus Torvalds 
7791da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
7801da177e4SLinus Torvalds 
7811da177e4SLinus Torvalds 	return err;
7821da177e4SLinus Torvalds }
7831da177e4SLinus Torvalds 
78401178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
78542c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
78642c6b129SJohan Hedberg 				    unsigned long opt),
7871da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
7881da177e4SLinus Torvalds {
7891da177e4SLinus Torvalds 	int ret;
7901da177e4SLinus Torvalds 
7917c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
7927c6a329eSMarcel Holtmann 		return -ENETDOWN;
7937c6a329eSMarcel Holtmann 
7941da177e4SLinus Torvalds 	/* Serialize all requests */
7951da177e4SLinus Torvalds 	hci_req_lock(hdev);
79601178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
7971da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7981da177e4SLinus Torvalds 
7991da177e4SLinus Torvalds 	return ret;
8001da177e4SLinus Torvalds }
8011da177e4SLinus Torvalds 
80242c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
8031da177e4SLinus Torvalds {
80442c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
8051da177e4SLinus Torvalds 
8061da177e4SLinus Torvalds 	/* Reset device */
80742c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
80842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
8091da177e4SLinus Torvalds }
8101da177e4SLinus Torvalds 
81142c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
8121da177e4SLinus Torvalds {
81342c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
8142455a3eaSAndrei Emeltchenko 
8151da177e4SLinus Torvalds 	/* Read Local Supported Features */
81642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
8171da177e4SLinus Torvalds 
8181143e5a6SMarcel Holtmann 	/* Read Local Version */
81942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
8202177bab5SJohan Hedberg 
8212177bab5SJohan Hedberg 	/* Read BD Address */
82242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
8231da177e4SLinus Torvalds }
8241da177e4SLinus Torvalds 
82542c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
826e61ef499SAndrei Emeltchenko {
82742c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
8282455a3eaSAndrei Emeltchenko 
829e61ef499SAndrei Emeltchenko 	/* Read Local Version */
83042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
8316bcbc489SAndrei Emeltchenko 
832f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
833f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
834f6996cfeSMarcel Holtmann 
835f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
836f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
837f6996cfeSMarcel Holtmann 
8386bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
83942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
840e71dfabaSAndrei Emeltchenko 
841e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
84242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
8437528ca1cSMarcel Holtmann 
844f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
845f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
846f38ba941SMarcel Holtmann 
8477528ca1cSMarcel Holtmann 	/* Read Location Data */
8487528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
849e61ef499SAndrei Emeltchenko }
850e61ef499SAndrei Emeltchenko 
85142c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
852e61ef499SAndrei Emeltchenko {
85342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
854e61ef499SAndrei Emeltchenko 
855e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
856e61ef499SAndrei Emeltchenko 
85711778716SAndrei Emeltchenko 	/* Reset */
85811778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
85942c6b129SJohan Hedberg 		hci_reset_req(req, 0);
86011778716SAndrei Emeltchenko 
861e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
862e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
86342c6b129SJohan Hedberg 		bredr_init(req);
864e61ef499SAndrei Emeltchenko 		break;
865e61ef499SAndrei Emeltchenko 
866e61ef499SAndrei Emeltchenko 	case HCI_AMP:
86742c6b129SJohan Hedberg 		amp_init(req);
868e61ef499SAndrei Emeltchenko 		break;
869e61ef499SAndrei Emeltchenko 
870e61ef499SAndrei Emeltchenko 	default:
871e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
872e61ef499SAndrei Emeltchenko 		break;
873e61ef499SAndrei Emeltchenko 	}
874e61ef499SAndrei Emeltchenko }
875e61ef499SAndrei Emeltchenko 
87642c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
8772177bab5SJohan Hedberg {
8782177bab5SJohan Hedberg 	__le16 param;
8792177bab5SJohan Hedberg 	__u8 flt_type;
8802177bab5SJohan Hedberg 
8812177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
88242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
8832177bab5SJohan Hedberg 
8842177bab5SJohan Hedberg 	/* Read Class of Device */
88542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
8862177bab5SJohan Hedberg 
8872177bab5SJohan Hedberg 	/* Read Local Name */
88842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
8892177bab5SJohan Hedberg 
8902177bab5SJohan Hedberg 	/* Read Voice Setting */
89142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
8922177bab5SJohan Hedberg 
893b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
894b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
895b4cb9fb2SMarcel Holtmann 
8964b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
8974b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
8984b836f39SMarcel Holtmann 
8992177bab5SJohan Hedberg 	/* Clear Event Filters */
9002177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
90142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
9022177bab5SJohan Hedberg 
9032177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
904dcf4adbfSJoe Perches 	param = cpu_to_le16(0x7d00);
90542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
9062177bab5SJohan Hedberg }
9072177bab5SJohan Hedberg 
90842c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
9092177bab5SJohan Hedberg {
910c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
911c73eee91SJohan Hedberg 
9122177bab5SJohan Hedberg 	/* Read LE Buffer Size */
91342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
9142177bab5SJohan Hedberg 
9152177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
91642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
9172177bab5SJohan Hedberg 
918747d3f03SMarcel Holtmann 	/* Read LE Supported States */
919747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
920747d3f03SMarcel Holtmann 
9212177bab5SJohan Hedberg 	/* Read LE White List Size */
92242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
9232177bab5SJohan Hedberg 
924747d3f03SMarcel Holtmann 	/* Clear LE White List */
925747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
926c73eee91SJohan Hedberg 
927c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
928c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
929c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
9302177bab5SJohan Hedberg }
9312177bab5SJohan Hedberg 
9322177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
9332177bab5SJohan Hedberg {
9342177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
9352177bab5SJohan Hedberg 		return 0x02;
9362177bab5SJohan Hedberg 
9372177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
9382177bab5SJohan Hedberg 		return 0x01;
9392177bab5SJohan Hedberg 
9402177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
9412177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
9422177bab5SJohan Hedberg 		return 0x01;
9432177bab5SJohan Hedberg 
9442177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
9452177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
9462177bab5SJohan Hedberg 			return 0x01;
9472177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
9482177bab5SJohan Hedberg 			return 0x01;
9492177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
9502177bab5SJohan Hedberg 			return 0x01;
9512177bab5SJohan Hedberg 	}
9522177bab5SJohan Hedberg 
9532177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
9542177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
9552177bab5SJohan Hedberg 		return 0x01;
9562177bab5SJohan Hedberg 
9572177bab5SJohan Hedberg 	return 0x00;
9582177bab5SJohan Hedberg }
9592177bab5SJohan Hedberg 
96042c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
9612177bab5SJohan Hedberg {
9622177bab5SJohan Hedberg 	u8 mode;
9632177bab5SJohan Hedberg 
96442c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
9652177bab5SJohan Hedberg 
96642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
9672177bab5SJohan Hedberg }
9682177bab5SJohan Hedberg 
96942c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
9702177bab5SJohan Hedberg {
97142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
97242c6b129SJohan Hedberg 
9732177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
9742177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
9752177bab5SJohan Hedberg 	 * command otherwise.
9762177bab5SJohan Hedberg 	 */
9772177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
9782177bab5SJohan Hedberg 
9792177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
9802177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
9812177bab5SJohan Hedberg 	 */
9822177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
9832177bab5SJohan Hedberg 		return;
9842177bab5SJohan Hedberg 
9852177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
9862177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
9872177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
9882177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
9892177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
9902177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
991c7882cbdSMarcel Holtmann 	} else {
992c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
993c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
994c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
995c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
996c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
997c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
998c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
999c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
1000c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
10010da71f1bSMarcel Holtmann 
10020da71f1bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION) {
10030da71f1bSMarcel Holtmann 			events[0] |= 0x80; /* Encryption Change */
1004c7882cbdSMarcel Holtmann 			events[5] |= 0x80; /* Encryption Key Refresh Complete */
10052177bab5SJohan Hedberg 		}
10060da71f1bSMarcel Holtmann 	}
10072177bab5SJohan Hedberg 
10082177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
10092177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
10102177bab5SJohan Hedberg 
10112177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
10122177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
10132177bab5SJohan Hedberg 
10142177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
10152177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
10162177bab5SJohan Hedberg 
10172177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
10182177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
10192177bab5SJohan Hedberg 
10202177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
10212177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
10222177bab5SJohan Hedberg 
10232177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
10242177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
10252177bab5SJohan Hedberg 
10262177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
10272177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
10282177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
10292177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
10302177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
10312177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
10322177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
10332177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
10342177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
10352177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
10362177bab5SJohan Hedberg 					 * Features Notification
10372177bab5SJohan Hedberg 					 */
10382177bab5SJohan Hedberg 	}
10392177bab5SJohan Hedberg 
10402177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
10412177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
10422177bab5SJohan Hedberg 
104342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
10442177bab5SJohan Hedberg }
10452177bab5SJohan Hedberg 
104642c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
10472177bab5SJohan Hedberg {
104842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
104942c6b129SJohan Hedberg 
10502177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
105142c6b129SJohan Hedberg 		bredr_setup(req);
105256f87901SJohan Hedberg 	else
105356f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
10542177bab5SJohan Hedberg 
10552177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
105642c6b129SJohan Hedberg 		le_setup(req);
10572177bab5SJohan Hedberg 
10583f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
10593f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
10603f8e2d75SJohan Hedberg 	 */
10613f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
106242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
10632177bab5SJohan Hedberg 
10642177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
106557af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
106657af75a8SMarcel Holtmann 		 * should also be available as well. However some
106757af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
106857af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
106957af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
107057af75a8SMarcel Holtmann 		 */
107157af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
107257af75a8SMarcel Holtmann 
10732177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
10742177bab5SJohan Hedberg 			u8 mode = 0x01;
107542c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
10762177bab5SJohan Hedberg 				    sizeof(mode), &mode);
10772177bab5SJohan Hedberg 		} else {
10782177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
10792177bab5SJohan Hedberg 
10802177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
10812177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
10822177bab5SJohan Hedberg 
108342c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
10842177bab5SJohan Hedberg 		}
10852177bab5SJohan Hedberg 	}
10862177bab5SJohan Hedberg 
10872177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
108842c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
10892177bab5SJohan Hedberg 
10902177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
109142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
10922177bab5SJohan Hedberg 
10932177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
10942177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
10952177bab5SJohan Hedberg 
10962177bab5SJohan Hedberg 		cp.page = 0x01;
109742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
109842c6b129SJohan Hedberg 			    sizeof(cp), &cp);
10992177bab5SJohan Hedberg 	}
11002177bab5SJohan Hedberg 
11012177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
11022177bab5SJohan Hedberg 		u8 enable = 1;
110342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
11042177bab5SJohan Hedberg 			    &enable);
11052177bab5SJohan Hedberg 	}
11062177bab5SJohan Hedberg }
11072177bab5SJohan Hedberg 
110842c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
11092177bab5SJohan Hedberg {
111042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
11112177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
11122177bab5SJohan Hedberg 	u16 link_policy = 0;
11132177bab5SJohan Hedberg 
11142177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
11152177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
11162177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
11172177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
11182177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
11192177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
11202177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
11212177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
11222177bab5SJohan Hedberg 
11232177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
112442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
11252177bab5SJohan Hedberg }
11262177bab5SJohan Hedberg 
112742c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
11282177bab5SJohan Hedberg {
112942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
11302177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
11312177bab5SJohan Hedberg 
1132c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
1133c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1134c73eee91SJohan Hedberg 		return;
1135c73eee91SJohan Hedberg 
11362177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
11372177bab5SJohan Hedberg 
11382177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
11392177bab5SJohan Hedberg 		cp.le = 0x01;
114032226e4fSMarcel Holtmann 		cp.simul = 0x00;
11412177bab5SJohan Hedberg 	}
11422177bab5SJohan Hedberg 
11432177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
114442c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
11452177bab5SJohan Hedberg 			    &cp);
11462177bab5SJohan Hedberg }
11472177bab5SJohan Hedberg 
1148d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
1149d62e6d67SJohan Hedberg {
1150d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1151d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1152d62e6d67SJohan Hedberg 
1153d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
1154d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1155d62e6d67SJohan Hedberg 	 */
115653b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
1157d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
1158d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
1159d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
1160d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
1161d62e6d67SJohan Hedberg 	}
1162d62e6d67SJohan Hedberg 
1163d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
1164d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1165d62e6d67SJohan Hedberg 	 */
116653b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
1167d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
1168d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
1169d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
1170d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
1171d62e6d67SJohan Hedberg 	}
1172d62e6d67SJohan Hedberg 
117340c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
1174cd7ca0ecSMarcel Holtmann 	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
117540c59fcbSMarcel Holtmann 		events[2] |= 0x80;
117640c59fcbSMarcel Holtmann 
1177d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
1178d62e6d67SJohan Hedberg }
1179d62e6d67SJohan Hedberg 
118042c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
11812177bab5SJohan Hedberg {
118242c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1183d2c5d77fSJohan Hedberg 	u8 p;
118442c6b129SJohan Hedberg 
11850da71f1bSMarcel Holtmann 	hci_setup_event_mask(req);
11860da71f1bSMarcel Holtmann 
1187b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
1188b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
1189b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
1190b8f4e068SGustavo Padovan 	 *
1191b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
1192b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
1193b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
1194b8f4e068SGustavo Padovan 	 * command redundant anyway.
1195f9f462faSMarcel Holtmann 	 *
1196f9f462faSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
1197f9f462faSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
1198f9f462faSMarcel Holtmann 	 * just disable this command.
1199b8f4e068SGustavo Padovan 	 */
1200f9f462faSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
1201f9f462faSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
120259f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
120359f45d57SJohan Hedberg 
120459f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
120559f45d57SJohan Hedberg 		cp.delete_all = 0x01;
120659f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
120759f45d57SJohan Hedberg 			    sizeof(cp), &cp);
120859f45d57SJohan Hedberg 	}
120959f45d57SJohan Hedberg 
12102177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
121142c6b129SJohan Hedberg 		hci_setup_link_policy(req);
12122177bab5SJohan Hedberg 
1213417287deSMarcel Holtmann 	if (hdev->commands[8] & 0x01)
1214417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
1215417287deSMarcel Holtmann 
1216417287deSMarcel Holtmann 	/* Some older Broadcom based Bluetooth 1.2 controllers do not
1217417287deSMarcel Holtmann 	 * support the Read Page Scan Type command. Check support for
1218417287deSMarcel Holtmann 	 * this command in the bit mask of supported commands.
1219417287deSMarcel Holtmann 	 */
1220417287deSMarcel Holtmann 	if (hdev->commands[13] & 0x01)
1221417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
1222417287deSMarcel Holtmann 
12239193c6e8SAndre Guedes 	if (lmp_le_capable(hdev)) {
12249193c6e8SAndre Guedes 		u8 events[8];
12259193c6e8SAndre Guedes 
12269193c6e8SAndre Guedes 		memset(events, 0, sizeof(events));
12274d6c705bSMarcel Holtmann 		events[0] = 0x0f;
12284d6c705bSMarcel Holtmann 
12294d6c705bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
12304d6c705bSMarcel Holtmann 			events[0] |= 0x10;	/* LE Long Term Key Request */
1231662bc2e6SAndre Guedes 
1232662bc2e6SAndre Guedes 		/* If controller supports the Connection Parameters Request
1233662bc2e6SAndre Guedes 		 * Link Layer Procedure, enable the corresponding event.
1234662bc2e6SAndre Guedes 		 */
1235662bc2e6SAndre Guedes 		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
1236662bc2e6SAndre Guedes 			events[0] |= 0x20;	/* LE Remote Connection
1237662bc2e6SAndre Guedes 						 * Parameter Request
1238662bc2e6SAndre Guedes 						 */
1239662bc2e6SAndre Guedes 
12404b71bba4SMarcel Holtmann 		/* If the controller supports Extended Scanner Filter
12414b71bba4SMarcel Holtmann 		 * Policies, enable the correspondig event.
12424b71bba4SMarcel Holtmann 		 */
12434b71bba4SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)
12444b71bba4SMarcel Holtmann 			events[1] |= 0x04;	/* LE Direct Advertising
12454b71bba4SMarcel Holtmann 						 * Report
12464b71bba4SMarcel Holtmann 						 */
12474b71bba4SMarcel Holtmann 
12485a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Read Local P-256
12495a34bd5fSMarcel Holtmann 		 * Public Key command, enable the corresponding event.
12505a34bd5fSMarcel Holtmann 		 */
12515a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x02)
12525a34bd5fSMarcel Holtmann 			events[0] |= 0x80;	/* LE Read Local P-256
12535a34bd5fSMarcel Holtmann 						 * Public Key Complete
12545a34bd5fSMarcel Holtmann 						 */
12555a34bd5fSMarcel Holtmann 
12565a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Generate DHKey
12575a34bd5fSMarcel Holtmann 		 * command, enable the corresponding event.
12585a34bd5fSMarcel Holtmann 		 */
12595a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x04)
12605a34bd5fSMarcel Holtmann 			events[1] |= 0x01;	/* LE Generate DHKey Complete */
12615a34bd5fSMarcel Holtmann 
12629193c6e8SAndre Guedes 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
12639193c6e8SAndre Guedes 			    events);
12649193c6e8SAndre Guedes 
126515a49ccaSMarcel Holtmann 		if (hdev->commands[25] & 0x40) {
126615a49ccaSMarcel Holtmann 			/* Read LE Advertising Channel TX Power */
126715a49ccaSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
126815a49ccaSMarcel Holtmann 		}
126915a49ccaSMarcel Holtmann 
127042c6b129SJohan Hedberg 		hci_set_le_support(req);
12719193c6e8SAndre Guedes 	}
1272d2c5d77fSJohan Hedberg 
1273d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
1274d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
1275d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
1276d2c5d77fSJohan Hedberg 
1277d2c5d77fSJohan Hedberg 		cp.page = p;
1278d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
1279d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
1280d2c5d77fSJohan Hedberg 	}
12812177bab5SJohan Hedberg }
12822177bab5SJohan Hedberg 
12835d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
12845d4e7e8dSJohan Hedberg {
12855d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
12865d4e7e8dSJohan Hedberg 
1287d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
1288d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
1289d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
1290d62e6d67SJohan Hedberg 
1291109e3191SMarcel Holtmann 	/* Read local codec list if the HCI command is supported */
1292109e3191SMarcel Holtmann 	if (hdev->commands[29] & 0x20)
1293109e3191SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
1294109e3191SMarcel Holtmann 
1295f4fe73edSMarcel Holtmann 	/* Get MWS transport configuration if the HCI command is supported */
1296f4fe73edSMarcel Holtmann 	if (hdev->commands[30] & 0x08)
1297f4fe73edSMarcel Holtmann 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
1298f4fe73edSMarcel Holtmann 
12995d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
130053b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
13015d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
1302a6d0d690SMarcel Holtmann 
1303a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
1304710f11c0SJohan Hedberg 	if (bredr_sc_enabled(hdev)) {
1305a6d0d690SMarcel Holtmann 		u8 support = 0x01;
1306a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
1307a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
1308a6d0d690SMarcel Holtmann 	}
13095d4e7e8dSJohan Hedberg }
13105d4e7e8dSJohan Hedberg 
13112177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
13122177bab5SJohan Hedberg {
13132177bab5SJohan Hedberg 	int err;
13142177bab5SJohan Hedberg 
13152177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
13162177bab5SJohan Hedberg 	if (err < 0)
13172177bab5SJohan Hedberg 		return err;
13182177bab5SJohan Hedberg 
13194b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
13204b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
13214b4148e9SMarcel Holtmann 	 */
13224b4148e9SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
13234b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
13244b4148e9SMarcel Holtmann 				    &dut_mode_fops);
13254b4148e9SMarcel Holtmann 	}
13264b4148e9SMarcel Holtmann 
13272177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
13282177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
13292177bab5SJohan Hedberg 	 * first stage init.
13302177bab5SJohan Hedberg 	 */
13312177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
13322177bab5SJohan Hedberg 		return 0;
13332177bab5SJohan Hedberg 
13342177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
13352177bab5SJohan Hedberg 	if (err < 0)
13362177bab5SJohan Hedberg 		return err;
13372177bab5SJohan Hedberg 
13385d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
13395d4e7e8dSJohan Hedberg 	if (err < 0)
13405d4e7e8dSJohan Hedberg 		return err;
13415d4e7e8dSJohan Hedberg 
1342baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
1343baf27f6eSMarcel Holtmann 	if (err < 0)
1344baf27f6eSMarcel Holtmann 		return err;
1345baf27f6eSMarcel Holtmann 
1346baf27f6eSMarcel Holtmann 	/* Only create debugfs entries during the initial setup
1347baf27f6eSMarcel Holtmann 	 * phase and not every time the controller gets powered on.
1348baf27f6eSMarcel Holtmann 	 */
1349baf27f6eSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1350baf27f6eSMarcel Holtmann 		return 0;
1351baf27f6eSMarcel Holtmann 
135260c5f5fbSMarcel Holtmann 	hci_debugfs_create_common(hdev);
135360c5f5fbSMarcel Holtmann 
135471c3b60eSMarcel Holtmann 	if (lmp_bredr_capable(hdev))
135560c5f5fbSMarcel Holtmann 		hci_debugfs_create_bredr(hdev);
13562bfa3531SMarcel Holtmann 
1357d0f729b8SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1358ac345813SMarcel Holtmann 		debugfs_create_file("identity", 0400, hdev->debugfs,
1359ac345813SMarcel Holtmann 				    hdev, &identity_fops);
1360ac345813SMarcel Holtmann 		debugfs_create_file("rpa_timeout", 0644, hdev->debugfs,
1361ac345813SMarcel Holtmann 				    hdev, &rpa_timeout_fops);
13627a4cd51dSMarcel Holtmann 		debugfs_create_file("random_address", 0444, hdev->debugfs,
13637a4cd51dSMarcel Holtmann 				    hdev, &random_address_fops);
1364e7b8fc92SMarcel Holtmann 		debugfs_create_file("static_address", 0444, hdev->debugfs,
1365e7b8fc92SMarcel Holtmann 				    hdev, &static_address_fops);
1366b32bba6cSMarcel Holtmann 
1367b32bba6cSMarcel Holtmann 		/* For controllers with a public address, provide a debug
1368b32bba6cSMarcel Holtmann 		 * option to force the usage of the configured static
1369b32bba6cSMarcel Holtmann 		 * address. By default the public address is used.
1370b32bba6cSMarcel Holtmann 		 */
1371b32bba6cSMarcel Holtmann 		if (bacmp(&hdev->bdaddr, BDADDR_ANY))
1372b32bba6cSMarcel Holtmann 			debugfs_create_file("force_static_address", 0644,
1373b32bba6cSMarcel Holtmann 					    hdev->debugfs, hdev,
1374b32bba6cSMarcel Holtmann 					    &force_static_address_fops);
1375b32bba6cSMarcel Holtmann 
1376b32bba6cSMarcel Holtmann 		debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1377b32bba6cSMarcel Holtmann 				  &hdev->le_white_list_size);
1378d2ab0ac1SMarcel Holtmann 		debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
1379d2ab0ac1SMarcel Holtmann 				    &white_list_fops);
13803698d704SMarcel Holtmann 		debugfs_create_file("identity_resolving_keys", 0400,
13813698d704SMarcel Holtmann 				    hdev->debugfs, hdev,
13823698d704SMarcel Holtmann 				    &identity_resolving_keys_fops);
13838f8625cdSMarcel Holtmann 		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
13848f8625cdSMarcel Holtmann 				    hdev, &long_term_keys_fops);
13854e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
13864e70c7e7SMarcel Holtmann 				    hdev, &conn_min_interval_fops);
13874e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
13884e70c7e7SMarcel Holtmann 				    hdev, &conn_max_interval_fops);
1389816a93d1SMarcel Holtmann 		debugfs_create_file("conn_latency", 0644, hdev->debugfs,
1390816a93d1SMarcel Holtmann 				    hdev, &conn_latency_fops);
1391f1649577SMarcel Holtmann 		debugfs_create_file("supervision_timeout", 0644, hdev->debugfs,
1392f1649577SMarcel Holtmann 				    hdev, &supervision_timeout_fops);
13933f959d46SMarcel Holtmann 		debugfs_create_file("adv_channel_map", 0644, hdev->debugfs,
13943f959d46SMarcel Holtmann 				    hdev, &adv_channel_map_fops);
1395729a1051SGeorg Lukas 		debugfs_create_file("adv_min_interval", 0644, hdev->debugfs,
1396729a1051SGeorg Lukas 				    hdev, &adv_min_interval_fops);
1397729a1051SGeorg Lukas 		debugfs_create_file("adv_max_interval", 0644, hdev->debugfs,
1398729a1051SGeorg Lukas 				    hdev, &adv_max_interval_fops);
1399b9a7a61eSLukasz Rymanowski 		debugfs_create_u16("discov_interleaved_timeout", 0644,
1400b9a7a61eSLukasz Rymanowski 				   hdev->debugfs,
1401b9a7a61eSLukasz Rymanowski 				   &hdev->discov_interleaved_timeout);
140254506918SJohan Hedberg 
140360c5f5fbSMarcel Holtmann 		hci_debugfs_create_le(hdev);
140460c5f5fbSMarcel Holtmann 
1405711eafe3SJohan Hedberg 		smp_register(hdev);
1406d0f729b8SMarcel Holtmann 	}
1407e7b8fc92SMarcel Holtmann 
1408baf27f6eSMarcel Holtmann 	return 0;
14092177bab5SJohan Hedberg }
14102177bab5SJohan Hedberg 
14110ebca7d6SMarcel Holtmann static void hci_init0_req(struct hci_request *req, unsigned long opt)
14120ebca7d6SMarcel Holtmann {
14130ebca7d6SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
14140ebca7d6SMarcel Holtmann 
14150ebca7d6SMarcel Holtmann 	BT_DBG("%s %ld", hdev->name, opt);
14160ebca7d6SMarcel Holtmann 
14170ebca7d6SMarcel Holtmann 	/* Reset */
14180ebca7d6SMarcel Holtmann 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
14190ebca7d6SMarcel Holtmann 		hci_reset_req(req, 0);
14200ebca7d6SMarcel Holtmann 
14210ebca7d6SMarcel Holtmann 	/* Read Local Version */
14220ebca7d6SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
14230ebca7d6SMarcel Holtmann 
14240ebca7d6SMarcel Holtmann 	/* Read BD Address */
14250ebca7d6SMarcel Holtmann 	if (hdev->set_bdaddr)
14260ebca7d6SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
14270ebca7d6SMarcel Holtmann }
14280ebca7d6SMarcel Holtmann 
14290ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev)
14300ebca7d6SMarcel Holtmann {
14310ebca7d6SMarcel Holtmann 	int err;
14320ebca7d6SMarcel Holtmann 
1433cc78b44bSMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1434cc78b44bSMarcel Holtmann 		return 0;
1435cc78b44bSMarcel Holtmann 
14360ebca7d6SMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT);
14370ebca7d6SMarcel Holtmann 	if (err < 0)
14380ebca7d6SMarcel Holtmann 		return err;
14390ebca7d6SMarcel Holtmann 
14400ebca7d6SMarcel Holtmann 	return 0;
14410ebca7d6SMarcel Holtmann }
14420ebca7d6SMarcel Holtmann 
144342c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
14441da177e4SLinus Torvalds {
14451da177e4SLinus Torvalds 	__u8 scan = opt;
14461da177e4SLinus Torvalds 
144742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
14481da177e4SLinus Torvalds 
14491da177e4SLinus Torvalds 	/* Inquiry and Page scans */
145042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
14511da177e4SLinus Torvalds }
14521da177e4SLinus Torvalds 
145342c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
14541da177e4SLinus Torvalds {
14551da177e4SLinus Torvalds 	__u8 auth = opt;
14561da177e4SLinus Torvalds 
145742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
14581da177e4SLinus Torvalds 
14591da177e4SLinus Torvalds 	/* Authentication */
146042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
14611da177e4SLinus Torvalds }
14621da177e4SLinus Torvalds 
146342c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
14641da177e4SLinus Torvalds {
14651da177e4SLinus Torvalds 	__u8 encrypt = opt;
14661da177e4SLinus Torvalds 
146742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
14681da177e4SLinus Torvalds 
1469e4e8e37cSMarcel Holtmann 	/* Encryption */
147042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
14711da177e4SLinus Torvalds }
14721da177e4SLinus Torvalds 
147342c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
1474e4e8e37cSMarcel Holtmann {
1475e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
1476e4e8e37cSMarcel Holtmann 
147742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
1478e4e8e37cSMarcel Holtmann 
1479e4e8e37cSMarcel Holtmann 	/* Default link policy */
148042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
1481e4e8e37cSMarcel Holtmann }
1482e4e8e37cSMarcel Holtmann 
14831da177e4SLinus Torvalds /* Get HCI device by index.
14841da177e4SLinus Torvalds  * Device is held on return. */
14851da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
14861da177e4SLinus Torvalds {
14878035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
14881da177e4SLinus Torvalds 
14891da177e4SLinus Torvalds 	BT_DBG("%d", index);
14901da177e4SLinus Torvalds 
14911da177e4SLinus Torvalds 	if (index < 0)
14921da177e4SLinus Torvalds 		return NULL;
14931da177e4SLinus Torvalds 
14941da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
14958035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
14961da177e4SLinus Torvalds 		if (d->id == index) {
14971da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
14981da177e4SLinus Torvalds 			break;
14991da177e4SLinus Torvalds 		}
15001da177e4SLinus Torvalds 	}
15011da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
15021da177e4SLinus Torvalds 	return hdev;
15031da177e4SLinus Torvalds }
15041da177e4SLinus Torvalds 
15051da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1506ff9ef578SJohan Hedberg 
150730dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
150830dc78e1SJohan Hedberg {
150930dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
151030dc78e1SJohan Hedberg 
15116fbe195dSAndre Guedes 	switch (discov->state) {
1512343f935bSAndre Guedes 	case DISCOVERY_FINDING:
15136fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
151430dc78e1SJohan Hedberg 		return true;
151530dc78e1SJohan Hedberg 
15166fbe195dSAndre Guedes 	default:
151730dc78e1SJohan Hedberg 		return false;
151830dc78e1SJohan Hedberg 	}
15196fbe195dSAndre Guedes }
152030dc78e1SJohan Hedberg 
1521ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1522ff9ef578SJohan Hedberg {
1523bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
1524bb3e0a33SJohan Hedberg 
1525ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1526ff9ef578SJohan Hedberg 
1527bb3e0a33SJohan Hedberg 	if (old_state == state)
1528ff9ef578SJohan Hedberg 		return;
1529ff9ef578SJohan Hedberg 
1530bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
1531bb3e0a33SJohan Hedberg 
1532ff9ef578SJohan Hedberg 	switch (state) {
1533ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1534c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
1535c54c3860SAndre Guedes 
1536bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
1537ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1538ff9ef578SJohan Hedberg 		break;
1539ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1540ff9ef578SJohan Hedberg 		break;
1541343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1542ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1543ff9ef578SJohan Hedberg 		break;
154430dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
154530dc78e1SJohan Hedberg 		break;
1546ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1547ff9ef578SJohan Hedberg 		break;
1548ff9ef578SJohan Hedberg 	}
1549ff9ef578SJohan Hedberg }
1550ff9ef578SJohan Hedberg 
15511f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
15521da177e4SLinus Torvalds {
155330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1554b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
15551da177e4SLinus Torvalds 
1556561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
1557561aafbcSJohan Hedberg 		list_del(&p->all);
1558b57c1a56SJohan Hedberg 		kfree(p);
15591da177e4SLinus Torvalds 	}
1560561aafbcSJohan Hedberg 
1561561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
1562561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
15631da177e4SLinus Torvalds }
15641da177e4SLinus Torvalds 
1565a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
1566a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
15671da177e4SLinus Torvalds {
156830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
15691da177e4SLinus Torvalds 	struct inquiry_entry *e;
15701da177e4SLinus Torvalds 
15716ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
15721da177e4SLinus Torvalds 
1573561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
15741da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
15751da177e4SLinus Torvalds 			return e;
15761da177e4SLinus Torvalds 	}
15771da177e4SLinus Torvalds 
1578b57c1a56SJohan Hedberg 	return NULL;
1579b57c1a56SJohan Hedberg }
1580b57c1a56SJohan Hedberg 
1581561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
1582561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
1583561aafbcSJohan Hedberg {
158430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1585561aafbcSJohan Hedberg 	struct inquiry_entry *e;
1586561aafbcSJohan Hedberg 
15876ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1588561aafbcSJohan Hedberg 
1589561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
1590561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
1591561aafbcSJohan Hedberg 			return e;
1592561aafbcSJohan Hedberg 	}
1593561aafbcSJohan Hedberg 
1594561aafbcSJohan Hedberg 	return NULL;
1595561aafbcSJohan Hedberg }
1596561aafbcSJohan Hedberg 
159730dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
159830dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
159930dc78e1SJohan Hedberg 						       int state)
160030dc78e1SJohan Hedberg {
160130dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
160230dc78e1SJohan Hedberg 	struct inquiry_entry *e;
160330dc78e1SJohan Hedberg 
16046ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
160530dc78e1SJohan Hedberg 
160630dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
160730dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
160830dc78e1SJohan Hedberg 			return e;
160930dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
161030dc78e1SJohan Hedberg 			return e;
161130dc78e1SJohan Hedberg 	}
161230dc78e1SJohan Hedberg 
161330dc78e1SJohan Hedberg 	return NULL;
161430dc78e1SJohan Hedberg }
161530dc78e1SJohan Hedberg 
1616a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
1617a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
1618a3d4e20aSJohan Hedberg {
1619a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1620a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
1621a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
1622a3d4e20aSJohan Hedberg 
1623a3d4e20aSJohan Hedberg 	list_del(&ie->list);
1624a3d4e20aSJohan Hedberg 
1625a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
1626a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
1627a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
1628a3d4e20aSJohan Hedberg 			break;
1629a3d4e20aSJohan Hedberg 		pos = &p->list;
1630a3d4e20aSJohan Hedberg 	}
1631a3d4e20aSJohan Hedberg 
1632a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
1633a3d4e20aSJohan Hedberg }
1634a3d4e20aSJohan Hedberg 
1635af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
1636af58925cSMarcel Holtmann 			     bool name_known)
16371da177e4SLinus Torvalds {
163830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
163970f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
1640af58925cSMarcel Holtmann 	u32 flags = 0;
16411da177e4SLinus Torvalds 
16426ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
16431da177e4SLinus Torvalds 
16446928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
16452b2fec4dSSzymon Janc 
1646af58925cSMarcel Holtmann 	if (!data->ssp_mode)
1647af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1648388fc8faSJohan Hedberg 
164970f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
1650a3d4e20aSJohan Hedberg 	if (ie) {
1651af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
1652af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1653388fc8faSJohan Hedberg 
1654a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
1655a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
1656a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
1657a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
1658a3d4e20aSJohan Hedberg 		}
1659a3d4e20aSJohan Hedberg 
1660561aafbcSJohan Hedberg 		goto update;
1661a3d4e20aSJohan Hedberg 	}
1662561aafbcSJohan Hedberg 
16631da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
166427f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
1665af58925cSMarcel Holtmann 	if (!ie) {
1666af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
1667af58925cSMarcel Holtmann 		goto done;
1668af58925cSMarcel Holtmann 	}
166970f23020SAndrei Emeltchenko 
1670561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
1671561aafbcSJohan Hedberg 
1672561aafbcSJohan Hedberg 	if (name_known) {
1673561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1674561aafbcSJohan Hedberg 	} else {
1675561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
1676561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
1677561aafbcSJohan Hedberg 	}
1678561aafbcSJohan Hedberg 
1679561aafbcSJohan Hedberg update:
1680561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
1681561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
1682561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1683561aafbcSJohan Hedberg 		list_del(&ie->list);
16841da177e4SLinus Torvalds 	}
16851da177e4SLinus Torvalds 
168670f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
168770f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
16881da177e4SLinus Torvalds 	cache->timestamp = jiffies;
16893175405bSJohan Hedberg 
16903175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
1691af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
16923175405bSJohan Hedberg 
1693af58925cSMarcel Holtmann done:
1694af58925cSMarcel Holtmann 	return flags;
16951da177e4SLinus Torvalds }
16961da177e4SLinus Torvalds 
16971da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
16981da177e4SLinus Torvalds {
169930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
17001da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
17011da177e4SLinus Torvalds 	struct inquiry_entry *e;
17021da177e4SLinus Torvalds 	int copied = 0;
17031da177e4SLinus Torvalds 
1704561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
17051da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
1706b57c1a56SJohan Hedberg 
1707b57c1a56SJohan Hedberg 		if (copied >= num)
1708b57c1a56SJohan Hedberg 			break;
1709b57c1a56SJohan Hedberg 
17101da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
17111da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
17121da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
17131da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
17141da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
17151da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1716b57c1a56SJohan Hedberg 
17171da177e4SLinus Torvalds 		info++;
1718b57c1a56SJohan Hedberg 		copied++;
17191da177e4SLinus Torvalds 	}
17201da177e4SLinus Torvalds 
17211da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
17221da177e4SLinus Torvalds 	return copied;
17231da177e4SLinus Torvalds }
17241da177e4SLinus Torvalds 
172542c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
17261da177e4SLinus Torvalds {
17271da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
172842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
17291da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
17301da177e4SLinus Torvalds 
17311da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
17321da177e4SLinus Torvalds 
17331da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
17341da177e4SLinus Torvalds 		return;
17351da177e4SLinus Torvalds 
17361da177e4SLinus Torvalds 	/* Start Inquiry */
17371da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
17381da177e4SLinus Torvalds 	cp.length  = ir->length;
17391da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
174042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
17411da177e4SLinus Torvalds }
17421da177e4SLinus Torvalds 
17431da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
17441da177e4SLinus Torvalds {
17451da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
17461da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
17471da177e4SLinus Torvalds 	struct hci_dev *hdev;
17481da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
17491da177e4SLinus Torvalds 	long timeo;
17501da177e4SLinus Torvalds 	__u8 *buf;
17511da177e4SLinus Torvalds 
17521da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
17531da177e4SLinus Torvalds 		return -EFAULT;
17541da177e4SLinus Torvalds 
17555a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
17565a08ecceSAndrei Emeltchenko 	if (!hdev)
17571da177e4SLinus Torvalds 		return -ENODEV;
17581da177e4SLinus Torvalds 
17590736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
17600736cfa8SMarcel Holtmann 		err = -EBUSY;
17610736cfa8SMarcel Holtmann 		goto done;
17620736cfa8SMarcel Holtmann 	}
17630736cfa8SMarcel Holtmann 
17644a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
1765fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1766fee746b0SMarcel Holtmann 		goto done;
1767fee746b0SMarcel Holtmann 	}
1768fee746b0SMarcel Holtmann 
17695b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
17705b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
17715b69bef5SMarcel Holtmann 		goto done;
17725b69bef5SMarcel Holtmann 	}
17735b69bef5SMarcel Holtmann 
177456f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
177556f87901SJohan Hedberg 		err = -EOPNOTSUPP;
177656f87901SJohan Hedberg 		goto done;
177756f87901SJohan Hedberg 	}
177856f87901SJohan Hedberg 
177909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
17801da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1781a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
17821f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
17831da177e4SLinus Torvalds 		do_inquiry = 1;
17841da177e4SLinus Torvalds 	}
178509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
17861da177e4SLinus Torvalds 
178704837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
178870f23020SAndrei Emeltchenko 
178970f23020SAndrei Emeltchenko 	if (do_inquiry) {
179001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
179101178cd4SJohan Hedberg 				   timeo);
179270f23020SAndrei Emeltchenko 		if (err < 0)
17931da177e4SLinus Torvalds 			goto done;
17943e13fa1eSAndre Guedes 
17953e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
17963e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
17973e13fa1eSAndre Guedes 		 */
179874316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
17993e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
18003e13fa1eSAndre Guedes 			return -EINTR;
180170f23020SAndrei Emeltchenko 	}
18021da177e4SLinus Torvalds 
18038fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
18048fc9ced3SGustavo Padovan 	 * 255 entries
18058fc9ced3SGustavo Padovan 	 */
18061da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
18071da177e4SLinus Torvalds 
18081da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
18091da177e4SLinus Torvalds 	 * copy it to the user space.
18101da177e4SLinus Torvalds 	 */
181170f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
181270f23020SAndrei Emeltchenko 	if (!buf) {
18131da177e4SLinus Torvalds 		err = -ENOMEM;
18141da177e4SLinus Torvalds 		goto done;
18151da177e4SLinus Torvalds 	}
18161da177e4SLinus Torvalds 
181709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
18181da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
181909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
18201da177e4SLinus Torvalds 
18211da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
18221da177e4SLinus Torvalds 
18231da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
18241da177e4SLinus Torvalds 		ptr += sizeof(ir);
18251da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
18261da177e4SLinus Torvalds 				 ir.num_rsp))
18271da177e4SLinus Torvalds 			err = -EFAULT;
18281da177e4SLinus Torvalds 	} else
18291da177e4SLinus Torvalds 		err = -EFAULT;
18301da177e4SLinus Torvalds 
18311da177e4SLinus Torvalds 	kfree(buf);
18321da177e4SLinus Torvalds 
18331da177e4SLinus Torvalds done:
18341da177e4SLinus Torvalds 	hci_dev_put(hdev);
18351da177e4SLinus Torvalds 	return err;
18361da177e4SLinus Torvalds }
18371da177e4SLinus Torvalds 
1838cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
18391da177e4SLinus Torvalds {
18401da177e4SLinus Torvalds 	int ret = 0;
18411da177e4SLinus Torvalds 
18421da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
18431da177e4SLinus Torvalds 
18441da177e4SLinus Torvalds 	hci_req_lock(hdev);
18451da177e4SLinus Torvalds 
184694324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
184794324962SJohan Hovold 		ret = -ENODEV;
184894324962SJohan Hovold 		goto done;
184994324962SJohan Hovold 	}
185094324962SJohan Hovold 
1851d603b76bSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
1852d603b76bSMarcel Holtmann 	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
1853a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1854a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1855bf543036SJohan Hedberg 		 */
1856a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
1857611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1858611b30f7SMarcel Holtmann 			goto done;
1859611b30f7SMarcel Holtmann 		}
1860611b30f7SMarcel Holtmann 
1861a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1862a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1863a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1864a5c8f270SMarcel Holtmann 		 * or not.
1865a5c8f270SMarcel Holtmann 		 *
1866c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
1867c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
1868c6beca0eSMarcel Holtmann 		 * available.
1869c6beca0eSMarcel Holtmann 		 *
1870a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1871a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1872a5c8f270SMarcel Holtmann 		 */
1873c6beca0eSMarcel Holtmann 		if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
1874c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
1875a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1876a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1877a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1878a5c8f270SMarcel Holtmann 			goto done;
1879a5c8f270SMarcel Holtmann 		}
1880a5c8f270SMarcel Holtmann 	}
1881a5c8f270SMarcel Holtmann 
18821da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
18831da177e4SLinus Torvalds 		ret = -EALREADY;
18841da177e4SLinus Torvalds 		goto done;
18851da177e4SLinus Torvalds 	}
18861da177e4SLinus Torvalds 
18871da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
18881da177e4SLinus Torvalds 		ret = -EIO;
18891da177e4SLinus Torvalds 		goto done;
18901da177e4SLinus Torvalds 	}
18911da177e4SLinus Torvalds 
18921da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
18931da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1894f41c70c4SMarcel Holtmann 
1895af202f84SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
1896af202f84SMarcel Holtmann 		if (hdev->setup)
1897f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
1898f41c70c4SMarcel Holtmann 
1899af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
1900af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
1901af202f84SMarcel Holtmann 		 *
1902af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
1903af202f84SMarcel Holtmann 		 * start up as unconfigured.
1904af202f84SMarcel Holtmann 		 */
1905eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
1906eb1904f4SMarcel Holtmann 		    test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks))
190789bc22d2SMarcel Holtmann 			set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
1908f41c70c4SMarcel Holtmann 
19090ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
19100ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
19110ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
19120ebca7d6SMarcel Holtmann 		 *
19130ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
19140ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
19150ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
19160ebca7d6SMarcel Holtmann 		 */
19170ebca7d6SMarcel Holtmann 		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
19180ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
191989bc22d2SMarcel Holtmann 	}
192089bc22d2SMarcel Holtmann 
19219713c17bSMarcel Holtmann 	if (test_bit(HCI_CONFIG, &hdev->dev_flags)) {
19229713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
19239713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
19249713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
19259713c17bSMarcel Holtmann 		 * on procedure.
192624c457e2SMarcel Holtmann 		 */
19279713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
19289713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
192924c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
193024c457e2SMarcel Holtmann 		else
193124c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
193224c457e2SMarcel Holtmann 	}
193324c457e2SMarcel Holtmann 
1934f41c70c4SMarcel Holtmann 	if (!ret) {
19354a964404SMarcel Holtmann 		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
19360736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
19372177bab5SJohan Hedberg 			ret = __hci_init(hdev);
19381da177e4SLinus Torvalds 	}
19391da177e4SLinus Torvalds 
1940f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1941f41c70c4SMarcel Holtmann 
19421da177e4SLinus Torvalds 	if (!ret) {
19431da177e4SLinus Torvalds 		hci_dev_hold(hdev);
1944d6bfd59cSJohan Hedberg 		set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
19451da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
19461da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1947bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
1948d603b76bSMarcel Holtmann 		    !test_bit(HCI_CONFIG, &hdev->dev_flags) &&
19494a964404SMarcel Holtmann 		    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
19500736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
19511514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
195209fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1953744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
195409fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
195556e5cb86SJohan Hedberg 		}
19561da177e4SLinus Torvalds 	} else {
19571da177e4SLinus Torvalds 		/* Init failed, cleanup */
19583eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1959c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1960b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
19611da177e4SLinus Torvalds 
19621da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
19631da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
19641da177e4SLinus Torvalds 
19651da177e4SLinus Torvalds 		if (hdev->flush)
19661da177e4SLinus Torvalds 			hdev->flush(hdev);
19671da177e4SLinus Torvalds 
19681da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
19691da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
19701da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
19711da177e4SLinus Torvalds 		}
19721da177e4SLinus Torvalds 
19731da177e4SLinus Torvalds 		hdev->close(hdev);
1974fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
19751da177e4SLinus Torvalds 	}
19761da177e4SLinus Torvalds 
19771da177e4SLinus Torvalds done:
19781da177e4SLinus Torvalds 	hci_req_unlock(hdev);
19791da177e4SLinus Torvalds 	return ret;
19801da177e4SLinus Torvalds }
19811da177e4SLinus Torvalds 
1982cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1983cbed0ca1SJohan Hedberg 
1984cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1985cbed0ca1SJohan Hedberg {
1986cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1987cbed0ca1SJohan Hedberg 	int err;
1988cbed0ca1SJohan Hedberg 
1989cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1990cbed0ca1SJohan Hedberg 	if (!hdev)
1991cbed0ca1SJohan Hedberg 		return -ENODEV;
1992cbed0ca1SJohan Hedberg 
19934a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
1994fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
1995fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
1996fee746b0SMarcel Holtmann 	 * possible.
1997fee746b0SMarcel Holtmann 	 *
1998fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
1999fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
2000fee746b0SMarcel Holtmann 	 * open the device.
2001fee746b0SMarcel Holtmann 	 */
20024a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
2003fee746b0SMarcel Holtmann 	    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
2004fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2005fee746b0SMarcel Holtmann 		goto done;
2006fee746b0SMarcel Holtmann 	}
2007fee746b0SMarcel Holtmann 
2008e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
2009e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
2010e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
2011e1d08f40SJohan Hedberg 	 * completed.
2012e1d08f40SJohan Hedberg 	 */
2013e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2014e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
2015e1d08f40SJohan Hedberg 
2016a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
2017a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
2018a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
2019a5c8f270SMarcel Holtmann 	 */
2020e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
2021e1d08f40SJohan Hedberg 
202212aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
2023b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
202412aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
202512aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
202612aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
202712aa4f0aSMarcel Holtmann 	 */
202812aa4f0aSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
202912aa4f0aSMarcel Holtmann 	    !test_bit(HCI_MGMT, &hdev->dev_flags))
2030b6ae8457SJohan Hedberg 		set_bit(HCI_BONDABLE, &hdev->dev_flags);
203112aa4f0aSMarcel Holtmann 
2032cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
2033cbed0ca1SJohan Hedberg 
2034fee746b0SMarcel Holtmann done:
2035cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
2036cbed0ca1SJohan Hedberg 	return err;
2037cbed0ca1SJohan Hedberg }
2038cbed0ca1SJohan Hedberg 
2039d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
2040d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
2041d7347f3cSJohan Hedberg {
2042d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
2043d7347f3cSJohan Hedberg 
2044f161dd41SJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list) {
2045f161dd41SJohan Hedberg 		if (p->conn) {
2046f161dd41SJohan Hedberg 			hci_conn_drop(p->conn);
2047f8aaf9b6SJohan Hedberg 			hci_conn_put(p->conn);
2048f161dd41SJohan Hedberg 			p->conn = NULL;
2049f161dd41SJohan Hedberg 		}
2050d7347f3cSJohan Hedberg 		list_del_init(&p->action);
2051f161dd41SJohan Hedberg 	}
2052d7347f3cSJohan Hedberg 
2053d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
2054d7347f3cSJohan Hedberg }
2055d7347f3cSJohan Hedberg 
20561da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
20571da177e4SLinus Torvalds {
20581da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
20591da177e4SLinus Torvalds 
206078c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
206178c04c0bSVinicius Costa Gomes 
20621da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
20631da177e4SLinus Torvalds 	hci_req_lock(hdev);
20641da177e4SLinus Torvalds 
20651da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
206665cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
20671da177e4SLinus Torvalds 		hci_req_unlock(hdev);
20681da177e4SLinus Torvalds 		return 0;
20691da177e4SLinus Torvalds 	}
20701da177e4SLinus Torvalds 
20713eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
20723eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
2073b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
20741da177e4SLinus Torvalds 
207516ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
2076e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
207716ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
20785e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
2079310a3d48SMarcel Holtmann 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
208016ab91abSJohan Hedberg 	}
208116ab91abSJohan Hedberg 
2082a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
20837d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
20847d78525dSJohan Hedberg 
20857ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
20864518bb0fSJohan Hedberg 
20874518bb0fSJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
2088d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
20897ba8b4beSAndre Guedes 
209076727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
209176727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
209276727c02SJohan Hedberg 	 */
209376727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
209476727c02SJohan Hedberg 
209509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
20961aeb9c65SJohan Hedberg 
20971aeb9c65SJohan Hedberg 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
20981aeb9c65SJohan Hedberg 		if (hdev->dev_type == HCI_BREDR)
20991aeb9c65SJohan Hedberg 			mgmt_powered(hdev, 0);
21001aeb9c65SJohan Hedberg 	}
21011aeb9c65SJohan Hedberg 
21021f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
2103d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
2104f161dd41SJohan Hedberg 	hci_conn_hash_flush(hdev);
210509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
21061da177e4SLinus Torvalds 
21071da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
21081da177e4SLinus Torvalds 
21091da177e4SLinus Torvalds 	if (hdev->flush)
21101da177e4SLinus Torvalds 		hdev->flush(hdev);
21111da177e4SLinus Torvalds 
21121da177e4SLinus Torvalds 	/* Reset device */
21131da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
21141da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
21154a964404SMarcel Holtmann 	if (!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
21164a964404SMarcel Holtmann 	    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
2117a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
21181da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
211901178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
21201da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
21211da177e4SLinus Torvalds 	}
21221da177e4SLinus Torvalds 
2123c347b765SGustavo F. Padovan 	/* flush cmd  work */
2124c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
21251da177e4SLinus Torvalds 
21261da177e4SLinus Torvalds 	/* Drop queues */
21271da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
21281da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
21291da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
21301da177e4SLinus Torvalds 
21311da177e4SLinus Torvalds 	/* Drop last sent command */
21321da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
213365cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
21341da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
21351da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
21361da177e4SLinus Torvalds 	}
21371da177e4SLinus Torvalds 
2138b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
2139b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
2140b6ddb638SJohan Hedberg 
21411da177e4SLinus Torvalds 	/* After this point our queues are empty
21421da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
21431da177e4SLinus Torvalds 	hdev->close(hdev);
21441da177e4SLinus Torvalds 
214535b973c9SJohan Hedberg 	/* Clear flags */
2146fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
214735b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
214835b973c9SJohan Hedberg 
2149ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
2150536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
2151ced5c338SAndrei Emeltchenko 
2152e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
215309b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
21547a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
2155e59fda8dSJohan Hedberg 
21561da177e4SLinus Torvalds 	hci_req_unlock(hdev);
21571da177e4SLinus Torvalds 
21581da177e4SLinus Torvalds 	hci_dev_put(hdev);
21591da177e4SLinus Torvalds 	return 0;
21601da177e4SLinus Torvalds }
21611da177e4SLinus Torvalds 
21621da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
21631da177e4SLinus Torvalds {
21641da177e4SLinus Torvalds 	struct hci_dev *hdev;
21651da177e4SLinus Torvalds 	int err;
21661da177e4SLinus Torvalds 
216770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
216870f23020SAndrei Emeltchenko 	if (!hdev)
21691da177e4SLinus Torvalds 		return -ENODEV;
21708ee56540SMarcel Holtmann 
21710736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
21720736cfa8SMarcel Holtmann 		err = -EBUSY;
21730736cfa8SMarcel Holtmann 		goto done;
21740736cfa8SMarcel Holtmann 	}
21750736cfa8SMarcel Holtmann 
21768ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
21778ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
21788ee56540SMarcel Holtmann 
21791da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
21808ee56540SMarcel Holtmann 
21810736cfa8SMarcel Holtmann done:
21821da177e4SLinus Torvalds 	hci_dev_put(hdev);
21831da177e4SLinus Torvalds 	return err;
21841da177e4SLinus Torvalds }
21851da177e4SLinus Torvalds 
21861da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
21871da177e4SLinus Torvalds {
21881da177e4SLinus Torvalds 	struct hci_dev *hdev;
21891da177e4SLinus Torvalds 	int ret = 0;
21901da177e4SLinus Torvalds 
219170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
219270f23020SAndrei Emeltchenko 	if (!hdev)
21931da177e4SLinus Torvalds 		return -ENODEV;
21941da177e4SLinus Torvalds 
21951da177e4SLinus Torvalds 	hci_req_lock(hdev);
21961da177e4SLinus Torvalds 
2197808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
2198808a049eSMarcel Holtmann 		ret = -ENETDOWN;
21991da177e4SLinus Torvalds 		goto done;
2200808a049eSMarcel Holtmann 	}
22011da177e4SLinus Torvalds 
22020736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22030736cfa8SMarcel Holtmann 		ret = -EBUSY;
22040736cfa8SMarcel Holtmann 		goto done;
22050736cfa8SMarcel Holtmann 	}
22060736cfa8SMarcel Holtmann 
22074a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2208fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
2209fee746b0SMarcel Holtmann 		goto done;
2210fee746b0SMarcel Holtmann 	}
2211fee746b0SMarcel Holtmann 
22121da177e4SLinus Torvalds 	/* Drop queues */
22131da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
22141da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
22151da177e4SLinus Torvalds 
221676727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
221776727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
221876727c02SJohan Hedberg 	 */
221976727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
222076727c02SJohan Hedberg 
222109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
22221f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
22231da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
222409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
22251da177e4SLinus Torvalds 
22261da177e4SLinus Torvalds 	if (hdev->flush)
22271da177e4SLinus Torvalds 		hdev->flush(hdev);
22281da177e4SLinus Torvalds 
22291da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
22306ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
22311da177e4SLinus Torvalds 
223201178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
22331da177e4SLinus Torvalds 
22341da177e4SLinus Torvalds done:
22351da177e4SLinus Torvalds 	hci_req_unlock(hdev);
22361da177e4SLinus Torvalds 	hci_dev_put(hdev);
22371da177e4SLinus Torvalds 	return ret;
22381da177e4SLinus Torvalds }
22391da177e4SLinus Torvalds 
22401da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
22411da177e4SLinus Torvalds {
22421da177e4SLinus Torvalds 	struct hci_dev *hdev;
22431da177e4SLinus Torvalds 	int ret = 0;
22441da177e4SLinus Torvalds 
224570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
224670f23020SAndrei Emeltchenko 	if (!hdev)
22471da177e4SLinus Torvalds 		return -ENODEV;
22481da177e4SLinus Torvalds 
22490736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22500736cfa8SMarcel Holtmann 		ret = -EBUSY;
22510736cfa8SMarcel Holtmann 		goto done;
22520736cfa8SMarcel Holtmann 	}
22530736cfa8SMarcel Holtmann 
22544a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2255fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
2256fee746b0SMarcel Holtmann 		goto done;
2257fee746b0SMarcel Holtmann 	}
2258fee746b0SMarcel Holtmann 
22591da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
22601da177e4SLinus Torvalds 
22610736cfa8SMarcel Holtmann done:
22621da177e4SLinus Torvalds 	hci_dev_put(hdev);
22631da177e4SLinus Torvalds 	return ret;
22641da177e4SLinus Torvalds }
22651da177e4SLinus Torvalds 
2266123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
2267123abc08SJohan Hedberg {
2268bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
2269123abc08SJohan Hedberg 
2270123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
2271123abc08SJohan Hedberg 
2272123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
2273123abc08SJohan Hedberg 		conn_changed = !test_and_set_bit(HCI_CONNECTABLE,
2274123abc08SJohan Hedberg 						 &hdev->dev_flags);
2275123abc08SJohan Hedberg 	else
2276123abc08SJohan Hedberg 		conn_changed = test_and_clear_bit(HCI_CONNECTABLE,
2277123abc08SJohan Hedberg 						  &hdev->dev_flags);
2278123abc08SJohan Hedberg 
2279bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
2280bc6d2d04SJohan Hedberg 		discov_changed = !test_and_set_bit(HCI_DISCOVERABLE,
2281bc6d2d04SJohan Hedberg 						   &hdev->dev_flags);
2282bc6d2d04SJohan Hedberg 	} else {
2283bc6d2d04SJohan Hedberg 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
2284bc6d2d04SJohan Hedberg 		discov_changed = test_and_clear_bit(HCI_DISCOVERABLE,
2285bc6d2d04SJohan Hedberg 						    &hdev->dev_flags);
2286bc6d2d04SJohan Hedberg 	}
2287bc6d2d04SJohan Hedberg 
2288123abc08SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2289123abc08SJohan Hedberg 		return;
2290123abc08SJohan Hedberg 
2291bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
2292bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
2293bc6d2d04SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
2294bc6d2d04SJohan Hedberg 
2295bc6d2d04SJohan Hedberg 		if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
2296bc6d2d04SJohan Hedberg 			mgmt_update_adv_data(hdev);
2297bc6d2d04SJohan Hedberg 
2298123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
2299123abc08SJohan Hedberg 	}
2300bc6d2d04SJohan Hedberg }
2301123abc08SJohan Hedberg 
23021da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
23031da177e4SLinus Torvalds {
23041da177e4SLinus Torvalds 	struct hci_dev *hdev;
23051da177e4SLinus Torvalds 	struct hci_dev_req dr;
23061da177e4SLinus Torvalds 	int err = 0;
23071da177e4SLinus Torvalds 
23081da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
23091da177e4SLinus Torvalds 		return -EFAULT;
23101da177e4SLinus Torvalds 
231170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
231270f23020SAndrei Emeltchenko 	if (!hdev)
23131da177e4SLinus Torvalds 		return -ENODEV;
23141da177e4SLinus Torvalds 
23150736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
23160736cfa8SMarcel Holtmann 		err = -EBUSY;
23170736cfa8SMarcel Holtmann 		goto done;
23180736cfa8SMarcel Holtmann 	}
23190736cfa8SMarcel Holtmann 
23204a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2321fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2322fee746b0SMarcel Holtmann 		goto done;
2323fee746b0SMarcel Holtmann 	}
2324fee746b0SMarcel Holtmann 
23255b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
23265b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
23275b69bef5SMarcel Holtmann 		goto done;
23285b69bef5SMarcel Holtmann 	}
23295b69bef5SMarcel Holtmann 
233056f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
233156f87901SJohan Hedberg 		err = -EOPNOTSUPP;
233256f87901SJohan Hedberg 		goto done;
233356f87901SJohan Hedberg 	}
233456f87901SJohan Hedberg 
23351da177e4SLinus Torvalds 	switch (cmd) {
23361da177e4SLinus Torvalds 	case HCISETAUTH:
233701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
23385f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23391da177e4SLinus Torvalds 		break;
23401da177e4SLinus Torvalds 
23411da177e4SLinus Torvalds 	case HCISETENCRYPT:
23421da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
23431da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
23441da177e4SLinus Torvalds 			break;
23451da177e4SLinus Torvalds 		}
23461da177e4SLinus Torvalds 
23471da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
23481da177e4SLinus Torvalds 			/* Auth must be enabled first */
234901178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
23505f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
23511da177e4SLinus Torvalds 			if (err)
23521da177e4SLinus Torvalds 				break;
23531da177e4SLinus Torvalds 		}
23541da177e4SLinus Torvalds 
235501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
23565f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23571da177e4SLinus Torvalds 		break;
23581da177e4SLinus Torvalds 
23591da177e4SLinus Torvalds 	case HCISETSCAN:
236001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
23615f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
236291a668b0SJohan Hedberg 
2363bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
2364bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
236591a668b0SJohan Hedberg 		 */
2366123abc08SJohan Hedberg 		if (!err)
2367123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
23681da177e4SLinus Torvalds 		break;
23691da177e4SLinus Torvalds 
23701da177e4SLinus Torvalds 	case HCISETLINKPOL:
237101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
23725f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23731da177e4SLinus Torvalds 		break;
23741da177e4SLinus Torvalds 
23751da177e4SLinus Torvalds 	case HCISETLINKMODE:
2376e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2377e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2378e4e8e37cSMarcel Holtmann 		break;
2379e4e8e37cSMarcel Holtmann 
2380e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2381e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
23821da177e4SLinus Torvalds 		break;
23831da177e4SLinus Torvalds 
23841da177e4SLinus Torvalds 	case HCISETACLMTU:
23851da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
23861da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
23871da177e4SLinus Torvalds 		break;
23881da177e4SLinus Torvalds 
23891da177e4SLinus Torvalds 	case HCISETSCOMTU:
23901da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
23911da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
23921da177e4SLinus Torvalds 		break;
23931da177e4SLinus Torvalds 
23941da177e4SLinus Torvalds 	default:
23951da177e4SLinus Torvalds 		err = -EINVAL;
23961da177e4SLinus Torvalds 		break;
23971da177e4SLinus Torvalds 	}
2398e4e8e37cSMarcel Holtmann 
23990736cfa8SMarcel Holtmann done:
24001da177e4SLinus Torvalds 	hci_dev_put(hdev);
24011da177e4SLinus Torvalds 	return err;
24021da177e4SLinus Torvalds }
24031da177e4SLinus Torvalds 
24041da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
24051da177e4SLinus Torvalds {
24068035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
24071da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
24081da177e4SLinus Torvalds 	struct hci_dev_req *dr;
24091da177e4SLinus Torvalds 	int n = 0, size, err;
24101da177e4SLinus Torvalds 	__u16 dev_num;
24111da177e4SLinus Torvalds 
24121da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
24131da177e4SLinus Torvalds 		return -EFAULT;
24141da177e4SLinus Torvalds 
24151da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
24161da177e4SLinus Torvalds 		return -EINVAL;
24171da177e4SLinus Torvalds 
24181da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
24191da177e4SLinus Torvalds 
242070f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
242170f23020SAndrei Emeltchenko 	if (!dl)
24221da177e4SLinus Torvalds 		return -ENOMEM;
24231da177e4SLinus Torvalds 
24241da177e4SLinus Torvalds 	dr = dl->dev_req;
24251da177e4SLinus Torvalds 
2426f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
24278035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
24282e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
2429c542a06cSJohan Hedberg 
24302e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
24312e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
24322e84d8dbSMarcel Holtmann 		 * device is actually down.
24332e84d8dbSMarcel Holtmann 		 */
24342e84d8dbSMarcel Holtmann 		if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
24352e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
2436c542a06cSJohan Hedberg 
24371da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
24382e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
2439c542a06cSJohan Hedberg 
24401da177e4SLinus Torvalds 		if (++n >= dev_num)
24411da177e4SLinus Torvalds 			break;
24421da177e4SLinus Torvalds 	}
2443f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
24441da177e4SLinus Torvalds 
24451da177e4SLinus Torvalds 	dl->dev_num = n;
24461da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
24471da177e4SLinus Torvalds 
24481da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
24491da177e4SLinus Torvalds 	kfree(dl);
24501da177e4SLinus Torvalds 
24511da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
24521da177e4SLinus Torvalds }
24531da177e4SLinus Torvalds 
24541da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
24551da177e4SLinus Torvalds {
24561da177e4SLinus Torvalds 	struct hci_dev *hdev;
24571da177e4SLinus Torvalds 	struct hci_dev_info di;
24582e84d8dbSMarcel Holtmann 	unsigned long flags;
24591da177e4SLinus Torvalds 	int err = 0;
24601da177e4SLinus Torvalds 
24611da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
24621da177e4SLinus Torvalds 		return -EFAULT;
24631da177e4SLinus Torvalds 
246470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
246570f23020SAndrei Emeltchenko 	if (!hdev)
24661da177e4SLinus Torvalds 		return -ENODEV;
24671da177e4SLinus Torvalds 
24682e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
24692e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
24702e84d8dbSMarcel Holtmann 	 * device is actually down.
24712e84d8dbSMarcel Holtmann 	 */
24722e84d8dbSMarcel Holtmann 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
24732e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
24742e84d8dbSMarcel Holtmann 	else
24752e84d8dbSMarcel Holtmann 		flags = hdev->flags;
2476c542a06cSJohan Hedberg 
24771da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
24781da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
247960f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
24802e84d8dbSMarcel Holtmann 	di.flags    = flags;
24811da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2482572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
24831da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
24841da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
24851da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
24861da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2487572c7f84SJohan Hedberg 	} else {
2488572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2489572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2490572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2491572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2492572c7f84SJohan Hedberg 	}
24931da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
24941da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
24951da177e4SLinus Torvalds 
24961da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
24971da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
24981da177e4SLinus Torvalds 
24991da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
25001da177e4SLinus Torvalds 		err = -EFAULT;
25011da177e4SLinus Torvalds 
25021da177e4SLinus Torvalds 	hci_dev_put(hdev);
25031da177e4SLinus Torvalds 
25041da177e4SLinus Torvalds 	return err;
25051da177e4SLinus Torvalds }
25061da177e4SLinus Torvalds 
25071da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
25081da177e4SLinus Torvalds 
2509611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2510611b30f7SMarcel Holtmann {
2511611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2512611b30f7SMarcel Holtmann 
2513611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2514611b30f7SMarcel Holtmann 
25150736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
25160736cfa8SMarcel Holtmann 		return -EBUSY;
25170736cfa8SMarcel Holtmann 
25185e130367SJohan Hedberg 	if (blocked) {
25195e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
2520d603b76bSMarcel Holtmann 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
2521d603b76bSMarcel Holtmann 		    !test_bit(HCI_CONFIG, &hdev->dev_flags))
2522611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
25235e130367SJohan Hedberg 	} else {
25245e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
25255e130367SJohan Hedberg 	}
2526611b30f7SMarcel Holtmann 
2527611b30f7SMarcel Holtmann 	return 0;
2528611b30f7SMarcel Holtmann }
2529611b30f7SMarcel Holtmann 
2530611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2531611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2532611b30f7SMarcel Holtmann };
2533611b30f7SMarcel Holtmann 
2534ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2535ab81cbf9SJohan Hedberg {
2536ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
253796570ffcSJohan Hedberg 	int err;
2538ab81cbf9SJohan Hedberg 
2539ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2540ab81cbf9SJohan Hedberg 
2541cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
254296570ffcSJohan Hedberg 	if (err < 0) {
25433ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
254496570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
25453ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
2546ab81cbf9SJohan Hedberg 		return;
254796570ffcSJohan Hedberg 	}
2548ab81cbf9SJohan Hedberg 
2549a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2550a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2551a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2552a5c8f270SMarcel Holtmann 	 */
2553a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
25544a964404SMarcel Holtmann 	    test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) ||
2555a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
2556a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2557a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2558bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2559bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2560bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
256119202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
256219202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2563bf543036SJohan Hedberg 	}
2564ab81cbf9SJohan Hedberg 
2565fee746b0SMarcel Holtmann 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) {
25664a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
25674a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
25684a964404SMarcel Holtmann 		 */
25694a964404SMarcel Holtmann 		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
25704a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
25710602a8adSMarcel Holtmann 
25720602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
25730602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
25740602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
25750602a8adSMarcel Holtmann 		 *
25760602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
25770602a8adSMarcel Holtmann 		 * and no event will be send.
25780602a8adSMarcel Holtmann 		 */
2579744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2580d603b76bSMarcel Holtmann 	} else if (test_and_clear_bit(HCI_CONFIG, &hdev->dev_flags)) {
25815ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
25825ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
25835ea234d3SMarcel Holtmann 		 */
25845ea234d3SMarcel Holtmann 		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
25855ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
25865ea234d3SMarcel Holtmann 
2587d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
2588d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
2589d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
2590d603b76bSMarcel Holtmann 		 */
2591d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
2592ab81cbf9SJohan Hedberg 	}
2593ab81cbf9SJohan Hedberg }
2594ab81cbf9SJohan Hedberg 
2595ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2596ab81cbf9SJohan Hedberg {
25973243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
25983243553fSJohan Hedberg 					    power_off.work);
2599ab81cbf9SJohan Hedberg 
2600ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2601ab81cbf9SJohan Hedberg 
26028ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2603ab81cbf9SJohan Hedberg }
2604ab81cbf9SJohan Hedberg 
260516ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
260616ab91abSJohan Hedberg {
260716ab91abSJohan Hedberg 	struct hci_dev *hdev;
260816ab91abSJohan Hedberg 
260916ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
261016ab91abSJohan Hedberg 
261116ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
261216ab91abSJohan Hedberg 
2613d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
261416ab91abSJohan Hedberg }
261516ab91abSJohan Hedberg 
261635f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
26172aeb9a1aSJohan Hedberg {
26184821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
26192aeb9a1aSJohan Hedberg 
26204821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
26214821002cSJohan Hedberg 		list_del(&uuid->list);
26222aeb9a1aSJohan Hedberg 		kfree(uuid);
26232aeb9a1aSJohan Hedberg 	}
26242aeb9a1aSJohan Hedberg }
26252aeb9a1aSJohan Hedberg 
262635f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
262755ed8ca1SJohan Hedberg {
262855ed8ca1SJohan Hedberg 	struct link_key *key;
262955ed8ca1SJohan Hedberg 
26300378b597SJohan Hedberg 	list_for_each_entry_rcu(key, &hdev->link_keys, list) {
26310378b597SJohan Hedberg 		list_del_rcu(&key->list);
26320378b597SJohan Hedberg 		kfree_rcu(key, rcu);
263355ed8ca1SJohan Hedberg 	}
263455ed8ca1SJohan Hedberg }
263555ed8ca1SJohan Hedberg 
263635f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2637b899efafSVinicius Costa Gomes {
2638970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2639b899efafSVinicius Costa Gomes 
2640970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2641970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2642970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2643b899efafSVinicius Costa Gomes 	}
2644b899efafSVinicius Costa Gomes }
2645b899efafSVinicius Costa Gomes 
2646970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2647970c4e46SJohan Hedberg {
2648adae20cbSJohan Hedberg 	struct smp_irk *k;
2649970c4e46SJohan Hedberg 
2650adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2651adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2652adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2653970c4e46SJohan Hedberg 	}
2654970c4e46SJohan Hedberg }
2655970c4e46SJohan Hedberg 
265655ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
265755ed8ca1SJohan Hedberg {
265855ed8ca1SJohan Hedberg 	struct link_key *k;
265955ed8ca1SJohan Hedberg 
26600378b597SJohan Hedberg 	rcu_read_lock();
26610378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
26620378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
26630378b597SJohan Hedberg 			rcu_read_unlock();
266455ed8ca1SJohan Hedberg 			return k;
26650378b597SJohan Hedberg 		}
26660378b597SJohan Hedberg 	}
26670378b597SJohan Hedberg 	rcu_read_unlock();
266855ed8ca1SJohan Hedberg 
266955ed8ca1SJohan Hedberg 	return NULL;
267055ed8ca1SJohan Hedberg }
267155ed8ca1SJohan Hedberg 
2672745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2673d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2674d25e28abSJohan Hedberg {
2675d25e28abSJohan Hedberg 	/* Legacy key */
2676d25e28abSJohan Hedberg 	if (key_type < 0x03)
2677745c0ce3SVishal Agarwal 		return true;
2678d25e28abSJohan Hedberg 
2679d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2680d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2681745c0ce3SVishal Agarwal 		return false;
2682d25e28abSJohan Hedberg 
2683d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2684d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2685745c0ce3SVishal Agarwal 		return false;
2686d25e28abSJohan Hedberg 
2687d25e28abSJohan Hedberg 	/* Security mode 3 case */
2688d25e28abSJohan Hedberg 	if (!conn)
2689745c0ce3SVishal Agarwal 		return true;
2690d25e28abSJohan Hedberg 
2691e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
2692e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
2693e3befab9SJohan Hedberg 		return true;
2694e3befab9SJohan Hedberg 
2695d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2696d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2697745c0ce3SVishal Agarwal 		return true;
2698d25e28abSJohan Hedberg 
2699d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2700d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2701745c0ce3SVishal Agarwal 		return true;
2702d25e28abSJohan Hedberg 
2703d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2704d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2705745c0ce3SVishal Agarwal 		return true;
2706d25e28abSJohan Hedberg 
2707d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2708d25e28abSJohan Hedberg 	 * persistently */
2709745c0ce3SVishal Agarwal 	return false;
2710d25e28abSJohan Hedberg }
2711d25e28abSJohan Hedberg 
2712e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
271398a0b845SJohan Hedberg {
2714e804d25dSJohan Hedberg 	if (type == SMP_LTK)
2715e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
271698a0b845SJohan Hedberg 
2717e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
271898a0b845SJohan Hedberg }
271998a0b845SJohan Hedberg 
2720f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2721e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
272275d262c2SVinicius Costa Gomes {
2723c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
272475d262c2SVinicius Costa Gomes 
2725970d0f1bSJohan Hedberg 	rcu_read_lock();
2726970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
27275378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
27285378bc56SJohan Hedberg 			continue;
27295378bc56SJohan Hedberg 
2730923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
2731970d0f1bSJohan Hedberg 			rcu_read_unlock();
273275d262c2SVinicius Costa Gomes 			return k;
2733970d0f1bSJohan Hedberg 		}
2734970d0f1bSJohan Hedberg 	}
2735970d0f1bSJohan Hedberg 	rcu_read_unlock();
273675d262c2SVinicius Costa Gomes 
273775d262c2SVinicius Costa Gomes 	return NULL;
273875d262c2SVinicius Costa Gomes }
273975d262c2SVinicius Costa Gomes 
2740970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2741970c4e46SJohan Hedberg {
2742970c4e46SJohan Hedberg 	struct smp_irk *irk;
2743970c4e46SJohan Hedberg 
2744adae20cbSJohan Hedberg 	rcu_read_lock();
2745adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2746adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
2747adae20cbSJohan Hedberg 			rcu_read_unlock();
2748970c4e46SJohan Hedberg 			return irk;
2749970c4e46SJohan Hedberg 		}
2750adae20cbSJohan Hedberg 	}
2751970c4e46SJohan Hedberg 
2752adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2753defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
2754970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
2755adae20cbSJohan Hedberg 			rcu_read_unlock();
2756970c4e46SJohan Hedberg 			return irk;
2757970c4e46SJohan Hedberg 		}
2758970c4e46SJohan Hedberg 	}
2759adae20cbSJohan Hedberg 	rcu_read_unlock();
2760970c4e46SJohan Hedberg 
2761970c4e46SJohan Hedberg 	return NULL;
2762970c4e46SJohan Hedberg }
2763970c4e46SJohan Hedberg 
2764970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2765970c4e46SJohan Hedberg 				     u8 addr_type)
2766970c4e46SJohan Hedberg {
2767970c4e46SJohan Hedberg 	struct smp_irk *irk;
2768970c4e46SJohan Hedberg 
27696cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
27706cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
27716cfc9988SJohan Hedberg 		return NULL;
27726cfc9988SJohan Hedberg 
2773adae20cbSJohan Hedberg 	rcu_read_lock();
2774adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2775970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
2776adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
2777adae20cbSJohan Hedberg 			rcu_read_unlock();
2778970c4e46SJohan Hedberg 			return irk;
2779970c4e46SJohan Hedberg 		}
2780adae20cbSJohan Hedberg 	}
2781adae20cbSJohan Hedberg 	rcu_read_unlock();
2782970c4e46SJohan Hedberg 
2783970c4e46SJohan Hedberg 	return NULL;
2784970c4e46SJohan Hedberg }
2785970c4e46SJohan Hedberg 
2786567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
27877652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
27887652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
278955ed8ca1SJohan Hedberg {
279055ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2791745c0ce3SVishal Agarwal 	u8 old_key_type;
279255ed8ca1SJohan Hedberg 
279355ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
279455ed8ca1SJohan Hedberg 	if (old_key) {
279555ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
279655ed8ca1SJohan Hedberg 		key = old_key;
279755ed8ca1SJohan Hedberg 	} else {
279812adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
27990a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
280055ed8ca1SJohan Hedberg 		if (!key)
2801567fa2aaSJohan Hedberg 			return NULL;
28020378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
280355ed8ca1SJohan Hedberg 	}
280455ed8ca1SJohan Hedberg 
28056ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
280655ed8ca1SJohan Hedberg 
2807d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2808d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2809d25e28abSJohan Hedberg 	 * previous key */
2810d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2811a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2812d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2813655fe6ecSJohan Hedberg 		if (conn)
2814655fe6ecSJohan Hedberg 			conn->key_type = type;
2815655fe6ecSJohan Hedberg 	}
2816d25e28abSJohan Hedberg 
281755ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
28189b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
281955ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
282055ed8ca1SJohan Hedberg 
2821b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
282255ed8ca1SJohan Hedberg 		key->type = old_key_type;
28234748fed2SJohan Hedberg 	else
28244748fed2SJohan Hedberg 		key->type = type;
28254748fed2SJohan Hedberg 
28267652ff6aSJohan Hedberg 	if (persistent)
28277652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
28287652ff6aSJohan Hedberg 						 old_key_type);
28294df378a1SJohan Hedberg 
2830567fa2aaSJohan Hedberg 	return key;
283155ed8ca1SJohan Hedberg }
283255ed8ca1SJohan Hedberg 
2833ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
283435d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
2835fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
283675d262c2SVinicius Costa Gomes {
2837c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
2838e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
283975d262c2SVinicius Costa Gomes 
2840f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
2841c9839a11SVinicius Costa Gomes 	if (old_key)
284275d262c2SVinicius Costa Gomes 		key = old_key;
2843c9839a11SVinicius Costa Gomes 	else {
28440a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
284575d262c2SVinicius Costa Gomes 		if (!key)
2846ca9142b8SJohan Hedberg 			return NULL;
2847970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
284875d262c2SVinicius Costa Gomes 	}
284975d262c2SVinicius Costa Gomes 
285075d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2851c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2852c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2853c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2854c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2855fe39c7b2SMarcel Holtmann 	key->rand = rand;
2856c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2857c9839a11SVinicius Costa Gomes 	key->type = type;
285875d262c2SVinicius Costa Gomes 
2859ca9142b8SJohan Hedberg 	return key;
286075d262c2SVinicius Costa Gomes }
286175d262c2SVinicius Costa Gomes 
2862ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2863ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
2864970c4e46SJohan Hedberg {
2865970c4e46SJohan Hedberg 	struct smp_irk *irk;
2866970c4e46SJohan Hedberg 
2867970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2868970c4e46SJohan Hedberg 	if (!irk) {
2869970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
2870970c4e46SJohan Hedberg 		if (!irk)
2871ca9142b8SJohan Hedberg 			return NULL;
2872970c4e46SJohan Hedberg 
2873970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
2874970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
2875970c4e46SJohan Hedberg 
2876adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
2877970c4e46SJohan Hedberg 	}
2878970c4e46SJohan Hedberg 
2879970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
2880970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
2881970c4e46SJohan Hedberg 
2882ca9142b8SJohan Hedberg 	return irk;
2883970c4e46SJohan Hedberg }
2884970c4e46SJohan Hedberg 
288555ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
288655ed8ca1SJohan Hedberg {
288755ed8ca1SJohan Hedberg 	struct link_key *key;
288855ed8ca1SJohan Hedberg 
288955ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
289055ed8ca1SJohan Hedberg 	if (!key)
289155ed8ca1SJohan Hedberg 		return -ENOENT;
289255ed8ca1SJohan Hedberg 
28936ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
289455ed8ca1SJohan Hedberg 
28950378b597SJohan Hedberg 	list_del_rcu(&key->list);
28960378b597SJohan Hedberg 	kfree_rcu(key, rcu);
289755ed8ca1SJohan Hedberg 
289855ed8ca1SJohan Hedberg 	return 0;
289955ed8ca1SJohan Hedberg }
290055ed8ca1SJohan Hedberg 
2901e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2902b899efafSVinicius Costa Gomes {
2903970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2904c51ffa0bSJohan Hedberg 	int removed = 0;
2905b899efafSVinicius Costa Gomes 
2906970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2907e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2908b899efafSVinicius Costa Gomes 			continue;
2909b899efafSVinicius Costa Gomes 
29106ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2911b899efafSVinicius Costa Gomes 
2912970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2913970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2914c51ffa0bSJohan Hedberg 		removed++;
2915b899efafSVinicius Costa Gomes 	}
2916b899efafSVinicius Costa Gomes 
2917c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
2918b899efafSVinicius Costa Gomes }
2919b899efafSVinicius Costa Gomes 
2920a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
2921a7ec7338SJohan Hedberg {
2922adae20cbSJohan Hedberg 	struct smp_irk *k;
2923a7ec7338SJohan Hedberg 
2924adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2925a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
2926a7ec7338SJohan Hedberg 			continue;
2927a7ec7338SJohan Hedberg 
2928a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2929a7ec7338SJohan Hedberg 
2930adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2931adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2932a7ec7338SJohan Hedberg 	}
2933a7ec7338SJohan Hedberg }
2934a7ec7338SJohan Hedberg 
29356bd32326SVille Tervo /* HCI command timer function */
293665cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
29376bd32326SVille Tervo {
293865cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
293965cc2b49SMarcel Holtmann 					    cmd_timer.work);
29406bd32326SVille Tervo 
2941bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2942bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2943bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2944bda4f23aSAndrei Emeltchenko 
2945bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
2946bda4f23aSAndrei Emeltchenko 	} else {
29476bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
2948bda4f23aSAndrei Emeltchenko 	}
2949bda4f23aSAndrei Emeltchenko 
29506bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2951c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
29526bd32326SVille Tervo }
29536bd32326SVille Tervo 
29542763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
29556928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
29562763eda6SSzymon Janc {
29572763eda6SSzymon Janc 	struct oob_data *data;
29582763eda6SSzymon Janc 
29596928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
29606928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
29616928a924SJohan Hedberg 			continue;
29626928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
29636928a924SJohan Hedberg 			continue;
29642763eda6SSzymon Janc 		return data;
29656928a924SJohan Hedberg 	}
29662763eda6SSzymon Janc 
29672763eda6SSzymon Janc 	return NULL;
29682763eda6SSzymon Janc }
29692763eda6SSzymon Janc 
29706928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
29716928a924SJohan Hedberg 			       u8 bdaddr_type)
29722763eda6SSzymon Janc {
29732763eda6SSzymon Janc 	struct oob_data *data;
29742763eda6SSzymon Janc 
29756928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
29762763eda6SSzymon Janc 	if (!data)
29772763eda6SSzymon Janc 		return -ENOENT;
29782763eda6SSzymon Janc 
29796928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
29802763eda6SSzymon Janc 
29812763eda6SSzymon Janc 	list_del(&data->list);
29822763eda6SSzymon Janc 	kfree(data);
29832763eda6SSzymon Janc 
29842763eda6SSzymon Janc 	return 0;
29852763eda6SSzymon Janc }
29862763eda6SSzymon Janc 
298735f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
29882763eda6SSzymon Janc {
29892763eda6SSzymon Janc 	struct oob_data *data, *n;
29902763eda6SSzymon Janc 
29912763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
29922763eda6SSzymon Janc 		list_del(&data->list);
29932763eda6SSzymon Janc 		kfree(data);
29942763eda6SSzymon Janc 	}
29952763eda6SSzymon Janc }
29962763eda6SSzymon Janc 
29970798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
29986928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
299938da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
30000798872eSMarcel Holtmann {
30010798872eSMarcel Holtmann 	struct oob_data *data;
30020798872eSMarcel Holtmann 
30036928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
30040798872eSMarcel Holtmann 	if (!data) {
30050a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
30060798872eSMarcel Holtmann 		if (!data)
30070798872eSMarcel Holtmann 			return -ENOMEM;
30080798872eSMarcel Holtmann 
30090798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
30106928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
30110798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
30120798872eSMarcel Holtmann 	}
30130798872eSMarcel Holtmann 
301481328d5cSJohan Hedberg 	if (hash192 && rand192) {
30150798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
301638da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
301781328d5cSJohan Hedberg 	} else {
301881328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
301981328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
302081328d5cSJohan Hedberg 	}
30210798872eSMarcel Holtmann 
302281328d5cSJohan Hedberg 	if (hash256 && rand256) {
30230798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
302438da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
302581328d5cSJohan Hedberg 	} else {
302681328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
302781328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
302881328d5cSJohan Hedberg 	}
30290798872eSMarcel Holtmann 
30306ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
30312763eda6SSzymon Janc 
30322763eda6SSzymon Janc 	return 0;
30332763eda6SSzymon Janc }
30342763eda6SSzymon Janc 
3035dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
3036b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
3037b2a66aadSAntti Julku {
3038b2a66aadSAntti Julku 	struct bdaddr_list *b;
3039b2a66aadSAntti Julku 
3040dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
3041b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3042b2a66aadSAntti Julku 			return b;
3043b9ee0a78SMarcel Holtmann 	}
3044b2a66aadSAntti Julku 
3045b2a66aadSAntti Julku 	return NULL;
3046b2a66aadSAntti Julku }
3047b2a66aadSAntti Julku 
3048dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
3049b2a66aadSAntti Julku {
3050b2a66aadSAntti Julku 	struct list_head *p, *n;
3051b2a66aadSAntti Julku 
3052dcc36c16SJohan Hedberg 	list_for_each_safe(p, n, bdaddr_list) {
3053b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
3054b2a66aadSAntti Julku 
3055b2a66aadSAntti Julku 		list_del(p);
3056b2a66aadSAntti Julku 		kfree(b);
3057b2a66aadSAntti Julku 	}
3058b2a66aadSAntti Julku }
3059b2a66aadSAntti Julku 
3060dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3061b2a66aadSAntti Julku {
3062b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3063b2a66aadSAntti Julku 
3064b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3065b2a66aadSAntti Julku 		return -EBADF;
3066b2a66aadSAntti Julku 
3067dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
30685e762444SAntti Julku 		return -EEXIST;
3069b2a66aadSAntti Julku 
307027f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
30715e762444SAntti Julku 	if (!entry)
30725e762444SAntti Julku 		return -ENOMEM;
3073b2a66aadSAntti Julku 
3074b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3075b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3076b2a66aadSAntti Julku 
3077dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
3078b2a66aadSAntti Julku 
30792a8357f2SJohan Hedberg 	return 0;
3080b2a66aadSAntti Julku }
3081b2a66aadSAntti Julku 
3082dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3083b2a66aadSAntti Julku {
3084b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3085b2a66aadSAntti Julku 
308635f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3087dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
308835f7498aSJohan Hedberg 		return 0;
308935f7498aSJohan Hedberg 	}
3090b2a66aadSAntti Julku 
3091dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
3092d2ab0ac1SMarcel Holtmann 	if (!entry)
3093d2ab0ac1SMarcel Holtmann 		return -ENOENT;
3094d2ab0ac1SMarcel Holtmann 
3095d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
3096d2ab0ac1SMarcel Holtmann 	kfree(entry);
3097d2ab0ac1SMarcel Holtmann 
3098d2ab0ac1SMarcel Holtmann 	return 0;
3099d2ab0ac1SMarcel Holtmann }
3100d2ab0ac1SMarcel Holtmann 
310115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
310215819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
310315819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
310415819a70SAndre Guedes {
310515819a70SAndre Guedes 	struct hci_conn_params *params;
310615819a70SAndre Guedes 
3107738f6185SJohan Hedberg 	/* The conn params list only contains identity addresses */
3108738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
3109738f6185SJohan Hedberg 		return NULL;
3110738f6185SJohan Hedberg 
311115819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
311215819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
311315819a70SAndre Guedes 		    params->addr_type == addr_type) {
311415819a70SAndre Guedes 			return params;
311515819a70SAndre Guedes 		}
311615819a70SAndre Guedes 	}
311715819a70SAndre Guedes 
311815819a70SAndre Guedes 	return NULL;
311915819a70SAndre Guedes }
312015819a70SAndre Guedes 
312115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
3122501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
31234b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
312415819a70SAndre Guedes {
3125912b42efSJohan Hedberg 	struct hci_conn_params *param;
312615819a70SAndre Guedes 
3127738f6185SJohan Hedberg 	/* The list only contains identity addresses */
3128738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
3129738f6185SJohan Hedberg 		return NULL;
313015819a70SAndre Guedes 
3131501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
3132912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
3133912b42efSJohan Hedberg 		    param->addr_type == addr_type)
3134912b42efSJohan Hedberg 			return param;
31354b10966fSMarcel Holtmann 	}
31364b10966fSMarcel Holtmann 
31374b10966fSMarcel Holtmann 	return NULL;
313815819a70SAndre Guedes }
313915819a70SAndre Guedes 
314015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
314151d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
314251d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
314315819a70SAndre Guedes {
314415819a70SAndre Guedes 	struct hci_conn_params *params;
314515819a70SAndre Guedes 
3146c46245b3SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
314751d167c0SMarcel Holtmann 		return NULL;
3148a9b0a04cSAndre Guedes 
314915819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
3150cef952ceSAndre Guedes 	if (params)
315151d167c0SMarcel Holtmann 		return params;
315215819a70SAndre Guedes 
315315819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
315415819a70SAndre Guedes 	if (!params) {
315515819a70SAndre Guedes 		BT_ERR("Out of memory");
315651d167c0SMarcel Holtmann 		return NULL;
315715819a70SAndre Guedes 	}
315815819a70SAndre Guedes 
315915819a70SAndre Guedes 	bacpy(&params->addr, addr);
316015819a70SAndre Guedes 	params->addr_type = addr_type;
3161cef952ceSAndre Guedes 
3162cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
316393450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
3164cef952ceSAndre Guedes 
3165bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
3166bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
3167bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
3168bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
3169bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
3170bf5b3c8bSMarcel Holtmann 
3171bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
3172bf5b3c8bSMarcel Holtmann 
317351d167c0SMarcel Holtmann 	return params;
3174bf5b3c8bSMarcel Holtmann }
3175bf5b3c8bSMarcel Holtmann 
3176f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
3177f6c63249SJohan Hedberg {
3178f6c63249SJohan Hedberg 	if (params->conn) {
3179f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
3180f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
3181f6c63249SJohan Hedberg 	}
3182f6c63249SJohan Hedberg 
3183f6c63249SJohan Hedberg 	list_del(&params->action);
3184f6c63249SJohan Hedberg 	list_del(&params->list);
3185f6c63249SJohan Hedberg 	kfree(params);
3186f6c63249SJohan Hedberg }
3187f6c63249SJohan Hedberg 
318815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
318915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
319015819a70SAndre Guedes {
319115819a70SAndre Guedes 	struct hci_conn_params *params;
319215819a70SAndre Guedes 
319315819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
319415819a70SAndre Guedes 	if (!params)
319515819a70SAndre Guedes 		return;
319615819a70SAndre Guedes 
3197f6c63249SJohan Hedberg 	hci_conn_params_free(params);
319815819a70SAndre Guedes 
319995305baaSJohan Hedberg 	hci_update_background_scan(hdev);
320095305baaSJohan Hedberg 
320115819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
320215819a70SAndre Guedes }
320315819a70SAndre Guedes 
320415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
320555af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
320615819a70SAndre Guedes {
320715819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
320815819a70SAndre Guedes 
320915819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
321055af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
321155af49a8SJohan Hedberg 			continue;
321215819a70SAndre Guedes 		list_del(&params->list);
321315819a70SAndre Guedes 		kfree(params);
321415819a70SAndre Guedes 	}
321515819a70SAndre Guedes 
321655af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
321755af49a8SJohan Hedberg }
321855af49a8SJohan Hedberg 
321955af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
3220373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev)
322115819a70SAndre Guedes {
322215819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
322315819a70SAndre Guedes 
3224f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
3225f6c63249SJohan Hedberg 		hci_conn_params_free(params);
322615819a70SAndre Guedes 
3227a2f41a8fSJohan Hedberg 	hci_update_background_scan(hdev);
32281089b67dSMarcel Holtmann 
322915819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
323015819a70SAndre Guedes }
323115819a70SAndre Guedes 
32324c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
32337ba8b4beSAndre Guedes {
32344c87eaabSAndre Guedes 	if (status) {
32354c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
32367ba8b4beSAndre Guedes 
32374c87eaabSAndre Guedes 		hci_dev_lock(hdev);
32384c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
32394c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
32404c87eaabSAndre Guedes 		return;
32414c87eaabSAndre Guedes 	}
32427ba8b4beSAndre Guedes }
32437ba8b4beSAndre Guedes 
32444c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
32457ba8b4beSAndre Guedes {
32464c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
32474c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
32484c87eaabSAndre Guedes 	struct hci_request req;
32494c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
32507ba8b4beSAndre Guedes 	int err;
32517ba8b4beSAndre Guedes 
32524c87eaabSAndre Guedes 	if (status) {
32534c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
32544c87eaabSAndre Guedes 		return;
32557ba8b4beSAndre Guedes 	}
32567ba8b4beSAndre Guedes 
32574c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
32584c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
32594c87eaabSAndre Guedes 		hci_dev_lock(hdev);
32604c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
32614c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
32624c87eaabSAndre Guedes 		break;
32637dbfac1dSAndre Guedes 
32644c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
32654c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
32667dbfac1dSAndre Guedes 
32677dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
32684c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
32694c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
32704c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
32714c87eaabSAndre Guedes 
32724c87eaabSAndre Guedes 		hci_dev_lock(hdev);
32734c87eaabSAndre Guedes 
32744c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
32754c87eaabSAndre Guedes 
32764c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
32774c87eaabSAndre Guedes 		if (err) {
32784c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
32794c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
32807dbfac1dSAndre Guedes 		}
32817dbfac1dSAndre Guedes 
32824c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
32834c87eaabSAndre Guedes 		break;
32844c87eaabSAndre Guedes 	}
32857dbfac1dSAndre Guedes }
32867dbfac1dSAndre Guedes 
32877ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
32887ba8b4beSAndre Guedes {
32897ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
32907ba8b4beSAndre Guedes 					    le_scan_disable.work);
32914c87eaabSAndre Guedes 	struct hci_request req;
32924c87eaabSAndre Guedes 	int err;
32937ba8b4beSAndre Guedes 
32947ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
32957ba8b4beSAndre Guedes 
32964c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
32977ba8b4beSAndre Guedes 
3298b1efcc28SAndre Guedes 	hci_req_add_le_scan_disable(&req);
32997ba8b4beSAndre Guedes 
33004c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
33014c87eaabSAndre Guedes 	if (err)
33024c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
330328b75a89SAndre Guedes }
330428b75a89SAndre Guedes 
3305a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
3306a1f4c318SJohan Hedberg  *
3307a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
3308a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
3309a1f4c318SJohan Hedberg  * the static random address.
3310a1f4c318SJohan Hedberg  *
3311a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
3312a1f4c318SJohan Hedberg  * public address to use the static random address instead.
331350b5b952SMarcel Holtmann  *
331450b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
331550b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
331650b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
3317a1f4c318SJohan Hedberg  */
3318a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3319a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
3320a1f4c318SJohan Hedberg {
3321111902f7SMarcel Holtmann 	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
332250b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
332350b5b952SMarcel Holtmann 	    (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) &&
332450b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
3325a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
3326a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
3327a1f4c318SJohan Hedberg 	} else {
3328a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
3329a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
3330a1f4c318SJohan Hedberg 	}
3331a1f4c318SJohan Hedberg }
3332a1f4c318SJohan Hedberg 
33339be0dab7SDavid Herrmann /* Alloc HCI device */
33349be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
33359be0dab7SDavid Herrmann {
33369be0dab7SDavid Herrmann 	struct hci_dev *hdev;
33379be0dab7SDavid Herrmann 
333827f70f3eSJohan Hedberg 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
33399be0dab7SDavid Herrmann 	if (!hdev)
33409be0dab7SDavid Herrmann 		return NULL;
33419be0dab7SDavid Herrmann 
3342b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3343b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3344b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3345b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3346b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
334796c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
3348bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3349bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3350b1b813d4SDavid Herrmann 
3351b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3352b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3353b1b813d4SDavid Herrmann 
33543f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3355628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
3356628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
3357bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3358bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
33594e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
33604e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
336104fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
336204fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
3363bef64738SMarcel Holtmann 
3364d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3365b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
336631ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
336731ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
3368d6bfd59cSJohan Hedberg 
3369b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3370b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3371b1b813d4SDavid Herrmann 
3372b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3373b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
33746659358eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->whitelist);
3375b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3376b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3377b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3378970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3379b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
3380d2ab0ac1SMarcel Holtmann 	INIT_LIST_HEAD(&hdev->le_white_list);
338115819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
338277a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
338366f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
33846b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3385b1b813d4SDavid Herrmann 
3386b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3387b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3388b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3389b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3390b1b813d4SDavid Herrmann 
3391b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3392b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
3393b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
3394b1b813d4SDavid Herrmann 
3395b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3396b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3397b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3398b1b813d4SDavid Herrmann 
3399b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
3400b1b813d4SDavid Herrmann 
340165cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
3402b1b813d4SDavid Herrmann 
3403b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3404b1b813d4SDavid Herrmann 	discovery_init(hdev);
34059be0dab7SDavid Herrmann 
34069be0dab7SDavid Herrmann 	return hdev;
34079be0dab7SDavid Herrmann }
34089be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
34099be0dab7SDavid Herrmann 
34109be0dab7SDavid Herrmann /* Free HCI device */
34119be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
34129be0dab7SDavid Herrmann {
34139be0dab7SDavid Herrmann 	/* will free via device release */
34149be0dab7SDavid Herrmann 	put_device(&hdev->dev);
34159be0dab7SDavid Herrmann }
34169be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
34179be0dab7SDavid Herrmann 
34181da177e4SLinus Torvalds /* Register HCI device */
34191da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
34201da177e4SLinus Torvalds {
3421b1b813d4SDavid Herrmann 	int id, error;
34221da177e4SLinus Torvalds 
342374292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
34241da177e4SLinus Torvalds 		return -EINVAL;
34251da177e4SLinus Torvalds 
342608add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
342708add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
342808add513SMat Martineau 	 */
34293df92b31SSasha Levin 	switch (hdev->dev_type) {
34303df92b31SSasha Levin 	case HCI_BREDR:
34313df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
34321da177e4SLinus Torvalds 		break;
34333df92b31SSasha Levin 	case HCI_AMP:
34343df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
34353df92b31SSasha Levin 		break;
34363df92b31SSasha Levin 	default:
34373df92b31SSasha Levin 		return -EINVAL;
34381da177e4SLinus Torvalds 	}
34391da177e4SLinus Torvalds 
34403df92b31SSasha Levin 	if (id < 0)
34413df92b31SSasha Levin 		return id;
34423df92b31SSasha Levin 
34431da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
34441da177e4SLinus Torvalds 	hdev->id = id;
34452d8b3a11SAndrei Emeltchenko 
34462d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
34472d8b3a11SAndrei Emeltchenko 
3448d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3449d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
345033ca954dSDavid Herrmann 	if (!hdev->workqueue) {
345133ca954dSDavid Herrmann 		error = -ENOMEM;
345233ca954dSDavid Herrmann 		goto err;
345333ca954dSDavid Herrmann 	}
3454f48fd9c8SMarcel Holtmann 
3455d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3456d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
34576ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
34586ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
34596ead1bbcSJohan Hedberg 		error = -ENOMEM;
34606ead1bbcSJohan Hedberg 		goto err;
34616ead1bbcSJohan Hedberg 	}
34626ead1bbcSJohan Hedberg 
34630153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
34640153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
34650153e2ecSMarcel Holtmann 
3466bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3467bdc3e0f1SMarcel Holtmann 
3468bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
346933ca954dSDavid Herrmann 	if (error < 0)
347054506918SJohan Hedberg 		goto err_wqueue;
34711da177e4SLinus Torvalds 
3472611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3473a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3474a8c5fb1aSGustavo Padovan 				    hdev);
3475611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3476611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3477611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3478611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3479611b30f7SMarcel Holtmann 		}
3480611b30f7SMarcel Holtmann 	}
3481611b30f7SMarcel Holtmann 
34825e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
34835e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
34845e130367SJohan Hedberg 
3485a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
3486004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
3487ce2be9acSAndrei Emeltchenko 
348801cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
348956f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
349056f87901SJohan Hedberg 		 * through reading supported features during init.
349156f87901SJohan Hedberg 		 */
349256f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
349356f87901SJohan Hedberg 	}
3494ce2be9acSAndrei Emeltchenko 
3495fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3496fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3497fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3498fcee3377SGustavo Padovan 
34994a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
35004a964404SMarcel Holtmann 	 * and should not be included in normal operation.
3501fee746b0SMarcel Holtmann 	 */
3502fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
35034a964404SMarcel Holtmann 		set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
3504fee746b0SMarcel Holtmann 
35051da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
3506dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
35071da177e4SLinus Torvalds 
350819202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3509fbe96d6fSMarcel Holtmann 
35101da177e4SLinus Torvalds 	return id;
3511f48fd9c8SMarcel Holtmann 
351233ca954dSDavid Herrmann err_wqueue:
351333ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
35146ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
351533ca954dSDavid Herrmann err:
35163df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
3517f48fd9c8SMarcel Holtmann 
351833ca954dSDavid Herrmann 	return error;
35191da177e4SLinus Torvalds }
35201da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
35211da177e4SLinus Torvalds 
35221da177e4SLinus Torvalds /* Unregister HCI device */
352359735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
35241da177e4SLinus Torvalds {
35253df92b31SSasha Levin 	int i, id;
3526ef222013SMarcel Holtmann 
3527c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
35281da177e4SLinus Torvalds 
352994324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
353094324962SJohan Hovold 
35313df92b31SSasha Levin 	id = hdev->id;
35323df92b31SSasha Levin 
3533f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
35341da177e4SLinus Torvalds 	list_del(&hdev->list);
3535f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
35361da177e4SLinus Torvalds 
35371da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
35381da177e4SLinus Torvalds 
3539cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
3540ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
3541ef222013SMarcel Holtmann 
3542b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
3543b9b5ef18SGustavo Padovan 
3544ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
3545d603b76bSMarcel Holtmann 	    !test_bit(HCI_SETUP, &hdev->dev_flags) &&
3546d603b76bSMarcel Holtmann 	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
354709fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
3548744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
354909fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
355056e5cb86SJohan Hedberg 	}
3551ab81cbf9SJohan Hedberg 
35522e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
35532e58ef3eSJohan Hedberg 	 * pending list */
35542e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
35552e58ef3eSJohan Hedberg 
35561da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
35571da177e4SLinus Torvalds 
3558611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3559611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
3560611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
3561611b30f7SMarcel Holtmann 	}
3562611b30f7SMarcel Holtmann 
3563711eafe3SJohan Hedberg 	smp_unregister(hdev);
356499780a7bSJohan Hedberg 
3565bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
3566147e2d59SDave Young 
35670153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
35680153e2ecSMarcel Holtmann 
3569f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
35706ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
3571f48fd9c8SMarcel Holtmann 
357209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
3573dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->blacklist);
35746659358eSJohan Hedberg 	hci_bdaddr_list_clear(&hdev->whitelist);
35752aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
357655ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
3577b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
3578970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
35792763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
3580dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->le_white_list);
3581373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
358222078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
358309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
3584e2e0cacbSJohan Hedberg 
3585dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
35863df92b31SSasha Levin 
35873df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
35881da177e4SLinus Torvalds }
35891da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
35901da177e4SLinus Torvalds 
35911da177e4SLinus Torvalds /* Suspend HCI device */
35921da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
35931da177e4SLinus Torvalds {
35941da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
35951da177e4SLinus Torvalds 	return 0;
35961da177e4SLinus Torvalds }
35971da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
35981da177e4SLinus Torvalds 
35991da177e4SLinus Torvalds /* Resume HCI device */
36001da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
36011da177e4SLinus Torvalds {
36021da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
36031da177e4SLinus Torvalds 	return 0;
36041da177e4SLinus Torvalds }
36051da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
36061da177e4SLinus Torvalds 
360775e0569fSMarcel Holtmann /* Reset HCI device */
360875e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
360975e0569fSMarcel Holtmann {
361075e0569fSMarcel Holtmann 	const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
361175e0569fSMarcel Holtmann 	struct sk_buff *skb;
361275e0569fSMarcel Holtmann 
361375e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
361475e0569fSMarcel Holtmann 	if (!skb)
361575e0569fSMarcel Holtmann 		return -ENOMEM;
361675e0569fSMarcel Holtmann 
361775e0569fSMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
361875e0569fSMarcel Holtmann 	memcpy(skb_put(skb, 3), hw_err, 3);
361975e0569fSMarcel Holtmann 
362075e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
362175e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
362275e0569fSMarcel Holtmann }
362375e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
362475e0569fSMarcel Holtmann 
362576bca880SMarcel Holtmann /* Receive frame from HCI drivers */
3626e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
362776bca880SMarcel Holtmann {
362876bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
362976bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
363076bca880SMarcel Holtmann 		kfree_skb(skb);
363176bca880SMarcel Holtmann 		return -ENXIO;
363276bca880SMarcel Holtmann 	}
363376bca880SMarcel Holtmann 
3634d82603c6SJorrit Schippers 	/* Incoming skb */
363576bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
363676bca880SMarcel Holtmann 
363776bca880SMarcel Holtmann 	/* Time stamp */
363876bca880SMarcel Holtmann 	__net_timestamp(skb);
363976bca880SMarcel Holtmann 
364076bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3641b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3642c78ae283SMarcel Holtmann 
364376bca880SMarcel Holtmann 	return 0;
364476bca880SMarcel Holtmann }
364576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
364676bca880SMarcel Holtmann 
364733e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
36481e429f38SGustavo F. Padovan 			  int count, __u8 index)
364933e882a5SSuraj Sumangala {
365033e882a5SSuraj Sumangala 	int len = 0;
365133e882a5SSuraj Sumangala 	int hlen = 0;
365233e882a5SSuraj Sumangala 	int remain = count;
365333e882a5SSuraj Sumangala 	struct sk_buff *skb;
365433e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
365533e882a5SSuraj Sumangala 
365633e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
365733e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
365833e882a5SSuraj Sumangala 		return -EILSEQ;
365933e882a5SSuraj Sumangala 
366033e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
366133e882a5SSuraj Sumangala 
366233e882a5SSuraj Sumangala 	if (!skb) {
366333e882a5SSuraj Sumangala 		switch (type) {
366433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
366533e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
366633e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
366733e882a5SSuraj Sumangala 			break;
366833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
366933e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
367033e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
367133e882a5SSuraj Sumangala 			break;
367233e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
367333e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
367433e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
367533e882a5SSuraj Sumangala 			break;
367633e882a5SSuraj Sumangala 		}
367733e882a5SSuraj Sumangala 
36781e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
367933e882a5SSuraj Sumangala 		if (!skb)
368033e882a5SSuraj Sumangala 			return -ENOMEM;
368133e882a5SSuraj Sumangala 
368233e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
368333e882a5SSuraj Sumangala 		scb->expect = hlen;
368433e882a5SSuraj Sumangala 		scb->pkt_type = type;
368533e882a5SSuraj Sumangala 
368633e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
368733e882a5SSuraj Sumangala 	}
368833e882a5SSuraj Sumangala 
368933e882a5SSuraj Sumangala 	while (count) {
369033e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
369189bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
369233e882a5SSuraj Sumangala 
369333e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
369433e882a5SSuraj Sumangala 
369533e882a5SSuraj Sumangala 		count -= len;
369633e882a5SSuraj Sumangala 		data += len;
369733e882a5SSuraj Sumangala 		scb->expect -= len;
369833e882a5SSuraj Sumangala 		remain = count;
369933e882a5SSuraj Sumangala 
370033e882a5SSuraj Sumangala 		switch (type) {
370133e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
370233e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
370333e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
370433e882a5SSuraj Sumangala 				scb->expect = h->plen;
370533e882a5SSuraj Sumangala 
370633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
370733e882a5SSuraj Sumangala 					kfree_skb(skb);
370833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
370933e882a5SSuraj Sumangala 					return -ENOMEM;
371033e882a5SSuraj Sumangala 				}
371133e882a5SSuraj Sumangala 			}
371233e882a5SSuraj Sumangala 			break;
371333e882a5SSuraj Sumangala 
371433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
371533e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
371633e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
371733e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
371833e882a5SSuraj Sumangala 
371933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
372033e882a5SSuraj Sumangala 					kfree_skb(skb);
372133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
372233e882a5SSuraj Sumangala 					return -ENOMEM;
372333e882a5SSuraj Sumangala 				}
372433e882a5SSuraj Sumangala 			}
372533e882a5SSuraj Sumangala 			break;
372633e882a5SSuraj Sumangala 
372733e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
372833e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
372933e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
373033e882a5SSuraj Sumangala 				scb->expect = h->dlen;
373133e882a5SSuraj Sumangala 
373233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
373333e882a5SSuraj Sumangala 					kfree_skb(skb);
373433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
373533e882a5SSuraj Sumangala 					return -ENOMEM;
373633e882a5SSuraj Sumangala 				}
373733e882a5SSuraj Sumangala 			}
373833e882a5SSuraj Sumangala 			break;
373933e882a5SSuraj Sumangala 		}
374033e882a5SSuraj Sumangala 
374133e882a5SSuraj Sumangala 		if (scb->expect == 0) {
374233e882a5SSuraj Sumangala 			/* Complete frame */
374333e882a5SSuraj Sumangala 
374433e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
3745e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
374633e882a5SSuraj Sumangala 
374733e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
374833e882a5SSuraj Sumangala 			return remain;
374933e882a5SSuraj Sumangala 		}
375033e882a5SSuraj Sumangala 	}
375133e882a5SSuraj Sumangala 
375233e882a5SSuraj Sumangala 	return remain;
375333e882a5SSuraj Sumangala }
375433e882a5SSuraj Sumangala 
375599811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
375699811510SSuraj Sumangala 
375799811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
375899811510SSuraj Sumangala {
375999811510SSuraj Sumangala 	int type;
376099811510SSuraj Sumangala 	int rem = 0;
376199811510SSuraj Sumangala 
3762da5f6c37SGustavo F. Padovan 	while (count) {
376399811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
376499811510SSuraj Sumangala 
376599811510SSuraj Sumangala 		if (!skb) {
376699811510SSuraj Sumangala 			struct { char type; } *pkt;
376799811510SSuraj Sumangala 
376899811510SSuraj Sumangala 			/* Start of the frame */
376999811510SSuraj Sumangala 			pkt = data;
377099811510SSuraj Sumangala 			type = pkt->type;
377199811510SSuraj Sumangala 
377299811510SSuraj Sumangala 			data++;
377399811510SSuraj Sumangala 			count--;
377499811510SSuraj Sumangala 		} else
377599811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
377699811510SSuraj Sumangala 
37771e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
37781e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
377999811510SSuraj Sumangala 		if (rem < 0)
378099811510SSuraj Sumangala 			return rem;
378199811510SSuraj Sumangala 
378299811510SSuraj Sumangala 		data += (count - rem);
378399811510SSuraj Sumangala 		count = rem;
3784f81c6224SJoe Perches 	}
378599811510SSuraj Sumangala 
378699811510SSuraj Sumangala 	return rem;
378799811510SSuraj Sumangala }
378899811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
378999811510SSuraj Sumangala 
37901da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
37911da177e4SLinus Torvalds 
37921da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
37931da177e4SLinus Torvalds {
37941da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
37951da177e4SLinus Torvalds 
3796f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
37971da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
3798f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
37991da177e4SLinus Torvalds 
38001da177e4SLinus Torvalds 	return 0;
38011da177e4SLinus Torvalds }
38021da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
38031da177e4SLinus Torvalds 
38041da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
38051da177e4SLinus Torvalds {
38061da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
38071da177e4SLinus Torvalds 
3808f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
38091da177e4SLinus Torvalds 	list_del(&cb->list);
3810f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
38111da177e4SLinus Torvalds 
38121da177e4SLinus Torvalds 	return 0;
38131da177e4SLinus Torvalds }
38141da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
38151da177e4SLinus Torvalds 
381651086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
38171da177e4SLinus Torvalds {
3818cdc52faaSMarcel Holtmann 	int err;
3819cdc52faaSMarcel Holtmann 
38200d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
38211da177e4SLinus Torvalds 
38221da177e4SLinus Torvalds 	/* Time stamp */
3823a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
38241da177e4SLinus Torvalds 
3825cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3826cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3827cd82e61cSMarcel Holtmann 
3828cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3829cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3830470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
38311da177e4SLinus Torvalds 	}
38321da177e4SLinus Torvalds 
38331da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
38341da177e4SLinus Torvalds 	skb_orphan(skb);
38351da177e4SLinus Torvalds 
3836cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
3837cdc52faaSMarcel Holtmann 	if (err < 0) {
3838cdc52faaSMarcel Holtmann 		BT_ERR("%s sending frame failed (%d)", hdev->name, err);
3839cdc52faaSMarcel Holtmann 		kfree_skb(skb);
3840cdc52faaSMarcel Holtmann 	}
38411da177e4SLinus Torvalds }
38421da177e4SLinus Torvalds 
3843899de765SMarcel Holtmann bool hci_req_pending(struct hci_dev *hdev)
3844899de765SMarcel Holtmann {
3845899de765SMarcel Holtmann 	return (hdev->req_status == HCI_REQ_PEND);
3846899de765SMarcel Holtmann }
3847899de765SMarcel Holtmann 
38481ca3a9d0SJohan Hedberg /* Send HCI command */
384907dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
385007dc93ddSJohan Hedberg 		 const void *param)
38511ca3a9d0SJohan Hedberg {
38521ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
38531ca3a9d0SJohan Hedberg 
38541ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
38551ca3a9d0SJohan Hedberg 
38561ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
38571ca3a9d0SJohan Hedberg 	if (!skb) {
38581ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
38591ca3a9d0SJohan Hedberg 		return -ENOMEM;
38601ca3a9d0SJohan Hedberg 	}
38611ca3a9d0SJohan Hedberg 
386249c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
386311714b3dSJohan Hedberg 	 * single-command requests.
386411714b3dSJohan Hedberg 	 */
386511714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
386611714b3dSJohan Hedberg 
38671da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3868c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
38691da177e4SLinus Torvalds 
38701da177e4SLinus Torvalds 	return 0;
38711da177e4SLinus Torvalds }
38721da177e4SLinus Torvalds 
38731da177e4SLinus Torvalds /* Get data from the previously sent command */
3874a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
38751da177e4SLinus Torvalds {
38761da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
38771da177e4SLinus Torvalds 
38781da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
38791da177e4SLinus Torvalds 		return NULL;
38801da177e4SLinus Torvalds 
38811da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
38821da177e4SLinus Torvalds 
3883a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
38841da177e4SLinus Torvalds 		return NULL;
38851da177e4SLinus Torvalds 
3886f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
38871da177e4SLinus Torvalds 
38881da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
38891da177e4SLinus Torvalds }
38901da177e4SLinus Torvalds 
38911da177e4SLinus Torvalds /* Send ACL data */
38921da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
38931da177e4SLinus Torvalds {
38941da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
38951da177e4SLinus Torvalds 	int len = skb->len;
38961da177e4SLinus Torvalds 
3897badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3898badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
38999c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3900aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3901aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
39021da177e4SLinus Torvalds }
39031da177e4SLinus Torvalds 
3904ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
390573d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
39061da177e4SLinus Torvalds {
3907ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
39081da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
39091da177e4SLinus Torvalds 	struct sk_buff *list;
39101da177e4SLinus Torvalds 
3911087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3912087bfd99SGustavo Padovan 	skb->data_len = 0;
3913087bfd99SGustavo Padovan 
3914087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3915204a6e54SAndrei Emeltchenko 
3916204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3917204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
3918087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3919204a6e54SAndrei Emeltchenko 		break;
3920204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3921204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3922204a6e54SAndrei Emeltchenko 		break;
3923204a6e54SAndrei Emeltchenko 	default:
3924204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
3925204a6e54SAndrei Emeltchenko 		return;
3926204a6e54SAndrei Emeltchenko 	}
3927087bfd99SGustavo Padovan 
392870f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
392970f23020SAndrei Emeltchenko 	if (!list) {
39301da177e4SLinus Torvalds 		/* Non fragmented */
39311da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
39321da177e4SLinus Torvalds 
393373d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
39341da177e4SLinus Torvalds 	} else {
39351da177e4SLinus Torvalds 		/* Fragmented */
39361da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
39371da177e4SLinus Torvalds 
39381da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
39391da177e4SLinus Torvalds 
39409cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
39419cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
39429cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
39439cfd5a23SJukka Rissanen 		 * deadlocks.
39449cfd5a23SJukka Rissanen 		 */
39459cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
39461da177e4SLinus Torvalds 
394773d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3948e702112fSAndrei Emeltchenko 
3949e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3950e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
39511da177e4SLinus Torvalds 		do {
39521da177e4SLinus Torvalds 			skb = list; list = list->next;
39531da177e4SLinus Torvalds 
39540d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3955e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
39561da177e4SLinus Torvalds 
39571da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
39581da177e4SLinus Torvalds 
395973d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
39601da177e4SLinus Torvalds 		} while (list);
39611da177e4SLinus Torvalds 
39629cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
39631da177e4SLinus Torvalds 	}
396473d80debSLuiz Augusto von Dentz }
396573d80debSLuiz Augusto von Dentz 
396673d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
396773d80debSLuiz Augusto von Dentz {
3968ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
396973d80debSLuiz Augusto von Dentz 
3970f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
397173d80debSLuiz Augusto von Dentz 
3972ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
39731da177e4SLinus Torvalds 
39743eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
39751da177e4SLinus Torvalds }
39761da177e4SLinus Torvalds 
39771da177e4SLinus Torvalds /* Send SCO data */
39780d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
39791da177e4SLinus Torvalds {
39801da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
39811da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
39821da177e4SLinus Torvalds 
39831da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
39841da177e4SLinus Torvalds 
3985aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
39861da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
39871da177e4SLinus Torvalds 
3988badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3989badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
39909c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
39911da177e4SLinus Torvalds 
39920d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
3993c78ae283SMarcel Holtmann 
39941da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
39953eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
39961da177e4SLinus Torvalds }
39971da177e4SLinus Torvalds 
39981da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
39991da177e4SLinus Torvalds 
40001da177e4SLinus Torvalds /* HCI Connection scheduler */
40016039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
4002a8c5fb1aSGustavo Padovan 				     int *quote)
40031da177e4SLinus Torvalds {
40041da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
40058035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
4006abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
40071da177e4SLinus Torvalds 
40081da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
40091da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
4010bf4c6325SGustavo F. Padovan 
4011bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4012bf4c6325SGustavo F. Padovan 
4013bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4014769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
40151da177e4SLinus Torvalds 			continue;
4016769be974SMarcel Holtmann 
4017769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
4018769be974SMarcel Holtmann 			continue;
4019769be974SMarcel Holtmann 
40201da177e4SLinus Torvalds 		num++;
40211da177e4SLinus Torvalds 
40221da177e4SLinus Torvalds 		if (c->sent < min) {
40231da177e4SLinus Torvalds 			min  = c->sent;
40241da177e4SLinus Torvalds 			conn = c;
40251da177e4SLinus Torvalds 		}
402652087a79SLuiz Augusto von Dentz 
402752087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
402852087a79SLuiz Augusto von Dentz 			break;
40291da177e4SLinus Torvalds 	}
40301da177e4SLinus Torvalds 
4031bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4032bf4c6325SGustavo F. Padovan 
40331da177e4SLinus Torvalds 	if (conn) {
40346ed58ec5SVille Tervo 		int cnt, q;
40356ed58ec5SVille Tervo 
40366ed58ec5SVille Tervo 		switch (conn->type) {
40376ed58ec5SVille Tervo 		case ACL_LINK:
40386ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
40396ed58ec5SVille Tervo 			break;
40406ed58ec5SVille Tervo 		case SCO_LINK:
40416ed58ec5SVille Tervo 		case ESCO_LINK:
40426ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
40436ed58ec5SVille Tervo 			break;
40446ed58ec5SVille Tervo 		case LE_LINK:
40456ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
40466ed58ec5SVille Tervo 			break;
40476ed58ec5SVille Tervo 		default:
40486ed58ec5SVille Tervo 			cnt = 0;
40496ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
40506ed58ec5SVille Tervo 		}
40516ed58ec5SVille Tervo 
40526ed58ec5SVille Tervo 		q = cnt / num;
40531da177e4SLinus Torvalds 		*quote = q ? q : 1;
40541da177e4SLinus Torvalds 	} else
40551da177e4SLinus Torvalds 		*quote = 0;
40561da177e4SLinus Torvalds 
40571da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
40581da177e4SLinus Torvalds 	return conn;
40591da177e4SLinus Torvalds }
40601da177e4SLinus Torvalds 
40616039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
40621da177e4SLinus Torvalds {
40631da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
40641da177e4SLinus Torvalds 	struct hci_conn *c;
40651da177e4SLinus Torvalds 
4066bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
40671da177e4SLinus Torvalds 
4068bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4069bf4c6325SGustavo F. Padovan 
40701da177e4SLinus Torvalds 	/* Kill stalled connections */
4071bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4072bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
40736ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
40746ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
4075bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
40761da177e4SLinus Torvalds 		}
40771da177e4SLinus Torvalds 	}
4078bf4c6325SGustavo F. Padovan 
4079bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
40801da177e4SLinus Torvalds }
40811da177e4SLinus Torvalds 
40826039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
408373d80debSLuiz Augusto von Dentz 				      int *quote)
408473d80debSLuiz Augusto von Dentz {
408573d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
408673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4087abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
408873d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
408973d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
409073d80debSLuiz Augusto von Dentz 
409173d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
409273d80debSLuiz Augusto von Dentz 
4093bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4094bf4c6325SGustavo F. Padovan 
4095bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
409673d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
409773d80debSLuiz Augusto von Dentz 
409873d80debSLuiz Augusto von Dentz 		if (conn->type != type)
409973d80debSLuiz Augusto von Dentz 			continue;
410073d80debSLuiz Augusto von Dentz 
410173d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
410273d80debSLuiz Augusto von Dentz 			continue;
410373d80debSLuiz Augusto von Dentz 
410473d80debSLuiz Augusto von Dentz 		conn_num++;
410573d80debSLuiz Augusto von Dentz 
41068192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
410773d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
410873d80debSLuiz Augusto von Dentz 
410973d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
411073d80debSLuiz Augusto von Dentz 				continue;
411173d80debSLuiz Augusto von Dentz 
411273d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
411373d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
411473d80debSLuiz Augusto von Dentz 				continue;
411573d80debSLuiz Augusto von Dentz 
411673d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
411773d80debSLuiz Augusto von Dentz 				num = 0;
411873d80debSLuiz Augusto von Dentz 				min = ~0;
411973d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
412073d80debSLuiz Augusto von Dentz 			}
412173d80debSLuiz Augusto von Dentz 
412273d80debSLuiz Augusto von Dentz 			num++;
412373d80debSLuiz Augusto von Dentz 
412473d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
412573d80debSLuiz Augusto von Dentz 				min  = conn->sent;
412673d80debSLuiz Augusto von Dentz 				chan = tmp;
412773d80debSLuiz Augusto von Dentz 			}
412873d80debSLuiz Augusto von Dentz 		}
412973d80debSLuiz Augusto von Dentz 
413073d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
413173d80debSLuiz Augusto von Dentz 			break;
413273d80debSLuiz Augusto von Dentz 	}
413373d80debSLuiz Augusto von Dentz 
4134bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4135bf4c6325SGustavo F. Padovan 
413673d80debSLuiz Augusto von Dentz 	if (!chan)
413773d80debSLuiz Augusto von Dentz 		return NULL;
413873d80debSLuiz Augusto von Dentz 
413973d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
414073d80debSLuiz Augusto von Dentz 	case ACL_LINK:
414173d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
414273d80debSLuiz Augusto von Dentz 		break;
4143bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4144bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4145bd1eb66bSAndrei Emeltchenko 		break;
414673d80debSLuiz Augusto von Dentz 	case SCO_LINK:
414773d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
414873d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
414973d80debSLuiz Augusto von Dentz 		break;
415073d80debSLuiz Augusto von Dentz 	case LE_LINK:
415173d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
415273d80debSLuiz Augusto von Dentz 		break;
415373d80debSLuiz Augusto von Dentz 	default:
415473d80debSLuiz Augusto von Dentz 		cnt = 0;
415573d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
415673d80debSLuiz Augusto von Dentz 	}
415773d80debSLuiz Augusto von Dentz 
415873d80debSLuiz Augusto von Dentz 	q = cnt / num;
415973d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
416073d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
416173d80debSLuiz Augusto von Dentz 	return chan;
416273d80debSLuiz Augusto von Dentz }
416373d80debSLuiz Augusto von Dentz 
416402b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
416502b20f0bSLuiz Augusto von Dentz {
416602b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
416702b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
416802b20f0bSLuiz Augusto von Dentz 	int num = 0;
416902b20f0bSLuiz Augusto von Dentz 
417002b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
417102b20f0bSLuiz Augusto von Dentz 
4172bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4173bf4c6325SGustavo F. Padovan 
4174bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
417502b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
417602b20f0bSLuiz Augusto von Dentz 
417702b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
417802b20f0bSLuiz Augusto von Dentz 			continue;
417902b20f0bSLuiz Augusto von Dentz 
418002b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
418102b20f0bSLuiz Augusto von Dentz 			continue;
418202b20f0bSLuiz Augusto von Dentz 
418302b20f0bSLuiz Augusto von Dentz 		num++;
418402b20f0bSLuiz Augusto von Dentz 
41858192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
418602b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
418702b20f0bSLuiz Augusto von Dentz 
418802b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
418902b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
419002b20f0bSLuiz Augusto von Dentz 				continue;
419102b20f0bSLuiz Augusto von Dentz 			}
419202b20f0bSLuiz Augusto von Dentz 
419302b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
419402b20f0bSLuiz Augusto von Dentz 				continue;
419502b20f0bSLuiz Augusto von Dentz 
419602b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
419702b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
419802b20f0bSLuiz Augusto von Dentz 				continue;
419902b20f0bSLuiz Augusto von Dentz 
420002b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
420102b20f0bSLuiz Augusto von Dentz 
420202b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
420302b20f0bSLuiz Augusto von Dentz 			       skb->priority);
420402b20f0bSLuiz Augusto von Dentz 		}
420502b20f0bSLuiz Augusto von Dentz 
420602b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
420702b20f0bSLuiz Augusto von Dentz 			break;
420802b20f0bSLuiz Augusto von Dentz 	}
4209bf4c6325SGustavo F. Padovan 
4210bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4211bf4c6325SGustavo F. Padovan 
421202b20f0bSLuiz Augusto von Dentz }
421302b20f0bSLuiz Augusto von Dentz 
4214b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4215b71d385aSAndrei Emeltchenko {
4216b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4217b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4218b71d385aSAndrei Emeltchenko }
4219b71d385aSAndrei Emeltchenko 
42206039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
42211da177e4SLinus Torvalds {
42224a964404SMarcel Holtmann 	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
42231da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
42241da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
422563d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
42265f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4227bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
42281da177e4SLinus Torvalds 	}
422963d2bc1bSAndrei Emeltchenko }
42301da177e4SLinus Torvalds 
42316039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
423263d2bc1bSAndrei Emeltchenko {
423363d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
423463d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
423563d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
423663d2bc1bSAndrei Emeltchenko 	int quote;
423763d2bc1bSAndrei Emeltchenko 
423863d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
423904837f64SMarcel Holtmann 
424073d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
424173d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4242ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4243ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
424473d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
424573d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
424673d80debSLuiz Augusto von Dentz 
4247ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4248ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4249ec1cce24SLuiz Augusto von Dentz 				break;
4250ec1cce24SLuiz Augusto von Dentz 
4251ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4252ec1cce24SLuiz Augusto von Dentz 
425373d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
425473d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
425504837f64SMarcel Holtmann 
425657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
42571da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
42581da177e4SLinus Torvalds 
42591da177e4SLinus Torvalds 			hdev->acl_cnt--;
426073d80debSLuiz Augusto von Dentz 			chan->sent++;
426173d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
42621da177e4SLinus Torvalds 		}
42631da177e4SLinus Torvalds 	}
426402b20f0bSLuiz Augusto von Dentz 
426502b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
426602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
42671da177e4SLinus Torvalds }
42681da177e4SLinus Torvalds 
42696039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4270b71d385aSAndrei Emeltchenko {
427163d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4272b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4273b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4274b71d385aSAndrei Emeltchenko 	int quote;
4275bd1eb66bSAndrei Emeltchenko 	u8 type;
4276b71d385aSAndrei Emeltchenko 
427763d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
4278b71d385aSAndrei Emeltchenko 
4279bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4280bd1eb66bSAndrei Emeltchenko 
4281bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
4282bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
4283bd1eb66bSAndrei Emeltchenko 	else
4284bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
4285bd1eb66bSAndrei Emeltchenko 
4286b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
4287bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
4288b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
4289b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
4290b71d385aSAndrei Emeltchenko 			int blocks;
4291b71d385aSAndrei Emeltchenko 
4292b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
4293b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
4294b71d385aSAndrei Emeltchenko 
4295b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
4296b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
4297b71d385aSAndrei Emeltchenko 				break;
4298b71d385aSAndrei Emeltchenko 
4299b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
4300b71d385aSAndrei Emeltchenko 
4301b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
4302b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
4303b71d385aSAndrei Emeltchenko 				return;
4304b71d385aSAndrei Emeltchenko 
4305b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
4306b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
4307b71d385aSAndrei Emeltchenko 
430857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4309b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4310b71d385aSAndrei Emeltchenko 
4311b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4312b71d385aSAndrei Emeltchenko 			quote -= blocks;
4313b71d385aSAndrei Emeltchenko 
4314b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4315b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4316b71d385aSAndrei Emeltchenko 		}
4317b71d385aSAndrei Emeltchenko 	}
4318b71d385aSAndrei Emeltchenko 
4319b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4320bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4321b71d385aSAndrei Emeltchenko }
4322b71d385aSAndrei Emeltchenko 
43236039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4324b71d385aSAndrei Emeltchenko {
4325b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4326b71d385aSAndrei Emeltchenko 
4327bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4328bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
4329bd1eb66bSAndrei Emeltchenko 		return;
4330bd1eb66bSAndrei Emeltchenko 
4331bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4332bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4333b71d385aSAndrei Emeltchenko 		return;
4334b71d385aSAndrei Emeltchenko 
4335b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4336b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4337b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4338b71d385aSAndrei Emeltchenko 		break;
4339b71d385aSAndrei Emeltchenko 
4340b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4341b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4342b71d385aSAndrei Emeltchenko 		break;
4343b71d385aSAndrei Emeltchenko 	}
4344b71d385aSAndrei Emeltchenko }
4345b71d385aSAndrei Emeltchenko 
43461da177e4SLinus Torvalds /* Schedule SCO */
43476039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
43481da177e4SLinus Torvalds {
43491da177e4SLinus Torvalds 	struct hci_conn *conn;
43501da177e4SLinus Torvalds 	struct sk_buff *skb;
43511da177e4SLinus Torvalds 	int quote;
43521da177e4SLinus Torvalds 
43531da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
43541da177e4SLinus Torvalds 
435552087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
435652087a79SLuiz Augusto von Dentz 		return;
435752087a79SLuiz Augusto von Dentz 
43581da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
43591da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
43601da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
436157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
43621da177e4SLinus Torvalds 
43631da177e4SLinus Torvalds 			conn->sent++;
43641da177e4SLinus Torvalds 			if (conn->sent == ~0)
43651da177e4SLinus Torvalds 				conn->sent = 0;
43661da177e4SLinus Torvalds 		}
43671da177e4SLinus Torvalds 	}
43681da177e4SLinus Torvalds }
43691da177e4SLinus Torvalds 
43706039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
4371b6a0dc82SMarcel Holtmann {
4372b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4373b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
4374b6a0dc82SMarcel Holtmann 	int quote;
4375b6a0dc82SMarcel Holtmann 
4376b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
4377b6a0dc82SMarcel Holtmann 
437852087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
437952087a79SLuiz Augusto von Dentz 		return;
438052087a79SLuiz Augusto von Dentz 
43818fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
43828fc9ced3SGustavo Padovan 						     &quote))) {
4383b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
4384b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
438557d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4386b6a0dc82SMarcel Holtmann 
4387b6a0dc82SMarcel Holtmann 			conn->sent++;
4388b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
4389b6a0dc82SMarcel Holtmann 				conn->sent = 0;
4390b6a0dc82SMarcel Holtmann 		}
4391b6a0dc82SMarcel Holtmann 	}
4392b6a0dc82SMarcel Holtmann }
4393b6a0dc82SMarcel Holtmann 
43946039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
43956ed58ec5SVille Tervo {
439673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
43976ed58ec5SVille Tervo 	struct sk_buff *skb;
439802b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
43996ed58ec5SVille Tervo 
44006ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
44016ed58ec5SVille Tervo 
440252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
440352087a79SLuiz Augusto von Dentz 		return;
440452087a79SLuiz Augusto von Dentz 
44054a964404SMarcel Holtmann 	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
44066ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
44076ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
4408bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
44096ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
4410bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
44116ed58ec5SVille Tervo 	}
44126ed58ec5SVille Tervo 
44136ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
441402b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
441573d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4416ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4417ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
441873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
441973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
44206ed58ec5SVille Tervo 
4421ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4422ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4423ec1cce24SLuiz Augusto von Dentz 				break;
4424ec1cce24SLuiz Augusto von Dentz 
4425ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4426ec1cce24SLuiz Augusto von Dentz 
442757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
44286ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
44296ed58ec5SVille Tervo 
44306ed58ec5SVille Tervo 			cnt--;
443173d80debSLuiz Augusto von Dentz 			chan->sent++;
443273d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
44336ed58ec5SVille Tervo 		}
44346ed58ec5SVille Tervo 	}
443573d80debSLuiz Augusto von Dentz 
44366ed58ec5SVille Tervo 	if (hdev->le_pkts)
44376ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
44386ed58ec5SVille Tervo 	else
44396ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
444002b20f0bSLuiz Augusto von Dentz 
444102b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
444202b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
44436ed58ec5SVille Tervo }
44446ed58ec5SVille Tervo 
44453eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
44461da177e4SLinus Torvalds {
44473eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
44481da177e4SLinus Torvalds 	struct sk_buff *skb;
44491da177e4SLinus Torvalds 
44506ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
44516ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
44521da177e4SLinus Torvalds 
445352de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
44541da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
44551da177e4SLinus Torvalds 		hci_sched_acl(hdev);
44561da177e4SLinus Torvalds 		hci_sched_sco(hdev);
4457b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
44586ed58ec5SVille Tervo 		hci_sched_le(hdev);
445952de599eSMarcel Holtmann 	}
44606ed58ec5SVille Tervo 
44611da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
44621da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
446357d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
44641da177e4SLinus Torvalds }
44651da177e4SLinus Torvalds 
446625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
44671da177e4SLinus Torvalds 
44681da177e4SLinus Torvalds /* ACL data packet */
44696039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
44701da177e4SLinus Torvalds {
44711da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
44721da177e4SLinus Torvalds 	struct hci_conn *conn;
44731da177e4SLinus Torvalds 	__u16 handle, flags;
44741da177e4SLinus Torvalds 
44751da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
44761da177e4SLinus Torvalds 
44771da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
44781da177e4SLinus Torvalds 	flags  = hci_flags(handle);
44791da177e4SLinus Torvalds 	handle = hci_handle(handle);
44801da177e4SLinus Torvalds 
4481f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4482a8c5fb1aSGustavo Padovan 	       handle, flags);
44831da177e4SLinus Torvalds 
44841da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
44851da177e4SLinus Torvalds 
44861da177e4SLinus Torvalds 	hci_dev_lock(hdev);
44871da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
44881da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
44891da177e4SLinus Torvalds 
44901da177e4SLinus Torvalds 	if (conn) {
449165983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
449204837f64SMarcel Holtmann 
44931da177e4SLinus Torvalds 		/* Send to upper protocol */
4494686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
44951da177e4SLinus Torvalds 		return;
44961da177e4SLinus Torvalds 	} else {
44971da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
44981da177e4SLinus Torvalds 		       hdev->name, handle);
44991da177e4SLinus Torvalds 	}
45001da177e4SLinus Torvalds 
45011da177e4SLinus Torvalds 	kfree_skb(skb);
45021da177e4SLinus Torvalds }
45031da177e4SLinus Torvalds 
45041da177e4SLinus Torvalds /* SCO data packet */
45056039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
45061da177e4SLinus Torvalds {
45071da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
45081da177e4SLinus Torvalds 	struct hci_conn *conn;
45091da177e4SLinus Torvalds 	__u16 handle;
45101da177e4SLinus Torvalds 
45111da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
45121da177e4SLinus Torvalds 
45131da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
45141da177e4SLinus Torvalds 
4515f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
45161da177e4SLinus Torvalds 
45171da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
45181da177e4SLinus Torvalds 
45191da177e4SLinus Torvalds 	hci_dev_lock(hdev);
45201da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
45211da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
45221da177e4SLinus Torvalds 
45231da177e4SLinus Torvalds 	if (conn) {
45241da177e4SLinus Torvalds 		/* Send to upper protocol */
4525686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
45261da177e4SLinus Torvalds 		return;
45271da177e4SLinus Torvalds 	} else {
45281da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
45291da177e4SLinus Torvalds 		       hdev->name, handle);
45301da177e4SLinus Torvalds 	}
45311da177e4SLinus Torvalds 
45321da177e4SLinus Torvalds 	kfree_skb(skb);
45331da177e4SLinus Torvalds }
45341da177e4SLinus Torvalds 
45359238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
45369238f36aSJohan Hedberg {
45379238f36aSJohan Hedberg 	struct sk_buff *skb;
45389238f36aSJohan Hedberg 
45399238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
45409238f36aSJohan Hedberg 	if (!skb)
45419238f36aSJohan Hedberg 		return true;
45429238f36aSJohan Hedberg 
45439238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
45449238f36aSJohan Hedberg }
45459238f36aSJohan Hedberg 
454642c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
454742c6b129SJohan Hedberg {
454842c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
454942c6b129SJohan Hedberg 	struct sk_buff *skb;
455042c6b129SJohan Hedberg 	u16 opcode;
455142c6b129SJohan Hedberg 
455242c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
455342c6b129SJohan Hedberg 		return;
455442c6b129SJohan Hedberg 
455542c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
455642c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
455742c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
455842c6b129SJohan Hedberg 		return;
455942c6b129SJohan Hedberg 
456042c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
456142c6b129SJohan Hedberg 	if (!skb)
456242c6b129SJohan Hedberg 		return;
456342c6b129SJohan Hedberg 
456442c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
456542c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
456642c6b129SJohan Hedberg }
456742c6b129SJohan Hedberg 
45689238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
45699238f36aSJohan Hedberg {
45709238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
45719238f36aSJohan Hedberg 	struct sk_buff *skb;
45729238f36aSJohan Hedberg 	unsigned long flags;
45739238f36aSJohan Hedberg 
45749238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
45759238f36aSJohan Hedberg 
457642c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
457742c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
45789238f36aSJohan Hedberg 	 */
457942c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
458042c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
458142c6b129SJohan Hedberg 		 * reset complete event during init and any pending
458242c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
458342c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
458442c6b129SJohan Hedberg 		 * command.
458542c6b129SJohan Hedberg 		 */
458642c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
458742c6b129SJohan Hedberg 			hci_resend_last(hdev);
458842c6b129SJohan Hedberg 
45899238f36aSJohan Hedberg 		return;
459042c6b129SJohan Hedberg 	}
45919238f36aSJohan Hedberg 
45929238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
45939238f36aSJohan Hedberg 	 * this request the request is not yet complete.
45949238f36aSJohan Hedberg 	 */
45959238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
45969238f36aSJohan Hedberg 		return;
45979238f36aSJohan Hedberg 
45989238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
45999238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
46009238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
46019238f36aSJohan Hedberg 	 */
46029238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
46039238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
460453e21fbcSJohan Hedberg 
460553e21fbcSJohan Hedberg 		if (req_complete) {
460653e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
460753e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
460853e21fbcSJohan Hedberg 			 * this function gets called again.
460953e21fbcSJohan Hedberg 			 */
461053e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
461153e21fbcSJohan Hedberg 
46129238f36aSJohan Hedberg 			goto call_complete;
46139238f36aSJohan Hedberg 		}
461453e21fbcSJohan Hedberg 	}
46159238f36aSJohan Hedberg 
46169238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
46179238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
46189238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
46199238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
46209238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
46219238f36aSJohan Hedberg 			break;
46229238f36aSJohan Hedberg 		}
46239238f36aSJohan Hedberg 
46249238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
46259238f36aSJohan Hedberg 		kfree_skb(skb);
46269238f36aSJohan Hedberg 	}
46279238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
46289238f36aSJohan Hedberg 
46299238f36aSJohan Hedberg call_complete:
46309238f36aSJohan Hedberg 	if (req_complete)
46319238f36aSJohan Hedberg 		req_complete(hdev, status);
46329238f36aSJohan Hedberg }
46339238f36aSJohan Hedberg 
4634b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
46351da177e4SLinus Torvalds {
4636b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
46371da177e4SLinus Torvalds 	struct sk_buff *skb;
46381da177e4SLinus Torvalds 
46391da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
46401da177e4SLinus Torvalds 
46411da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
4642cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4643cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4644cd82e61cSMarcel Holtmann 
46451da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
46461da177e4SLinus Torvalds 			/* Send copy to the sockets */
4647470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
46481da177e4SLinus Torvalds 		}
46491da177e4SLinus Torvalds 
4650fee746b0SMarcel Holtmann 		if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
46511da177e4SLinus Torvalds 			kfree_skb(skb);
46521da177e4SLinus Torvalds 			continue;
46531da177e4SLinus Torvalds 		}
46541da177e4SLinus Torvalds 
46551da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
46561da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
46570d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
46581da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
46591da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
46601da177e4SLinus Torvalds 				kfree_skb(skb);
46611da177e4SLinus Torvalds 				continue;
46623ff50b79SStephen Hemminger 			}
46631da177e4SLinus Torvalds 		}
46641da177e4SLinus Torvalds 
46651da177e4SLinus Torvalds 		/* Process frame */
46660d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
46671da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4668b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
46691da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
46701da177e4SLinus Torvalds 			break;
46711da177e4SLinus Torvalds 
46721da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
46731da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
46741da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
46751da177e4SLinus Torvalds 			break;
46761da177e4SLinus Torvalds 
46771da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
46781da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
46791da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
46801da177e4SLinus Torvalds 			break;
46811da177e4SLinus Torvalds 
46821da177e4SLinus Torvalds 		default:
46831da177e4SLinus Torvalds 			kfree_skb(skb);
46841da177e4SLinus Torvalds 			break;
46851da177e4SLinus Torvalds 		}
46861da177e4SLinus Torvalds 	}
46871da177e4SLinus Torvalds }
46881da177e4SLinus Torvalds 
4689c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
46901da177e4SLinus Torvalds {
4691c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
46921da177e4SLinus Torvalds 	struct sk_buff *skb;
46931da177e4SLinus Torvalds 
46942104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
46952104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
46961da177e4SLinus Torvalds 
46971da177e4SLinus Torvalds 	/* Send queued commands */
46985a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
46995a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
47005a08ecceSAndrei Emeltchenko 		if (!skb)
47015a08ecceSAndrei Emeltchenko 			return;
47025a08ecceSAndrei Emeltchenko 
47031da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
47041da177e4SLinus Torvalds 
4705a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
470670f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
47071da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
470857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
47097bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
471065cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
47117bdb8a5cSSzymon Janc 			else
471265cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
471365cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
47141da177e4SLinus Torvalds 		} else {
47151da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
4716c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
47171da177e4SLinus Torvalds 		}
47181da177e4SLinus Torvalds 	}
47191da177e4SLinus Torvalds }
4720