xref: /openbmc/linux/net/bluetooth/hci_core.c (revision f41a4b2b)
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>
29611b30f7SMarcel Holtmann #include <linux/rfkill.h>
30baf27f6eSMarcel Holtmann #include <linux/debugfs.h>
3199780a7bSJohan Hedberg #include <linux/crypto.h>
327a0e5b15SMatthias Kaehlcke #include <linux/property.h>
339952d90eSAbhishek Pandit-Subedi #include <linux/suspend.h>
349952d90eSAbhishek Pandit-Subedi #include <linux/wait.h>
3547219839SMarcel Holtmann #include <asm/unaligned.h>
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
381da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
394bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
40af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h>
411da177e4SLinus Torvalds 
420857dd3bSJohan Hedberg #include "hci_request.h"
4360c5f5fbSMarcel Holtmann #include "hci_debugfs.h"
44970c4e46SJohan Hedberg #include "smp.h"
456d5d2ee6SHeiner Kallweit #include "leds.h"
46145373cbSMiao-chen Chou #include "msft.h"
47f67743f9SMarcel Holtmann #include "aosp.h"
48970c4e46SJohan Hedberg 
49b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
50c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
513eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
521da177e4SLinus Torvalds 
531da177e4SLinus Torvalds /* HCI device list */
541da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
551da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
561da177e4SLinus Torvalds 
571da177e4SLinus Torvalds /* HCI callback list */
581da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
59fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock);
601da177e4SLinus Torvalds 
613df92b31SSasha Levin /* HCI ID Numbering */
623df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
633df92b31SSasha Levin 
64baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
65baf27f6eSMarcel Holtmann 
664b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
674b4148e9SMarcel Holtmann 			     size_t count, loff_t *ppos)
684b4148e9SMarcel Holtmann {
694b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
704b4148e9SMarcel Holtmann 	char buf[3];
714b4148e9SMarcel Holtmann 
72b7cb93e5SMarcel Holtmann 	buf[0] = hci_dev_test_flag(hdev, HCI_DUT_MODE) ? 'Y' : 'N';
734b4148e9SMarcel Holtmann 	buf[1] = '\n';
744b4148e9SMarcel Holtmann 	buf[2] = '\0';
754b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
764b4148e9SMarcel Holtmann }
774b4148e9SMarcel Holtmann 
784b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
794b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
804b4148e9SMarcel Holtmann {
814b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
824b4148e9SMarcel Holtmann 	struct sk_buff *skb;
834b4148e9SMarcel Holtmann 	bool enable;
843bf5e97dSAndy Shevchenko 	int err;
854b4148e9SMarcel Holtmann 
864b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
874b4148e9SMarcel Holtmann 		return -ENETDOWN;
884b4148e9SMarcel Holtmann 
893bf5e97dSAndy Shevchenko 	err = kstrtobool_from_user(user_buf, count, &enable);
903bf5e97dSAndy Shevchenko 	if (err)
913bf5e97dSAndy Shevchenko 		return err;
924b4148e9SMarcel Holtmann 
93b7cb93e5SMarcel Holtmann 	if (enable == hci_dev_test_flag(hdev, HCI_DUT_MODE))
944b4148e9SMarcel Holtmann 		return -EALREADY;
954b4148e9SMarcel Holtmann 
96b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
974b4148e9SMarcel Holtmann 	if (enable)
984b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
994b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1004b4148e9SMarcel Holtmann 	else
1014b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1024b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
103b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
1044b4148e9SMarcel Holtmann 
1054b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1064b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1074b4148e9SMarcel Holtmann 
1084b4148e9SMarcel Holtmann 	kfree_skb(skb);
1094b4148e9SMarcel Holtmann 
110b7cb93e5SMarcel Holtmann 	hci_dev_change_flag(hdev, HCI_DUT_MODE);
1114b4148e9SMarcel Holtmann 
1124b4148e9SMarcel Holtmann 	return count;
1134b4148e9SMarcel Holtmann }
1144b4148e9SMarcel Holtmann 
1154b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1164b4148e9SMarcel Holtmann 	.open		= simple_open,
1174b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1184b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1194b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1204b4148e9SMarcel Holtmann };
1214b4148e9SMarcel Holtmann 
1224b4113d6SMarcel Holtmann static ssize_t vendor_diag_read(struct file *file, char __user *user_buf,
1234b4113d6SMarcel Holtmann 				size_t count, loff_t *ppos)
1244b4113d6SMarcel Holtmann {
1254b4113d6SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
1264b4113d6SMarcel Holtmann 	char buf[3];
1274b4113d6SMarcel Holtmann 
1284b4113d6SMarcel Holtmann 	buf[0] = hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) ? 'Y' : 'N';
1294b4113d6SMarcel Holtmann 	buf[1] = '\n';
1304b4113d6SMarcel Holtmann 	buf[2] = '\0';
1314b4113d6SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
1324b4113d6SMarcel Holtmann }
1334b4113d6SMarcel Holtmann 
1344b4113d6SMarcel Holtmann static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf,
1354b4113d6SMarcel Holtmann 				 size_t count, loff_t *ppos)
1364b4113d6SMarcel Holtmann {
1374b4113d6SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
1384b4113d6SMarcel Holtmann 	bool enable;
1394b4113d6SMarcel Holtmann 	int err;
1404b4113d6SMarcel Holtmann 
1413bf5e97dSAndy Shevchenko 	err = kstrtobool_from_user(user_buf, count, &enable);
1423bf5e97dSAndy Shevchenko 	if (err)
1433bf5e97dSAndy Shevchenko 		return err;
1444b4113d6SMarcel Holtmann 
1457e995b9eSMarcel Holtmann 	/* When the diagnostic flags are not persistent and the transport
146b56c7b25SMarcel Holtmann 	 * is not active or in user channel operation, then there is no need
147b56c7b25SMarcel Holtmann 	 * for the vendor callback. Instead just store the desired value and
148b56c7b25SMarcel Holtmann 	 * the setting will be programmed when the controller gets powered on.
1497e995b9eSMarcel Holtmann 	 */
1507e995b9eSMarcel Holtmann 	if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
151b56c7b25SMarcel Holtmann 	    (!test_bit(HCI_RUNNING, &hdev->flags) ||
152b56c7b25SMarcel Holtmann 	     hci_dev_test_flag(hdev, HCI_USER_CHANNEL)))
1537e995b9eSMarcel Holtmann 		goto done;
1547e995b9eSMarcel Holtmann 
155b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
1564b4113d6SMarcel Holtmann 	err = hdev->set_diag(hdev, enable);
157b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
1584b4113d6SMarcel Holtmann 
1594b4113d6SMarcel Holtmann 	if (err < 0)
1604b4113d6SMarcel Holtmann 		return err;
1614b4113d6SMarcel Holtmann 
1627e995b9eSMarcel Holtmann done:
1634b4113d6SMarcel Holtmann 	if (enable)
1644b4113d6SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_VENDOR_DIAG);
1654b4113d6SMarcel Holtmann 	else
1664b4113d6SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_VENDOR_DIAG);
1674b4113d6SMarcel Holtmann 
1684b4113d6SMarcel Holtmann 	return count;
1694b4113d6SMarcel Holtmann }
1704b4113d6SMarcel Holtmann 
1714b4113d6SMarcel Holtmann static const struct file_operations vendor_diag_fops = {
1724b4113d6SMarcel Holtmann 	.open		= simple_open,
1734b4113d6SMarcel Holtmann 	.read		= vendor_diag_read,
1744b4113d6SMarcel Holtmann 	.write		= vendor_diag_write,
1754b4113d6SMarcel Holtmann 	.llseek		= default_llseek,
1764b4113d6SMarcel Holtmann };
1774b4113d6SMarcel Holtmann 
178f640ee98SMarcel Holtmann static void hci_debugfs_create_basic(struct hci_dev *hdev)
179f640ee98SMarcel Holtmann {
180f640ee98SMarcel Holtmann 	debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
181f640ee98SMarcel Holtmann 			    &dut_mode_fops);
182f640ee98SMarcel Holtmann 
183f640ee98SMarcel Holtmann 	if (hdev->set_diag)
184f640ee98SMarcel Holtmann 		debugfs_create_file("vendor_diag", 0644, hdev->debugfs, hdev,
185f640ee98SMarcel Holtmann 				    &vendor_diag_fops);
186f640ee98SMarcel Holtmann }
187f640ee98SMarcel Holtmann 
188a1d01db1SJohan Hedberg static int hci_reset_req(struct hci_request *req, unsigned long opt)
1891da177e4SLinus Torvalds {
19042c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
1911da177e4SLinus Torvalds 
1921da177e4SLinus Torvalds 	/* Reset device */
19342c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
19442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
195a1d01db1SJohan Hedberg 	return 0;
1961da177e4SLinus Torvalds }
1971da177e4SLinus Torvalds 
19842c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
1991da177e4SLinus Torvalds {
20042c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
2012455a3eaSAndrei Emeltchenko 
2021da177e4SLinus Torvalds 	/* Read Local Supported Features */
20342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
2041da177e4SLinus Torvalds 
2051143e5a6SMarcel Holtmann 	/* Read Local Version */
20642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2072177bab5SJohan Hedberg 
2082177bab5SJohan Hedberg 	/* Read BD Address */
20942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
2101da177e4SLinus Torvalds }
2111da177e4SLinus Torvalds 
2120af801b9SJohan Hedberg static void amp_init1(struct hci_request *req)
213e61ef499SAndrei Emeltchenko {
21442c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
2152455a3eaSAndrei Emeltchenko 
216e61ef499SAndrei Emeltchenko 	/* Read Local Version */
21742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2186bcbc489SAndrei Emeltchenko 
219f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
220f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
221f6996cfeSMarcel Holtmann 
2226bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
22342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
224e71dfabaSAndrei Emeltchenko 
225e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
22642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
2277528ca1cSMarcel Holtmann 
228f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
229f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
230f38ba941SMarcel Holtmann 
2317528ca1cSMarcel Holtmann 	/* Read Location Data */
2327528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
233e61ef499SAndrei Emeltchenko }
234e61ef499SAndrei Emeltchenko 
235a1d01db1SJohan Hedberg static int amp_init2(struct hci_request *req)
2360af801b9SJohan Hedberg {
2370af801b9SJohan Hedberg 	/* Read Local Supported Features. Not all AMP controllers
2380af801b9SJohan Hedberg 	 * support this so it's placed conditionally in the second
2390af801b9SJohan Hedberg 	 * stage init.
2400af801b9SJohan Hedberg 	 */
2410af801b9SJohan Hedberg 	if (req->hdev->commands[14] & 0x20)
2420af801b9SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
243a1d01db1SJohan Hedberg 
244a1d01db1SJohan Hedberg 	return 0;
2450af801b9SJohan Hedberg }
2460af801b9SJohan Hedberg 
247a1d01db1SJohan Hedberg static int hci_init1_req(struct hci_request *req, unsigned long opt)
248e61ef499SAndrei Emeltchenko {
24942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
250e61ef499SAndrei Emeltchenko 
251e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
252e61ef499SAndrei Emeltchenko 
25311778716SAndrei Emeltchenko 	/* Reset */
25411778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
25542c6b129SJohan Hedberg 		hci_reset_req(req, 0);
25611778716SAndrei Emeltchenko 
257e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
258ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
25942c6b129SJohan Hedberg 		bredr_init(req);
260e61ef499SAndrei Emeltchenko 		break;
261e61ef499SAndrei Emeltchenko 	case HCI_AMP:
2620af801b9SJohan Hedberg 		amp_init1(req);
263e61ef499SAndrei Emeltchenko 		break;
264e61ef499SAndrei Emeltchenko 	default:
2652064ee33SMarcel Holtmann 		bt_dev_err(hdev, "Unknown device type %d", hdev->dev_type);
266e61ef499SAndrei Emeltchenko 		break;
267e61ef499SAndrei Emeltchenko 	}
268a1d01db1SJohan Hedberg 
269a1d01db1SJohan Hedberg 	return 0;
270e61ef499SAndrei Emeltchenko }
271e61ef499SAndrei Emeltchenko 
27242c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
2732177bab5SJohan Hedberg {
2742177bab5SJohan Hedberg 	__le16 param;
2752177bab5SJohan Hedberg 	__u8 flt_type;
2762177bab5SJohan Hedberg 
2772177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
27842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
2792177bab5SJohan Hedberg 
2802177bab5SJohan Hedberg 	/* Read Class of Device */
28142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
2822177bab5SJohan Hedberg 
2832177bab5SJohan Hedberg 	/* Read Local Name */
28442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2852177bab5SJohan Hedberg 
2862177bab5SJohan Hedberg 	/* Read Voice Setting */
28742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2882177bab5SJohan Hedberg 
289b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
290b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
291b4cb9fb2SMarcel Holtmann 
2924b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
2934b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
2944b836f39SMarcel Holtmann 
2952177bab5SJohan Hedberg 	/* Clear Event Filters */
2962177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
29742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2982177bab5SJohan Hedberg 
2992177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
300dcf4adbfSJoe Perches 	param = cpu_to_le16(0x7d00);
30142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
3022177bab5SJohan Hedberg }
3032177bab5SJohan Hedberg 
30442c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
3052177bab5SJohan Hedberg {
306c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
307c73eee91SJohan Hedberg 
3082177bab5SJohan Hedberg 	/* Read LE Buffer Size */
30942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
3102177bab5SJohan Hedberg 
3112177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
31242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
3132177bab5SJohan Hedberg 
314747d3f03SMarcel Holtmann 	/* Read LE Supported States */
315747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
316747d3f03SMarcel Holtmann 
317c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
318c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
319a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ENABLED);
3202177bab5SJohan Hedberg }
3212177bab5SJohan Hedberg 
32242c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
3232177bab5SJohan Hedberg {
32442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
32542c6b129SJohan Hedberg 
3262177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
3272177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
3282177bab5SJohan Hedberg 	 * command otherwise.
3292177bab5SJohan Hedberg 	 */
3302177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
3312177bab5SJohan Hedberg 
3322177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
3332177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
3342177bab5SJohan Hedberg 	 */
3352177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
3362177bab5SJohan Hedberg 		return;
3372177bab5SJohan Hedberg 
3382177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
3392177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
340c7882cbdSMarcel Holtmann 	} else {
341c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
342c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
343c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
344c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
345c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
3465c3d3b4cSMarcel Holtmann 
3475c3d3b4cSMarcel Holtmann 		/* If the controller supports the Disconnect command, enable
3485c3d3b4cSMarcel Holtmann 		 * the corresponding event. In addition enable packet flow
3495c3d3b4cSMarcel Holtmann 		 * control related events.
3505c3d3b4cSMarcel Holtmann 		 */
3515c3d3b4cSMarcel Holtmann 		if (hdev->commands[0] & 0x20) {
3525c3d3b4cSMarcel Holtmann 			events[0] |= 0x10; /* Disconnection Complete */
353c7882cbdSMarcel Holtmann 			events[2] |= 0x04; /* Number of Completed Packets */
354c7882cbdSMarcel Holtmann 			events[3] |= 0x02; /* Data Buffer Overflow */
3555c3d3b4cSMarcel Holtmann 		}
3565c3d3b4cSMarcel Holtmann 
3575c3d3b4cSMarcel Holtmann 		/* If the controller supports the Read Remote Version
3585c3d3b4cSMarcel Holtmann 		 * Information command, enable the corresponding event.
3595c3d3b4cSMarcel Holtmann 		 */
3605c3d3b4cSMarcel Holtmann 		if (hdev->commands[2] & 0x80)
3615c3d3b4cSMarcel Holtmann 			events[1] |= 0x08; /* Read Remote Version Information
3625c3d3b4cSMarcel Holtmann 					    * Complete
3635c3d3b4cSMarcel Holtmann 					    */
3640da71f1bSMarcel Holtmann 
3650da71f1bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION) {
3660da71f1bSMarcel Holtmann 			events[0] |= 0x80; /* Encryption Change */
367c7882cbdSMarcel Holtmann 			events[5] |= 0x80; /* Encryption Key Refresh Complete */
3682177bab5SJohan Hedberg 		}
3690da71f1bSMarcel Holtmann 	}
3702177bab5SJohan Hedberg 
3719fe759ceSMarcel Holtmann 	if (lmp_inq_rssi_capable(hdev) ||
3729fe759ceSMarcel Holtmann 	    test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks))
3732177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
3742177bab5SJohan Hedberg 
37570f56aa2SMarcel Holtmann 	if (lmp_ext_feat_capable(hdev))
37670f56aa2SMarcel Holtmann 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
37770f56aa2SMarcel Holtmann 
37870f56aa2SMarcel Holtmann 	if (lmp_esco_capable(hdev)) {
37970f56aa2SMarcel Holtmann 		events[5] |= 0x08; /* Synchronous Connection Complete */
38070f56aa2SMarcel Holtmann 		events[5] |= 0x10; /* Synchronous Connection Changed */
38170f56aa2SMarcel Holtmann 	}
38270f56aa2SMarcel Holtmann 
3832177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
3842177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
3852177bab5SJohan Hedberg 
3862177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
3872177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
3882177bab5SJohan Hedberg 
3892177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
3902177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
3912177bab5SJohan Hedberg 
3922177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
3932177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
3942177bab5SJohan Hedberg 
3952177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
3962177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
3972177bab5SJohan Hedberg 
3982177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
3992177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
4002177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
4012177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
4022177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
4032177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
4042177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
4052177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
4062177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
4072177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
4082177bab5SJohan Hedberg 					 * Features Notification
4092177bab5SJohan Hedberg 					 */
4102177bab5SJohan Hedberg 	}
4112177bab5SJohan Hedberg 
4122177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
4132177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
4142177bab5SJohan Hedberg 
41542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
4162177bab5SJohan Hedberg }
4172177bab5SJohan Hedberg 
418a1d01db1SJohan Hedberg static int hci_init2_req(struct hci_request *req, unsigned long opt)
4192177bab5SJohan Hedberg {
42042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
42142c6b129SJohan Hedberg 
4220af801b9SJohan Hedberg 	if (hdev->dev_type == HCI_AMP)
4230af801b9SJohan Hedberg 		return amp_init2(req);
4240af801b9SJohan Hedberg 
4252177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
42642c6b129SJohan Hedberg 		bredr_setup(req);
42756f87901SJohan Hedberg 	else
428a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED);
4292177bab5SJohan Hedberg 
4302177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
43142c6b129SJohan Hedberg 		le_setup(req);
4322177bab5SJohan Hedberg 
4330f3adeaeSMarcel Holtmann 	/* All Bluetooth 1.2 and later controllers should support the
4340f3adeaeSMarcel Holtmann 	 * HCI command for reading the local supported commands.
4350f3adeaeSMarcel Holtmann 	 *
4360f3adeaeSMarcel Holtmann 	 * Unfortunately some controllers indicate Bluetooth 1.2 support,
4370f3adeaeSMarcel Holtmann 	 * but do not have support for this command. If that is the case,
4380f3adeaeSMarcel Holtmann 	 * the driver can quirk the behavior and skip reading the local
4390f3adeaeSMarcel Holtmann 	 * supported commands.
4403f8e2d75SJohan Hedberg 	 */
4410f3adeaeSMarcel Holtmann 	if (hdev->hci_ver > BLUETOOTH_VER_1_1 &&
4420f3adeaeSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks))
44342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
4442177bab5SJohan Hedberg 
4452177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
44657af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
44757af75a8SMarcel Holtmann 		 * should also be available as well. However some
44857af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
44957af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
45057af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
45157af75a8SMarcel Holtmann 		 */
45257af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
45357af75a8SMarcel Holtmann 
454d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
4552177bab5SJohan Hedberg 			u8 mode = 0x01;
456574ea3c7SMarcel Holtmann 
45742c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
4582177bab5SJohan Hedberg 				    sizeof(mode), &mode);
4592177bab5SJohan Hedberg 		} else {
4602177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
4612177bab5SJohan Hedberg 
4622177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
4632177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
4642177bab5SJohan Hedberg 
46542c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
4662177bab5SJohan Hedberg 		}
4672177bab5SJohan Hedberg 	}
4682177bab5SJohan Hedberg 
469043ec9bfSMarcel Holtmann 	if (lmp_inq_rssi_capable(hdev) ||
470043ec9bfSMarcel Holtmann 	    test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) {
47104422da9SMarcel Holtmann 		u8 mode;
47204422da9SMarcel Holtmann 
47304422da9SMarcel Holtmann 		/* If Extended Inquiry Result events are supported, then
47404422da9SMarcel Holtmann 		 * they are clearly preferred over Inquiry Result with RSSI
47504422da9SMarcel Holtmann 		 * events.
47604422da9SMarcel Holtmann 		 */
47704422da9SMarcel Holtmann 		mode = lmp_ext_inq_capable(hdev) ? 0x02 : 0x01;
47804422da9SMarcel Holtmann 
47904422da9SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
48004422da9SMarcel Holtmann 	}
4812177bab5SJohan Hedberg 
4822177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
48342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
4842177bab5SJohan Hedberg 
4852177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
4862177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
4872177bab5SJohan Hedberg 
4882177bab5SJohan Hedberg 		cp.page = 0x01;
48942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
49042c6b129SJohan Hedberg 			    sizeof(cp), &cp);
4912177bab5SJohan Hedberg 	}
4922177bab5SJohan Hedberg 
493d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_LINK_SECURITY)) {
4942177bab5SJohan Hedberg 		u8 enable = 1;
49542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
4962177bab5SJohan Hedberg 			    &enable);
4972177bab5SJohan Hedberg 	}
498a1d01db1SJohan Hedberg 
499a1d01db1SJohan Hedberg 	return 0;
5002177bab5SJohan Hedberg }
5012177bab5SJohan Hedberg 
50242c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
5032177bab5SJohan Hedberg {
50442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5052177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
5062177bab5SJohan Hedberg 	u16 link_policy = 0;
5072177bab5SJohan Hedberg 
5082177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
5092177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
5102177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
5112177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
5122177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
5132177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
5142177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
5152177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
5162177bab5SJohan Hedberg 
5172177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
51842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
5192177bab5SJohan Hedberg }
5202177bab5SJohan Hedberg 
52142c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
5222177bab5SJohan Hedberg {
52342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5242177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
5252177bab5SJohan Hedberg 
526c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
527c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
528c73eee91SJohan Hedberg 		return;
529c73eee91SJohan Hedberg 
5302177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
5312177bab5SJohan Hedberg 
532d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
5332177bab5SJohan Hedberg 		cp.le = 0x01;
53432226e4fSMarcel Holtmann 		cp.simul = 0x00;
5352177bab5SJohan Hedberg 	}
5362177bab5SJohan Hedberg 
5372177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
53842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
5392177bab5SJohan Hedberg 			    &cp);
5402177bab5SJohan Hedberg }
5412177bab5SJohan Hedberg 
542d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
543d62e6d67SJohan Hedberg {
544d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
545d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
546313f6888SMarcel Holtmann 	bool changed = false;
547d62e6d67SJohan Hedberg 
5486397729bSArchie Pusaka 	/* If Connectionless Peripheral Broadcast central role is supported
549d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
550d62e6d67SJohan Hedberg 	 */
5516397729bSArchie Pusaka 	if (lmp_cpb_central_capable(hdev)) {
552d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
553d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
5546397729bSArchie Pusaka 		events[2] |= 0x10;	/* Peripheral Page Response Timeout */
5556397729bSArchie Pusaka 		events[2] |= 0x20;	/* CPB Channel Map Change */
556313f6888SMarcel Holtmann 		changed = true;
557d62e6d67SJohan Hedberg 	}
558d62e6d67SJohan Hedberg 
5596397729bSArchie Pusaka 	/* If Connectionless Peripheral Broadcast peripheral role is supported
560d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
561d62e6d67SJohan Hedberg 	 */
5626397729bSArchie Pusaka 	if (lmp_cpb_peripheral_capable(hdev)) {
563d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
5646397729bSArchie Pusaka 		events[2] |= 0x02;	/* CPB Receive */
5656397729bSArchie Pusaka 		events[2] |= 0x04;	/* CPB Timeout */
566d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
567313f6888SMarcel Holtmann 		changed = true;
568d62e6d67SJohan Hedberg 	}
569d62e6d67SJohan Hedberg 
57040c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
571313f6888SMarcel Holtmann 	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) {
57240c59fcbSMarcel Holtmann 		events[2] |= 0x80;
573313f6888SMarcel Holtmann 		changed = true;
574313f6888SMarcel Holtmann 	}
57540c59fcbSMarcel Holtmann 
576313f6888SMarcel Holtmann 	/* Some Broadcom based controllers indicate support for Set Event
577313f6888SMarcel Holtmann 	 * Mask Page 2 command, but then actually do not support it. Since
578313f6888SMarcel Holtmann 	 * the default value is all bits set to zero, the command is only
579313f6888SMarcel Holtmann 	 * required if the event mask has to be changed. In case no change
580313f6888SMarcel Holtmann 	 * to the event mask is needed, skip this command.
581313f6888SMarcel Holtmann 	 */
582313f6888SMarcel Holtmann 	if (changed)
583313f6888SMarcel Holtmann 		hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2,
584313f6888SMarcel Holtmann 			    sizeof(events), events);
585d62e6d67SJohan Hedberg }
586d62e6d67SJohan Hedberg 
587a1d01db1SJohan Hedberg static int hci_init3_req(struct hci_request *req, unsigned long opt)
5882177bab5SJohan Hedberg {
58942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
590d2c5d77fSJohan Hedberg 	u8 p;
59142c6b129SJohan Hedberg 
5920da71f1bSMarcel Holtmann 	hci_setup_event_mask(req);
5930da71f1bSMarcel Holtmann 
594e81be90bSJohan Hedberg 	if (hdev->commands[6] & 0x20 &&
595e81be90bSJohan Hedberg 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
59648ce62c4SMarcel Holtmann 		struct hci_cp_read_stored_link_key cp;
59748ce62c4SMarcel Holtmann 
59848ce62c4SMarcel Holtmann 		bacpy(&cp.bdaddr, BDADDR_ANY);
59948ce62c4SMarcel Holtmann 		cp.read_all = 0x01;
60048ce62c4SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_STORED_LINK_KEY, sizeof(cp), &cp);
60148ce62c4SMarcel Holtmann 	}
60248ce62c4SMarcel Holtmann 
6032177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
60442c6b129SJohan Hedberg 		hci_setup_link_policy(req);
6052177bab5SJohan Hedberg 
606417287deSMarcel Holtmann 	if (hdev->commands[8] & 0x01)
607417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
608417287deSMarcel Holtmann 
609cde1a8a9SIsmael Ferreras Morezuelas 	if (hdev->commands[18] & 0x04 &&
610cde1a8a9SIsmael Ferreras Morezuelas 	    !test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
61100bce3fbSAlain Michaud 		hci_req_add(req, HCI_OP_READ_DEF_ERR_DATA_REPORTING, 0, NULL);
61200bce3fbSAlain Michaud 
613417287deSMarcel Holtmann 	/* Some older Broadcom based Bluetooth 1.2 controllers do not
614417287deSMarcel Holtmann 	 * support the Read Page Scan Type command. Check support for
615417287deSMarcel Holtmann 	 * this command in the bit mask of supported commands.
616417287deSMarcel Holtmann 	 */
617417287deSMarcel Holtmann 	if (hdev->commands[13] & 0x01)
618417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
619417287deSMarcel Holtmann 
6209193c6e8SAndre Guedes 	if (lmp_le_capable(hdev)) {
6219193c6e8SAndre Guedes 		u8 events[8];
6229193c6e8SAndre Guedes 
6239193c6e8SAndre Guedes 		memset(events, 0, sizeof(events));
6244d6c705bSMarcel Holtmann 
6254d6c705bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
6264d6c705bSMarcel Holtmann 			events[0] |= 0x10;	/* LE Long Term Key Request */
627662bc2e6SAndre Guedes 
628662bc2e6SAndre Guedes 		/* If controller supports the Connection Parameters Request
629662bc2e6SAndre Guedes 		 * Link Layer Procedure, enable the corresponding event.
630662bc2e6SAndre Guedes 		 */
631662bc2e6SAndre Guedes 		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
632662bc2e6SAndre Guedes 			events[0] |= 0x20;	/* LE Remote Connection
633662bc2e6SAndre Guedes 						 * Parameter Request
634662bc2e6SAndre Guedes 						 */
635662bc2e6SAndre Guedes 
636a9f6068eSMarcel Holtmann 		/* If the controller supports the Data Length Extension
637a9f6068eSMarcel Holtmann 		 * feature, enable the corresponding event.
638a9f6068eSMarcel Holtmann 		 */
639a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
640a9f6068eSMarcel Holtmann 			events[0] |= 0x40;	/* LE Data Length Change */
641a9f6068eSMarcel Holtmann 
642ff3b8df2SMarcel Holtmann 		/* If the controller supports LL Privacy feature, enable
643ff3b8df2SMarcel Holtmann 		 * the corresponding event.
644ff3b8df2SMarcel Holtmann 		 */
645ff3b8df2SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_LL_PRIVACY)
646ff3b8df2SMarcel Holtmann 			events[1] |= 0x02;	/* LE Enhanced Connection
647ff3b8df2SMarcel Holtmann 						 * Complete
648ff3b8df2SMarcel Holtmann 						 */
649ff3b8df2SMarcel Holtmann 
6504b71bba4SMarcel Holtmann 		/* If the controller supports Extended Scanner Filter
65191641b79SZheng Yongjun 		 * Policies, enable the corresponding event.
6524b71bba4SMarcel Holtmann 		 */
6534b71bba4SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)
6544b71bba4SMarcel Holtmann 			events[1] |= 0x04;	/* LE Direct Advertising
6554b71bba4SMarcel Holtmann 						 * Report
6564b71bba4SMarcel Holtmann 						 */
6574b71bba4SMarcel Holtmann 
6589756d33bSMarcel Holtmann 		/* If the controller supports Channel Selection Algorithm #2
6599756d33bSMarcel Holtmann 		 * feature, enable the corresponding event.
6609756d33bSMarcel Holtmann 		 */
6619756d33bSMarcel Holtmann 		if (hdev->le_features[1] & HCI_LE_CHAN_SEL_ALG2)
6629756d33bSMarcel Holtmann 			events[2] |= 0x08;	/* LE Channel Selection
6639756d33bSMarcel Holtmann 						 * Algorithm
6649756d33bSMarcel Holtmann 						 */
6659756d33bSMarcel Holtmann 
6667d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Set Scan Enable command,
6677d26f5c4SMarcel Holtmann 		 * enable the corresponding advertising report event.
6687d26f5c4SMarcel Holtmann 		 */
6697d26f5c4SMarcel Holtmann 		if (hdev->commands[26] & 0x08)
6707d26f5c4SMarcel Holtmann 			events[0] |= 0x02;	/* LE Advertising Report */
6717d26f5c4SMarcel Holtmann 
6727d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Create Connection
6737d26f5c4SMarcel Holtmann 		 * command, enable the corresponding event.
6747d26f5c4SMarcel Holtmann 		 */
6757d26f5c4SMarcel Holtmann 		if (hdev->commands[26] & 0x10)
6767d26f5c4SMarcel Holtmann 			events[0] |= 0x01;	/* LE Connection Complete */
6777d26f5c4SMarcel Holtmann 
6787d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Connection Update
6797d26f5c4SMarcel Holtmann 		 * command, enable the corresponding event.
6807d26f5c4SMarcel Holtmann 		 */
6817d26f5c4SMarcel Holtmann 		if (hdev->commands[27] & 0x04)
6827d26f5c4SMarcel Holtmann 			events[0] |= 0x04;	/* LE Connection Update
6837d26f5c4SMarcel Holtmann 						 * Complete
6847d26f5c4SMarcel Holtmann 						 */
6857d26f5c4SMarcel Holtmann 
6867d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Read Remote Used Features
6877d26f5c4SMarcel Holtmann 		 * command, enable the corresponding event.
6887d26f5c4SMarcel Holtmann 		 */
6897d26f5c4SMarcel Holtmann 		if (hdev->commands[27] & 0x20)
6907d26f5c4SMarcel Holtmann 			events[0] |= 0x08;	/* LE Read Remote Used
6917d26f5c4SMarcel Holtmann 						 * Features Complete
6927d26f5c4SMarcel Holtmann 						 */
6937d26f5c4SMarcel Holtmann 
6945a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Read Local P-256
6955a34bd5fSMarcel Holtmann 		 * Public Key command, enable the corresponding event.
6965a34bd5fSMarcel Holtmann 		 */
6975a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x02)
6985a34bd5fSMarcel Holtmann 			events[0] |= 0x80;	/* LE Read Local P-256
6995a34bd5fSMarcel Holtmann 						 * Public Key Complete
7005a34bd5fSMarcel Holtmann 						 */
7015a34bd5fSMarcel Holtmann 
7025a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Generate DHKey
7035a34bd5fSMarcel Holtmann 		 * command, enable the corresponding event.
7045a34bd5fSMarcel Holtmann 		 */
7055a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x04)
7065a34bd5fSMarcel Holtmann 			events[1] |= 0x01;	/* LE Generate DHKey Complete */
7075a34bd5fSMarcel Holtmann 
70827bbca44SMarcel Holtmann 		/* If the controller supports the LE Set Default PHY or
70927bbca44SMarcel Holtmann 		 * LE Set PHY commands, enable the corresponding event.
71027bbca44SMarcel Holtmann 		 */
71127bbca44SMarcel Holtmann 		if (hdev->commands[35] & (0x20 | 0x40))
71227bbca44SMarcel Holtmann 			events[1] |= 0x08;        /* LE PHY Update Complete */
71327bbca44SMarcel Holtmann 
714c215e939SJaganath Kanakkassery 		/* If the controller supports LE Set Extended Scan Parameters
715c215e939SJaganath Kanakkassery 		 * and LE Set Extended Scan Enable commands, enable the
716c215e939SJaganath Kanakkassery 		 * corresponding event.
717c215e939SJaganath Kanakkassery 		 */
718c215e939SJaganath Kanakkassery 		if (use_ext_scan(hdev))
719c215e939SJaganath Kanakkassery 			events[1] |= 0x10;	/* LE Extended Advertising
720c215e939SJaganath Kanakkassery 						 * Report
721c215e939SJaganath Kanakkassery 						 */
722c215e939SJaganath Kanakkassery 
723acf0aeaeSJaganath Kanakkassery 		/* If the controller supports the LE Extended Advertising
724acf0aeaeSJaganath Kanakkassery 		 * command, enable the corresponding event.
725acf0aeaeSJaganath Kanakkassery 		 */
726acf0aeaeSJaganath Kanakkassery 		if (ext_adv_capable(hdev))
727acf0aeaeSJaganath Kanakkassery 			events[2] |= 0x02;	/* LE Advertising Set
728acf0aeaeSJaganath Kanakkassery 						 * Terminated
729acf0aeaeSJaganath Kanakkassery 						 */
730acf0aeaeSJaganath Kanakkassery 
7319193c6e8SAndre Guedes 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
7329193c6e8SAndre Guedes 			    events);
7339193c6e8SAndre Guedes 
73415a49ccaSMarcel Holtmann 		/* Read LE Advertising Channel TX Power */
7356b49bcb4SJaganath Kanakkassery 		if ((hdev->commands[25] & 0x40) && !ext_adv_capable(hdev)) {
7366b49bcb4SJaganath Kanakkassery 			/* HCI TS spec forbids mixing of legacy and extended
7376b49bcb4SJaganath Kanakkassery 			 * advertising commands wherein READ_ADV_TX_POWER is
7386b49bcb4SJaganath Kanakkassery 			 * also included. So do not call it if extended adv
7396b49bcb4SJaganath Kanakkassery 			 * is supported otherwise controller will return
7406b49bcb4SJaganath Kanakkassery 			 * COMMAND_DISALLOWED for extended commands.
7416b49bcb4SJaganath Kanakkassery 			 */
74215a49ccaSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
74315a49ccaSMarcel Holtmann 		}
74415a49ccaSMarcel Holtmann 
7457c395ea5SDaniel Winkler 		if (hdev->commands[38] & 0x80) {
7467c395ea5SDaniel Winkler 			/* Read LE Min/Max Tx Power*/
7477c395ea5SDaniel Winkler 			hci_req_add(req, HCI_OP_LE_READ_TRANSMIT_POWER,
7487c395ea5SDaniel Winkler 				    0, NULL);
7497c395ea5SDaniel Winkler 		}
7507c395ea5SDaniel Winkler 
7512ab216a7SMarcel Holtmann 		if (hdev->commands[26] & 0x40) {
7523d4f9c00SArchie Pusaka 			/* Read LE Accept List Size */
7533d4f9c00SArchie Pusaka 			hci_req_add(req, HCI_OP_LE_READ_ACCEPT_LIST_SIZE,
7542ab216a7SMarcel Holtmann 				    0, NULL);
7552ab216a7SMarcel Holtmann 		}
7562ab216a7SMarcel Holtmann 
7572ab216a7SMarcel Holtmann 		if (hdev->commands[26] & 0x80) {
7583d4f9c00SArchie Pusaka 			/* Clear LE Accept List */
7593d4f9c00SArchie Pusaka 			hci_req_add(req, HCI_OP_LE_CLEAR_ACCEPT_LIST, 0, NULL);
7602ab216a7SMarcel Holtmann 		}
7612ab216a7SMarcel Holtmann 
762cfdb0c2dSAnkit Navik 		if (hdev->commands[34] & 0x40) {
763cfdb0c2dSAnkit Navik 			/* Read LE Resolving List Size */
764cfdb0c2dSAnkit Navik 			hci_req_add(req, HCI_OP_LE_READ_RESOLV_LIST_SIZE,
765cfdb0c2dSAnkit Navik 				    0, NULL);
766cfdb0c2dSAnkit Navik 		}
767cfdb0c2dSAnkit Navik 
768545f2596SAnkit Navik 		if (hdev->commands[34] & 0x20) {
769545f2596SAnkit Navik 			/* Clear LE Resolving List */
770545f2596SAnkit Navik 			hci_req_add(req, HCI_OP_LE_CLEAR_RESOLV_LIST, 0, NULL);
771545f2596SAnkit Navik 		}
772545f2596SAnkit Navik 
773a31489d2SEdward Vear 		if (hdev->commands[35] & 0x04) {
774b2cc2339SSathish Narasimman 			__le16 rpa_timeout = cpu_to_le16(hdev->rpa_timeout);
775b2cc2339SSathish Narasimman 
776b2cc2339SSathish Narasimman 			/* Set RPA timeout */
777b2cc2339SSathish Narasimman 			hci_req_add(req, HCI_OP_LE_SET_RPA_TIMEOUT, 2,
778b2cc2339SSathish Narasimman 				    &rpa_timeout);
779b2cc2339SSathish Narasimman 		}
780b2cc2339SSathish Narasimman 
781a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
782a9f6068eSMarcel Holtmann 			/* Read LE Maximum Data Length */
783a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL);
784a9f6068eSMarcel Holtmann 
785a9f6068eSMarcel Holtmann 			/* Read LE Suggested Default Data Length */
786a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL);
787a9f6068eSMarcel Holtmann 		}
788a9f6068eSMarcel Holtmann 
7896b49bcb4SJaganath Kanakkassery 		if (ext_adv_capable(hdev)) {
7906b49bcb4SJaganath Kanakkassery 			/* Read LE Number of Supported Advertising Sets */
7916b49bcb4SJaganath Kanakkassery 			hci_req_add(req, HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS,
7926b49bcb4SJaganath Kanakkassery 				    0, NULL);
7936b49bcb4SJaganath Kanakkassery 		}
7946b49bcb4SJaganath Kanakkassery 
79542c6b129SJohan Hedberg 		hci_set_le_support(req);
7969193c6e8SAndre Guedes 	}
797d2c5d77fSJohan Hedberg 
798d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
799d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
800d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
801d2c5d77fSJohan Hedberg 
802d2c5d77fSJohan Hedberg 		cp.page = p;
803d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
804d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
805d2c5d77fSJohan Hedberg 	}
806a1d01db1SJohan Hedberg 
807a1d01db1SJohan Hedberg 	return 0;
8082177bab5SJohan Hedberg }
8092177bab5SJohan Hedberg 
810a1d01db1SJohan Hedberg static int hci_init4_req(struct hci_request *req, unsigned long opt)
8115d4e7e8dSJohan Hedberg {
8125d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
8135d4e7e8dSJohan Hedberg 
81436f260ceSMarcel Holtmann 	/* Some Broadcom based Bluetooth controllers do not support the
81536f260ceSMarcel Holtmann 	 * Delete Stored Link Key command. They are clearly indicating its
81636f260ceSMarcel Holtmann 	 * absence in the bit mask of supported commands.
81736f260ceSMarcel Holtmann 	 *
818bb6d6895SRandy Dunlap 	 * Check the supported commands and only if the command is marked
81936f260ceSMarcel Holtmann 	 * as supported send it. If not supported assume that the controller
82036f260ceSMarcel Holtmann 	 * does not have actual support for stored link keys which makes this
82136f260ceSMarcel Holtmann 	 * command redundant anyway.
82236f260ceSMarcel Holtmann 	 *
82336f260ceSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
82436f260ceSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
82536f260ceSMarcel Holtmann 	 * just disable this command.
82636f260ceSMarcel Holtmann 	 */
82736f260ceSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
82836f260ceSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
82936f260ceSMarcel Holtmann 		struct hci_cp_delete_stored_link_key cp;
83036f260ceSMarcel Holtmann 
83136f260ceSMarcel Holtmann 		bacpy(&cp.bdaddr, BDADDR_ANY);
83236f260ceSMarcel Holtmann 		cp.delete_all = 0x01;
83336f260ceSMarcel Holtmann 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
83436f260ceSMarcel Holtmann 			    sizeof(cp), &cp);
83536f260ceSMarcel Holtmann 	}
83636f260ceSMarcel Holtmann 
837d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
838d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
839d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
840d62e6d67SJohan Hedberg 
841109e3191SMarcel Holtmann 	/* Read local codec list if the HCI command is supported */
842109e3191SMarcel Holtmann 	if (hdev->commands[29] & 0x20)
843109e3191SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
844109e3191SMarcel Holtmann 
845a4790360SMarcel Holtmann 	/* Read local pairing options if the HCI command is supported */
846a4790360SMarcel Holtmann 	if (hdev->commands[41] & 0x08)
847a4790360SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_PAIRING_OPTS, 0, NULL);
848a4790360SMarcel Holtmann 
849f4fe73edSMarcel Holtmann 	/* Get MWS transport configuration if the HCI command is supported */
850f4fe73edSMarcel Holtmann 	if (hdev->commands[30] & 0x08)
851f4fe73edSMarcel Holtmann 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
852f4fe73edSMarcel Holtmann 
8535d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
85453b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
8555d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
856a6d0d690SMarcel Holtmann 
857a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
858d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) &&
859574ea3c7SMarcel Holtmann 	    bredr_sc_enabled(hdev)) {
860a6d0d690SMarcel Holtmann 		u8 support = 0x01;
861574ea3c7SMarcel Holtmann 
862a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
863a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
864a6d0d690SMarcel Holtmann 	}
865a1d01db1SJohan Hedberg 
86600bce3fbSAlain Michaud 	/* Set erroneous data reporting if supported to the wideband speech
86700bce3fbSAlain Michaud 	 * setting value
86800bce3fbSAlain Michaud 	 */
869cde1a8a9SIsmael Ferreras Morezuelas 	if (hdev->commands[18] & 0x08 &&
870cde1a8a9SIsmael Ferreras Morezuelas 	    !test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks)) {
87100bce3fbSAlain Michaud 		bool enabled = hci_dev_test_flag(hdev,
87200bce3fbSAlain Michaud 						 HCI_WIDEBAND_SPEECH_ENABLED);
87300bce3fbSAlain Michaud 
87400bce3fbSAlain Michaud 		if (enabled !=
87500bce3fbSAlain Michaud 		    (hdev->err_data_reporting == ERR_DATA_REPORTING_ENABLED)) {
87600bce3fbSAlain Michaud 			struct hci_cp_write_def_err_data_reporting cp;
87700bce3fbSAlain Michaud 
87800bce3fbSAlain Michaud 			cp.err_data_reporting = enabled ?
87900bce3fbSAlain Michaud 						ERR_DATA_REPORTING_ENABLED :
88000bce3fbSAlain Michaud 						ERR_DATA_REPORTING_DISABLED;
88100bce3fbSAlain Michaud 
88200bce3fbSAlain Michaud 			hci_req_add(req, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING,
88300bce3fbSAlain Michaud 				    sizeof(cp), &cp);
88400bce3fbSAlain Michaud 		}
88500bce3fbSAlain Michaud 	}
88600bce3fbSAlain Michaud 
88712204875SMarcel Holtmann 	/* Set Suggested Default Data Length to maximum if supported */
88812204875SMarcel Holtmann 	if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
88912204875SMarcel Holtmann 		struct hci_cp_le_write_def_data_len cp;
89012204875SMarcel Holtmann 
891727ea61aSBen Dooks (Codethink) 		cp.tx_len = cpu_to_le16(hdev->le_max_tx_len);
892727ea61aSBen Dooks (Codethink) 		cp.tx_time = cpu_to_le16(hdev->le_max_tx_time);
89312204875SMarcel Holtmann 		hci_req_add(req, HCI_OP_LE_WRITE_DEF_DATA_LEN, sizeof(cp), &cp);
89412204875SMarcel Holtmann 	}
89512204875SMarcel Holtmann 
896de2ba303SMarcel Holtmann 	/* Set Default PHY parameters if command is supported */
897de2ba303SMarcel Holtmann 	if (hdev->commands[35] & 0x20) {
898de2ba303SMarcel Holtmann 		struct hci_cp_le_set_default_phy cp;
899de2ba303SMarcel Holtmann 
9006decb5b4SJaganath Kanakkassery 		cp.all_phys = 0x00;
9016decb5b4SJaganath Kanakkassery 		cp.tx_phys = hdev->le_tx_def_phys;
9026decb5b4SJaganath Kanakkassery 		cp.rx_phys = hdev->le_rx_def_phys;
903de2ba303SMarcel Holtmann 
904de2ba303SMarcel Holtmann 		hci_req_add(req, HCI_OP_LE_SET_DEFAULT_PHY, sizeof(cp), &cp);
905de2ba303SMarcel Holtmann 	}
906de2ba303SMarcel Holtmann 
907a1d01db1SJohan Hedberg 	return 0;
9085d4e7e8dSJohan Hedberg }
9095d4e7e8dSJohan Hedberg 
9102177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
9112177bab5SJohan Hedberg {
9122177bab5SJohan Hedberg 	int err;
9132177bab5SJohan Hedberg 
9144ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT, NULL);
9152177bab5SJohan Hedberg 	if (err < 0)
9162177bab5SJohan Hedberg 		return err;
9172177bab5SJohan Hedberg 
918f640ee98SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP))
919f640ee98SMarcel Holtmann 		hci_debugfs_create_basic(hdev);
9204b4148e9SMarcel Holtmann 
9214ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT, NULL);
9222177bab5SJohan Hedberg 	if (err < 0)
9232177bab5SJohan Hedberg 		return err;
9242177bab5SJohan Hedberg 
925ca8bee5dSMarcel Holtmann 	/* HCI_PRIMARY covers both single-mode LE, BR/EDR and dual-mode
9260af801b9SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
9270af801b9SJohan Hedberg 	 * first two stages of init.
9280af801b9SJohan Hedberg 	 */
929ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY)
9300af801b9SJohan Hedberg 		return 0;
9310af801b9SJohan Hedberg 
9324ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT, NULL);
9335d4e7e8dSJohan Hedberg 	if (err < 0)
9345d4e7e8dSJohan Hedberg 		return err;
9355d4e7e8dSJohan Hedberg 
9364ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT, NULL);
937baf27f6eSMarcel Holtmann 	if (err < 0)
938baf27f6eSMarcel Holtmann 		return err;
939baf27f6eSMarcel Holtmann 
940ec6cef9cSMarcel Holtmann 	/* This function is only called when the controller is actually in
941ec6cef9cSMarcel Holtmann 	 * configured state. When the controller is marked as unconfigured,
942ec6cef9cSMarcel Holtmann 	 * this initialization procedure is not run.
943ec6cef9cSMarcel Holtmann 	 *
944ec6cef9cSMarcel Holtmann 	 * It means that it is possible that a controller runs through its
945ec6cef9cSMarcel Holtmann 	 * setup phase and then discovers missing settings. If that is the
946ec6cef9cSMarcel Holtmann 	 * case, then this function will not be called. It then will only
947ec6cef9cSMarcel Holtmann 	 * be called during the config phase.
948ec6cef9cSMarcel Holtmann 	 *
949ec6cef9cSMarcel Holtmann 	 * So only when in setup phase or config phase, create the debugfs
950ec6cef9cSMarcel Holtmann 	 * entries and register the SMP channels.
951baf27f6eSMarcel Holtmann 	 */
952d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
953d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG))
954baf27f6eSMarcel Holtmann 		return 0;
955baf27f6eSMarcel Holtmann 
95660c5f5fbSMarcel Holtmann 	hci_debugfs_create_common(hdev);
95760c5f5fbSMarcel Holtmann 
95871c3b60eSMarcel Holtmann 	if (lmp_bredr_capable(hdev))
95960c5f5fbSMarcel Holtmann 		hci_debugfs_create_bredr(hdev);
9602bfa3531SMarcel Holtmann 
961162a3bacSMarcel Holtmann 	if (lmp_le_capable(hdev))
96260c5f5fbSMarcel Holtmann 		hci_debugfs_create_le(hdev);
963e7b8fc92SMarcel Holtmann 
964baf27f6eSMarcel Holtmann 	return 0;
9652177bab5SJohan Hedberg }
9662177bab5SJohan Hedberg 
967a1d01db1SJohan Hedberg static int hci_init0_req(struct hci_request *req, unsigned long opt)
9680ebca7d6SMarcel Holtmann {
9690ebca7d6SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
9700ebca7d6SMarcel Holtmann 
9710ebca7d6SMarcel Holtmann 	BT_DBG("%s %ld", hdev->name, opt);
9720ebca7d6SMarcel Holtmann 
9730ebca7d6SMarcel Holtmann 	/* Reset */
9740ebca7d6SMarcel Holtmann 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
9750ebca7d6SMarcel Holtmann 		hci_reset_req(req, 0);
9760ebca7d6SMarcel Holtmann 
9770ebca7d6SMarcel Holtmann 	/* Read Local Version */
9780ebca7d6SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
9790ebca7d6SMarcel Holtmann 
9800ebca7d6SMarcel Holtmann 	/* Read BD Address */
9810ebca7d6SMarcel Holtmann 	if (hdev->set_bdaddr)
9820ebca7d6SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
983a1d01db1SJohan Hedberg 
984a1d01db1SJohan Hedberg 	return 0;
9850ebca7d6SMarcel Holtmann }
9860ebca7d6SMarcel Holtmann 
9870ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev)
9880ebca7d6SMarcel Holtmann {
9890ebca7d6SMarcel Holtmann 	int err;
9900ebca7d6SMarcel Holtmann 
991cc78b44bSMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
992cc78b44bSMarcel Holtmann 		return 0;
993cc78b44bSMarcel Holtmann 
9944ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT, NULL);
9950ebca7d6SMarcel Holtmann 	if (err < 0)
9960ebca7d6SMarcel Holtmann 		return err;
9970ebca7d6SMarcel Holtmann 
998f640ee98SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP))
999f640ee98SMarcel Holtmann 		hci_debugfs_create_basic(hdev);
1000f640ee98SMarcel Holtmann 
10010ebca7d6SMarcel Holtmann 	return 0;
10020ebca7d6SMarcel Holtmann }
10030ebca7d6SMarcel Holtmann 
1004a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt)
10051da177e4SLinus Torvalds {
10061da177e4SLinus Torvalds 	__u8 scan = opt;
10071da177e4SLinus Torvalds 
100842c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
10091da177e4SLinus Torvalds 
10101da177e4SLinus Torvalds 	/* Inquiry and Page scans */
101142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
1012a1d01db1SJohan Hedberg 	return 0;
10131da177e4SLinus Torvalds }
10141da177e4SLinus Torvalds 
1015a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt)
10161da177e4SLinus Torvalds {
10171da177e4SLinus Torvalds 	__u8 auth = opt;
10181da177e4SLinus Torvalds 
101942c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
10201da177e4SLinus Torvalds 
10211da177e4SLinus Torvalds 	/* Authentication */
102242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
1023a1d01db1SJohan Hedberg 	return 0;
10241da177e4SLinus Torvalds }
10251da177e4SLinus Torvalds 
1026a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt)
10271da177e4SLinus Torvalds {
10281da177e4SLinus Torvalds 	__u8 encrypt = opt;
10291da177e4SLinus Torvalds 
103042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
10311da177e4SLinus Torvalds 
1032e4e8e37cSMarcel Holtmann 	/* Encryption */
103342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
1034a1d01db1SJohan Hedberg 	return 0;
10351da177e4SLinus Torvalds }
10361da177e4SLinus Torvalds 
1037a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt)
1038e4e8e37cSMarcel Holtmann {
1039e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
1040e4e8e37cSMarcel Holtmann 
104142c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
1042e4e8e37cSMarcel Holtmann 
1043e4e8e37cSMarcel Holtmann 	/* Default link policy */
104442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
1045a1d01db1SJohan Hedberg 	return 0;
1046e4e8e37cSMarcel Holtmann }
1047e4e8e37cSMarcel Holtmann 
10481da177e4SLinus Torvalds /* Get HCI device by index.
10491da177e4SLinus Torvalds  * Device is held on return. */
10501da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
10511da177e4SLinus Torvalds {
10528035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
10531da177e4SLinus Torvalds 
10541da177e4SLinus Torvalds 	BT_DBG("%d", index);
10551da177e4SLinus Torvalds 
10561da177e4SLinus Torvalds 	if (index < 0)
10571da177e4SLinus Torvalds 		return NULL;
10581da177e4SLinus Torvalds 
10591da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
10608035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
10611da177e4SLinus Torvalds 		if (d->id == index) {
10621da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
10631da177e4SLinus Torvalds 			break;
10641da177e4SLinus Torvalds 		}
10651da177e4SLinus Torvalds 	}
10661da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
10671da177e4SLinus Torvalds 	return hdev;
10681da177e4SLinus Torvalds }
10691da177e4SLinus Torvalds 
10701da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1071ff9ef578SJohan Hedberg 
107230dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
107330dc78e1SJohan Hedberg {
107430dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
107530dc78e1SJohan Hedberg 
10766fbe195dSAndre Guedes 	switch (discov->state) {
1077343f935bSAndre Guedes 	case DISCOVERY_FINDING:
10786fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
107930dc78e1SJohan Hedberg 		return true;
108030dc78e1SJohan Hedberg 
10816fbe195dSAndre Guedes 	default:
108230dc78e1SJohan Hedberg 		return false;
108330dc78e1SJohan Hedberg 	}
10846fbe195dSAndre Guedes }
108530dc78e1SJohan Hedberg 
1086ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1087ff9ef578SJohan Hedberg {
1088bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
1089bb3e0a33SJohan Hedberg 
1090ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1091ff9ef578SJohan Hedberg 
1092bb3e0a33SJohan Hedberg 	if (old_state == state)
1093ff9ef578SJohan Hedberg 		return;
1094ff9ef578SJohan Hedberg 
1095bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
1096bb3e0a33SJohan Hedberg 
1097ff9ef578SJohan Hedberg 	switch (state) {
1098ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1099c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
1100c54c3860SAndre Guedes 
1101bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
1102ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1103ff9ef578SJohan Hedberg 		break;
1104ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1105ff9ef578SJohan Hedberg 		break;
1106343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1107ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1108ff9ef578SJohan Hedberg 		break;
110930dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
111030dc78e1SJohan Hedberg 		break;
1111ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1112ff9ef578SJohan Hedberg 		break;
1113ff9ef578SJohan Hedberg 	}
1114ff9ef578SJohan Hedberg }
1115ff9ef578SJohan Hedberg 
11161f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
11171da177e4SLinus Torvalds {
111830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1119b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
11201da177e4SLinus Torvalds 
1121561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
1122561aafbcSJohan Hedberg 		list_del(&p->all);
1123b57c1a56SJohan Hedberg 		kfree(p);
11241da177e4SLinus Torvalds 	}
1125561aafbcSJohan Hedberg 
1126561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
1127561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
11281da177e4SLinus Torvalds }
11291da177e4SLinus Torvalds 
1130a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
1131a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
11321da177e4SLinus Torvalds {
113330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
11341da177e4SLinus Torvalds 	struct inquiry_entry *e;
11351da177e4SLinus Torvalds 
11366ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
11371da177e4SLinus Torvalds 
1138561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
11391da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
11401da177e4SLinus Torvalds 			return e;
11411da177e4SLinus Torvalds 	}
11421da177e4SLinus Torvalds 
1143b57c1a56SJohan Hedberg 	return NULL;
1144b57c1a56SJohan Hedberg }
1145b57c1a56SJohan Hedberg 
1146561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
1147561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
1148561aafbcSJohan Hedberg {
114930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1150561aafbcSJohan Hedberg 	struct inquiry_entry *e;
1151561aafbcSJohan Hedberg 
11526ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1153561aafbcSJohan Hedberg 
1154561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
1155561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
1156561aafbcSJohan Hedberg 			return e;
1157561aafbcSJohan Hedberg 	}
1158561aafbcSJohan Hedberg 
1159561aafbcSJohan Hedberg 	return NULL;
1160561aafbcSJohan Hedberg }
1161561aafbcSJohan Hedberg 
116230dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
116330dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
116430dc78e1SJohan Hedberg 						       int state)
116530dc78e1SJohan Hedberg {
116630dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
116730dc78e1SJohan Hedberg 	struct inquiry_entry *e;
116830dc78e1SJohan Hedberg 
11696ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
117030dc78e1SJohan Hedberg 
117130dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
117230dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
117330dc78e1SJohan Hedberg 			return e;
117430dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
117530dc78e1SJohan Hedberg 			return e;
117630dc78e1SJohan Hedberg 	}
117730dc78e1SJohan Hedberg 
117830dc78e1SJohan Hedberg 	return NULL;
117930dc78e1SJohan Hedberg }
118030dc78e1SJohan Hedberg 
1181a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
1182a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
1183a3d4e20aSJohan Hedberg {
1184a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1185a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
1186a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
1187a3d4e20aSJohan Hedberg 
1188a3d4e20aSJohan Hedberg 	list_del(&ie->list);
1189a3d4e20aSJohan Hedberg 
1190a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
1191a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
1192a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
1193a3d4e20aSJohan Hedberg 			break;
1194a3d4e20aSJohan Hedberg 		pos = &p->list;
1195a3d4e20aSJohan Hedberg 	}
1196a3d4e20aSJohan Hedberg 
1197a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
1198a3d4e20aSJohan Hedberg }
1199a3d4e20aSJohan Hedberg 
1200af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
1201af58925cSMarcel Holtmann 			     bool name_known)
12021da177e4SLinus Torvalds {
120330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
120470f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
1205af58925cSMarcel Holtmann 	u32 flags = 0;
12061da177e4SLinus Torvalds 
12076ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
12081da177e4SLinus Torvalds 
12096928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
12102b2fec4dSSzymon Janc 
1211af58925cSMarcel Holtmann 	if (!data->ssp_mode)
1212af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1213388fc8faSJohan Hedberg 
121470f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
1215a3d4e20aSJohan Hedberg 	if (ie) {
1216af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
1217af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1218388fc8faSJohan Hedberg 
1219a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
1220a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
1221a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
1222a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
1223a3d4e20aSJohan Hedberg 		}
1224a3d4e20aSJohan Hedberg 
1225561aafbcSJohan Hedberg 		goto update;
1226a3d4e20aSJohan Hedberg 	}
1227561aafbcSJohan Hedberg 
12281da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
122927f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
1230af58925cSMarcel Holtmann 	if (!ie) {
1231af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
1232af58925cSMarcel Holtmann 		goto done;
1233af58925cSMarcel Holtmann 	}
123470f23020SAndrei Emeltchenko 
1235561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
1236561aafbcSJohan Hedberg 
1237561aafbcSJohan Hedberg 	if (name_known) {
1238561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1239561aafbcSJohan Hedberg 	} else {
1240561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
1241561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
1242561aafbcSJohan Hedberg 	}
1243561aafbcSJohan Hedberg 
1244561aafbcSJohan Hedberg update:
1245561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
1246561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
1247561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1248561aafbcSJohan Hedberg 		list_del(&ie->list);
12491da177e4SLinus Torvalds 	}
12501da177e4SLinus Torvalds 
125170f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
125270f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
12531da177e4SLinus Torvalds 	cache->timestamp = jiffies;
12543175405bSJohan Hedberg 
12553175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
1256af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
12573175405bSJohan Hedberg 
1258af58925cSMarcel Holtmann done:
1259af58925cSMarcel Holtmann 	return flags;
12601da177e4SLinus Torvalds }
12611da177e4SLinus Torvalds 
12621da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
12631da177e4SLinus Torvalds {
126430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
12651da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
12661da177e4SLinus Torvalds 	struct inquiry_entry *e;
12671da177e4SLinus Torvalds 	int copied = 0;
12681da177e4SLinus Torvalds 
1269561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
12701da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
1271b57c1a56SJohan Hedberg 
1272b57c1a56SJohan Hedberg 		if (copied >= num)
1273b57c1a56SJohan Hedberg 			break;
1274b57c1a56SJohan Hedberg 
12751da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
12761da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
12771da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
12781da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
12791da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
12801da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1281b57c1a56SJohan Hedberg 
12821da177e4SLinus Torvalds 		info++;
1283b57c1a56SJohan Hedberg 		copied++;
12841da177e4SLinus Torvalds 	}
12851da177e4SLinus Torvalds 
12861da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
12871da177e4SLinus Torvalds 	return copied;
12881da177e4SLinus Torvalds }
12891da177e4SLinus Torvalds 
1290a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt)
12911da177e4SLinus Torvalds {
12921da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
129342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
12941da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
12951da177e4SLinus Torvalds 
12961da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
12971da177e4SLinus Torvalds 
12981da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
1299a1d01db1SJohan Hedberg 		return 0;
13001da177e4SLinus Torvalds 
13011da177e4SLinus Torvalds 	/* Start Inquiry */
13021da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
13031da177e4SLinus Torvalds 	cp.length  = ir->length;
13041da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
130542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
1306a1d01db1SJohan Hedberg 
1307a1d01db1SJohan Hedberg 	return 0;
13081da177e4SLinus Torvalds }
13091da177e4SLinus Torvalds 
13101da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
13111da177e4SLinus Torvalds {
13121da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
13131da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
13141da177e4SLinus Torvalds 	struct hci_dev *hdev;
13151da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
13161da177e4SLinus Torvalds 	long timeo;
13171da177e4SLinus Torvalds 	__u8 *buf;
13181da177e4SLinus Torvalds 
13191da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
13201da177e4SLinus Torvalds 		return -EFAULT;
13211da177e4SLinus Torvalds 
13225a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
13235a08ecceSAndrei Emeltchenko 	if (!hdev)
13241da177e4SLinus Torvalds 		return -ENODEV;
13251da177e4SLinus Torvalds 
1326d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
13270736cfa8SMarcel Holtmann 		err = -EBUSY;
13280736cfa8SMarcel Holtmann 		goto done;
13290736cfa8SMarcel Holtmann 	}
13300736cfa8SMarcel Holtmann 
1331d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1332fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1333fee746b0SMarcel Holtmann 		goto done;
1334fee746b0SMarcel Holtmann 	}
1335fee746b0SMarcel Holtmann 
1336ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
13375b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
13385b69bef5SMarcel Holtmann 		goto done;
13395b69bef5SMarcel Holtmann 	}
13405b69bef5SMarcel Holtmann 
1341d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
134256f87901SJohan Hedberg 		err = -EOPNOTSUPP;
134356f87901SJohan Hedberg 		goto done;
134456f87901SJohan Hedberg 	}
134556f87901SJohan Hedberg 
1346*f41a4b2bSPavel Skripkin 	/* Restrict maximum inquiry length to 60 seconds */
1347*f41a4b2bSPavel Skripkin 	if (ir.length > 60) {
1348*f41a4b2bSPavel Skripkin 		err = -EINVAL;
1349*f41a4b2bSPavel Skripkin 		goto done;
1350*f41a4b2bSPavel Skripkin 	}
1351*f41a4b2bSPavel Skripkin 
135209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13531da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1354a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
13551f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
13561da177e4SLinus Torvalds 		do_inquiry = 1;
13571da177e4SLinus Torvalds 	}
135809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13591da177e4SLinus Torvalds 
136004837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
136170f23020SAndrei Emeltchenko 
136270f23020SAndrei Emeltchenko 	if (do_inquiry) {
136301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
13644ebeee2dSJohan Hedberg 				   timeo, NULL);
136570f23020SAndrei Emeltchenko 		if (err < 0)
13661da177e4SLinus Torvalds 			goto done;
13673e13fa1eSAndre Guedes 
13683e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
13693e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
13703e13fa1eSAndre Guedes 		 */
137174316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
137228a758c8SPan Bian 				TASK_INTERRUPTIBLE)) {
137328a758c8SPan Bian 			err = -EINTR;
137428a758c8SPan Bian 			goto done;
137528a758c8SPan Bian 		}
137670f23020SAndrei Emeltchenko 	}
13771da177e4SLinus Torvalds 
13788fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
13798fc9ced3SGustavo Padovan 	 * 255 entries
13808fc9ced3SGustavo Padovan 	 */
13811da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
13821da177e4SLinus Torvalds 
13831da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
13841da177e4SLinus Torvalds 	 * copy it to the user space.
13851da177e4SLinus Torvalds 	 */
13866da2ec56SKees Cook 	buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL);
138770f23020SAndrei Emeltchenko 	if (!buf) {
13881da177e4SLinus Torvalds 		err = -ENOMEM;
13891da177e4SLinus Torvalds 		goto done;
13901da177e4SLinus Torvalds 	}
13911da177e4SLinus Torvalds 
139209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13931da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
139409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13951da177e4SLinus Torvalds 
13961da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
13971da177e4SLinus Torvalds 
13981da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
13991da177e4SLinus Torvalds 		ptr += sizeof(ir);
14001da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
14011da177e4SLinus Torvalds 				 ir.num_rsp))
14021da177e4SLinus Torvalds 			err = -EFAULT;
14031da177e4SLinus Torvalds 	} else
14041da177e4SLinus Torvalds 		err = -EFAULT;
14051da177e4SLinus Torvalds 
14061da177e4SLinus Torvalds 	kfree(buf);
14071da177e4SLinus Torvalds 
14081da177e4SLinus Torvalds done:
14091da177e4SLinus Torvalds 	hci_dev_put(hdev);
14101da177e4SLinus Torvalds 	return err;
14111da177e4SLinus Torvalds }
14121da177e4SLinus Torvalds 
14137a0e5b15SMatthias Kaehlcke /**
14147a0e5b15SMatthias Kaehlcke  * hci_dev_get_bd_addr_from_property - Get the Bluetooth Device Address
14157a0e5b15SMatthias Kaehlcke  *				       (BD_ADDR) for a HCI device from
14167a0e5b15SMatthias Kaehlcke  *				       a firmware node property.
14177a0e5b15SMatthias Kaehlcke  * @hdev:	The HCI device
14187a0e5b15SMatthias Kaehlcke  *
14197a0e5b15SMatthias Kaehlcke  * Search the firmware node for 'local-bd-address'.
14207a0e5b15SMatthias Kaehlcke  *
14217a0e5b15SMatthias Kaehlcke  * All-zero BD addresses are rejected, because those could be properties
14227a0e5b15SMatthias Kaehlcke  * that exist in the firmware tables, but were not updated by the firmware. For
14237a0e5b15SMatthias Kaehlcke  * example, the DTS could define 'local-bd-address', with zero BD addresses.
14247a0e5b15SMatthias Kaehlcke  */
14257a0e5b15SMatthias Kaehlcke static void hci_dev_get_bd_addr_from_property(struct hci_dev *hdev)
14267a0e5b15SMatthias Kaehlcke {
14277a0e5b15SMatthias Kaehlcke 	struct fwnode_handle *fwnode = dev_fwnode(hdev->dev.parent);
14287a0e5b15SMatthias Kaehlcke 	bdaddr_t ba;
14297a0e5b15SMatthias Kaehlcke 	int ret;
14307a0e5b15SMatthias Kaehlcke 
14317a0e5b15SMatthias Kaehlcke 	ret = fwnode_property_read_u8_array(fwnode, "local-bd-address",
14327a0e5b15SMatthias Kaehlcke 					    (u8 *)&ba, sizeof(ba));
14337a0e5b15SMatthias Kaehlcke 	if (ret < 0 || !bacmp(&ba, BDADDR_ANY))
14347a0e5b15SMatthias Kaehlcke 		return;
14357a0e5b15SMatthias Kaehlcke 
14367a0e5b15SMatthias Kaehlcke 	bacpy(&hdev->public_addr, &ba);
14377a0e5b15SMatthias Kaehlcke }
14387a0e5b15SMatthias Kaehlcke 
1439cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
14401da177e4SLinus Torvalds {
14411da177e4SLinus Torvalds 	int ret = 0;
14421da177e4SLinus Torvalds 
14431da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
14441da177e4SLinus Torvalds 
1445b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
14461da177e4SLinus Torvalds 
1447d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
144894324962SJohan Hovold 		ret = -ENODEV;
144994324962SJohan Hovold 		goto done;
145094324962SJohan Hovold 	}
145194324962SJohan Hovold 
1452d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1453d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
1454a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1455a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1456bf543036SJohan Hedberg 		 */
1457d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
1458611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1459611b30f7SMarcel Holtmann 			goto done;
1460611b30f7SMarcel Holtmann 		}
1461611b30f7SMarcel Holtmann 
1462a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
146391641b79SZheng Yongjun 		 * random address, but let the HCI setup proceed to
1464a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1465a5c8f270SMarcel Holtmann 		 * or not.
1466a5c8f270SMarcel Holtmann 		 *
1467c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
1468c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
1469c6beca0eSMarcel Holtmann 		 * available.
1470c6beca0eSMarcel Holtmann 		 *
1471a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1472a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1473a5c8f270SMarcel Holtmann 		 */
1474d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1475ca8bee5dSMarcel Holtmann 		    hdev->dev_type == HCI_PRIMARY &&
1476a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1477a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1478a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1479a5c8f270SMarcel Holtmann 			goto done;
1480a5c8f270SMarcel Holtmann 		}
1481a5c8f270SMarcel Holtmann 	}
1482a5c8f270SMarcel Holtmann 
14831da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
14841da177e4SLinus Torvalds 		ret = -EALREADY;
14851da177e4SLinus Torvalds 		goto done;
14861da177e4SLinus Torvalds 	}
14871da177e4SLinus Torvalds 
14881da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
14891da177e4SLinus Torvalds 		ret = -EIO;
14901da177e4SLinus Torvalds 		goto done;
14911da177e4SLinus Torvalds 	}
14921da177e4SLinus Torvalds 
1493e9ca8bf1SMarcel Holtmann 	set_bit(HCI_RUNNING, &hdev->flags);
149405fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_OPEN);
14954a3f95b7SMarcel Holtmann 
14961da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
14971da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1498f41c70c4SMarcel Holtmann 
1499740011cfSSean Wang 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
1500740011cfSSean Wang 	    test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
15017fdf6c6aSMarcel Holtmann 		bool invalid_bdaddr;
15027fdf6c6aSMarcel Holtmann 
1503e131d74aSMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_SETUP);
1504e131d74aSMarcel Holtmann 
1505af202f84SMarcel Holtmann 		if (hdev->setup)
1506f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
1507f41c70c4SMarcel Holtmann 
15087fdf6c6aSMarcel Holtmann 		/* The transport driver can set the quirk to mark the
15097fdf6c6aSMarcel Holtmann 		 * BD_ADDR invalid before creating the HCI device or in
15107fdf6c6aSMarcel Holtmann 		 * its setup callback.
15117fdf6c6aSMarcel Holtmann 		 */
15127fdf6c6aSMarcel Holtmann 		invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR,
15137fdf6c6aSMarcel Holtmann 					  &hdev->quirks);
15147fdf6c6aSMarcel Holtmann 
15157a0e5b15SMatthias Kaehlcke 		if (ret)
15167a0e5b15SMatthias Kaehlcke 			goto setup_failed;
15177a0e5b15SMatthias Kaehlcke 
15187a0e5b15SMatthias Kaehlcke 		if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) {
15197a0e5b15SMatthias Kaehlcke 			if (!bacmp(&hdev->public_addr, BDADDR_ANY))
15207a0e5b15SMatthias Kaehlcke 				hci_dev_get_bd_addr_from_property(hdev);
15217a0e5b15SMatthias Kaehlcke 
15227a0e5b15SMatthias Kaehlcke 			if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
15237fdf6c6aSMarcel Holtmann 			    hdev->set_bdaddr) {
15247a0e5b15SMatthias Kaehlcke 				ret = hdev->set_bdaddr(hdev,
15257a0e5b15SMatthias Kaehlcke 						       &hdev->public_addr);
15267fdf6c6aSMarcel Holtmann 
15277fdf6c6aSMarcel Holtmann 				/* If setting of the BD_ADDR from the device
15287fdf6c6aSMarcel Holtmann 				 * property succeeds, then treat the address
15297fdf6c6aSMarcel Holtmann 				 * as valid even if the invalid BD_ADDR
15307fdf6c6aSMarcel Holtmann 				 * quirk indicates otherwise.
15317fdf6c6aSMarcel Holtmann 				 */
15327fdf6c6aSMarcel Holtmann 				if (!ret)
15337fdf6c6aSMarcel Holtmann 					invalid_bdaddr = false;
15347fdf6c6aSMarcel Holtmann 			}
15357a0e5b15SMatthias Kaehlcke 		}
15367a0e5b15SMatthias Kaehlcke 
15377a0e5b15SMatthias Kaehlcke setup_failed:
1538af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
1539af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
1540af202f84SMarcel Holtmann 		 *
15417fdf6c6aSMarcel Holtmann 		 * For the invalid BD_ADDR quirk it is possible that
15427fdf6c6aSMarcel Holtmann 		 * it becomes a valid address if the bootloader does
15437fdf6c6aSMarcel Holtmann 		 * provide it (see above).
15447fdf6c6aSMarcel Holtmann 		 *
1545af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
1546af202f84SMarcel Holtmann 		 * start up as unconfigured.
1547af202f84SMarcel Holtmann 		 */
1548eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
15497fdf6c6aSMarcel Holtmann 		    invalid_bdaddr)
1550a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
1551f41c70c4SMarcel Holtmann 
15520ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
15530ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
15540ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
15550ebca7d6SMarcel Holtmann 		 *
15560ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
15570ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
15580ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
15590ebca7d6SMarcel Holtmann 		 */
1560d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
15610ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
156289bc22d2SMarcel Holtmann 	}
156389bc22d2SMarcel Holtmann 
1564d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_CONFIG)) {
15659713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
15669713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
15679713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
15689713c17bSMarcel Holtmann 		 * on procedure.
156924c457e2SMarcel Holtmann 		 */
15709713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
15719713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
157224c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
157324c457e2SMarcel Holtmann 		else
157424c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
157524c457e2SMarcel Holtmann 	}
157624c457e2SMarcel Holtmann 
1577f41c70c4SMarcel Holtmann 	if (!ret) {
1578d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
157998a63aafSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
15802177bab5SJohan Hedberg 			ret = __hci_init(hdev);
158198a63aafSMarcel Holtmann 			if (!ret && hdev->post_init)
158298a63aafSMarcel Holtmann 				ret = hdev->post_init(hdev);
158398a63aafSMarcel Holtmann 		}
15841da177e4SLinus Torvalds 	}
15851da177e4SLinus Torvalds 
15867e995b9eSMarcel Holtmann 	/* If the HCI Reset command is clearing all diagnostic settings,
15877e995b9eSMarcel Holtmann 	 * then they need to be reprogrammed after the init procedure
15887e995b9eSMarcel Holtmann 	 * completed.
15897e995b9eSMarcel Holtmann 	 */
15907e995b9eSMarcel Holtmann 	if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
1591b56c7b25SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
15927e995b9eSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
15937e995b9eSMarcel Holtmann 		ret = hdev->set_diag(hdev, true);
15947e995b9eSMarcel Holtmann 
1595145373cbSMiao-chen Chou 	msft_do_open(hdev);
1596f67743f9SMarcel Holtmann 	aosp_do_open(hdev);
1597145373cbSMiao-chen Chou 
1598f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1599f41c70c4SMarcel Holtmann 
16001da177e4SLinus Torvalds 	if (!ret) {
16011da177e4SLinus Torvalds 		hci_dev_hold(hdev);
1602a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
1603a73c046aSJaganath Kanakkassery 		hci_adv_instances_set_rpa_expired(hdev, true);
16041da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
160505fcd4c4SMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_UP);
16066d5d2ee6SHeiner Kallweit 		hci_leds_update_powered(hdev, true);
1607d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1608d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG) &&
1609d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1610d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
16112ff13894SJohan Hedberg 		    hci_dev_test_flag(hdev, HCI_MGMT) &&
1612ca8bee5dSMarcel Holtmann 		    hdev->dev_type == HCI_PRIMARY) {
16132ff13894SJohan Hedberg 			ret = __hci_req_hci_power_on(hdev);
16142ff13894SJohan Hedberg 			mgmt_power_on(hdev, ret);
161556e5cb86SJohan Hedberg 		}
16161da177e4SLinus Torvalds 	} else {
16171da177e4SLinus Torvalds 		/* Init failed, cleanup */
16183eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
16196a137caeSLin Ma 
16206a137caeSLin Ma 		/* Since hci_rx_work() is possible to awake new cmd_work
16216a137caeSLin Ma 		 * it should be flushed first to avoid unexpected call of
16226a137caeSLin Ma 		 * hci_cmd_work()
16236a137caeSLin Ma 		 */
1624b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
16256a137caeSLin Ma 		flush_work(&hdev->cmd_work);
16261da177e4SLinus Torvalds 
16271da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
16281da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
16291da177e4SLinus Torvalds 
16301da177e4SLinus Torvalds 		if (hdev->flush)
16311da177e4SLinus Torvalds 			hdev->flush(hdev);
16321da177e4SLinus Torvalds 
16331da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
16341da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
16351da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
16361da177e4SLinus Torvalds 		}
16371da177e4SLinus Torvalds 
1638e9ca8bf1SMarcel Holtmann 		clear_bit(HCI_RUNNING, &hdev->flags);
163905fcd4c4SMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
16404a3f95b7SMarcel Holtmann 
16411da177e4SLinus Torvalds 		hdev->close(hdev);
1642fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
16431da177e4SLinus Torvalds 	}
16441da177e4SLinus Torvalds 
16451da177e4SLinus Torvalds done:
1646b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
16471da177e4SLinus Torvalds 	return ret;
16481da177e4SLinus Torvalds }
16491da177e4SLinus Torvalds 
1650cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1651cbed0ca1SJohan Hedberg 
1652cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1653cbed0ca1SJohan Hedberg {
1654cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1655cbed0ca1SJohan Hedberg 	int err;
1656cbed0ca1SJohan Hedberg 
1657cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1658cbed0ca1SJohan Hedberg 	if (!hdev)
1659cbed0ca1SJohan Hedberg 		return -ENODEV;
1660cbed0ca1SJohan Hedberg 
16614a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
1662fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
1663fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
1664fee746b0SMarcel Holtmann 	 * possible.
1665fee746b0SMarcel Holtmann 	 *
1666fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
1667fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
1668fee746b0SMarcel Holtmann 	 * open the device.
1669fee746b0SMarcel Holtmann 	 */
1670d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1671d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1672fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1673fee746b0SMarcel Holtmann 		goto done;
1674fee746b0SMarcel Holtmann 	}
1675fee746b0SMarcel Holtmann 
1676e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
1677e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
1678e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
1679e1d08f40SJohan Hedberg 	 * completed.
1680e1d08f40SJohan Hedberg 	 */
1681a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
1682e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
1683e1d08f40SJohan Hedberg 
1684a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
1685a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
1686a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
1687a5c8f270SMarcel Holtmann 	 */
1688e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
1689e1d08f40SJohan Hedberg 
169012aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
1691b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
169212aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
169312aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
169412aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
169512aa4f0aSMarcel Holtmann 	 */
1696d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1697d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
1698a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
169912aa4f0aSMarcel Holtmann 
1700cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
1701cbed0ca1SJohan Hedberg 
1702fee746b0SMarcel Holtmann done:
1703cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
1704cbed0ca1SJohan Hedberg 	return err;
1705cbed0ca1SJohan Hedberg }
1706cbed0ca1SJohan Hedberg 
1707d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
1708d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
1709d7347f3cSJohan Hedberg {
1710d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
1711d7347f3cSJohan Hedberg 
1712f161dd41SJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list) {
1713f161dd41SJohan Hedberg 		if (p->conn) {
1714f161dd41SJohan Hedberg 			hci_conn_drop(p->conn);
1715f8aaf9b6SJohan Hedberg 			hci_conn_put(p->conn);
1716f161dd41SJohan Hedberg 			p->conn = NULL;
1717f161dd41SJohan Hedberg 		}
1718d7347f3cSJohan Hedberg 		list_del_init(&p->action);
1719f161dd41SJohan Hedberg 	}
1720d7347f3cSJohan Hedberg 
1721d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
1722d7347f3cSJohan Hedberg }
1723d7347f3cSJohan Hedberg 
17246b3cc1dbSSimon Fels int hci_dev_do_close(struct hci_dev *hdev)
17251da177e4SLinus Torvalds {
1726acc649c6SMarcel Holtmann 	bool auto_off;
1727acc649c6SMarcel Holtmann 
17281da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
17291da177e4SLinus Torvalds 
173078c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
1731de75cd0dSManish Mandlik 	cancel_delayed_work(&hdev->ncmd_timer);
173278c04c0bSVinicius Costa Gomes 
17337df0f73eSJohan Hedberg 	hci_request_cancel_all(hdev);
1734b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
17351da177e4SLinus Torvalds 
17360ea53674SKai-Heng Feng 	if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
17370ea53674SKai-Heng Feng 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
17380ea53674SKai-Heng Feng 	    test_bit(HCI_UP, &hdev->flags)) {
17390ea53674SKai-Heng Feng 		/* Execute vendor specific shutdown routine */
17400ea53674SKai-Heng Feng 		if (hdev->shutdown)
17410ea53674SKai-Heng Feng 			hdev->shutdown(hdev);
17420ea53674SKai-Heng Feng 	}
17430ea53674SKai-Heng Feng 
17441da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
174565cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
1746b504430cSJohan Hedberg 		hci_req_sync_unlock(hdev);
17471da177e4SLinus Torvalds 		return 0;
17481da177e4SLinus Torvalds 	}
17491da177e4SLinus Torvalds 
17506d5d2ee6SHeiner Kallweit 	hci_leds_update_powered(hdev, false);
17516d5d2ee6SHeiner Kallweit 
17523eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
17533eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1754b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
17551da177e4SLinus Torvalds 
175616ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
175716ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
1758a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
1759a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
176016ab91abSJohan Hedberg 	}
176116ab91abSJohan Hedberg 
1762a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
17637d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
17647d78525dSJohan Hedberg 
1765a73c046aSJaganath Kanakkassery 	if (hci_dev_test_flag(hdev, HCI_MGMT)) {
1766a73c046aSJaganath Kanakkassery 		struct adv_info *adv_instance;
1767a73c046aSJaganath Kanakkassery 
1768d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
17697ba8b4beSAndre Guedes 
1770a73c046aSJaganath Kanakkassery 		list_for_each_entry(adv_instance, &hdev->adv_instances, list)
1771a73c046aSJaganath Kanakkassery 			cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1772a73c046aSJaganath Kanakkassery 	}
1773a73c046aSJaganath Kanakkassery 
177476727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
177576727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
177676727c02SJohan Hedberg 	 */
177776727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
177876727c02SJohan Hedberg 
177909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
17801aeb9c65SJohan Hedberg 
17818f502f84SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
17828f502f84SJohan Hedberg 
1783acc649c6SMarcel Holtmann 	auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF);
1784acc649c6SMarcel Holtmann 
1785ca8bee5dSMarcel Holtmann 	if (!auto_off && hdev->dev_type == HCI_PRIMARY &&
1786baab7932SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
17872ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT))
17882ff13894SJohan Hedberg 		__mgmt_power_off(hdev);
17891aeb9c65SJohan Hedberg 
17901f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
1791d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
1792f161dd41SJohan Hedberg 	hci_conn_hash_flush(hdev);
179309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
17941da177e4SLinus Torvalds 
179564dae967SMarcel Holtmann 	smp_unregister(hdev);
179664dae967SMarcel Holtmann 
179705fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_DOWN);
17981da177e4SLinus Torvalds 
1799f67743f9SMarcel Holtmann 	aosp_do_close(hdev);
1800145373cbSMiao-chen Chou 	msft_do_close(hdev);
1801145373cbSMiao-chen Chou 
18021da177e4SLinus Torvalds 	if (hdev->flush)
18031da177e4SLinus Torvalds 		hdev->flush(hdev);
18041da177e4SLinus Torvalds 
18051da177e4SLinus Torvalds 	/* Reset device */
18061da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
18071da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
1808acc649c6SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) &&
1809acc649c6SMarcel Holtmann 	    !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
18101da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
18114ebeee2dSJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL);
18121da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
18131da177e4SLinus Torvalds 	}
18141da177e4SLinus Torvalds 
1815c347b765SGustavo F. Padovan 	/* flush cmd  work */
1816c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
18171da177e4SLinus Torvalds 
18181da177e4SLinus Torvalds 	/* Drop queues */
18191da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
18201da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
18211da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
18221da177e4SLinus Torvalds 
18231da177e4SLinus Torvalds 	/* Drop last sent command */
18241da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
182565cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
18261da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
18271da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
18281da177e4SLinus Torvalds 	}
18291da177e4SLinus Torvalds 
1830e9ca8bf1SMarcel Holtmann 	clear_bit(HCI_RUNNING, &hdev->flags);
183105fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
18324a3f95b7SMarcel Holtmann 
18339952d90eSAbhishek Pandit-Subedi 	if (test_and_clear_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks))
18349952d90eSAbhishek Pandit-Subedi 		wake_up(&hdev->suspend_wait_q);
18359952d90eSAbhishek Pandit-Subedi 
18361da177e4SLinus Torvalds 	/* After this point our queues are empty
18371da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
18381da177e4SLinus Torvalds 	hdev->close(hdev);
18391da177e4SLinus Torvalds 
184035b973c9SJohan Hedberg 	/* Clear flags */
1841fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
1842eacb44dfSMarcel Holtmann 	hci_dev_clear_volatile_flags(hdev);
184335b973c9SJohan Hedberg 
1844ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1845536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1846ced5c338SAndrei Emeltchenko 
1847e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
184809b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
18497a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
1850e59fda8dSJohan Hedberg 
1851b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
18521da177e4SLinus Torvalds 
18531da177e4SLinus Torvalds 	hci_dev_put(hdev);
18541da177e4SLinus Torvalds 	return 0;
18551da177e4SLinus Torvalds }
18561da177e4SLinus Torvalds 
18571da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
18581da177e4SLinus Torvalds {
18591da177e4SLinus Torvalds 	struct hci_dev *hdev;
18601da177e4SLinus Torvalds 	int err;
18611da177e4SLinus Torvalds 
186270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
186370f23020SAndrei Emeltchenko 	if (!hdev)
18641da177e4SLinus Torvalds 		return -ENODEV;
18658ee56540SMarcel Holtmann 
1866d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
18670736cfa8SMarcel Holtmann 		err = -EBUSY;
18680736cfa8SMarcel Holtmann 		goto done;
18690736cfa8SMarcel Holtmann 	}
18700736cfa8SMarcel Holtmann 
1871a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
18728ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
18738ee56540SMarcel Holtmann 
18741da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
18758ee56540SMarcel Holtmann 
18760736cfa8SMarcel Holtmann done:
18771da177e4SLinus Torvalds 	hci_dev_put(hdev);
18781da177e4SLinus Torvalds 	return err;
18791da177e4SLinus Torvalds }
18801da177e4SLinus Torvalds 
18815c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
18821da177e4SLinus Torvalds {
18835c912495SMarcel Holtmann 	int ret;
18841da177e4SLinus Torvalds 
18855c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
18861da177e4SLinus Torvalds 
1887b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
18881da177e4SLinus Torvalds 
18891da177e4SLinus Torvalds 	/* Drop queues */
18901da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
18911da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
18921da177e4SLinus Torvalds 
189376727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
189476727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
189576727c02SJohan Hedberg 	 */
189676727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
189776727c02SJohan Hedberg 
189809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
18991f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
19001da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
190109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
19021da177e4SLinus Torvalds 
19031da177e4SLinus Torvalds 	if (hdev->flush)
19041da177e4SLinus Torvalds 		hdev->flush(hdev);
19051da177e4SLinus Torvalds 
19061da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
19076ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
19081da177e4SLinus Torvalds 
19094ebeee2dSJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT, NULL);
19101da177e4SLinus Torvalds 
1911b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
19121da177e4SLinus Torvalds 	return ret;
19131da177e4SLinus Torvalds }
19141da177e4SLinus Torvalds 
19155c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
19165c912495SMarcel Holtmann {
19175c912495SMarcel Holtmann 	struct hci_dev *hdev;
19185c912495SMarcel Holtmann 	int err;
19195c912495SMarcel Holtmann 
19205c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
19215c912495SMarcel Holtmann 	if (!hdev)
19225c912495SMarcel Holtmann 		return -ENODEV;
19235c912495SMarcel Holtmann 
19245c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
19255c912495SMarcel Holtmann 		err = -ENETDOWN;
19265c912495SMarcel Holtmann 		goto done;
19275c912495SMarcel Holtmann 	}
19285c912495SMarcel Holtmann 
1929d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
19305c912495SMarcel Holtmann 		err = -EBUSY;
19315c912495SMarcel Holtmann 		goto done;
19325c912495SMarcel Holtmann 	}
19335c912495SMarcel Holtmann 
1934d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
19355c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
19365c912495SMarcel Holtmann 		goto done;
19375c912495SMarcel Holtmann 	}
19385c912495SMarcel Holtmann 
19395c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
19405c912495SMarcel Holtmann 
19415c912495SMarcel Holtmann done:
19425c912495SMarcel Holtmann 	hci_dev_put(hdev);
19435c912495SMarcel Holtmann 	return err;
19445c912495SMarcel Holtmann }
19455c912495SMarcel Holtmann 
19461da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
19471da177e4SLinus Torvalds {
19481da177e4SLinus Torvalds 	struct hci_dev *hdev;
19491da177e4SLinus Torvalds 	int ret = 0;
19501da177e4SLinus Torvalds 
195170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
195270f23020SAndrei Emeltchenko 	if (!hdev)
19531da177e4SLinus Torvalds 		return -ENODEV;
19541da177e4SLinus Torvalds 
1955d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
19560736cfa8SMarcel Holtmann 		ret = -EBUSY;
19570736cfa8SMarcel Holtmann 		goto done;
19580736cfa8SMarcel Holtmann 	}
19590736cfa8SMarcel Holtmann 
1960d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1961fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
1962fee746b0SMarcel Holtmann 		goto done;
1963fee746b0SMarcel Holtmann 	}
1964fee746b0SMarcel Holtmann 
19651da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
19661da177e4SLinus Torvalds 
19670736cfa8SMarcel Holtmann done:
19681da177e4SLinus Torvalds 	hci_dev_put(hdev);
19691da177e4SLinus Torvalds 	return ret;
19701da177e4SLinus Torvalds }
19711da177e4SLinus Torvalds 
1972123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
1973123abc08SJohan Hedberg {
1974bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
1975123abc08SJohan Hedberg 
1976123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
1977123abc08SJohan Hedberg 
1978123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
1979238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
1980238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
1981123abc08SJohan Hedberg 	else
1982a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
1983a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
1984123abc08SJohan Hedberg 
1985bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
1986238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
1987238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
1988bc6d2d04SJohan Hedberg 	} else {
1989a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1990a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
1991a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
1992bc6d2d04SJohan Hedberg 	}
1993bc6d2d04SJohan Hedberg 
1994d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
1995123abc08SJohan Hedberg 		return;
1996123abc08SJohan Hedberg 
1997bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
1998bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
1999a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
2000bc6d2d04SJohan Hedberg 
2001d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
2002cab054abSJohan Hedberg 			hci_req_update_adv_data(hdev, hdev->cur_adv_instance);
2003bc6d2d04SJohan Hedberg 
2004123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
2005123abc08SJohan Hedberg 	}
2006bc6d2d04SJohan Hedberg }
2007123abc08SJohan Hedberg 
20081da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
20091da177e4SLinus Torvalds {
20101da177e4SLinus Torvalds 	struct hci_dev *hdev;
20111da177e4SLinus Torvalds 	struct hci_dev_req dr;
20121da177e4SLinus Torvalds 	int err = 0;
20131da177e4SLinus Torvalds 
20141da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
20151da177e4SLinus Torvalds 		return -EFAULT;
20161da177e4SLinus Torvalds 
201770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
201870f23020SAndrei Emeltchenko 	if (!hdev)
20191da177e4SLinus Torvalds 		return -ENODEV;
20201da177e4SLinus Torvalds 
2021d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
20220736cfa8SMarcel Holtmann 		err = -EBUSY;
20230736cfa8SMarcel Holtmann 		goto done;
20240736cfa8SMarcel Holtmann 	}
20250736cfa8SMarcel Holtmann 
2026d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
2027fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2028fee746b0SMarcel Holtmann 		goto done;
2029fee746b0SMarcel Holtmann 	}
2030fee746b0SMarcel Holtmann 
2031ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
20325b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
20335b69bef5SMarcel Holtmann 		goto done;
20345b69bef5SMarcel Holtmann 	}
20355b69bef5SMarcel Holtmann 
2036d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
203756f87901SJohan Hedberg 		err = -EOPNOTSUPP;
203856f87901SJohan Hedberg 		goto done;
203956f87901SJohan Hedberg 	}
204056f87901SJohan Hedberg 
20411da177e4SLinus Torvalds 	switch (cmd) {
20421da177e4SLinus Torvalds 	case HCISETAUTH:
204301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
20444ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20451da177e4SLinus Torvalds 		break;
20461da177e4SLinus Torvalds 
20471da177e4SLinus Torvalds 	case HCISETENCRYPT:
20481da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
20491da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
20501da177e4SLinus Torvalds 			break;
20511da177e4SLinus Torvalds 		}
20521da177e4SLinus Torvalds 
20531da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
20541da177e4SLinus Torvalds 			/* Auth must be enabled first */
205501178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
20564ebeee2dSJohan Hedberg 					   HCI_INIT_TIMEOUT, NULL);
20571da177e4SLinus Torvalds 			if (err)
20581da177e4SLinus Torvalds 				break;
20591da177e4SLinus Torvalds 		}
20601da177e4SLinus Torvalds 
206101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
20624ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20631da177e4SLinus Torvalds 		break;
20641da177e4SLinus Torvalds 
20651da177e4SLinus Torvalds 	case HCISETSCAN:
206601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
20674ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
206891a668b0SJohan Hedberg 
2069bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
2070bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
207191a668b0SJohan Hedberg 		 */
2072123abc08SJohan Hedberg 		if (!err)
2073123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
20741da177e4SLinus Torvalds 		break;
20751da177e4SLinus Torvalds 
20761da177e4SLinus Torvalds 	case HCISETLINKPOL:
207701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
20784ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20791da177e4SLinus Torvalds 		break;
20801da177e4SLinus Torvalds 
20811da177e4SLinus Torvalds 	case HCISETLINKMODE:
2082e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2083e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2084e4e8e37cSMarcel Holtmann 		break;
2085e4e8e37cSMarcel Holtmann 
2086e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2087b7c23df8SJaganath Kanakkassery 		if (hdev->pkt_type == (__u16) dr.dev_opt)
2088b7c23df8SJaganath Kanakkassery 			break;
2089b7c23df8SJaganath Kanakkassery 
2090e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
2091b7c23df8SJaganath Kanakkassery 		mgmt_phy_configuration_changed(hdev, NULL);
20921da177e4SLinus Torvalds 		break;
20931da177e4SLinus Torvalds 
20941da177e4SLinus Torvalds 	case HCISETACLMTU:
20951da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
20961da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
20971da177e4SLinus Torvalds 		break;
20981da177e4SLinus Torvalds 
20991da177e4SLinus Torvalds 	case HCISETSCOMTU:
21001da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
21011da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
21021da177e4SLinus Torvalds 		break;
21031da177e4SLinus Torvalds 
21041da177e4SLinus Torvalds 	default:
21051da177e4SLinus Torvalds 		err = -EINVAL;
21061da177e4SLinus Torvalds 		break;
21071da177e4SLinus Torvalds 	}
2108e4e8e37cSMarcel Holtmann 
21090736cfa8SMarcel Holtmann done:
21101da177e4SLinus Torvalds 	hci_dev_put(hdev);
21111da177e4SLinus Torvalds 	return err;
21121da177e4SLinus Torvalds }
21131da177e4SLinus Torvalds 
21141da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
21151da177e4SLinus Torvalds {
21168035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
21171da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
21181da177e4SLinus Torvalds 	struct hci_dev_req *dr;
21191da177e4SLinus Torvalds 	int n = 0, size, err;
21201da177e4SLinus Torvalds 	__u16 dev_num;
21211da177e4SLinus Torvalds 
21221da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
21231da177e4SLinus Torvalds 		return -EFAULT;
21241da177e4SLinus Torvalds 
21251da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
21261da177e4SLinus Torvalds 		return -EINVAL;
21271da177e4SLinus Torvalds 
21281da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
21291da177e4SLinus Torvalds 
213070f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
213170f23020SAndrei Emeltchenko 	if (!dl)
21321da177e4SLinus Torvalds 		return -ENOMEM;
21331da177e4SLinus Torvalds 
21341da177e4SLinus Torvalds 	dr = dl->dev_req;
21351da177e4SLinus Torvalds 
2136f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
21378035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
21382e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
2139c542a06cSJohan Hedberg 
21402e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
21412e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
21422e84d8dbSMarcel Holtmann 		 * device is actually down.
21432e84d8dbSMarcel Holtmann 		 */
2144d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
21452e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
2146c542a06cSJohan Hedberg 
21471da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
21482e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
2149c542a06cSJohan Hedberg 
21501da177e4SLinus Torvalds 		if (++n >= dev_num)
21511da177e4SLinus Torvalds 			break;
21521da177e4SLinus Torvalds 	}
2153f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
21541da177e4SLinus Torvalds 
21551da177e4SLinus Torvalds 	dl->dev_num = n;
21561da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
21571da177e4SLinus Torvalds 
21581da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
21591da177e4SLinus Torvalds 	kfree(dl);
21601da177e4SLinus Torvalds 
21611da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
21621da177e4SLinus Torvalds }
21631da177e4SLinus Torvalds 
21641da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
21651da177e4SLinus Torvalds {
21661da177e4SLinus Torvalds 	struct hci_dev *hdev;
21671da177e4SLinus Torvalds 	struct hci_dev_info di;
21682e84d8dbSMarcel Holtmann 	unsigned long flags;
21691da177e4SLinus Torvalds 	int err = 0;
21701da177e4SLinus Torvalds 
21711da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
21721da177e4SLinus Torvalds 		return -EFAULT;
21731da177e4SLinus Torvalds 
217470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
217570f23020SAndrei Emeltchenko 	if (!hdev)
21761da177e4SLinus Torvalds 		return -ENODEV;
21771da177e4SLinus Torvalds 
21782e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
21792e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
21802e84d8dbSMarcel Holtmann 	 * device is actually down.
21812e84d8dbSMarcel Holtmann 	 */
2182d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
21832e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
21842e84d8dbSMarcel Holtmann 	else
21852e84d8dbSMarcel Holtmann 		flags = hdev->flags;
2186c542a06cSJohan Hedberg 
21871da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
21881da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
218960f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
21902e84d8dbSMarcel Holtmann 	di.flags    = flags;
21911da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2192572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
21931da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
21941da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
21951da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
21961da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2197572c7f84SJohan Hedberg 	} else {
2198572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2199572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2200572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2201572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2202572c7f84SJohan Hedberg 	}
22031da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
22041da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
22051da177e4SLinus Torvalds 
22061da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
22071da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
22081da177e4SLinus Torvalds 
22091da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
22101da177e4SLinus Torvalds 		err = -EFAULT;
22111da177e4SLinus Torvalds 
22121da177e4SLinus Torvalds 	hci_dev_put(hdev);
22131da177e4SLinus Torvalds 
22141da177e4SLinus Torvalds 	return err;
22151da177e4SLinus Torvalds }
22161da177e4SLinus Torvalds 
22171da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
22181da177e4SLinus Torvalds 
2219611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2220611b30f7SMarcel Holtmann {
2221611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2222611b30f7SMarcel Holtmann 
2223611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2224611b30f7SMarcel Holtmann 
2225d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
22260736cfa8SMarcel Holtmann 		return -EBUSY;
22270736cfa8SMarcel Holtmann 
22285e130367SJohan Hedberg 	if (blocked) {
2229a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
2230d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
2231d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
2232611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
22335e130367SJohan Hedberg 	} else {
2234a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
22355e130367SJohan Hedberg 	}
2236611b30f7SMarcel Holtmann 
2237611b30f7SMarcel Holtmann 	return 0;
2238611b30f7SMarcel Holtmann }
2239611b30f7SMarcel Holtmann 
2240611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2241611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2242611b30f7SMarcel Holtmann };
2243611b30f7SMarcel Holtmann 
2244ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2245ab81cbf9SJohan Hedberg {
2246ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
224796570ffcSJohan Hedberg 	int err;
2248ab81cbf9SJohan Hedberg 
2249ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2250ab81cbf9SJohan Hedberg 
22512ff13894SJohan Hedberg 	if (test_bit(HCI_UP, &hdev->flags) &&
22522ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT) &&
22532ff13894SJohan Hedberg 	    hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
2254d82142a8SWei-Ning Huang 		cancel_delayed_work(&hdev->power_off);
22552ff13894SJohan Hedberg 		hci_req_sync_lock(hdev);
22562ff13894SJohan Hedberg 		err = __hci_req_hci_power_on(hdev);
22572ff13894SJohan Hedberg 		hci_req_sync_unlock(hdev);
22582ff13894SJohan Hedberg 		mgmt_power_on(hdev, err);
22592ff13894SJohan Hedberg 		return;
22602ff13894SJohan Hedberg 	}
22612ff13894SJohan Hedberg 
2262cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
226396570ffcSJohan Hedberg 	if (err < 0) {
22643ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
226596570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
22663ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
2267ab81cbf9SJohan Hedberg 		return;
226896570ffcSJohan Hedberg 	}
2269ab81cbf9SJohan Hedberg 
2270a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2271a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2272a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2273a5c8f270SMarcel Holtmann 	 */
2274d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
2275d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
2276ca8bee5dSMarcel Holtmann 	    (hdev->dev_type == HCI_PRIMARY &&
2277a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2278a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2279a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
2280bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2281d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
228219202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
228319202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2284bf543036SJohan Hedberg 	}
2285ab81cbf9SJohan Hedberg 
2286a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
22874a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
22884a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
22894a964404SMarcel Holtmann 		 */
2290d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
22914a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
22920602a8adSMarcel Holtmann 
22930602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
22940602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
22950602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
22960602a8adSMarcel Holtmann 		 *
22970602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
22980602a8adSMarcel Holtmann 		 * and no event will be send.
22990602a8adSMarcel Holtmann 		 */
2300744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2301a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
23025ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
23035ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
23045ea234d3SMarcel Holtmann 		 */
2305d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
23065ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
23075ea234d3SMarcel Holtmann 
2308d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
2309d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
2310d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
2311d603b76bSMarcel Holtmann 		 */
2312d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
2313ab81cbf9SJohan Hedberg 	}
2314ab81cbf9SJohan Hedberg }
2315ab81cbf9SJohan Hedberg 
2316ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2317ab81cbf9SJohan Hedberg {
23183243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
23193243553fSJohan Hedberg 					    power_off.work);
2320ab81cbf9SJohan Hedberg 
2321ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2322ab81cbf9SJohan Hedberg 
23238ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2324ab81cbf9SJohan Hedberg }
2325ab81cbf9SJohan Hedberg 
2326c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
2327c7741d16SMarcel Holtmann {
2328c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
2329c7741d16SMarcel Holtmann 
2330c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2331c7741d16SMarcel Holtmann 
2332c7741d16SMarcel Holtmann 	if (hdev->hw_error)
2333c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
2334c7741d16SMarcel Holtmann 	else
23352064ee33SMarcel Holtmann 		bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
2336c7741d16SMarcel Holtmann 
2337c7741d16SMarcel Holtmann 	if (hci_dev_do_close(hdev))
2338c7741d16SMarcel Holtmann 		return;
2339c7741d16SMarcel Holtmann 
2340c7741d16SMarcel Holtmann 	hci_dev_do_open(hdev);
2341c7741d16SMarcel Holtmann }
2342c7741d16SMarcel Holtmann 
234335f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
23442aeb9a1aSJohan Hedberg {
23454821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
23462aeb9a1aSJohan Hedberg 
23474821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
23484821002cSJohan Hedberg 		list_del(&uuid->list);
23492aeb9a1aSJohan Hedberg 		kfree(uuid);
23502aeb9a1aSJohan Hedberg 	}
23512aeb9a1aSJohan Hedberg }
23522aeb9a1aSJohan Hedberg 
235335f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
235455ed8ca1SJohan Hedberg {
235555ed8ca1SJohan Hedberg 	struct link_key *key;
235655ed8ca1SJohan Hedberg 
2357d7d41682SMadhuparna Bhowmik 	list_for_each_entry(key, &hdev->link_keys, list) {
23580378b597SJohan Hedberg 		list_del_rcu(&key->list);
23590378b597SJohan Hedberg 		kfree_rcu(key, rcu);
236055ed8ca1SJohan Hedberg 	}
236155ed8ca1SJohan Hedberg }
236255ed8ca1SJohan Hedberg 
236335f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2364b899efafSVinicius Costa Gomes {
2365970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2366b899efafSVinicius Costa Gomes 
2367d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->long_term_keys, list) {
2368970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2369970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2370b899efafSVinicius Costa Gomes 	}
2371b899efafSVinicius Costa Gomes }
2372b899efafSVinicius Costa Gomes 
2373970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2374970c4e46SJohan Hedberg {
2375adae20cbSJohan Hedberg 	struct smp_irk *k;
2376970c4e46SJohan Hedberg 
2377d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->identity_resolving_keys, list) {
2378adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2379adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2380970c4e46SJohan Hedberg 	}
2381970c4e46SJohan Hedberg }
2382970c4e46SJohan Hedberg 
2383600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev)
2384600a8749SAlain Michaud {
2385600a8749SAlain Michaud 	struct blocked_key *b;
2386600a8749SAlain Michaud 
2387d7d41682SMadhuparna Bhowmik 	list_for_each_entry(b, &hdev->blocked_keys, list) {
2388600a8749SAlain Michaud 		list_del_rcu(&b->list);
2389600a8749SAlain Michaud 		kfree_rcu(b, rcu);
2390600a8749SAlain Michaud 	}
2391600a8749SAlain Michaud }
2392600a8749SAlain Michaud 
2393600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16])
2394600a8749SAlain Michaud {
2395600a8749SAlain Michaud 	bool blocked = false;
2396600a8749SAlain Michaud 	struct blocked_key *b;
2397600a8749SAlain Michaud 
2398600a8749SAlain Michaud 	rcu_read_lock();
23990c2ac7d4SMadhuparna Bhowmik 	list_for_each_entry_rcu(b, &hdev->blocked_keys, list) {
2400600a8749SAlain Michaud 		if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) {
2401600a8749SAlain Michaud 			blocked = true;
2402600a8749SAlain Michaud 			break;
2403600a8749SAlain Michaud 		}
2404600a8749SAlain Michaud 	}
2405600a8749SAlain Michaud 
2406600a8749SAlain Michaud 	rcu_read_unlock();
2407600a8749SAlain Michaud 	return blocked;
2408600a8749SAlain Michaud }
2409600a8749SAlain Michaud 
241055ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
241155ed8ca1SJohan Hedberg {
241255ed8ca1SJohan Hedberg 	struct link_key *k;
241355ed8ca1SJohan Hedberg 
24140378b597SJohan Hedberg 	rcu_read_lock();
24150378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
24160378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
24170378b597SJohan Hedberg 			rcu_read_unlock();
2418600a8749SAlain Michaud 
2419600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev,
2420600a8749SAlain Michaud 					       HCI_BLOCKED_KEY_TYPE_LINKKEY,
2421600a8749SAlain Michaud 					       k->val)) {
2422600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
2423600a8749SAlain Michaud 							"Link key blocked for %pMR",
2424600a8749SAlain Michaud 							&k->bdaddr);
2425600a8749SAlain Michaud 				return NULL;
2426600a8749SAlain Michaud 			}
2427600a8749SAlain Michaud 
242855ed8ca1SJohan Hedberg 			return k;
24290378b597SJohan Hedberg 		}
24300378b597SJohan Hedberg 	}
24310378b597SJohan Hedberg 	rcu_read_unlock();
243255ed8ca1SJohan Hedberg 
243355ed8ca1SJohan Hedberg 	return NULL;
243455ed8ca1SJohan Hedberg }
243555ed8ca1SJohan Hedberg 
2436745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2437d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2438d25e28abSJohan Hedberg {
2439d25e28abSJohan Hedberg 	/* Legacy key */
2440d25e28abSJohan Hedberg 	if (key_type < 0x03)
2441745c0ce3SVishal Agarwal 		return true;
2442d25e28abSJohan Hedberg 
2443d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2444d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2445745c0ce3SVishal Agarwal 		return false;
2446d25e28abSJohan Hedberg 
2447d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2448d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2449745c0ce3SVishal Agarwal 		return false;
2450d25e28abSJohan Hedberg 
2451d25e28abSJohan Hedberg 	/* Security mode 3 case */
2452d25e28abSJohan Hedberg 	if (!conn)
2453745c0ce3SVishal Agarwal 		return true;
2454d25e28abSJohan Hedberg 
2455e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
2456e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
2457e3befab9SJohan Hedberg 		return true;
2458e3befab9SJohan Hedberg 
2459d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2460d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2461745c0ce3SVishal Agarwal 		return true;
2462d25e28abSJohan Hedberg 
2463d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2464d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2465745c0ce3SVishal Agarwal 		return true;
2466d25e28abSJohan Hedberg 
2467d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2468d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2469745c0ce3SVishal Agarwal 		return true;
2470d25e28abSJohan Hedberg 
2471d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2472d25e28abSJohan Hedberg 	 * persistently */
2473745c0ce3SVishal Agarwal 	return false;
2474d25e28abSJohan Hedberg }
2475d25e28abSJohan Hedberg 
2476e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
247798a0b845SJohan Hedberg {
2478e804d25dSJohan Hedberg 	if (type == SMP_LTK)
2479e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
248098a0b845SJohan Hedberg 
2481e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
248298a0b845SJohan Hedberg }
248398a0b845SJohan Hedberg 
2484f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2485e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
248675d262c2SVinicius Costa Gomes {
2487c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
248875d262c2SVinicius Costa Gomes 
2489970d0f1bSJohan Hedberg 	rcu_read_lock();
2490970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
24915378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
24925378bc56SJohan Hedberg 			continue;
24935378bc56SJohan Hedberg 
2494923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
2495970d0f1bSJohan Hedberg 			rcu_read_unlock();
2496600a8749SAlain Michaud 
2497600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK,
2498600a8749SAlain Michaud 					       k->val)) {
2499600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
2500600a8749SAlain Michaud 							"LTK blocked for %pMR",
2501600a8749SAlain Michaud 							&k->bdaddr);
2502600a8749SAlain Michaud 				return NULL;
2503600a8749SAlain Michaud 			}
2504600a8749SAlain Michaud 
250575d262c2SVinicius Costa Gomes 			return k;
2506970d0f1bSJohan Hedberg 		}
2507970d0f1bSJohan Hedberg 	}
2508970d0f1bSJohan Hedberg 	rcu_read_unlock();
250975d262c2SVinicius Costa Gomes 
251075d262c2SVinicius Costa Gomes 	return NULL;
251175d262c2SVinicius Costa Gomes }
251275d262c2SVinicius Costa Gomes 
2513970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2514970c4e46SJohan Hedberg {
2515600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
2516970c4e46SJohan Hedberg 	struct smp_irk *irk;
2517970c4e46SJohan Hedberg 
2518adae20cbSJohan Hedberg 	rcu_read_lock();
2519adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2520adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
2521600a8749SAlain Michaud 			irk_to_return = irk;
2522600a8749SAlain Michaud 			goto done;
2523970c4e46SJohan Hedberg 		}
2524adae20cbSJohan Hedberg 	}
2525970c4e46SJohan Hedberg 
2526adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2527defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
2528970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
2529600a8749SAlain Michaud 			irk_to_return = irk;
2530600a8749SAlain Michaud 			goto done;
2531970c4e46SJohan Hedberg 		}
2532970c4e46SJohan Hedberg 	}
2533600a8749SAlain Michaud 
2534600a8749SAlain Michaud done:
2535600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
2536600a8749SAlain Michaud 						irk_to_return->val)) {
2537600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
2538600a8749SAlain Michaud 					&irk_to_return->bdaddr);
2539600a8749SAlain Michaud 		irk_to_return = NULL;
2540600a8749SAlain Michaud 	}
2541600a8749SAlain Michaud 
2542adae20cbSJohan Hedberg 	rcu_read_unlock();
2543970c4e46SJohan Hedberg 
2544600a8749SAlain Michaud 	return irk_to_return;
2545970c4e46SJohan Hedberg }
2546970c4e46SJohan Hedberg 
2547970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2548970c4e46SJohan Hedberg 				     u8 addr_type)
2549970c4e46SJohan Hedberg {
2550600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
2551970c4e46SJohan Hedberg 	struct smp_irk *irk;
2552970c4e46SJohan Hedberg 
25536cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
25546cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
25556cfc9988SJohan Hedberg 		return NULL;
25566cfc9988SJohan Hedberg 
2557adae20cbSJohan Hedberg 	rcu_read_lock();
2558adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2559970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
2560adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
2561600a8749SAlain Michaud 			irk_to_return = irk;
2562600a8749SAlain Michaud 			goto done;
2563970c4e46SJohan Hedberg 		}
2564adae20cbSJohan Hedberg 	}
2565600a8749SAlain Michaud 
2566600a8749SAlain Michaud done:
2567600a8749SAlain Michaud 
2568600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
2569600a8749SAlain Michaud 						irk_to_return->val)) {
2570600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
2571600a8749SAlain Michaud 					&irk_to_return->bdaddr);
2572600a8749SAlain Michaud 		irk_to_return = NULL;
2573600a8749SAlain Michaud 	}
2574600a8749SAlain Michaud 
2575adae20cbSJohan Hedberg 	rcu_read_unlock();
2576970c4e46SJohan Hedberg 
2577600a8749SAlain Michaud 	return irk_to_return;
2578970c4e46SJohan Hedberg }
2579970c4e46SJohan Hedberg 
2580567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
25817652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
25827652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
258355ed8ca1SJohan Hedberg {
258455ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2585745c0ce3SVishal Agarwal 	u8 old_key_type;
258655ed8ca1SJohan Hedberg 
258755ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
258855ed8ca1SJohan Hedberg 	if (old_key) {
258955ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
259055ed8ca1SJohan Hedberg 		key = old_key;
259155ed8ca1SJohan Hedberg 	} else {
259212adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
25930a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
259455ed8ca1SJohan Hedberg 		if (!key)
2595567fa2aaSJohan Hedberg 			return NULL;
25960378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
259755ed8ca1SJohan Hedberg 	}
259855ed8ca1SJohan Hedberg 
25996ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
260055ed8ca1SJohan Hedberg 
2601d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2602d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2603d25e28abSJohan Hedberg 	 * previous key */
2604d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2605a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2606d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2607655fe6ecSJohan Hedberg 		if (conn)
2608655fe6ecSJohan Hedberg 			conn->key_type = type;
2609655fe6ecSJohan Hedberg 	}
2610d25e28abSJohan Hedberg 
261155ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
26129b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
261355ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
261455ed8ca1SJohan Hedberg 
2615b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
261655ed8ca1SJohan Hedberg 		key->type = old_key_type;
26174748fed2SJohan Hedberg 	else
26184748fed2SJohan Hedberg 		key->type = type;
26194748fed2SJohan Hedberg 
26207652ff6aSJohan Hedberg 	if (persistent)
26217652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
26227652ff6aSJohan Hedberg 						 old_key_type);
26234df378a1SJohan Hedberg 
2624567fa2aaSJohan Hedberg 	return key;
262555ed8ca1SJohan Hedberg }
262655ed8ca1SJohan Hedberg 
2627ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
262835d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
2629fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
263075d262c2SVinicius Costa Gomes {
2631c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
2632e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
263375d262c2SVinicius Costa Gomes 
2634f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
2635c9839a11SVinicius Costa Gomes 	if (old_key)
263675d262c2SVinicius Costa Gomes 		key = old_key;
2637c9839a11SVinicius Costa Gomes 	else {
26380a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
263975d262c2SVinicius Costa Gomes 		if (!key)
2640ca9142b8SJohan Hedberg 			return NULL;
2641970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
264275d262c2SVinicius Costa Gomes 	}
264375d262c2SVinicius Costa Gomes 
264475d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2645c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2646c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2647c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2648c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2649fe39c7b2SMarcel Holtmann 	key->rand = rand;
2650c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2651c9839a11SVinicius Costa Gomes 	key->type = type;
265275d262c2SVinicius Costa Gomes 
2653ca9142b8SJohan Hedberg 	return key;
265475d262c2SVinicius Costa Gomes }
265575d262c2SVinicius Costa Gomes 
2656ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2657ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
2658970c4e46SJohan Hedberg {
2659970c4e46SJohan Hedberg 	struct smp_irk *irk;
2660970c4e46SJohan Hedberg 
2661970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2662970c4e46SJohan Hedberg 	if (!irk) {
2663970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
2664970c4e46SJohan Hedberg 		if (!irk)
2665ca9142b8SJohan Hedberg 			return NULL;
2666970c4e46SJohan Hedberg 
2667970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
2668970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
2669970c4e46SJohan Hedberg 
2670adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
2671970c4e46SJohan Hedberg 	}
2672970c4e46SJohan Hedberg 
2673970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
2674970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
2675970c4e46SJohan Hedberg 
2676ca9142b8SJohan Hedberg 	return irk;
2677970c4e46SJohan Hedberg }
2678970c4e46SJohan Hedberg 
267955ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
268055ed8ca1SJohan Hedberg {
268155ed8ca1SJohan Hedberg 	struct link_key *key;
268255ed8ca1SJohan Hedberg 
268355ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
268455ed8ca1SJohan Hedberg 	if (!key)
268555ed8ca1SJohan Hedberg 		return -ENOENT;
268655ed8ca1SJohan Hedberg 
26876ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
268855ed8ca1SJohan Hedberg 
26890378b597SJohan Hedberg 	list_del_rcu(&key->list);
26900378b597SJohan Hedberg 	kfree_rcu(key, rcu);
269155ed8ca1SJohan Hedberg 
269255ed8ca1SJohan Hedberg 	return 0;
269355ed8ca1SJohan Hedberg }
269455ed8ca1SJohan Hedberg 
2695e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2696b899efafSVinicius Costa Gomes {
2697970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2698c51ffa0bSJohan Hedberg 	int removed = 0;
2699b899efafSVinicius Costa Gomes 
2700970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2701e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2702b899efafSVinicius Costa Gomes 			continue;
2703b899efafSVinicius Costa Gomes 
27046ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2705b899efafSVinicius Costa Gomes 
2706970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2707970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2708c51ffa0bSJohan Hedberg 		removed++;
2709b899efafSVinicius Costa Gomes 	}
2710b899efafSVinicius Costa Gomes 
2711c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
2712b899efafSVinicius Costa Gomes }
2713b899efafSVinicius Costa Gomes 
2714a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
2715a7ec7338SJohan Hedberg {
2716adae20cbSJohan Hedberg 	struct smp_irk *k;
2717a7ec7338SJohan Hedberg 
2718adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2719a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
2720a7ec7338SJohan Hedberg 			continue;
2721a7ec7338SJohan Hedberg 
2722a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2723a7ec7338SJohan Hedberg 
2724adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2725adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2726a7ec7338SJohan Hedberg 	}
2727a7ec7338SJohan Hedberg }
2728a7ec7338SJohan Hedberg 
272955e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
273055e76b38SJohan Hedberg {
273155e76b38SJohan Hedberg 	struct smp_ltk *k;
27324ba9faf3SJohan Hedberg 	struct smp_irk *irk;
273355e76b38SJohan Hedberg 	u8 addr_type;
273455e76b38SJohan Hedberg 
273555e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
273655e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
273755e76b38SJohan Hedberg 			return true;
273855e76b38SJohan Hedberg 		return false;
273955e76b38SJohan Hedberg 	}
274055e76b38SJohan Hedberg 
274155e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
274255e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
274355e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
274455e76b38SJohan Hedberg 	else
274555e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
274655e76b38SJohan Hedberg 
27474ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
27484ba9faf3SJohan Hedberg 	if (irk) {
27494ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
27504ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
27514ba9faf3SJohan Hedberg 	}
27524ba9faf3SJohan Hedberg 
275355e76b38SJohan Hedberg 	rcu_read_lock();
275455e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
275587c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
275687c8b28dSJohan Hedberg 			rcu_read_unlock();
275755e76b38SJohan Hedberg 			return true;
275855e76b38SJohan Hedberg 		}
275987c8b28dSJohan Hedberg 	}
276055e76b38SJohan Hedberg 	rcu_read_unlock();
276155e76b38SJohan Hedberg 
276255e76b38SJohan Hedberg 	return false;
276355e76b38SJohan Hedberg }
276455e76b38SJohan Hedberg 
27656bd32326SVille Tervo /* HCI command timer function */
276665cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
27676bd32326SVille Tervo {
276865cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
276965cc2b49SMarcel Holtmann 					    cmd_timer.work);
27706bd32326SVille Tervo 
2771bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2772bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2773bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2774bda4f23aSAndrei Emeltchenko 
27752064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
2776bda4f23aSAndrei Emeltchenko 	} else {
27772064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command tx timeout");
2778bda4f23aSAndrei Emeltchenko 	}
2779bda4f23aSAndrei Emeltchenko 
2780e2bef384SRajat Jain 	if (hdev->cmd_timeout)
2781e2bef384SRajat Jain 		hdev->cmd_timeout(hdev);
2782e2bef384SRajat Jain 
27836bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2784c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
27856bd32326SVille Tervo }
27866bd32326SVille Tervo 
2787de75cd0dSManish Mandlik /* HCI ncmd timer function */
2788de75cd0dSManish Mandlik static void hci_ncmd_timeout(struct work_struct *work)
2789de75cd0dSManish Mandlik {
2790de75cd0dSManish Mandlik 	struct hci_dev *hdev = container_of(work, struct hci_dev,
2791de75cd0dSManish Mandlik 					    ncmd_timer.work);
2792de75cd0dSManish Mandlik 
2793de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Controller not accepting commands anymore: ncmd = 0");
2794de75cd0dSManish Mandlik 
2795de75cd0dSManish Mandlik 	/* During HCI_INIT phase no events can be injected if the ncmd timer
2796de75cd0dSManish Mandlik 	 * triggers since the procedure has its own timeout handling.
2797de75cd0dSManish Mandlik 	 */
2798de75cd0dSManish Mandlik 	if (test_bit(HCI_INIT, &hdev->flags))
2799de75cd0dSManish Mandlik 		return;
2800de75cd0dSManish Mandlik 
2801de75cd0dSManish Mandlik 	/* This is an irrecoverable state, inject hardware error event */
2802de75cd0dSManish Mandlik 	hci_reset_dev(hdev);
2803de75cd0dSManish Mandlik }
2804de75cd0dSManish Mandlik 
28052763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
28066928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
28072763eda6SSzymon Janc {
28082763eda6SSzymon Janc 	struct oob_data *data;
28092763eda6SSzymon Janc 
28106928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
28116928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
28126928a924SJohan Hedberg 			continue;
28136928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
28146928a924SJohan Hedberg 			continue;
28152763eda6SSzymon Janc 		return data;
28166928a924SJohan Hedberg 	}
28172763eda6SSzymon Janc 
28182763eda6SSzymon Janc 	return NULL;
28192763eda6SSzymon Janc }
28202763eda6SSzymon Janc 
28216928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
28226928a924SJohan Hedberg 			       u8 bdaddr_type)
28232763eda6SSzymon Janc {
28242763eda6SSzymon Janc 	struct oob_data *data;
28252763eda6SSzymon Janc 
28266928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
28272763eda6SSzymon Janc 	if (!data)
28282763eda6SSzymon Janc 		return -ENOENT;
28292763eda6SSzymon Janc 
28306928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
28312763eda6SSzymon Janc 
28322763eda6SSzymon Janc 	list_del(&data->list);
28332763eda6SSzymon Janc 	kfree(data);
28342763eda6SSzymon Janc 
28352763eda6SSzymon Janc 	return 0;
28362763eda6SSzymon Janc }
28372763eda6SSzymon Janc 
283835f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
28392763eda6SSzymon Janc {
28402763eda6SSzymon Janc 	struct oob_data *data, *n;
28412763eda6SSzymon Janc 
28422763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
28432763eda6SSzymon Janc 		list_del(&data->list);
28442763eda6SSzymon Janc 		kfree(data);
28452763eda6SSzymon Janc 	}
28462763eda6SSzymon Janc }
28472763eda6SSzymon Janc 
28480798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
28496928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
285038da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
28510798872eSMarcel Holtmann {
28520798872eSMarcel Holtmann 	struct oob_data *data;
28530798872eSMarcel Holtmann 
28546928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
28550798872eSMarcel Holtmann 	if (!data) {
28560a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
28570798872eSMarcel Holtmann 		if (!data)
28580798872eSMarcel Holtmann 			return -ENOMEM;
28590798872eSMarcel Holtmann 
28600798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
28616928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
28620798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
28630798872eSMarcel Holtmann 	}
28640798872eSMarcel Holtmann 
286581328d5cSJohan Hedberg 	if (hash192 && rand192) {
28660798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
286738da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
2868f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2869f7697b16SMarcel Holtmann 			data->present = 0x03;
287081328d5cSJohan Hedberg 	} else {
287181328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
287281328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
2873f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2874f7697b16SMarcel Holtmann 			data->present = 0x02;
2875f7697b16SMarcel Holtmann 		else
2876f7697b16SMarcel Holtmann 			data->present = 0x00;
287781328d5cSJohan Hedberg 	}
28780798872eSMarcel Holtmann 
287981328d5cSJohan Hedberg 	if (hash256 && rand256) {
28800798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
288138da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
288281328d5cSJohan Hedberg 	} else {
288381328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
288481328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
2885f7697b16SMarcel Holtmann 		if (hash192 && rand192)
2886f7697b16SMarcel Holtmann 			data->present = 0x01;
288781328d5cSJohan Hedberg 	}
28880798872eSMarcel Holtmann 
28896ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
28902763eda6SSzymon Janc 
28912763eda6SSzymon Janc 	return 0;
28922763eda6SSzymon Janc }
28932763eda6SSzymon Janc 
2894d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2895d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
2896d2609b34SFlorian Grandel {
2897d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2898d2609b34SFlorian Grandel 
2899d2609b34SFlorian Grandel 	list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
2900d2609b34SFlorian Grandel 		if (adv_instance->instance == instance)
2901d2609b34SFlorian Grandel 			return adv_instance;
2902d2609b34SFlorian Grandel 	}
2903d2609b34SFlorian Grandel 
2904d2609b34SFlorian Grandel 	return NULL;
2905d2609b34SFlorian Grandel }
2906d2609b34SFlorian Grandel 
2907d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
290874b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
290974b93e9fSPrasanna Karthik {
2910d2609b34SFlorian Grandel 	struct adv_info *cur_instance;
2911d2609b34SFlorian Grandel 
2912d2609b34SFlorian Grandel 	cur_instance = hci_find_adv_instance(hdev, instance);
2913d2609b34SFlorian Grandel 	if (!cur_instance)
2914d2609b34SFlorian Grandel 		return NULL;
2915d2609b34SFlorian Grandel 
2916d2609b34SFlorian Grandel 	if (cur_instance == list_last_entry(&hdev->adv_instances,
2917d2609b34SFlorian Grandel 					    struct adv_info, list))
2918d2609b34SFlorian Grandel 		return list_first_entry(&hdev->adv_instances,
2919d2609b34SFlorian Grandel 						 struct adv_info, list);
2920d2609b34SFlorian Grandel 	else
2921d2609b34SFlorian Grandel 		return list_next_entry(cur_instance, list);
2922d2609b34SFlorian Grandel }
2923d2609b34SFlorian Grandel 
2924d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2925d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
2926d2609b34SFlorian Grandel {
2927d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2928d2609b34SFlorian Grandel 
2929d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
2930d2609b34SFlorian Grandel 	if (!adv_instance)
2931d2609b34SFlorian Grandel 		return -ENOENT;
2932d2609b34SFlorian Grandel 
2933d2609b34SFlorian Grandel 	BT_DBG("%s removing %dMR", hdev->name, instance);
2934d2609b34SFlorian Grandel 
2935cab054abSJohan Hedberg 	if (hdev->cur_adv_instance == instance) {
2936cab054abSJohan Hedberg 		if (hdev->adv_instance_timeout) {
29375d900e46SFlorian Grandel 			cancel_delayed_work(&hdev->adv_instance_expire);
29385d900e46SFlorian Grandel 			hdev->adv_instance_timeout = 0;
29395d900e46SFlorian Grandel 		}
2940cab054abSJohan Hedberg 		hdev->cur_adv_instance = 0x00;
2941cab054abSJohan Hedberg 	}
29425d900e46SFlorian Grandel 
2943a73c046aSJaganath Kanakkassery 	cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
2944a73c046aSJaganath Kanakkassery 
2945d2609b34SFlorian Grandel 	list_del(&adv_instance->list);
2946d2609b34SFlorian Grandel 	kfree(adv_instance);
2947d2609b34SFlorian Grandel 
2948d2609b34SFlorian Grandel 	hdev->adv_instance_cnt--;
2949d2609b34SFlorian Grandel 
2950d2609b34SFlorian Grandel 	return 0;
2951d2609b34SFlorian Grandel }
2952d2609b34SFlorian Grandel 
2953a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired)
2954a73c046aSJaganath Kanakkassery {
2955a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance, *n;
2956a73c046aSJaganath Kanakkassery 
2957a73c046aSJaganath Kanakkassery 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list)
2958a73c046aSJaganath Kanakkassery 		adv_instance->rpa_expired = rpa_expired;
2959a73c046aSJaganath Kanakkassery }
2960a73c046aSJaganath Kanakkassery 
2961d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2962d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev)
2963d2609b34SFlorian Grandel {
2964d2609b34SFlorian Grandel 	struct adv_info *adv_instance, *n;
2965d2609b34SFlorian Grandel 
29665d900e46SFlorian Grandel 	if (hdev->adv_instance_timeout) {
29675d900e46SFlorian Grandel 		cancel_delayed_work(&hdev->adv_instance_expire);
29685d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
29695d900e46SFlorian Grandel 	}
29705d900e46SFlorian Grandel 
2971d2609b34SFlorian Grandel 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
2972a73c046aSJaganath Kanakkassery 		cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
2973d2609b34SFlorian Grandel 		list_del(&adv_instance->list);
2974d2609b34SFlorian Grandel 		kfree(adv_instance);
2975d2609b34SFlorian Grandel 	}
2976d2609b34SFlorian Grandel 
2977d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
2978cab054abSJohan Hedberg 	hdev->cur_adv_instance = 0x00;
2979d2609b34SFlorian Grandel }
2980d2609b34SFlorian Grandel 
2981a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work)
2982a73c046aSJaganath Kanakkassery {
2983a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance = container_of(work, struct adv_info,
2984a73c046aSJaganath Kanakkassery 						     rpa_expired_cb.work);
2985a73c046aSJaganath Kanakkassery 
2986a73c046aSJaganath Kanakkassery 	BT_DBG("");
2987a73c046aSJaganath Kanakkassery 
2988a73c046aSJaganath Kanakkassery 	adv_instance->rpa_expired = true;
2989a73c046aSJaganath Kanakkassery }
2990a73c046aSJaganath Kanakkassery 
2991d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2992d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
2993d2609b34SFlorian Grandel 			 u16 adv_data_len, u8 *adv_data,
2994d2609b34SFlorian Grandel 			 u16 scan_rsp_len, u8 *scan_rsp_data,
29959bf9f4b6SDaniel Winkler 			 u16 timeout, u16 duration, s8 tx_power,
29969bf9f4b6SDaniel Winkler 			 u32 min_interval, u32 max_interval)
2997d2609b34SFlorian Grandel {
2998d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2999d2609b34SFlorian Grandel 
3000d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
3001d2609b34SFlorian Grandel 	if (adv_instance) {
3002d2609b34SFlorian Grandel 		memset(adv_instance->adv_data, 0,
3003d2609b34SFlorian Grandel 		       sizeof(adv_instance->adv_data));
3004d2609b34SFlorian Grandel 		memset(adv_instance->scan_rsp_data, 0,
3005d2609b34SFlorian Grandel 		       sizeof(adv_instance->scan_rsp_data));
3006d2609b34SFlorian Grandel 	} else {
30071d0fac2cSLuiz Augusto von Dentz 		if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
300887597482SDaniel Winkler 		    instance < 1 || instance > hdev->le_num_of_adv_sets)
3009d2609b34SFlorian Grandel 			return -EOVERFLOW;
3010d2609b34SFlorian Grandel 
301139ecfad6SJohan Hedberg 		adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL);
3012d2609b34SFlorian Grandel 		if (!adv_instance)
3013d2609b34SFlorian Grandel 			return -ENOMEM;
3014d2609b34SFlorian Grandel 
3015fffd38bcSFlorian Grandel 		adv_instance->pending = true;
3016d2609b34SFlorian Grandel 		adv_instance->instance = instance;
3017d2609b34SFlorian Grandel 		list_add(&adv_instance->list, &hdev->adv_instances);
3018d2609b34SFlorian Grandel 		hdev->adv_instance_cnt++;
3019d2609b34SFlorian Grandel 	}
3020d2609b34SFlorian Grandel 
3021d2609b34SFlorian Grandel 	adv_instance->flags = flags;
3022d2609b34SFlorian Grandel 	adv_instance->adv_data_len = adv_data_len;
3023d2609b34SFlorian Grandel 	adv_instance->scan_rsp_len = scan_rsp_len;
30249bf9f4b6SDaniel Winkler 	adv_instance->min_interval = min_interval;
30259bf9f4b6SDaniel Winkler 	adv_instance->max_interval = max_interval;
30269bf9f4b6SDaniel Winkler 	adv_instance->tx_power = tx_power;
3027d2609b34SFlorian Grandel 
3028d2609b34SFlorian Grandel 	if (adv_data_len)
3029d2609b34SFlorian Grandel 		memcpy(adv_instance->adv_data, adv_data, adv_data_len);
3030d2609b34SFlorian Grandel 
3031d2609b34SFlorian Grandel 	if (scan_rsp_len)
3032d2609b34SFlorian Grandel 		memcpy(adv_instance->scan_rsp_data,
3033d2609b34SFlorian Grandel 		       scan_rsp_data, scan_rsp_len);
3034d2609b34SFlorian Grandel 
3035d2609b34SFlorian Grandel 	adv_instance->timeout = timeout;
30365d900e46SFlorian Grandel 	adv_instance->remaining_time = timeout;
3037d2609b34SFlorian Grandel 
3038d2609b34SFlorian Grandel 	if (duration == 0)
303910873f99SAlain Michaud 		adv_instance->duration = hdev->def_multi_adv_rotation_duration;
3040d2609b34SFlorian Grandel 	else
3041d2609b34SFlorian Grandel 		adv_instance->duration = duration;
3042d2609b34SFlorian Grandel 
3043a73c046aSJaganath Kanakkassery 	INIT_DELAYED_WORK(&adv_instance->rpa_expired_cb,
3044a73c046aSJaganath Kanakkassery 			  adv_instance_rpa_expired);
3045a73c046aSJaganath Kanakkassery 
3046d2609b34SFlorian Grandel 	BT_DBG("%s for %dMR", hdev->name, instance);
3047d2609b34SFlorian Grandel 
3048d2609b34SFlorian Grandel 	return 0;
3049d2609b34SFlorian Grandel }
3050d2609b34SFlorian Grandel 
3051e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */
305231aab5c2SDaniel Winkler int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,
305331aab5c2SDaniel Winkler 			      u16 adv_data_len, u8 *adv_data,
305431aab5c2SDaniel Winkler 			      u16 scan_rsp_len, u8 *scan_rsp_data)
305531aab5c2SDaniel Winkler {
305631aab5c2SDaniel Winkler 	struct adv_info *adv_instance;
305731aab5c2SDaniel Winkler 
305831aab5c2SDaniel Winkler 	adv_instance = hci_find_adv_instance(hdev, instance);
305931aab5c2SDaniel Winkler 
306031aab5c2SDaniel Winkler 	/* If advertisement doesn't exist, we can't modify its data */
306131aab5c2SDaniel Winkler 	if (!adv_instance)
306231aab5c2SDaniel Winkler 		return -ENOENT;
306331aab5c2SDaniel Winkler 
306431aab5c2SDaniel Winkler 	if (adv_data_len) {
306531aab5c2SDaniel Winkler 		memset(adv_instance->adv_data, 0,
306631aab5c2SDaniel Winkler 		       sizeof(adv_instance->adv_data));
306731aab5c2SDaniel Winkler 		memcpy(adv_instance->adv_data, adv_data, adv_data_len);
306831aab5c2SDaniel Winkler 		adv_instance->adv_data_len = adv_data_len;
306931aab5c2SDaniel Winkler 	}
307031aab5c2SDaniel Winkler 
307131aab5c2SDaniel Winkler 	if (scan_rsp_len) {
307231aab5c2SDaniel Winkler 		memset(adv_instance->scan_rsp_data, 0,
307331aab5c2SDaniel Winkler 		       sizeof(adv_instance->scan_rsp_data));
307431aab5c2SDaniel Winkler 		memcpy(adv_instance->scan_rsp_data,
307531aab5c2SDaniel Winkler 		       scan_rsp_data, scan_rsp_len);
307631aab5c2SDaniel Winkler 		adv_instance->scan_rsp_len = scan_rsp_len;
307731aab5c2SDaniel Winkler 	}
307831aab5c2SDaniel Winkler 
307931aab5c2SDaniel Winkler 	return 0;
308031aab5c2SDaniel Winkler }
308131aab5c2SDaniel Winkler 
308231aab5c2SDaniel Winkler /* This function requires the caller holds hdev->lock */
3083e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev)
3084e5e1e7fdSMiao-chen Chou {
3085b139553dSMiao-chen Chou 	struct adv_monitor *monitor;
3086b139553dSMiao-chen Chou 	int handle;
3087b139553dSMiao-chen Chou 
3088b139553dSMiao-chen Chou 	idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
308966bd095aSArchie Pusaka 		hci_free_adv_monitor(hdev, monitor);
3090b139553dSMiao-chen Chou 
3091e5e1e7fdSMiao-chen Chou 	idr_destroy(&hdev->adv_monitors_idr);
3092e5e1e7fdSMiao-chen Chou }
3093e5e1e7fdSMiao-chen Chou 
309466bd095aSArchie Pusaka /* Frees the monitor structure and do some bookkeepings.
309566bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
309666bd095aSArchie Pusaka  */
309766bd095aSArchie Pusaka void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
3098b139553dSMiao-chen Chou {
3099b139553dSMiao-chen Chou 	struct adv_pattern *pattern;
3100b139553dSMiao-chen Chou 	struct adv_pattern *tmp;
3101b139553dSMiao-chen Chou 
3102b139553dSMiao-chen Chou 	if (!monitor)
3103b139553dSMiao-chen Chou 		return;
3104b139553dSMiao-chen Chou 
310566bd095aSArchie Pusaka 	list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) {
310666bd095aSArchie Pusaka 		list_del(&pattern->list);
3107b139553dSMiao-chen Chou 		kfree(pattern);
310866bd095aSArchie Pusaka 	}
310966bd095aSArchie Pusaka 
311066bd095aSArchie Pusaka 	if (monitor->handle)
311166bd095aSArchie Pusaka 		idr_remove(&hdev->adv_monitors_idr, monitor->handle);
311266bd095aSArchie Pusaka 
311366bd095aSArchie Pusaka 	if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) {
311466bd095aSArchie Pusaka 		hdev->adv_monitors_cnt--;
311566bd095aSArchie Pusaka 		mgmt_adv_monitor_removed(hdev, monitor->handle);
311666bd095aSArchie Pusaka 	}
3117b139553dSMiao-chen Chou 
3118b139553dSMiao-chen Chou 	kfree(monitor);
3119b139553dSMiao-chen Chou }
3120b139553dSMiao-chen Chou 
3121a2a4dedfSArchie Pusaka int hci_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status)
3122a2a4dedfSArchie Pusaka {
3123a2a4dedfSArchie Pusaka 	return mgmt_add_adv_patterns_monitor_complete(hdev, status);
3124a2a4dedfSArchie Pusaka }
3125a2a4dedfSArchie Pusaka 
312666bd095aSArchie Pusaka int hci_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status)
312766bd095aSArchie Pusaka {
312866bd095aSArchie Pusaka 	return mgmt_remove_adv_monitor_complete(hdev, status);
312966bd095aSArchie Pusaka }
313066bd095aSArchie Pusaka 
3131a2a4dedfSArchie Pusaka /* Assigns handle to a monitor, and if offloading is supported and power is on,
3132a2a4dedfSArchie Pusaka  * also attempts to forward the request to the controller.
3133a2a4dedfSArchie Pusaka  * Returns true if request is forwarded (result is pending), false otherwise.
3134a2a4dedfSArchie Pusaka  * This function requires the caller holds hdev->lock.
3135a2a4dedfSArchie Pusaka  */
3136a2a4dedfSArchie Pusaka bool hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor,
3137a2a4dedfSArchie Pusaka 			 int *err)
3138b139553dSMiao-chen Chou {
3139b139553dSMiao-chen Chou 	int min, max, handle;
3140b139553dSMiao-chen Chou 
3141a2a4dedfSArchie Pusaka 	*err = 0;
3142a2a4dedfSArchie Pusaka 
3143a2a4dedfSArchie Pusaka 	if (!monitor) {
3144a2a4dedfSArchie Pusaka 		*err = -EINVAL;
3145a2a4dedfSArchie Pusaka 		return false;
3146a2a4dedfSArchie Pusaka 	}
3147b139553dSMiao-chen Chou 
3148b139553dSMiao-chen Chou 	min = HCI_MIN_ADV_MONITOR_HANDLE;
3149b139553dSMiao-chen Chou 	max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES;
3150b139553dSMiao-chen Chou 	handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max,
3151b139553dSMiao-chen Chou 			   GFP_KERNEL);
3152a2a4dedfSArchie Pusaka 	if (handle < 0) {
3153a2a4dedfSArchie Pusaka 		*err = handle;
3154a2a4dedfSArchie Pusaka 		return false;
3155a2a4dedfSArchie Pusaka 	}
3156b139553dSMiao-chen Chou 
3157b139553dSMiao-chen Chou 	monitor->handle = handle;
31588208f5a9SMiao-chen Chou 
3159a2a4dedfSArchie Pusaka 	if (!hdev_is_powered(hdev))
3160a2a4dedfSArchie Pusaka 		return false;
31618208f5a9SMiao-chen Chou 
3162a2a4dedfSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
3163a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE:
3164a2a4dedfSArchie Pusaka 		hci_update_background_scan(hdev);
3165a2a4dedfSArchie Pusaka 		bt_dev_dbg(hdev, "%s add monitor status %d", hdev->name, *err);
3166a2a4dedfSArchie Pusaka 		/* Message was not forwarded to controller - not an error */
3167a2a4dedfSArchie Pusaka 		return false;
3168a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
3169a2a4dedfSArchie Pusaka 		*err = msft_add_monitor_pattern(hdev, monitor);
3170a2a4dedfSArchie Pusaka 		bt_dev_dbg(hdev, "%s add monitor msft status %d", hdev->name,
3171a2a4dedfSArchie Pusaka 			   *err);
3172a2a4dedfSArchie Pusaka 		break;
3173a2a4dedfSArchie Pusaka 	}
3174a2a4dedfSArchie Pusaka 
3175a2a4dedfSArchie Pusaka 	return (*err == 0);
3176b139553dSMiao-chen Chou }
3177b139553dSMiao-chen Chou 
317866bd095aSArchie Pusaka /* Attempts to tell the controller and free the monitor. If somehow the
317966bd095aSArchie Pusaka  * controller doesn't have a corresponding handle, remove anyway.
318066bd095aSArchie Pusaka  * Returns true if request is forwarded (result is pending), false otherwise.
318166bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
318266bd095aSArchie Pusaka  */
318366bd095aSArchie Pusaka static bool hci_remove_adv_monitor(struct hci_dev *hdev,
318466bd095aSArchie Pusaka 				   struct adv_monitor *monitor,
318566bd095aSArchie Pusaka 				   u16 handle, int *err)
3186bd2fbc6cSMiao-chen Chou {
318766bd095aSArchie Pusaka 	*err = 0;
3188bd2fbc6cSMiao-chen Chou 
318966bd095aSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
319066bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */
319166bd095aSArchie Pusaka 		goto free_monitor;
319266bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
319366bd095aSArchie Pusaka 		*err = msft_remove_monitor(hdev, monitor, handle);
319466bd095aSArchie Pusaka 		break;
3195bd2fbc6cSMiao-chen Chou 	}
3196bd2fbc6cSMiao-chen Chou 
319766bd095aSArchie Pusaka 	/* In case no matching handle registered, just free the monitor */
319866bd095aSArchie Pusaka 	if (*err == -ENOENT)
319966bd095aSArchie Pusaka 		goto free_monitor;
3200bd2fbc6cSMiao-chen Chou 
320166bd095aSArchie Pusaka 	return (*err == 0);
3202bd2fbc6cSMiao-chen Chou 
320366bd095aSArchie Pusaka free_monitor:
320466bd095aSArchie Pusaka 	if (*err == -ENOENT)
320566bd095aSArchie Pusaka 		bt_dev_warn(hdev, "Removing monitor with no matching handle %d",
320666bd095aSArchie Pusaka 			    monitor->handle);
320766bd095aSArchie Pusaka 	hci_free_adv_monitor(hdev, monitor);
320866bd095aSArchie Pusaka 
320966bd095aSArchie Pusaka 	*err = 0;
321066bd095aSArchie Pusaka 	return false;
3211bd2fbc6cSMiao-chen Chou }
3212bd2fbc6cSMiao-chen Chou 
321366bd095aSArchie Pusaka /* Returns true if request is forwarded (result is pending), false otherwise.
321466bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
321566bd095aSArchie Pusaka  */
321666bd095aSArchie Pusaka bool hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle, int *err)
321766bd095aSArchie Pusaka {
321866bd095aSArchie Pusaka 	struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle);
321966bd095aSArchie Pusaka 	bool pending;
322066bd095aSArchie Pusaka 
322166bd095aSArchie Pusaka 	if (!monitor) {
322266bd095aSArchie Pusaka 		*err = -EINVAL;
322366bd095aSArchie Pusaka 		return false;
322466bd095aSArchie Pusaka 	}
322566bd095aSArchie Pusaka 
322666bd095aSArchie Pusaka 	pending = hci_remove_adv_monitor(hdev, monitor, handle, err);
322766bd095aSArchie Pusaka 	if (!*err && !pending)
32288208f5a9SMiao-chen Chou 		hci_update_background_scan(hdev);
32298208f5a9SMiao-chen Chou 
323066bd095aSArchie Pusaka 	bt_dev_dbg(hdev, "%s remove monitor handle %d, status %d, %spending",
323166bd095aSArchie Pusaka 		   hdev->name, handle, *err, pending ? "" : "not ");
323266bd095aSArchie Pusaka 
323366bd095aSArchie Pusaka 	return pending;
323466bd095aSArchie Pusaka }
323566bd095aSArchie Pusaka 
323666bd095aSArchie Pusaka /* Returns true if request is forwarded (result is pending), false otherwise.
323766bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
323866bd095aSArchie Pusaka  */
323966bd095aSArchie Pusaka bool hci_remove_all_adv_monitor(struct hci_dev *hdev, int *err)
324066bd095aSArchie Pusaka {
324166bd095aSArchie Pusaka 	struct adv_monitor *monitor;
324266bd095aSArchie Pusaka 	int idr_next_id = 0;
324366bd095aSArchie Pusaka 	bool pending = false;
324466bd095aSArchie Pusaka 	bool update = false;
324566bd095aSArchie Pusaka 
324666bd095aSArchie Pusaka 	*err = 0;
324766bd095aSArchie Pusaka 
324866bd095aSArchie Pusaka 	while (!*err && !pending) {
324966bd095aSArchie Pusaka 		monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id);
325066bd095aSArchie Pusaka 		if (!monitor)
325166bd095aSArchie Pusaka 			break;
325266bd095aSArchie Pusaka 
325366bd095aSArchie Pusaka 		pending = hci_remove_adv_monitor(hdev, monitor, 0, err);
325466bd095aSArchie Pusaka 
325566bd095aSArchie Pusaka 		if (!*err && !pending)
325666bd095aSArchie Pusaka 			update = true;
325766bd095aSArchie Pusaka 	}
325866bd095aSArchie Pusaka 
325966bd095aSArchie Pusaka 	if (update)
326066bd095aSArchie Pusaka 		hci_update_background_scan(hdev);
326166bd095aSArchie Pusaka 
326266bd095aSArchie Pusaka 	bt_dev_dbg(hdev, "%s remove all monitors status %d, %spending",
326366bd095aSArchie Pusaka 		   hdev->name, *err, pending ? "" : "not ");
326466bd095aSArchie Pusaka 
326566bd095aSArchie Pusaka 	return pending;
3266bd2fbc6cSMiao-chen Chou }
3267bd2fbc6cSMiao-chen Chou 
32688208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */
32698208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev)
32708208f5a9SMiao-chen Chou {
32718208f5a9SMiao-chen Chou 	return !idr_is_empty(&hdev->adv_monitors_idr);
32728208f5a9SMiao-chen Chou }
32738208f5a9SMiao-chen Chou 
3274a2a4dedfSArchie Pusaka int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev)
3275a2a4dedfSArchie Pusaka {
3276a2a4dedfSArchie Pusaka 	if (msft_monitor_supported(hdev))
3277a2a4dedfSArchie Pusaka 		return HCI_ADV_MONITOR_EXT_MSFT;
3278a2a4dedfSArchie Pusaka 
3279a2a4dedfSArchie Pusaka 	return HCI_ADV_MONITOR_EXT_NONE;
3280a2a4dedfSArchie Pusaka }
3281a2a4dedfSArchie Pusaka 
3282dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
3283b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
3284b2a66aadSAntti Julku {
3285b2a66aadSAntti Julku 	struct bdaddr_list *b;
3286b2a66aadSAntti Julku 
3287dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
3288b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3289b2a66aadSAntti Julku 			return b;
3290b9ee0a78SMarcel Holtmann 	}
3291b2a66aadSAntti Julku 
3292b2a66aadSAntti Julku 	return NULL;
3293b2a66aadSAntti Julku }
3294b2a66aadSAntti Julku 
3295b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
3296b950aa88SAnkit Navik 				struct list_head *bdaddr_list, bdaddr_t *bdaddr,
3297b950aa88SAnkit Navik 				u8 type)
3298b950aa88SAnkit Navik {
3299b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *b;
3300b950aa88SAnkit Navik 
3301b950aa88SAnkit Navik 	list_for_each_entry(b, bdaddr_list, list) {
3302b950aa88SAnkit Navik 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3303b950aa88SAnkit Navik 			return b;
3304b950aa88SAnkit Navik 	}
3305b950aa88SAnkit Navik 
3306b950aa88SAnkit Navik 	return NULL;
3307b950aa88SAnkit Navik }
3308b950aa88SAnkit Navik 
33098baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *
33108baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
33118baaa403SAbhishek Pandit-Subedi 				  bdaddr_t *bdaddr, u8 type)
33128baaa403SAbhishek Pandit-Subedi {
33138baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *b;
33148baaa403SAbhishek Pandit-Subedi 
33158baaa403SAbhishek Pandit-Subedi 	list_for_each_entry(b, bdaddr_list, list) {
33168baaa403SAbhishek Pandit-Subedi 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
33178baaa403SAbhishek Pandit-Subedi 			return b;
33188baaa403SAbhishek Pandit-Subedi 	}
33198baaa403SAbhishek Pandit-Subedi 
33208baaa403SAbhishek Pandit-Subedi 	return NULL;
33218baaa403SAbhishek Pandit-Subedi }
33228baaa403SAbhishek Pandit-Subedi 
3323dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
3324b2a66aadSAntti Julku {
33257eb7404fSGeliang Tang 	struct bdaddr_list *b, *n;
3326b2a66aadSAntti Julku 
33277eb7404fSGeliang Tang 	list_for_each_entry_safe(b, n, bdaddr_list, list) {
33287eb7404fSGeliang Tang 		list_del(&b->list);
3329b2a66aadSAntti Julku 		kfree(b);
3330b2a66aadSAntti Julku 	}
3331b2a66aadSAntti Julku }
3332b2a66aadSAntti Julku 
3333dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3334b2a66aadSAntti Julku {
3335b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3336b2a66aadSAntti Julku 
3337b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3338b2a66aadSAntti Julku 		return -EBADF;
3339b2a66aadSAntti Julku 
3340dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
33415e762444SAntti Julku 		return -EEXIST;
3342b2a66aadSAntti Julku 
334327f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
33445e762444SAntti Julku 	if (!entry)
33455e762444SAntti Julku 		return -ENOMEM;
3346b2a66aadSAntti Julku 
3347b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3348b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3349b2a66aadSAntti Julku 
3350dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
3351b2a66aadSAntti Julku 
33522a8357f2SJohan Hedberg 	return 0;
3353b2a66aadSAntti Julku }
3354b2a66aadSAntti Julku 
3355b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
3356b950aa88SAnkit Navik 					u8 type, u8 *peer_irk, u8 *local_irk)
3357b950aa88SAnkit Navik {
3358b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
3359b950aa88SAnkit Navik 
3360b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY))
3361b950aa88SAnkit Navik 		return -EBADF;
3362b950aa88SAnkit Navik 
3363b950aa88SAnkit Navik 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
3364b950aa88SAnkit Navik 		return -EEXIST;
3365b950aa88SAnkit Navik 
3366b950aa88SAnkit Navik 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
3367b950aa88SAnkit Navik 	if (!entry)
3368b950aa88SAnkit Navik 		return -ENOMEM;
3369b950aa88SAnkit Navik 
3370b950aa88SAnkit Navik 	bacpy(&entry->bdaddr, bdaddr);
3371b950aa88SAnkit Navik 	entry->bdaddr_type = type;
3372b950aa88SAnkit Navik 
3373b950aa88SAnkit Navik 	if (peer_irk)
3374b950aa88SAnkit Navik 		memcpy(entry->peer_irk, peer_irk, 16);
3375b950aa88SAnkit Navik 
3376b950aa88SAnkit Navik 	if (local_irk)
3377b950aa88SAnkit Navik 		memcpy(entry->local_irk, local_irk, 16);
3378b950aa88SAnkit Navik 
3379b950aa88SAnkit Navik 	list_add(&entry->list, list);
3380b950aa88SAnkit Navik 
3381b950aa88SAnkit Navik 	return 0;
3382b950aa88SAnkit Navik }
3383b950aa88SAnkit Navik 
33848baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
33858baaa403SAbhishek Pandit-Subedi 				   u8 type, u32 flags)
33868baaa403SAbhishek Pandit-Subedi {
33878baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
33888baaa403SAbhishek Pandit-Subedi 
33898baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY))
33908baaa403SAbhishek Pandit-Subedi 		return -EBADF;
33918baaa403SAbhishek Pandit-Subedi 
33928baaa403SAbhishek Pandit-Subedi 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
33938baaa403SAbhishek Pandit-Subedi 		return -EEXIST;
33948baaa403SAbhishek Pandit-Subedi 
33958baaa403SAbhishek Pandit-Subedi 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
33968baaa403SAbhishek Pandit-Subedi 	if (!entry)
33978baaa403SAbhishek Pandit-Subedi 		return -ENOMEM;
33988baaa403SAbhishek Pandit-Subedi 
33998baaa403SAbhishek Pandit-Subedi 	bacpy(&entry->bdaddr, bdaddr);
34008baaa403SAbhishek Pandit-Subedi 	entry->bdaddr_type = type;
34018baaa403SAbhishek Pandit-Subedi 	entry->current_flags = flags;
34028baaa403SAbhishek Pandit-Subedi 
34038baaa403SAbhishek Pandit-Subedi 	list_add(&entry->list, list);
34048baaa403SAbhishek Pandit-Subedi 
34058baaa403SAbhishek Pandit-Subedi 	return 0;
34068baaa403SAbhishek Pandit-Subedi }
34078baaa403SAbhishek Pandit-Subedi 
3408dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3409b2a66aadSAntti Julku {
3410b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3411b2a66aadSAntti Julku 
341235f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3413dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
341435f7498aSJohan Hedberg 		return 0;
341535f7498aSJohan Hedberg 	}
3416b2a66aadSAntti Julku 
3417dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
3418d2ab0ac1SMarcel Holtmann 	if (!entry)
3419d2ab0ac1SMarcel Holtmann 		return -ENOENT;
3420d2ab0ac1SMarcel Holtmann 
3421d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
3422d2ab0ac1SMarcel Holtmann 	kfree(entry);
3423d2ab0ac1SMarcel Holtmann 
3424d2ab0ac1SMarcel Holtmann 	return 0;
3425d2ab0ac1SMarcel Holtmann }
3426d2ab0ac1SMarcel Holtmann 
3427b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
3428b950aa88SAnkit Navik 							u8 type)
3429b950aa88SAnkit Navik {
3430b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
3431b950aa88SAnkit Navik 
3432b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3433b950aa88SAnkit Navik 		hci_bdaddr_list_clear(list);
3434b950aa88SAnkit Navik 		return 0;
3435b950aa88SAnkit Navik 	}
3436b950aa88SAnkit Navik 
3437b950aa88SAnkit Navik 	entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
3438b950aa88SAnkit Navik 	if (!entry)
3439b950aa88SAnkit Navik 		return -ENOENT;
3440b950aa88SAnkit Navik 
3441b950aa88SAnkit Navik 	list_del(&entry->list);
3442b950aa88SAnkit Navik 	kfree(entry);
3443b950aa88SAnkit Navik 
3444b950aa88SAnkit Navik 	return 0;
3445b950aa88SAnkit Navik }
3446b950aa88SAnkit Navik 
34478baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
34488baaa403SAbhishek Pandit-Subedi 				   u8 type)
34498baaa403SAbhishek Pandit-Subedi {
34508baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
34518baaa403SAbhishek Pandit-Subedi 
34528baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY)) {
34538baaa403SAbhishek Pandit-Subedi 		hci_bdaddr_list_clear(list);
34548baaa403SAbhishek Pandit-Subedi 		return 0;
34558baaa403SAbhishek Pandit-Subedi 	}
34568baaa403SAbhishek Pandit-Subedi 
34578baaa403SAbhishek Pandit-Subedi 	entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
34588baaa403SAbhishek Pandit-Subedi 	if (!entry)
34598baaa403SAbhishek Pandit-Subedi 		return -ENOENT;
34608baaa403SAbhishek Pandit-Subedi 
34618baaa403SAbhishek Pandit-Subedi 	list_del(&entry->list);
34628baaa403SAbhishek Pandit-Subedi 	kfree(entry);
34638baaa403SAbhishek Pandit-Subedi 
34648baaa403SAbhishek Pandit-Subedi 	return 0;
34658baaa403SAbhishek Pandit-Subedi }
34668baaa403SAbhishek Pandit-Subedi 
346715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
346815819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
346915819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
347015819a70SAndre Guedes {
347115819a70SAndre Guedes 	struct hci_conn_params *params;
347215819a70SAndre Guedes 
347315819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
347415819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
347515819a70SAndre Guedes 		    params->addr_type == addr_type) {
347615819a70SAndre Guedes 			return params;
347715819a70SAndre Guedes 		}
347815819a70SAndre Guedes 	}
347915819a70SAndre Guedes 
348015819a70SAndre Guedes 	return NULL;
348115819a70SAndre Guedes }
348215819a70SAndre Guedes 
348315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
3484501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
34854b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
348615819a70SAndre Guedes {
3487912b42efSJohan Hedberg 	struct hci_conn_params *param;
348815819a70SAndre Guedes 
34896540351eSMarcel Holtmann 	switch (addr_type) {
34906540351eSMarcel Holtmann 	case ADDR_LE_DEV_PUBLIC_RESOLVED:
34916540351eSMarcel Holtmann 		addr_type = ADDR_LE_DEV_PUBLIC;
34926540351eSMarcel Holtmann 		break;
34936540351eSMarcel Holtmann 	case ADDR_LE_DEV_RANDOM_RESOLVED:
34946540351eSMarcel Holtmann 		addr_type = ADDR_LE_DEV_RANDOM;
34956540351eSMarcel Holtmann 		break;
34966540351eSMarcel Holtmann 	}
34976540351eSMarcel Holtmann 
3498501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
3499912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
3500912b42efSJohan Hedberg 		    param->addr_type == addr_type)
3501912b42efSJohan Hedberg 			return param;
35024b10966fSMarcel Holtmann 	}
35034b10966fSMarcel Holtmann 
35044b10966fSMarcel Holtmann 	return NULL;
350515819a70SAndre Guedes }
350615819a70SAndre Guedes 
350715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
350851d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
350951d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
351015819a70SAndre Guedes {
351115819a70SAndre Guedes 	struct hci_conn_params *params;
351215819a70SAndre Guedes 
351315819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
3514cef952ceSAndre Guedes 	if (params)
351551d167c0SMarcel Holtmann 		return params;
351615819a70SAndre Guedes 
351715819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
351815819a70SAndre Guedes 	if (!params) {
35192064ee33SMarcel Holtmann 		bt_dev_err(hdev, "out of memory");
352051d167c0SMarcel Holtmann 		return NULL;
352115819a70SAndre Guedes 	}
352215819a70SAndre Guedes 
352315819a70SAndre Guedes 	bacpy(&params->addr, addr);
352415819a70SAndre Guedes 	params->addr_type = addr_type;
3525cef952ceSAndre Guedes 
3526cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
352793450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
3528cef952ceSAndre Guedes 
3529bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
3530bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
3531bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
3532bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
3533bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
3534bf5b3c8bSMarcel Holtmann 
3535bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
3536bf5b3c8bSMarcel Holtmann 
353751d167c0SMarcel Holtmann 	return params;
3538bf5b3c8bSMarcel Holtmann }
3539bf5b3c8bSMarcel Holtmann 
3540f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
3541f6c63249SJohan Hedberg {
3542f6c63249SJohan Hedberg 	if (params->conn) {
3543f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
3544f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
3545f6c63249SJohan Hedberg 	}
3546f6c63249SJohan Hedberg 
3547f6c63249SJohan Hedberg 	list_del(&params->action);
3548f6c63249SJohan Hedberg 	list_del(&params->list);
3549f6c63249SJohan Hedberg 	kfree(params);
3550f6c63249SJohan Hedberg }
3551f6c63249SJohan Hedberg 
355215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
355315819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
355415819a70SAndre Guedes {
355515819a70SAndre Guedes 	struct hci_conn_params *params;
355615819a70SAndre Guedes 
355715819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
355815819a70SAndre Guedes 	if (!params)
355915819a70SAndre Guedes 		return;
356015819a70SAndre Guedes 
3561f6c63249SJohan Hedberg 	hci_conn_params_free(params);
356215819a70SAndre Guedes 
356395305baaSJohan Hedberg 	hci_update_background_scan(hdev);
356495305baaSJohan Hedberg 
356515819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
356615819a70SAndre Guedes }
356715819a70SAndre Guedes 
356815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
356955af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
357015819a70SAndre Guedes {
357115819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
357215819a70SAndre Guedes 
357315819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
357455af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
357555af49a8SJohan Hedberg 			continue;
3576f75113a2SJakub Pawlowski 
357791641b79SZheng Yongjun 		/* If trying to establish one time connection to disabled
3578f75113a2SJakub Pawlowski 		 * device, leave the params, but mark them as just once.
3579f75113a2SJakub Pawlowski 		 */
3580f75113a2SJakub Pawlowski 		if (params->explicit_connect) {
3581f75113a2SJakub Pawlowski 			params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
3582f75113a2SJakub Pawlowski 			continue;
3583f75113a2SJakub Pawlowski 		}
3584f75113a2SJakub Pawlowski 
358515819a70SAndre Guedes 		list_del(&params->list);
358615819a70SAndre Guedes 		kfree(params);
358715819a70SAndre Guedes 	}
358815819a70SAndre Guedes 
358955af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
359055af49a8SJohan Hedberg }
359155af49a8SJohan Hedberg 
359255af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
3593030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev)
359415819a70SAndre Guedes {
359515819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
359615819a70SAndre Guedes 
3597f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
3598f6c63249SJohan Hedberg 		hci_conn_params_free(params);
359915819a70SAndre Guedes 
360015819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
360115819a70SAndre Guedes }
360215819a70SAndre Guedes 
3603a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
3604a1f4c318SJohan Hedberg  *
3605a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
3606a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
3607a1f4c318SJohan Hedberg  * the static random address.
3608a1f4c318SJohan Hedberg  *
3609a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
3610a1f4c318SJohan Hedberg  * public address to use the static random address instead.
361150b5b952SMarcel Holtmann  *
361250b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
361350b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
361450b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
3615a1f4c318SJohan Hedberg  */
3616a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3617a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
3618a1f4c318SJohan Hedberg {
3619b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
362050b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
3621d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
362250b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
3623a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
3624a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
3625a1f4c318SJohan Hedberg 	} else {
3626a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
3627a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
3628a1f4c318SJohan Hedberg 	}
3629a1f4c318SJohan Hedberg }
3630a1f4c318SJohan Hedberg 
36310e995280SAbhishek Pandit-Subedi static void hci_suspend_clear_tasks(struct hci_dev *hdev)
36320e995280SAbhishek Pandit-Subedi {
36330e995280SAbhishek Pandit-Subedi 	int i;
36340e995280SAbhishek Pandit-Subedi 
36350e995280SAbhishek Pandit-Subedi 	for (i = 0; i < __SUSPEND_NUM_TASKS; i++)
36360e995280SAbhishek Pandit-Subedi 		clear_bit(i, hdev->suspend_tasks);
36370e995280SAbhishek Pandit-Subedi 
36380e995280SAbhishek Pandit-Subedi 	wake_up(&hdev->suspend_wait_q);
36390e995280SAbhishek Pandit-Subedi }
36400e995280SAbhishek Pandit-Subedi 
36419952d90eSAbhishek Pandit-Subedi static int hci_suspend_wait_event(struct hci_dev *hdev)
36429952d90eSAbhishek Pandit-Subedi {
36439952d90eSAbhishek Pandit-Subedi #define WAKE_COND                                                              \
36449952d90eSAbhishek Pandit-Subedi 	(find_first_bit(hdev->suspend_tasks, __SUSPEND_NUM_TASKS) ==           \
36459952d90eSAbhishek Pandit-Subedi 	 __SUSPEND_NUM_TASKS)
36469952d90eSAbhishek Pandit-Subedi 
36479952d90eSAbhishek Pandit-Subedi 	int i;
36489952d90eSAbhishek Pandit-Subedi 	int ret = wait_event_timeout(hdev->suspend_wait_q,
36499952d90eSAbhishek Pandit-Subedi 				     WAKE_COND, SUSPEND_NOTIFIER_TIMEOUT);
36509952d90eSAbhishek Pandit-Subedi 
36519952d90eSAbhishek Pandit-Subedi 	if (ret == 0) {
3652a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Timed out waiting for suspend events");
36539952d90eSAbhishek Pandit-Subedi 		for (i = 0; i < __SUSPEND_NUM_TASKS; ++i) {
36549952d90eSAbhishek Pandit-Subedi 			if (test_bit(i, hdev->suspend_tasks))
3655a9ec8423SAbhishek Pandit-Subedi 				bt_dev_err(hdev, "Suspend timeout bit: %d", i);
36569952d90eSAbhishek Pandit-Subedi 			clear_bit(i, hdev->suspend_tasks);
36579952d90eSAbhishek Pandit-Subedi 		}
36589952d90eSAbhishek Pandit-Subedi 
36599952d90eSAbhishek Pandit-Subedi 		ret = -ETIMEDOUT;
36609952d90eSAbhishek Pandit-Subedi 	} else {
36619952d90eSAbhishek Pandit-Subedi 		ret = 0;
36629952d90eSAbhishek Pandit-Subedi 	}
36639952d90eSAbhishek Pandit-Subedi 
36649952d90eSAbhishek Pandit-Subedi 	return ret;
36659952d90eSAbhishek Pandit-Subedi }
36669952d90eSAbhishek Pandit-Subedi 
36679952d90eSAbhishek Pandit-Subedi static void hci_prepare_suspend(struct work_struct *work)
36689952d90eSAbhishek Pandit-Subedi {
36699952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
36709952d90eSAbhishek Pandit-Subedi 		container_of(work, struct hci_dev, suspend_prepare);
36719952d90eSAbhishek Pandit-Subedi 
36729952d90eSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
36739952d90eSAbhishek Pandit-Subedi 	hci_req_prepare_suspend(hdev, hdev->suspend_state_next);
36749952d90eSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
36759952d90eSAbhishek Pandit-Subedi }
36769952d90eSAbhishek Pandit-Subedi 
36778731840aSAbhishek Pandit-Subedi static int hci_change_suspend_state(struct hci_dev *hdev,
36788731840aSAbhishek Pandit-Subedi 				    enum suspended_state next)
36798731840aSAbhishek Pandit-Subedi {
36808731840aSAbhishek Pandit-Subedi 	hdev->suspend_state_next = next;
36818731840aSAbhishek Pandit-Subedi 	set_bit(SUSPEND_PREPARE_NOTIFIER, hdev->suspend_tasks);
36828731840aSAbhishek Pandit-Subedi 	queue_work(hdev->req_workqueue, &hdev->suspend_prepare);
36838731840aSAbhishek Pandit-Subedi 	return hci_suspend_wait_event(hdev);
36848731840aSAbhishek Pandit-Subedi }
36858731840aSAbhishek Pandit-Subedi 
36862f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev)
36872f20216cSAbhishek Pandit-Subedi {
36882f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
36892f20216cSAbhishek Pandit-Subedi 
36902f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = 0;
36912f20216cSAbhishek Pandit-Subedi 	bacpy(&hdev->wake_addr, BDADDR_ANY);
36922f20216cSAbhishek Pandit-Subedi 	hdev->wake_addr_type = 0;
36932f20216cSAbhishek Pandit-Subedi 
36942f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
36952f20216cSAbhishek Pandit-Subedi }
36962f20216cSAbhishek Pandit-Subedi 
36979952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
36989952d90eSAbhishek Pandit-Subedi 				void *data)
36999952d90eSAbhishek Pandit-Subedi {
37009952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
37019952d90eSAbhishek Pandit-Subedi 		container_of(nb, struct hci_dev, suspend_notifier);
37029952d90eSAbhishek Pandit-Subedi 	int ret = 0;
37032f20216cSAbhishek Pandit-Subedi 	u8 state = BT_RUNNING;
37049952d90eSAbhishek Pandit-Subedi 
37059952d90eSAbhishek Pandit-Subedi 	/* If powering down, wait for completion. */
37069952d90eSAbhishek Pandit-Subedi 	if (mgmt_powering_down(hdev)) {
37079952d90eSAbhishek Pandit-Subedi 		set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks);
37089952d90eSAbhishek Pandit-Subedi 		ret = hci_suspend_wait_event(hdev);
37099952d90eSAbhishek Pandit-Subedi 		if (ret)
37109952d90eSAbhishek Pandit-Subedi 			goto done;
37119952d90eSAbhishek Pandit-Subedi 	}
37129952d90eSAbhishek Pandit-Subedi 
37139952d90eSAbhishek Pandit-Subedi 	/* Suspend notifier should only act on events when powered. */
37145ff20cbeSVamshi K Sthambamkadi 	if (!hdev_is_powered(hdev) ||
37155ff20cbeSVamshi K Sthambamkadi 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
37169952d90eSAbhishek Pandit-Subedi 		goto done;
37179952d90eSAbhishek Pandit-Subedi 
37189952d90eSAbhishek Pandit-Subedi 	if (action == PM_SUSPEND_PREPARE) {
37194f40afc6SAbhishek Pandit-Subedi 		/* Suspend consists of two actions:
37204f40afc6SAbhishek Pandit-Subedi 		 *  - First, disconnect everything and make the controller not
37214f40afc6SAbhishek Pandit-Subedi 		 *    connectable (disabling scanning)
37223d4f9c00SArchie Pusaka 		 *  - Second, program event filter/accept list and enable scan
37234f40afc6SAbhishek Pandit-Subedi 		 */
37248731840aSAbhishek Pandit-Subedi 		ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT);
37252f20216cSAbhishek Pandit-Subedi 		if (!ret)
37262f20216cSAbhishek Pandit-Subedi 			state = BT_SUSPEND_DISCONNECT;
37274f40afc6SAbhishek Pandit-Subedi 
37283d4f9c00SArchie Pusaka 		/* Only configure accept list if disconnect succeeded and wake
372981dafad5SAbhishek Pandit-Subedi 		 * isn't being prevented.
373081dafad5SAbhishek Pandit-Subedi 		 */
37312f20216cSAbhishek Pandit-Subedi 		if (!ret && !(hdev->prevent_wake && hdev->prevent_wake(hdev))) {
37328731840aSAbhishek Pandit-Subedi 			ret = hci_change_suspend_state(hdev,
37330d2c9825SAbhishek Pandit-Subedi 						BT_SUSPEND_CONFIGURE_WAKE);
37342f20216cSAbhishek Pandit-Subedi 			if (!ret)
37352f20216cSAbhishek Pandit-Subedi 				state = BT_SUSPEND_CONFIGURE_WAKE;
37362f20216cSAbhishek Pandit-Subedi 		}
37372f20216cSAbhishek Pandit-Subedi 
37382f20216cSAbhishek Pandit-Subedi 		hci_clear_wake_reason(hdev);
37392f20216cSAbhishek Pandit-Subedi 		mgmt_suspending(hdev, state);
37402f20216cSAbhishek Pandit-Subedi 
37419952d90eSAbhishek Pandit-Subedi 	} else if (action == PM_POST_SUSPEND) {
37428731840aSAbhishek Pandit-Subedi 		ret = hci_change_suspend_state(hdev, BT_RUNNING);
37432f20216cSAbhishek Pandit-Subedi 
37442f20216cSAbhishek Pandit-Subedi 		mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
37452f20216cSAbhishek Pandit-Subedi 			      hdev->wake_addr_type);
37469952d90eSAbhishek Pandit-Subedi 	}
37479952d90eSAbhishek Pandit-Subedi 
37489952d90eSAbhishek Pandit-Subedi done:
3749a9ec8423SAbhishek Pandit-Subedi 	/* We always allow suspend even if suspend preparation failed and
3750a9ec8423SAbhishek Pandit-Subedi 	 * attempt to recover in resume.
3751a9ec8423SAbhishek Pandit-Subedi 	 */
3752a9ec8423SAbhishek Pandit-Subedi 	if (ret)
3753a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
3754a9ec8423SAbhishek Pandit-Subedi 			   action, ret);
3755a9ec8423SAbhishek Pandit-Subedi 
375624b06572SMax Chou 	return NOTIFY_DONE;
37579952d90eSAbhishek Pandit-Subedi }
37588731840aSAbhishek Pandit-Subedi 
37599be0dab7SDavid Herrmann /* Alloc HCI device */
37606ec56613STedd Ho-Jeong An struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
37619be0dab7SDavid Herrmann {
37629be0dab7SDavid Herrmann 	struct hci_dev *hdev;
37636ec56613STedd Ho-Jeong An 	unsigned int alloc_size;
37649be0dab7SDavid Herrmann 
37656ec56613STedd Ho-Jeong An 	alloc_size = sizeof(*hdev);
37666ec56613STedd Ho-Jeong An 	if (sizeof_priv) {
37676ec56613STedd Ho-Jeong An 		/* Fixme: May need ALIGN-ment? */
37686ec56613STedd Ho-Jeong An 		alloc_size += sizeof_priv;
37696ec56613STedd Ho-Jeong An 	}
37706ec56613STedd Ho-Jeong An 
37716ec56613STedd Ho-Jeong An 	hdev = kzalloc(alloc_size, GFP_KERNEL);
37729be0dab7SDavid Herrmann 	if (!hdev)
37739be0dab7SDavid Herrmann 		return NULL;
37749be0dab7SDavid Herrmann 
3775b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3776b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3777b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3778b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3779b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
378096c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
3781bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3782bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3783d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
3784d2609b34SFlorian Grandel 	hdev->cur_adv_instance = 0x00;
37855d900e46SFlorian Grandel 	hdev->adv_instance_timeout = 0;
3786b1b813d4SDavid Herrmann 
3787c4f1f408SHoward Chung 	hdev->advmon_allowlist_duration = 300;
3788c4f1f408SHoward Chung 	hdev->advmon_no_filter_duration = 500;
378980af16a3SHoward Chung 	hdev->enable_advmon_interleave_scan = 0x00;	/* Default to disable */
3790c4f1f408SHoward Chung 
3791b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3792b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3793b1b813d4SDavid Herrmann 
37943f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3795628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
3796628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
3797bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3798bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
379910873f99SAlain Michaud 	hdev->le_scan_int_suspend = 0x0400;
380010873f99SAlain Michaud 	hdev->le_scan_window_suspend = 0x0012;
380110873f99SAlain Michaud 	hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
380210873f99SAlain Michaud 	hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
3803ba29d036SMarcel Holtmann 	hdev->le_scan_int_adv_monitor = 0x0060;
3804ba29d036SMarcel Holtmann 	hdev->le_scan_window_adv_monitor = 0x0030;
380510873f99SAlain Michaud 	hdev->le_scan_int_connect = 0x0060;
380610873f99SAlain Michaud 	hdev->le_scan_window_connect = 0x0060;
3807b48c3b59SJonas Holmberg 	hdev->le_conn_min_interval = 0x0018;
3808b48c3b59SJonas Holmberg 	hdev->le_conn_max_interval = 0x0028;
380904fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
381004fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
3811a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
3812a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
3813a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
3814a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
3815a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
3816a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
381730d65e08SMatias Karhumaa 	hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
381830d65e08SMatias Karhumaa 	hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
38196decb5b4SJaganath Kanakkassery 	hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
38206decb5b4SJaganath Kanakkassery 	hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
38211d0fac2cSLuiz Augusto von Dentz 	hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
382210873f99SAlain Michaud 	hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
382349b020c1SAlain Michaud 	hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT;
38247c395ea5SDaniel Winkler 	hdev->min_le_tx_power = HCI_TX_POWER_INVALID;
38257c395ea5SDaniel Winkler 	hdev->max_le_tx_power = HCI_TX_POWER_INVALID;
3826bef64738SMarcel Holtmann 
3827d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3828b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
382931ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
383031ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
3831302975cbSSpoorthi Ravishankar Koppad 	hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
383258a96fc3SMarcel Holtmann 	hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
3833d6bfd59cSJohan Hedberg 
383410873f99SAlain Michaud 	/* default 1.28 sec page scan */
383510873f99SAlain Michaud 	hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
383610873f99SAlain Michaud 	hdev->def_page_scan_int = 0x0800;
383710873f99SAlain Michaud 	hdev->def_page_scan_window = 0x0012;
383810873f99SAlain Michaud 
3839b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3840b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3841b1b813d4SDavid Herrmann 
3842b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
38433d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->reject_list);
38443d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->accept_list);
3845b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3846b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3847b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3848970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3849b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
38503d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->le_accept_list);
3851cfdb0c2dSAnkit Navik 	INIT_LIST_HEAD(&hdev->le_resolv_list);
385215819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
385377a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
385466f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
38556b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3856d2609b34SFlorian Grandel 	INIT_LIST_HEAD(&hdev->adv_instances);
3857600a8749SAlain Michaud 	INIT_LIST_HEAD(&hdev->blocked_keys);
3858b1b813d4SDavid Herrmann 
3859b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3860b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3861b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3862b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3863c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
38649952d90eSAbhishek Pandit-Subedi 	INIT_WORK(&hdev->suspend_prepare, hci_prepare_suspend);
3865b1b813d4SDavid Herrmann 
3866b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3867b1b813d4SDavid Herrmann 
3868b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3869b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3870b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3871b1b813d4SDavid Herrmann 
3872b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
38739952d90eSAbhishek Pandit-Subedi 	init_waitqueue_head(&hdev->suspend_wait_q);
3874b1b813d4SDavid Herrmann 
387565cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
3876de75cd0dSManish Mandlik 	INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout);
3877b1b813d4SDavid Herrmann 
38785fc16cc4SJohan Hedberg 	hci_request_setup(hdev);
38795fc16cc4SJohan Hedberg 
3880b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3881b1b813d4SDavid Herrmann 	discovery_init(hdev);
38829be0dab7SDavid Herrmann 
38839be0dab7SDavid Herrmann 	return hdev;
38849be0dab7SDavid Herrmann }
38856ec56613STedd Ho-Jeong An EXPORT_SYMBOL(hci_alloc_dev_priv);
38869be0dab7SDavid Herrmann 
38879be0dab7SDavid Herrmann /* Free HCI device */
38889be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
38899be0dab7SDavid Herrmann {
38909be0dab7SDavid Herrmann 	/* will free via device release */
38919be0dab7SDavid Herrmann 	put_device(&hdev->dev);
38929be0dab7SDavid Herrmann }
38939be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
38949be0dab7SDavid Herrmann 
38951da177e4SLinus Torvalds /* Register HCI device */
38961da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
38971da177e4SLinus Torvalds {
3898b1b813d4SDavid Herrmann 	int id, error;
38991da177e4SLinus Torvalds 
390074292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
39011da177e4SLinus Torvalds 		return -EINVAL;
39021da177e4SLinus Torvalds 
390308add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
390408add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
390508add513SMat Martineau 	 */
39063df92b31SSasha Levin 	switch (hdev->dev_type) {
3907ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
39083df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
39091da177e4SLinus Torvalds 		break;
39103df92b31SSasha Levin 	case HCI_AMP:
39113df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
39123df92b31SSasha Levin 		break;
39133df92b31SSasha Levin 	default:
39143df92b31SSasha Levin 		return -EINVAL;
39151da177e4SLinus Torvalds 	}
39161da177e4SLinus Torvalds 
39173df92b31SSasha Levin 	if (id < 0)
39183df92b31SSasha Levin 		return id;
39193df92b31SSasha Levin 
39201da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
39211da177e4SLinus Torvalds 	hdev->id = id;
39222d8b3a11SAndrei Emeltchenko 
39232d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
39242d8b3a11SAndrei Emeltchenko 
392529e2dd0dSTejun Heo 	hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
392633ca954dSDavid Herrmann 	if (!hdev->workqueue) {
392733ca954dSDavid Herrmann 		error = -ENOMEM;
392833ca954dSDavid Herrmann 		goto err;
392933ca954dSDavid Herrmann 	}
3930f48fd9c8SMarcel Holtmann 
393129e2dd0dSTejun Heo 	hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
393229e2dd0dSTejun Heo 						      hdev->name);
39336ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
39346ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
39356ead1bbcSJohan Hedberg 		error = -ENOMEM;
39366ead1bbcSJohan Hedberg 		goto err;
39376ead1bbcSJohan Hedberg 	}
39386ead1bbcSJohan Hedberg 
39390153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
39400153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
39410153e2ecSMarcel Holtmann 
3942bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3943bdc3e0f1SMarcel Holtmann 
3944bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
394533ca954dSDavid Herrmann 	if (error < 0)
394654506918SJohan Hedberg 		goto err_wqueue;
39471da177e4SLinus Torvalds 
39486d5d2ee6SHeiner Kallweit 	hci_leds_init(hdev);
39496d5d2ee6SHeiner Kallweit 
3950611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3951a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3952a8c5fb1aSGustavo Padovan 				    hdev);
3953611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3954611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3955611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3956611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3957611b30f7SMarcel Holtmann 		}
3958611b30f7SMarcel Holtmann 	}
3959611b30f7SMarcel Holtmann 
39605e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
3961a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
39625e130367SJohan Hedberg 
3963a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
3964a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
3965ce2be9acSAndrei Emeltchenko 
3966ca8bee5dSMarcel Holtmann 	if (hdev->dev_type == HCI_PRIMARY) {
396756f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
396856f87901SJohan Hedberg 		 * through reading supported features during init.
396956f87901SJohan Hedberg 		 */
3970a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
397156f87901SJohan Hedberg 	}
3972ce2be9acSAndrei Emeltchenko 
3973fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3974fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3975fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3976fcee3377SGustavo Padovan 
39774a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
39784a964404SMarcel Holtmann 	 * and should not be included in normal operation.
3979fee746b0SMarcel Holtmann 	 */
3980fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
3981a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
3982fee746b0SMarcel Holtmann 
398305fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_REG);
3984dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
39851da177e4SLinus Torvalds 
3986219991e6SHans de Goede 	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
39879952d90eSAbhishek Pandit-Subedi 		hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
39889952d90eSAbhishek Pandit-Subedi 		error = register_pm_notifier(&hdev->suspend_notifier);
39899952d90eSAbhishek Pandit-Subedi 		if (error)
39909952d90eSAbhishek Pandit-Subedi 			goto err_wqueue;
3991219991e6SHans de Goede 	}
39929952d90eSAbhishek Pandit-Subedi 
399319202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3994fbe96d6fSMarcel Holtmann 
3995e5e1e7fdSMiao-chen Chou 	idr_init(&hdev->adv_monitors_idr);
3996e5e1e7fdSMiao-chen Chou 
39971da177e4SLinus Torvalds 	return id;
3998f48fd9c8SMarcel Holtmann 
399933ca954dSDavid Herrmann err_wqueue:
400033ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
40016ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
400233ca954dSDavid Herrmann err:
40033df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
4004f48fd9c8SMarcel Holtmann 
400533ca954dSDavid Herrmann 	return error;
40061da177e4SLinus Torvalds }
40071da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
40081da177e4SLinus Torvalds 
40091da177e4SLinus Torvalds /* Unregister HCI device */
401059735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
40111da177e4SLinus Torvalds {
4012c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
40131da177e4SLinus Torvalds 
4014a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
401594324962SJohan Hovold 
4016f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
40171da177e4SLinus Torvalds 	list_del(&hdev->list);
4018f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
40191da177e4SLinus Torvalds 
4020b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
4021b9b5ef18SGustavo Padovan 
4022219991e6SHans de Goede 	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
40230e995280SAbhishek Pandit-Subedi 		hci_suspend_clear_tasks(hdev);
40249952d90eSAbhishek Pandit-Subedi 		unregister_pm_notifier(&hdev->suspend_notifier);
40254e8c36c3SAbhishek Pandit-Subedi 		cancel_work_sync(&hdev->suspend_prepare);
4026219991e6SHans de Goede 	}
40274e8c36c3SAbhishek Pandit-Subedi 
40284e8c36c3SAbhishek Pandit-Subedi 	hci_dev_do_close(hdev);
40299952d90eSAbhishek Pandit-Subedi 
4030ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
4031d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
4032d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
403309fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
4034744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
403509fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
403656e5cb86SJohan Hedberg 	}
4037ab81cbf9SJohan Hedberg 
40382e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
40392e58ef3eSJohan Hedberg 	 * pending list */
40402e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
40412e58ef3eSJohan Hedberg 
404205fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_UNREG);
40431da177e4SLinus Torvalds 
4044611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
4045611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
4046611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
4047611b30f7SMarcel Holtmann 	}
4048611b30f7SMarcel Holtmann 
4049bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
405058ce6d5bSTetsuo Handa 	hci_dev_put(hdev);
405158ce6d5bSTetsuo Handa }
405258ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_unregister_dev);
4053147e2d59SDave Young 
405458ce6d5bSTetsuo Handa /* Release HCI device */
405558ce6d5bSTetsuo Handa void hci_release_dev(struct hci_dev *hdev)
405658ce6d5bSTetsuo Handa {
40570153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
40585177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
40595177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
40600153e2ecSMarcel Holtmann 
4061f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
40626ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
4063f48fd9c8SMarcel Holtmann 
406409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
40653d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->reject_list);
40663d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->accept_list);
40672aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
406855ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
4069b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
4070970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
40712763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
4072d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
4073e5e1e7fdSMiao-chen Chou 	hci_adv_monitors_clear(hdev);
40743d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
4075cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
4076373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
407722078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
4078600a8749SAlain Michaud 	hci_blocked_keys_clear(hdev);
407909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4080e2e0cacbSJohan Hedberg 
408158ce6d5bSTetsuo Handa 	ida_simple_remove(&hci_index_ida, hdev->id);
408258ce6d5bSTetsuo Handa 	kfree(hdev);
40831da177e4SLinus Torvalds }
408458ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_release_dev);
40851da177e4SLinus Torvalds 
40861da177e4SLinus Torvalds /* Suspend HCI device */
40871da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
40881da177e4SLinus Torvalds {
408905fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
40901da177e4SLinus Torvalds 	return 0;
40911da177e4SLinus Torvalds }
40921da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
40931da177e4SLinus Torvalds 
40941da177e4SLinus Torvalds /* Resume HCI device */
40951da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
40961da177e4SLinus Torvalds {
409705fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_RESUME);
40981da177e4SLinus Torvalds 	return 0;
40991da177e4SLinus Torvalds }
41001da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
41011da177e4SLinus Torvalds 
410275e0569fSMarcel Holtmann /* Reset HCI device */
410375e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
410475e0569fSMarcel Holtmann {
41051e4b6e91SColin Ian King 	static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
410675e0569fSMarcel Holtmann 	struct sk_buff *skb;
410775e0569fSMarcel Holtmann 
410875e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
410975e0569fSMarcel Holtmann 	if (!skb)
411075e0569fSMarcel Holtmann 		return -ENOMEM;
411175e0569fSMarcel Holtmann 
4112d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
411359ae1d12SJohannes Berg 	skb_put_data(skb, hw_err, 3);
411475e0569fSMarcel Holtmann 
4115de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Injecting HCI hardware error event");
4116de75cd0dSManish Mandlik 
411775e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
411875e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
411975e0569fSMarcel Holtmann }
412075e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
412175e0569fSMarcel Holtmann 
412276bca880SMarcel Holtmann /* Receive frame from HCI drivers */
4123e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
412476bca880SMarcel Holtmann {
412576bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
412676bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
412776bca880SMarcel Holtmann 		kfree_skb(skb);
412876bca880SMarcel Holtmann 		return -ENXIO;
412976bca880SMarcel Holtmann 	}
413076bca880SMarcel Holtmann 
4131d79f34e3SMarcel Holtmann 	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
4132d79f34e3SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
4133cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT &&
4134cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) {
4135fe806dceSMarcel Holtmann 		kfree_skb(skb);
4136fe806dceSMarcel Holtmann 		return -EINVAL;
4137fe806dceSMarcel Holtmann 	}
4138fe806dceSMarcel Holtmann 
4139d82603c6SJorrit Schippers 	/* Incoming skb */
414076bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
414176bca880SMarcel Holtmann 
414276bca880SMarcel Holtmann 	/* Time stamp */
414376bca880SMarcel Holtmann 	__net_timestamp(skb);
414476bca880SMarcel Holtmann 
414576bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
4146b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
4147c78ae283SMarcel Holtmann 
414876bca880SMarcel Holtmann 	return 0;
414976bca880SMarcel Holtmann }
415076bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
415176bca880SMarcel Holtmann 
4152e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
4153e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
4154e875ff84SMarcel Holtmann {
4155581d6fd6SMarcel Holtmann 	/* Mark as diagnostic packet */
4156d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
4157581d6fd6SMarcel Holtmann 
4158e875ff84SMarcel Holtmann 	/* Time stamp */
4159e875ff84SMarcel Holtmann 	__net_timestamp(skb);
4160e875ff84SMarcel Holtmann 
4161581d6fd6SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
4162581d6fd6SMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
4163e875ff84SMarcel Holtmann 
4164e875ff84SMarcel Holtmann 	return 0;
4165e875ff84SMarcel Holtmann }
4166e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
4167e875ff84SMarcel Holtmann 
41685177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
41695177a838SMarcel Holtmann {
41705177a838SMarcel Holtmann 	va_list vargs;
41715177a838SMarcel Holtmann 
41725177a838SMarcel Holtmann 	va_start(vargs, fmt);
41735177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
41745177a838SMarcel Holtmann 	hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
41755177a838SMarcel Holtmann 	va_end(vargs);
41765177a838SMarcel Holtmann }
41775177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
41785177a838SMarcel Holtmann 
41795177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
41805177a838SMarcel Holtmann {
41815177a838SMarcel Holtmann 	va_list vargs;
41825177a838SMarcel Holtmann 
41835177a838SMarcel Holtmann 	va_start(vargs, fmt);
41845177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
41855177a838SMarcel Holtmann 	hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
41865177a838SMarcel Holtmann 	va_end(vargs);
41875177a838SMarcel Holtmann }
41885177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
41895177a838SMarcel Holtmann 
41901da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
41911da177e4SLinus Torvalds 
41921da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
41931da177e4SLinus Torvalds {
41941da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
41951da177e4SLinus Torvalds 
4196fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
419700629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
4198fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
41991da177e4SLinus Torvalds 
42001da177e4SLinus Torvalds 	return 0;
42011da177e4SLinus Torvalds }
42021da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
42031da177e4SLinus Torvalds 
42041da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
42051da177e4SLinus Torvalds {
42061da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
42071da177e4SLinus Torvalds 
4208fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
42091da177e4SLinus Torvalds 	list_del(&cb->list);
4210fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
42111da177e4SLinus Torvalds 
42121da177e4SLinus Torvalds 	return 0;
42131da177e4SLinus Torvalds }
42141da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
42151da177e4SLinus Torvalds 
421651086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
42171da177e4SLinus Torvalds {
4218cdc52faaSMarcel Holtmann 	int err;
4219cdc52faaSMarcel Holtmann 
4220d79f34e3SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
4221d79f34e3SMarcel Holtmann 	       skb->len);
42221da177e4SLinus Torvalds 
42231da177e4SLinus Torvalds 	/* Time stamp */
4224a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
42251da177e4SLinus Torvalds 
4226cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
4227cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
4228cd82e61cSMarcel Holtmann 
4229cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
4230cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
4231470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
42321da177e4SLinus Torvalds 	}
42331da177e4SLinus Torvalds 
42341da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
42351da177e4SLinus Torvalds 	skb_orphan(skb);
42361da177e4SLinus Torvalds 
423773d0d3c8SMarcel Holtmann 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
423873d0d3c8SMarcel Holtmann 		kfree_skb(skb);
423973d0d3c8SMarcel Holtmann 		return;
424073d0d3c8SMarcel Holtmann 	}
424173d0d3c8SMarcel Holtmann 
4242cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
4243cdc52faaSMarcel Holtmann 	if (err < 0) {
42442064ee33SMarcel Holtmann 		bt_dev_err(hdev, "sending frame failed (%d)", err);
4245cdc52faaSMarcel Holtmann 		kfree_skb(skb);
4246cdc52faaSMarcel Holtmann 	}
42471da177e4SLinus Torvalds }
42481da177e4SLinus Torvalds 
42491ca3a9d0SJohan Hedberg /* Send HCI command */
425007dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
425107dc93ddSJohan Hedberg 		 const void *param)
42521ca3a9d0SJohan Hedberg {
42531ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
42541ca3a9d0SJohan Hedberg 
42551ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
42561ca3a9d0SJohan Hedberg 
42571ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
42581ca3a9d0SJohan Hedberg 	if (!skb) {
42592064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no memory for command");
42601ca3a9d0SJohan Hedberg 		return -ENOMEM;
42611ca3a9d0SJohan Hedberg 	}
42621ca3a9d0SJohan Hedberg 
426349c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
426411714b3dSJohan Hedberg 	 * single-command requests.
426511714b3dSJohan Hedberg 	 */
426644d27137SJohan Hedberg 	bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
426711714b3dSJohan Hedberg 
42681da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
4269c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
42701da177e4SLinus Torvalds 
42711da177e4SLinus Torvalds 	return 0;
42721da177e4SLinus Torvalds }
42731da177e4SLinus Torvalds 
4274d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
4275d6ee6ad7SLoic Poulain 		   const void *param)
4276d6ee6ad7SLoic Poulain {
4277d6ee6ad7SLoic Poulain 	struct sk_buff *skb;
4278d6ee6ad7SLoic Poulain 
4279d6ee6ad7SLoic Poulain 	if (hci_opcode_ogf(opcode) != 0x3f) {
4280d6ee6ad7SLoic Poulain 		/* A controller receiving a command shall respond with either
4281d6ee6ad7SLoic Poulain 		 * a Command Status Event or a Command Complete Event.
4282d6ee6ad7SLoic Poulain 		 * Therefore, all standard HCI commands must be sent via the
4283d6ee6ad7SLoic Poulain 		 * standard API, using hci_send_cmd or hci_cmd_sync helpers.
4284d6ee6ad7SLoic Poulain 		 * Some vendors do not comply with this rule for vendor-specific
4285d6ee6ad7SLoic Poulain 		 * commands and do not return any event. We want to support
4286d6ee6ad7SLoic Poulain 		 * unresponded commands for such cases only.
4287d6ee6ad7SLoic Poulain 		 */
4288d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "unresponded command not supported");
4289d6ee6ad7SLoic Poulain 		return -EINVAL;
4290d6ee6ad7SLoic Poulain 	}
4291d6ee6ad7SLoic Poulain 
4292d6ee6ad7SLoic Poulain 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
4293d6ee6ad7SLoic Poulain 	if (!skb) {
4294d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
4295d6ee6ad7SLoic Poulain 			   opcode);
4296d6ee6ad7SLoic Poulain 		return -ENOMEM;
4297d6ee6ad7SLoic Poulain 	}
4298d6ee6ad7SLoic Poulain 
4299d6ee6ad7SLoic Poulain 	hci_send_frame(hdev, skb);
4300d6ee6ad7SLoic Poulain 
4301d6ee6ad7SLoic Poulain 	return 0;
4302d6ee6ad7SLoic Poulain }
4303d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
4304d6ee6ad7SLoic Poulain 
43051da177e4SLinus Torvalds /* Get data from the previously sent command */
4306a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
43071da177e4SLinus Torvalds {
43081da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
43091da177e4SLinus Torvalds 
43101da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
43111da177e4SLinus Torvalds 		return NULL;
43121da177e4SLinus Torvalds 
43131da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
43141da177e4SLinus Torvalds 
4315a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
43161da177e4SLinus Torvalds 		return NULL;
43171da177e4SLinus Torvalds 
4318f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
43191da177e4SLinus Torvalds 
43201da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
43211da177e4SLinus Torvalds }
43221da177e4SLinus Torvalds 
432391641b79SZheng Yongjun /* Send HCI command and wait for command complete event */
4324fbef168fSLoic Poulain struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
4325fbef168fSLoic Poulain 			     const void *param, u32 timeout)
4326fbef168fSLoic Poulain {
4327fbef168fSLoic Poulain 	struct sk_buff *skb;
4328fbef168fSLoic Poulain 
4329fbef168fSLoic Poulain 	if (!test_bit(HCI_UP, &hdev->flags))
4330fbef168fSLoic Poulain 		return ERR_PTR(-ENETDOWN);
4331fbef168fSLoic Poulain 
4332fbef168fSLoic Poulain 	bt_dev_dbg(hdev, "opcode 0x%4.4x plen %d", opcode, plen);
4333fbef168fSLoic Poulain 
4334b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
4335fbef168fSLoic Poulain 	skb = __hci_cmd_sync(hdev, opcode, plen, param, timeout);
4336b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
4337fbef168fSLoic Poulain 
4338fbef168fSLoic Poulain 	return skb;
4339fbef168fSLoic Poulain }
4340fbef168fSLoic Poulain EXPORT_SYMBOL(hci_cmd_sync);
4341fbef168fSLoic Poulain 
43421da177e4SLinus Torvalds /* Send ACL data */
43431da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
43441da177e4SLinus Torvalds {
43451da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
43461da177e4SLinus Torvalds 	int len = skb->len;
43471da177e4SLinus Torvalds 
4348badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
4349badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
43509c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
4351aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
4352aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
43531da177e4SLinus Torvalds }
43541da177e4SLinus Torvalds 
4355ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
435673d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
43571da177e4SLinus Torvalds {
4358ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
43591da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
43601da177e4SLinus Torvalds 	struct sk_buff *list;
43611da177e4SLinus Torvalds 
4362087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
4363087bfd99SGustavo Padovan 	skb->data_len = 0;
4364087bfd99SGustavo Padovan 
4365d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
4366204a6e54SAndrei Emeltchenko 
4367204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
4368ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
4369087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
4370204a6e54SAndrei Emeltchenko 		break;
4371204a6e54SAndrei Emeltchenko 	case HCI_AMP:
4372204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
4373204a6e54SAndrei Emeltchenko 		break;
4374204a6e54SAndrei Emeltchenko 	default:
43752064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
4376204a6e54SAndrei Emeltchenko 		return;
4377204a6e54SAndrei Emeltchenko 	}
4378087bfd99SGustavo Padovan 
437970f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
438070f23020SAndrei Emeltchenko 	if (!list) {
43811da177e4SLinus Torvalds 		/* Non fragmented */
43821da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
43831da177e4SLinus Torvalds 
438473d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
43851da177e4SLinus Torvalds 	} else {
43861da177e4SLinus Torvalds 		/* Fragmented */
43871da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
43881da177e4SLinus Torvalds 
43891da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
43901da177e4SLinus Torvalds 
43919cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
43929cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
43939cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
43949cfd5a23SJukka Rissanen 		 * deadlocks.
43959cfd5a23SJukka Rissanen 		 */
43969cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
43971da177e4SLinus Torvalds 
439873d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
4399e702112fSAndrei Emeltchenko 
4400e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
4401e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
44021da177e4SLinus Torvalds 		do {
44031da177e4SLinus Torvalds 			skb = list; list = list->next;
44041da177e4SLinus Torvalds 
4405d79f34e3SMarcel Holtmann 			hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
4406e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
44071da177e4SLinus Torvalds 
44081da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
44091da177e4SLinus Torvalds 
441073d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
44111da177e4SLinus Torvalds 		} while (list);
44121da177e4SLinus Torvalds 
44139cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
44141da177e4SLinus Torvalds 	}
441573d80debSLuiz Augusto von Dentz }
441673d80debSLuiz Augusto von Dentz 
441773d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
441873d80debSLuiz Augusto von Dentz {
4419ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
442073d80debSLuiz Augusto von Dentz 
4421f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
442273d80debSLuiz Augusto von Dentz 
4423ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
44241da177e4SLinus Torvalds 
44253eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
44261da177e4SLinus Torvalds }
44271da177e4SLinus Torvalds 
44281da177e4SLinus Torvalds /* Send SCO data */
44290d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
44301da177e4SLinus Torvalds {
44311da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
44321da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
44331da177e4SLinus Torvalds 
44341da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
44351da177e4SLinus Torvalds 
4436aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
44371da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
44381da177e4SLinus Torvalds 
4439badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
4440badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
44419c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
44421da177e4SLinus Torvalds 
4443d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
4444c78ae283SMarcel Holtmann 
44451da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
44463eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
44471da177e4SLinus Torvalds }
44481da177e4SLinus Torvalds 
44491da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
44501da177e4SLinus Torvalds 
44511da177e4SLinus Torvalds /* HCI Connection scheduler */
44526039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
4453a8c5fb1aSGustavo Padovan 				     int *quote)
44541da177e4SLinus Torvalds {
44551da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
44568035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
4457abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
44581da177e4SLinus Torvalds 
44591da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
44601da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
4461bf4c6325SGustavo F. Padovan 
4462bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4463bf4c6325SGustavo F. Padovan 
4464bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4465769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
44661da177e4SLinus Torvalds 			continue;
4467769be974SMarcel Holtmann 
4468769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
4469769be974SMarcel Holtmann 			continue;
4470769be974SMarcel Holtmann 
44711da177e4SLinus Torvalds 		num++;
44721da177e4SLinus Torvalds 
44731da177e4SLinus Torvalds 		if (c->sent < min) {
44741da177e4SLinus Torvalds 			min  = c->sent;
44751da177e4SLinus Torvalds 			conn = c;
44761da177e4SLinus Torvalds 		}
447752087a79SLuiz Augusto von Dentz 
447852087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
447952087a79SLuiz Augusto von Dentz 			break;
44801da177e4SLinus Torvalds 	}
44811da177e4SLinus Torvalds 
4482bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4483bf4c6325SGustavo F. Padovan 
44841da177e4SLinus Torvalds 	if (conn) {
44856ed58ec5SVille Tervo 		int cnt, q;
44866ed58ec5SVille Tervo 
44876ed58ec5SVille Tervo 		switch (conn->type) {
44886ed58ec5SVille Tervo 		case ACL_LINK:
44896ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
44906ed58ec5SVille Tervo 			break;
44916ed58ec5SVille Tervo 		case SCO_LINK:
44926ed58ec5SVille Tervo 		case ESCO_LINK:
44936ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
44946ed58ec5SVille Tervo 			break;
44956ed58ec5SVille Tervo 		case LE_LINK:
44966ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
44976ed58ec5SVille Tervo 			break;
44986ed58ec5SVille Tervo 		default:
44996ed58ec5SVille Tervo 			cnt = 0;
45002064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown link type %d", conn->type);
45016ed58ec5SVille Tervo 		}
45026ed58ec5SVille Tervo 
45036ed58ec5SVille Tervo 		q = cnt / num;
45041da177e4SLinus Torvalds 		*quote = q ? q : 1;
45051da177e4SLinus Torvalds 	} else
45061da177e4SLinus Torvalds 		*quote = 0;
45071da177e4SLinus Torvalds 
45081da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
45091da177e4SLinus Torvalds 	return conn;
45101da177e4SLinus Torvalds }
45111da177e4SLinus Torvalds 
45126039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
45131da177e4SLinus Torvalds {
45141da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
45151da177e4SLinus Torvalds 	struct hci_conn *c;
45161da177e4SLinus Torvalds 
45172064ee33SMarcel Holtmann 	bt_dev_err(hdev, "link tx timeout");
45181da177e4SLinus Torvalds 
4519bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4520bf4c6325SGustavo F. Padovan 
45211da177e4SLinus Torvalds 	/* Kill stalled connections */
4522bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4523bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
45242064ee33SMarcel Holtmann 			bt_dev_err(hdev, "killing stalled connection %pMR",
45252064ee33SMarcel Holtmann 				   &c->dst);
4526bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
45271da177e4SLinus Torvalds 		}
45281da177e4SLinus Torvalds 	}
4529bf4c6325SGustavo F. Padovan 
4530bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
45311da177e4SLinus Torvalds }
45321da177e4SLinus Torvalds 
45336039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
453473d80debSLuiz Augusto von Dentz 				      int *quote)
453573d80debSLuiz Augusto von Dentz {
453673d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
453773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4538abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
453973d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
454073d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
454173d80debSLuiz Augusto von Dentz 
454273d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
454373d80debSLuiz Augusto von Dentz 
4544bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4545bf4c6325SGustavo F. Padovan 
4546bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
454773d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
454873d80debSLuiz Augusto von Dentz 
454973d80debSLuiz Augusto von Dentz 		if (conn->type != type)
455073d80debSLuiz Augusto von Dentz 			continue;
455173d80debSLuiz Augusto von Dentz 
455273d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
455373d80debSLuiz Augusto von Dentz 			continue;
455473d80debSLuiz Augusto von Dentz 
455573d80debSLuiz Augusto von Dentz 		conn_num++;
455673d80debSLuiz Augusto von Dentz 
45578192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
455873d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
455973d80debSLuiz Augusto von Dentz 
456073d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
456173d80debSLuiz Augusto von Dentz 				continue;
456273d80debSLuiz Augusto von Dentz 
456373d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
456473d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
456573d80debSLuiz Augusto von Dentz 				continue;
456673d80debSLuiz Augusto von Dentz 
456773d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
456873d80debSLuiz Augusto von Dentz 				num = 0;
456973d80debSLuiz Augusto von Dentz 				min = ~0;
457073d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
457173d80debSLuiz Augusto von Dentz 			}
457273d80debSLuiz Augusto von Dentz 
457373d80debSLuiz Augusto von Dentz 			num++;
457473d80debSLuiz Augusto von Dentz 
457573d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
457673d80debSLuiz Augusto von Dentz 				min  = conn->sent;
457773d80debSLuiz Augusto von Dentz 				chan = tmp;
457873d80debSLuiz Augusto von Dentz 			}
457973d80debSLuiz Augusto von Dentz 		}
458073d80debSLuiz Augusto von Dentz 
458173d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
458273d80debSLuiz Augusto von Dentz 			break;
458373d80debSLuiz Augusto von Dentz 	}
458473d80debSLuiz Augusto von Dentz 
4585bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4586bf4c6325SGustavo F. Padovan 
458773d80debSLuiz Augusto von Dentz 	if (!chan)
458873d80debSLuiz Augusto von Dentz 		return NULL;
458973d80debSLuiz Augusto von Dentz 
459073d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
459173d80debSLuiz Augusto von Dentz 	case ACL_LINK:
459273d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
459373d80debSLuiz Augusto von Dentz 		break;
4594bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4595bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4596bd1eb66bSAndrei Emeltchenko 		break;
459773d80debSLuiz Augusto von Dentz 	case SCO_LINK:
459873d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
459973d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
460073d80debSLuiz Augusto von Dentz 		break;
460173d80debSLuiz Augusto von Dentz 	case LE_LINK:
460273d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
460373d80debSLuiz Augusto von Dentz 		break;
460473d80debSLuiz Augusto von Dentz 	default:
460573d80debSLuiz Augusto von Dentz 		cnt = 0;
46062064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown link type %d", chan->conn->type);
460773d80debSLuiz Augusto von Dentz 	}
460873d80debSLuiz Augusto von Dentz 
460973d80debSLuiz Augusto von Dentz 	q = cnt / num;
461073d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
461173d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
461273d80debSLuiz Augusto von Dentz 	return chan;
461373d80debSLuiz Augusto von Dentz }
461473d80debSLuiz Augusto von Dentz 
461502b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
461602b20f0bSLuiz Augusto von Dentz {
461702b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
461802b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
461902b20f0bSLuiz Augusto von Dentz 	int num = 0;
462002b20f0bSLuiz Augusto von Dentz 
462102b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
462202b20f0bSLuiz Augusto von Dentz 
4623bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4624bf4c6325SGustavo F. Padovan 
4625bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
462602b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
462702b20f0bSLuiz Augusto von Dentz 
462802b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
462902b20f0bSLuiz Augusto von Dentz 			continue;
463002b20f0bSLuiz Augusto von Dentz 
463102b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
463202b20f0bSLuiz Augusto von Dentz 			continue;
463302b20f0bSLuiz Augusto von Dentz 
463402b20f0bSLuiz Augusto von Dentz 		num++;
463502b20f0bSLuiz Augusto von Dentz 
46368192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
463702b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
463802b20f0bSLuiz Augusto von Dentz 
463902b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
464002b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
464102b20f0bSLuiz Augusto von Dentz 				continue;
464202b20f0bSLuiz Augusto von Dentz 			}
464302b20f0bSLuiz Augusto von Dentz 
464402b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
464502b20f0bSLuiz Augusto von Dentz 				continue;
464602b20f0bSLuiz Augusto von Dentz 
464702b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
464802b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
464902b20f0bSLuiz Augusto von Dentz 				continue;
465002b20f0bSLuiz Augusto von Dentz 
465102b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
465202b20f0bSLuiz Augusto von Dentz 
465302b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
465402b20f0bSLuiz Augusto von Dentz 			       skb->priority);
465502b20f0bSLuiz Augusto von Dentz 		}
465602b20f0bSLuiz Augusto von Dentz 
465702b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
465802b20f0bSLuiz Augusto von Dentz 			break;
465902b20f0bSLuiz Augusto von Dentz 	}
4660bf4c6325SGustavo F. Padovan 
4661bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4662bf4c6325SGustavo F. Padovan 
466302b20f0bSLuiz Augusto von Dentz }
466402b20f0bSLuiz Augusto von Dentz 
4665b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4666b71d385aSAndrei Emeltchenko {
4667b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4668b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4669b71d385aSAndrei Emeltchenko }
4670b71d385aSAndrei Emeltchenko 
46716039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
46721da177e4SLinus Torvalds {
4673d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
46741da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
46751da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
467663d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
46775f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4678bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
46791da177e4SLinus Torvalds 	}
468063d2bc1bSAndrei Emeltchenko }
46811da177e4SLinus Torvalds 
46827fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
46837fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
46847fedd3bbSAbhishek Pandit-Subedi {
46857fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
46867fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
46877fedd3bbSAbhishek Pandit-Subedi 	int quote;
46887fedd3bbSAbhishek Pandit-Subedi 
46897fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
46907fedd3bbSAbhishek Pandit-Subedi 
46917fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, SCO_LINK))
46927fedd3bbSAbhishek Pandit-Subedi 		return;
46937fedd3bbSAbhishek Pandit-Subedi 
46947fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
46957fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
46967fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
46977fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
46987fedd3bbSAbhishek Pandit-Subedi 
46997fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
47007fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
47017fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
47027fedd3bbSAbhishek Pandit-Subedi 		}
47037fedd3bbSAbhishek Pandit-Subedi 	}
47047fedd3bbSAbhishek Pandit-Subedi }
47057fedd3bbSAbhishek Pandit-Subedi 
47067fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
47077fedd3bbSAbhishek Pandit-Subedi {
47087fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
47097fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
47107fedd3bbSAbhishek Pandit-Subedi 	int quote;
47117fedd3bbSAbhishek Pandit-Subedi 
47127fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
47137fedd3bbSAbhishek Pandit-Subedi 
47147fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, ESCO_LINK))
47157fedd3bbSAbhishek Pandit-Subedi 		return;
47167fedd3bbSAbhishek Pandit-Subedi 
47177fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
47187fedd3bbSAbhishek Pandit-Subedi 						     &quote))) {
47197fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
47207fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
47217fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
47227fedd3bbSAbhishek Pandit-Subedi 
47237fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
47247fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
47257fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
47267fedd3bbSAbhishek Pandit-Subedi 		}
47277fedd3bbSAbhishek Pandit-Subedi 	}
47287fedd3bbSAbhishek Pandit-Subedi }
47297fedd3bbSAbhishek Pandit-Subedi 
47306039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
473163d2bc1bSAndrei Emeltchenko {
473263d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
473363d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
473463d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
473563d2bc1bSAndrei Emeltchenko 	int quote;
473663d2bc1bSAndrei Emeltchenko 
473763d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
473804837f64SMarcel Holtmann 
473973d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
474073d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4741ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4742ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
474373d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
474473d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
474573d80debSLuiz Augusto von Dentz 
4746ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4747ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4748ec1cce24SLuiz Augusto von Dentz 				break;
4749ec1cce24SLuiz Augusto von Dentz 
4750ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4751ec1cce24SLuiz Augusto von Dentz 
475273d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
475373d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
475404837f64SMarcel Holtmann 
475557d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
47561da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
47571da177e4SLinus Torvalds 
47581da177e4SLinus Torvalds 			hdev->acl_cnt--;
475973d80debSLuiz Augusto von Dentz 			chan->sent++;
476073d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
47617fedd3bbSAbhishek Pandit-Subedi 
47627fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
47637fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
47647fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
47651da177e4SLinus Torvalds 		}
47661da177e4SLinus Torvalds 	}
476702b20f0bSLuiz Augusto von Dentz 
476802b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
476902b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
47701da177e4SLinus Torvalds }
47711da177e4SLinus Torvalds 
47726039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4773b71d385aSAndrei Emeltchenko {
477463d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4775b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4776b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4777b71d385aSAndrei Emeltchenko 	int quote;
4778bd1eb66bSAndrei Emeltchenko 	u8 type;
4779b71d385aSAndrei Emeltchenko 
478063d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
4781b71d385aSAndrei Emeltchenko 
4782bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4783bd1eb66bSAndrei Emeltchenko 
4784bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
4785bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
4786bd1eb66bSAndrei Emeltchenko 	else
4787bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
4788bd1eb66bSAndrei Emeltchenko 
4789b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
4790bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
4791b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
4792b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
4793b71d385aSAndrei Emeltchenko 			int blocks;
4794b71d385aSAndrei Emeltchenko 
4795b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
4796b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
4797b71d385aSAndrei Emeltchenko 
4798b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
4799b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
4800b71d385aSAndrei Emeltchenko 				break;
4801b71d385aSAndrei Emeltchenko 
4802b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
4803b71d385aSAndrei Emeltchenko 
4804b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
4805b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
4806b71d385aSAndrei Emeltchenko 				return;
4807b71d385aSAndrei Emeltchenko 
4808b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
4809b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
4810b71d385aSAndrei Emeltchenko 
481157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4812b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4813b71d385aSAndrei Emeltchenko 
4814b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4815b71d385aSAndrei Emeltchenko 			quote -= blocks;
4816b71d385aSAndrei Emeltchenko 
4817b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4818b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4819b71d385aSAndrei Emeltchenko 		}
4820b71d385aSAndrei Emeltchenko 	}
4821b71d385aSAndrei Emeltchenko 
4822b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4823bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4824b71d385aSAndrei Emeltchenko }
4825b71d385aSAndrei Emeltchenko 
48266039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4827b71d385aSAndrei Emeltchenko {
4828b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4829b71d385aSAndrei Emeltchenko 
4830bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4831ca8bee5dSMarcel Holtmann 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY)
4832bd1eb66bSAndrei Emeltchenko 		return;
4833bd1eb66bSAndrei Emeltchenko 
4834bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4835bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4836b71d385aSAndrei Emeltchenko 		return;
4837b71d385aSAndrei Emeltchenko 
4838b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4839b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4840b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4841b71d385aSAndrei Emeltchenko 		break;
4842b71d385aSAndrei Emeltchenko 
4843b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4844b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4845b71d385aSAndrei Emeltchenko 		break;
4846b71d385aSAndrei Emeltchenko 	}
4847b71d385aSAndrei Emeltchenko }
4848b71d385aSAndrei Emeltchenko 
48496039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
48506ed58ec5SVille Tervo {
485173d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
48526ed58ec5SVille Tervo 	struct sk_buff *skb;
485302b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
48546ed58ec5SVille Tervo 
48556ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
48566ed58ec5SVille Tervo 
485752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
485852087a79SLuiz Augusto von Dentz 		return;
485952087a79SLuiz Augusto von Dentz 
48606ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
48611b1d29e5SLuiz Augusto von Dentz 
48621b1d29e5SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt);
48631b1d29e5SLuiz Augusto von Dentz 
486402b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
486573d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4866ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4867ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
486873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
486973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
48706ed58ec5SVille Tervo 
4871ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4872ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4873ec1cce24SLuiz Augusto von Dentz 				break;
4874ec1cce24SLuiz Augusto von Dentz 
4875ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4876ec1cce24SLuiz Augusto von Dentz 
487757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
48786ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
48796ed58ec5SVille Tervo 
48806ed58ec5SVille Tervo 			cnt--;
488173d80debSLuiz Augusto von Dentz 			chan->sent++;
488273d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
48837fedd3bbSAbhishek Pandit-Subedi 
48847fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
48857fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
48867fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
48876ed58ec5SVille Tervo 		}
48886ed58ec5SVille Tervo 	}
488973d80debSLuiz Augusto von Dentz 
48906ed58ec5SVille Tervo 	if (hdev->le_pkts)
48916ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
48926ed58ec5SVille Tervo 	else
48936ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
489402b20f0bSLuiz Augusto von Dentz 
489502b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
489602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
48976ed58ec5SVille Tervo }
48986ed58ec5SVille Tervo 
48993eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
49001da177e4SLinus Torvalds {
49013eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
49021da177e4SLinus Torvalds 	struct sk_buff *skb;
49031da177e4SLinus Torvalds 
49046ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
49056ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
49061da177e4SLinus Torvalds 
4907d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
49081da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
49091da177e4SLinus Torvalds 		hci_sched_sco(hdev);
4910b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
49117fedd3bbSAbhishek Pandit-Subedi 		hci_sched_acl(hdev);
49126ed58ec5SVille Tervo 		hci_sched_le(hdev);
491352de599eSMarcel Holtmann 	}
49146ed58ec5SVille Tervo 
49151da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
49161da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
491757d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
49181da177e4SLinus Torvalds }
49191da177e4SLinus Torvalds 
492025985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
49211da177e4SLinus Torvalds 
49221da177e4SLinus Torvalds /* ACL data packet */
49236039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
49241da177e4SLinus Torvalds {
49251da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
49261da177e4SLinus Torvalds 	struct hci_conn *conn;
49271da177e4SLinus Torvalds 	__u16 handle, flags;
49281da177e4SLinus Torvalds 
49291da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
49301da177e4SLinus Torvalds 
49311da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
49321da177e4SLinus Torvalds 	flags  = hci_flags(handle);
49331da177e4SLinus Torvalds 	handle = hci_handle(handle);
49341da177e4SLinus Torvalds 
4935f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4936a8c5fb1aSGustavo Padovan 	       handle, flags);
49371da177e4SLinus Torvalds 
49381da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
49391da177e4SLinus Torvalds 
49401da177e4SLinus Torvalds 	hci_dev_lock(hdev);
49411da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
49421da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
49431da177e4SLinus Torvalds 
49441da177e4SLinus Torvalds 	if (conn) {
494565983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
494604837f64SMarcel Holtmann 
49471da177e4SLinus Torvalds 		/* Send to upper protocol */
4948686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
49491da177e4SLinus Torvalds 		return;
49501da177e4SLinus Torvalds 	} else {
49512064ee33SMarcel Holtmann 		bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
49522064ee33SMarcel Holtmann 			   handle);
49531da177e4SLinus Torvalds 	}
49541da177e4SLinus Torvalds 
49551da177e4SLinus Torvalds 	kfree_skb(skb);
49561da177e4SLinus Torvalds }
49571da177e4SLinus Torvalds 
49581da177e4SLinus Torvalds /* SCO data packet */
49596039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
49601da177e4SLinus Torvalds {
49611da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
49621da177e4SLinus Torvalds 	struct hci_conn *conn;
4963debdedf2SMarcel Holtmann 	__u16 handle, flags;
49641da177e4SLinus Torvalds 
49651da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
49661da177e4SLinus Torvalds 
49671da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
4968debdedf2SMarcel Holtmann 	flags  = hci_flags(handle);
4969debdedf2SMarcel Holtmann 	handle = hci_handle(handle);
49701da177e4SLinus Torvalds 
4971debdedf2SMarcel Holtmann 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4972debdedf2SMarcel Holtmann 	       handle, flags);
49731da177e4SLinus Torvalds 
49741da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
49751da177e4SLinus Torvalds 
49761da177e4SLinus Torvalds 	hci_dev_lock(hdev);
49771da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
49781da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
49791da177e4SLinus Torvalds 
49801da177e4SLinus Torvalds 	if (conn) {
49811da177e4SLinus Torvalds 		/* Send to upper protocol */
498200398e1dSAlain Michaud 		bt_cb(skb)->sco.pkt_status = flags & 0x03;
4983686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
49841da177e4SLinus Torvalds 		return;
49851da177e4SLinus Torvalds 	} else {
49862064ee33SMarcel Holtmann 		bt_dev_err(hdev, "SCO packet for unknown connection handle %d",
49872064ee33SMarcel Holtmann 			   handle);
49881da177e4SLinus Torvalds 	}
49891da177e4SLinus Torvalds 
49901da177e4SLinus Torvalds 	kfree_skb(skb);
49911da177e4SLinus Torvalds }
49921da177e4SLinus Torvalds 
49939238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
49949238f36aSJohan Hedberg {
49959238f36aSJohan Hedberg 	struct sk_buff *skb;
49969238f36aSJohan Hedberg 
49979238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
49989238f36aSJohan Hedberg 	if (!skb)
49999238f36aSJohan Hedberg 		return true;
50009238f36aSJohan Hedberg 
500144d27137SJohan Hedberg 	return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
50029238f36aSJohan Hedberg }
50039238f36aSJohan Hedberg 
500442c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
500542c6b129SJohan Hedberg {
500642c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
500742c6b129SJohan Hedberg 	struct sk_buff *skb;
500842c6b129SJohan Hedberg 	u16 opcode;
500942c6b129SJohan Hedberg 
501042c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
501142c6b129SJohan Hedberg 		return;
501242c6b129SJohan Hedberg 
501342c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
501442c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
501542c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
501642c6b129SJohan Hedberg 		return;
501742c6b129SJohan Hedberg 
501842c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
501942c6b129SJohan Hedberg 	if (!skb)
502042c6b129SJohan Hedberg 		return;
502142c6b129SJohan Hedberg 
502242c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
502342c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
502442c6b129SJohan Hedberg }
502542c6b129SJohan Hedberg 
5026e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
5027e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
5028e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
50299238f36aSJohan Hedberg {
50309238f36aSJohan Hedberg 	struct sk_buff *skb;
50319238f36aSJohan Hedberg 	unsigned long flags;
50329238f36aSJohan Hedberg 
50339238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
50349238f36aSJohan Hedberg 
503542c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
503642c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
50379238f36aSJohan Hedberg 	 */
503842c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
503942c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
504042c6b129SJohan Hedberg 		 * reset complete event during init and any pending
504142c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
504242c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
504342c6b129SJohan Hedberg 		 * command.
504442c6b129SJohan Hedberg 		 */
504542c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
504642c6b129SJohan Hedberg 			hci_resend_last(hdev);
504742c6b129SJohan Hedberg 
50489238f36aSJohan Hedberg 		return;
504942c6b129SJohan Hedberg 	}
50509238f36aSJohan Hedberg 
5051f80c5dadSJoão Paulo Rechi Vita 	/* If we reach this point this event matches the last command sent */
5052f80c5dadSJoão Paulo Rechi Vita 	hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
5053f80c5dadSJoão Paulo Rechi Vita 
50549238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
50559238f36aSJohan Hedberg 	 * this request the request is not yet complete.
50569238f36aSJohan Hedberg 	 */
50579238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
50589238f36aSJohan Hedberg 		return;
50599238f36aSJohan Hedberg 
50609238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
50619238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
50629238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
50639238f36aSJohan Hedberg 	 */
506444d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) {
506544d27137SJohan Hedberg 		*req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb;
5066e6214487SJohan Hedberg 		return;
50679238f36aSJohan Hedberg 	}
5068e6214487SJohan Hedberg 
506944d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_complete) {
507044d27137SJohan Hedberg 		*req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete;
5071e6214487SJohan Hedberg 		return;
507253e21fbcSJohan Hedberg 	}
50739238f36aSJohan Hedberg 
50749238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
50759238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
50769238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
507744d27137SJohan Hedberg 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
50789238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
50799238f36aSJohan Hedberg 			break;
50809238f36aSJohan Hedberg 		}
50819238f36aSJohan Hedberg 
50823bd7594eSDouglas Anderson 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
5083242c0ebdSMarcel Holtmann 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
50843bd7594eSDouglas Anderson 		else
50853bd7594eSDouglas Anderson 			*req_complete = bt_cb(skb)->hci.req_complete;
50869238f36aSJohan Hedberg 		kfree_skb(skb);
50879238f36aSJohan Hedberg 	}
50889238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
50899238f36aSJohan Hedberg }
50909238f36aSJohan Hedberg 
5091b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
50921da177e4SLinus Torvalds {
5093b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
50941da177e4SLinus Torvalds 	struct sk_buff *skb;
50951da177e4SLinus Torvalds 
50961da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
50971da177e4SLinus Torvalds 
50981da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
5099cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
5100cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
5101cd82e61cSMarcel Holtmann 
51021da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
51031da177e4SLinus Torvalds 			/* Send copy to the sockets */
5104470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
51051da177e4SLinus Torvalds 		}
51061da177e4SLinus Torvalds 
5107eb8c101eSMattijs Korpershoek 		/* If the device has been opened in HCI_USER_CHANNEL,
5108eb8c101eSMattijs Korpershoek 		 * the userspace has exclusive access to device.
5109eb8c101eSMattijs Korpershoek 		 * When device is HCI_INIT, we still need to process
5110eb8c101eSMattijs Korpershoek 		 * the data packets to the driver in order
5111eb8c101eSMattijs Korpershoek 		 * to complete its setup().
5112eb8c101eSMattijs Korpershoek 		 */
5113eb8c101eSMattijs Korpershoek 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
5114eb8c101eSMattijs Korpershoek 		    !test_bit(HCI_INIT, &hdev->flags)) {
51151da177e4SLinus Torvalds 			kfree_skb(skb);
51161da177e4SLinus Torvalds 			continue;
51171da177e4SLinus Torvalds 		}
51181da177e4SLinus Torvalds 
51191da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
51201da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
5121d79f34e3SMarcel Holtmann 			switch (hci_skb_pkt_type(skb)) {
51221da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
51231da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
5124cc974003SMarcel Holtmann 			case HCI_ISODATA_PKT:
51251da177e4SLinus Torvalds 				kfree_skb(skb);
51261da177e4SLinus Torvalds 				continue;
51273ff50b79SStephen Hemminger 			}
51281da177e4SLinus Torvalds 		}
51291da177e4SLinus Torvalds 
51301da177e4SLinus Torvalds 		/* Process frame */
5131d79f34e3SMarcel Holtmann 		switch (hci_skb_pkt_type(skb)) {
51321da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
5133b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
51341da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
51351da177e4SLinus Torvalds 			break;
51361da177e4SLinus Torvalds 
51371da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
51381da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
51391da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
51401da177e4SLinus Torvalds 			break;
51411da177e4SLinus Torvalds 
51421da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
51431da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
51441da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
51451da177e4SLinus Torvalds 			break;
51461da177e4SLinus Torvalds 
51471da177e4SLinus Torvalds 		default:
51481da177e4SLinus Torvalds 			kfree_skb(skb);
51491da177e4SLinus Torvalds 			break;
51501da177e4SLinus Torvalds 		}
51511da177e4SLinus Torvalds 	}
51521da177e4SLinus Torvalds }
51531da177e4SLinus Torvalds 
5154c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
51551da177e4SLinus Torvalds {
5156c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
51571da177e4SLinus Torvalds 	struct sk_buff *skb;
51581da177e4SLinus Torvalds 
51592104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
51602104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
51611da177e4SLinus Torvalds 
51621da177e4SLinus Torvalds 	/* Send queued commands */
51635a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
51645a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
51655a08ecceSAndrei Emeltchenko 		if (!skb)
51665a08ecceSAndrei Emeltchenko 			return;
51675a08ecceSAndrei Emeltchenko 
51681da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
51691da177e4SLinus Torvalds 
5170a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
517170f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
5172f80c5dadSJoão Paulo Rechi Vita 			if (hci_req_status_pend(hdev))
5173f80c5dadSJoão Paulo Rechi Vita 				hci_dev_set_flag(hdev, HCI_CMD_PENDING);
51741da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
517557d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
51767bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
517765cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
51787bdb8a5cSSzymon Janc 			else
517965cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
518065cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
51811da177e4SLinus Torvalds 		} else {
51821da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
5183c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
51841da177e4SLinus Torvalds 		}
51851da177e4SLinus Torvalds 	}
51861da177e4SLinus Torvalds }
5187