xref: /openbmc/linux/net/bluetooth/hci_core.c (revision e0448092)
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 
134609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13471da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1348a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
13491f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
13501da177e4SLinus Torvalds 		do_inquiry = 1;
13511da177e4SLinus Torvalds 	}
135209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13531da177e4SLinus Torvalds 
135404837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
135570f23020SAndrei Emeltchenko 
135670f23020SAndrei Emeltchenko 	if (do_inquiry) {
135701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
13584ebeee2dSJohan Hedberg 				   timeo, NULL);
135970f23020SAndrei Emeltchenko 		if (err < 0)
13601da177e4SLinus Torvalds 			goto done;
13613e13fa1eSAndre Guedes 
13623e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
13633e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
13643e13fa1eSAndre Guedes 		 */
136574316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
136628a758c8SPan Bian 				TASK_INTERRUPTIBLE)) {
136728a758c8SPan Bian 			err = -EINTR;
136828a758c8SPan Bian 			goto done;
136928a758c8SPan Bian 		}
137070f23020SAndrei Emeltchenko 	}
13711da177e4SLinus Torvalds 
13728fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
13738fc9ced3SGustavo Padovan 	 * 255 entries
13748fc9ced3SGustavo Padovan 	 */
13751da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
13761da177e4SLinus Torvalds 
13771da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
13781da177e4SLinus Torvalds 	 * copy it to the user space.
13791da177e4SLinus Torvalds 	 */
13806da2ec56SKees Cook 	buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL);
138170f23020SAndrei Emeltchenko 	if (!buf) {
13821da177e4SLinus Torvalds 		err = -ENOMEM;
13831da177e4SLinus Torvalds 		goto done;
13841da177e4SLinus Torvalds 	}
13851da177e4SLinus Torvalds 
138609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13871da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
138809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13891da177e4SLinus Torvalds 
13901da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
13911da177e4SLinus Torvalds 
13921da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
13931da177e4SLinus Torvalds 		ptr += sizeof(ir);
13941da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
13951da177e4SLinus Torvalds 				 ir.num_rsp))
13961da177e4SLinus Torvalds 			err = -EFAULT;
13971da177e4SLinus Torvalds 	} else
13981da177e4SLinus Torvalds 		err = -EFAULT;
13991da177e4SLinus Torvalds 
14001da177e4SLinus Torvalds 	kfree(buf);
14011da177e4SLinus Torvalds 
14021da177e4SLinus Torvalds done:
14031da177e4SLinus Torvalds 	hci_dev_put(hdev);
14041da177e4SLinus Torvalds 	return err;
14051da177e4SLinus Torvalds }
14061da177e4SLinus Torvalds 
14077a0e5b15SMatthias Kaehlcke /**
14087a0e5b15SMatthias Kaehlcke  * hci_dev_get_bd_addr_from_property - Get the Bluetooth Device Address
14097a0e5b15SMatthias Kaehlcke  *				       (BD_ADDR) for a HCI device from
14107a0e5b15SMatthias Kaehlcke  *				       a firmware node property.
14117a0e5b15SMatthias Kaehlcke  * @hdev:	The HCI device
14127a0e5b15SMatthias Kaehlcke  *
14137a0e5b15SMatthias Kaehlcke  * Search the firmware node for 'local-bd-address'.
14147a0e5b15SMatthias Kaehlcke  *
14157a0e5b15SMatthias Kaehlcke  * All-zero BD addresses are rejected, because those could be properties
14167a0e5b15SMatthias Kaehlcke  * that exist in the firmware tables, but were not updated by the firmware. For
14177a0e5b15SMatthias Kaehlcke  * example, the DTS could define 'local-bd-address', with zero BD addresses.
14187a0e5b15SMatthias Kaehlcke  */
14197a0e5b15SMatthias Kaehlcke static void hci_dev_get_bd_addr_from_property(struct hci_dev *hdev)
14207a0e5b15SMatthias Kaehlcke {
14217a0e5b15SMatthias Kaehlcke 	struct fwnode_handle *fwnode = dev_fwnode(hdev->dev.parent);
14227a0e5b15SMatthias Kaehlcke 	bdaddr_t ba;
14237a0e5b15SMatthias Kaehlcke 	int ret;
14247a0e5b15SMatthias Kaehlcke 
14257a0e5b15SMatthias Kaehlcke 	ret = fwnode_property_read_u8_array(fwnode, "local-bd-address",
14267a0e5b15SMatthias Kaehlcke 					    (u8 *)&ba, sizeof(ba));
14277a0e5b15SMatthias Kaehlcke 	if (ret < 0 || !bacmp(&ba, BDADDR_ANY))
14287a0e5b15SMatthias Kaehlcke 		return;
14297a0e5b15SMatthias Kaehlcke 
14307a0e5b15SMatthias Kaehlcke 	bacpy(&hdev->public_addr, &ba);
14317a0e5b15SMatthias Kaehlcke }
14327a0e5b15SMatthias Kaehlcke 
1433cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
14341da177e4SLinus Torvalds {
14351da177e4SLinus Torvalds 	int ret = 0;
14361da177e4SLinus Torvalds 
14371da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
14381da177e4SLinus Torvalds 
1439b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
14401da177e4SLinus Torvalds 
1441d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
144294324962SJohan Hovold 		ret = -ENODEV;
144394324962SJohan Hovold 		goto done;
144494324962SJohan Hovold 	}
144594324962SJohan Hovold 
1446d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1447d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
1448a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1449a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1450bf543036SJohan Hedberg 		 */
1451d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
1452611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1453611b30f7SMarcel Holtmann 			goto done;
1454611b30f7SMarcel Holtmann 		}
1455611b30f7SMarcel Holtmann 
1456a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
145791641b79SZheng Yongjun 		 * random address, but let the HCI setup proceed to
1458a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1459a5c8f270SMarcel Holtmann 		 * or not.
1460a5c8f270SMarcel Holtmann 		 *
1461c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
1462c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
1463c6beca0eSMarcel Holtmann 		 * available.
1464c6beca0eSMarcel Holtmann 		 *
1465a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1466a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1467a5c8f270SMarcel Holtmann 		 */
1468d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1469ca8bee5dSMarcel Holtmann 		    hdev->dev_type == HCI_PRIMARY &&
1470a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1471a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1472a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1473a5c8f270SMarcel Holtmann 			goto done;
1474a5c8f270SMarcel Holtmann 		}
1475a5c8f270SMarcel Holtmann 	}
1476a5c8f270SMarcel Holtmann 
14771da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
14781da177e4SLinus Torvalds 		ret = -EALREADY;
14791da177e4SLinus Torvalds 		goto done;
14801da177e4SLinus Torvalds 	}
14811da177e4SLinus Torvalds 
14821da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
14831da177e4SLinus Torvalds 		ret = -EIO;
14841da177e4SLinus Torvalds 		goto done;
14851da177e4SLinus Torvalds 	}
14861da177e4SLinus Torvalds 
1487e9ca8bf1SMarcel Holtmann 	set_bit(HCI_RUNNING, &hdev->flags);
148805fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_OPEN);
14894a3f95b7SMarcel Holtmann 
14901da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
14911da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1492f41c70c4SMarcel Holtmann 
1493740011cfSSean Wang 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
1494740011cfSSean Wang 	    test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
14957fdf6c6aSMarcel Holtmann 		bool invalid_bdaddr;
14967fdf6c6aSMarcel Holtmann 
1497e131d74aSMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_SETUP);
1498e131d74aSMarcel Holtmann 
1499af202f84SMarcel Holtmann 		if (hdev->setup)
1500f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
1501f41c70c4SMarcel Holtmann 
15027fdf6c6aSMarcel Holtmann 		/* The transport driver can set the quirk to mark the
15037fdf6c6aSMarcel Holtmann 		 * BD_ADDR invalid before creating the HCI device or in
15047fdf6c6aSMarcel Holtmann 		 * its setup callback.
15057fdf6c6aSMarcel Holtmann 		 */
15067fdf6c6aSMarcel Holtmann 		invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR,
15077fdf6c6aSMarcel Holtmann 					  &hdev->quirks);
15087fdf6c6aSMarcel Holtmann 
15097a0e5b15SMatthias Kaehlcke 		if (ret)
15107a0e5b15SMatthias Kaehlcke 			goto setup_failed;
15117a0e5b15SMatthias Kaehlcke 
15127a0e5b15SMatthias Kaehlcke 		if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) {
15137a0e5b15SMatthias Kaehlcke 			if (!bacmp(&hdev->public_addr, BDADDR_ANY))
15147a0e5b15SMatthias Kaehlcke 				hci_dev_get_bd_addr_from_property(hdev);
15157a0e5b15SMatthias Kaehlcke 
15167a0e5b15SMatthias Kaehlcke 			if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
15177fdf6c6aSMarcel Holtmann 			    hdev->set_bdaddr) {
15187a0e5b15SMatthias Kaehlcke 				ret = hdev->set_bdaddr(hdev,
15197a0e5b15SMatthias Kaehlcke 						       &hdev->public_addr);
15207fdf6c6aSMarcel Holtmann 
15217fdf6c6aSMarcel Holtmann 				/* If setting of the BD_ADDR from the device
15227fdf6c6aSMarcel Holtmann 				 * property succeeds, then treat the address
15237fdf6c6aSMarcel Holtmann 				 * as valid even if the invalid BD_ADDR
15247fdf6c6aSMarcel Holtmann 				 * quirk indicates otherwise.
15257fdf6c6aSMarcel Holtmann 				 */
15267fdf6c6aSMarcel Holtmann 				if (!ret)
15277fdf6c6aSMarcel Holtmann 					invalid_bdaddr = false;
15287fdf6c6aSMarcel Holtmann 			}
15297a0e5b15SMatthias Kaehlcke 		}
15307a0e5b15SMatthias Kaehlcke 
15317a0e5b15SMatthias Kaehlcke setup_failed:
1532af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
1533af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
1534af202f84SMarcel Holtmann 		 *
15357fdf6c6aSMarcel Holtmann 		 * For the invalid BD_ADDR quirk it is possible that
15367fdf6c6aSMarcel Holtmann 		 * it becomes a valid address if the bootloader does
15377fdf6c6aSMarcel Holtmann 		 * provide it (see above).
15387fdf6c6aSMarcel Holtmann 		 *
1539af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
1540af202f84SMarcel Holtmann 		 * start up as unconfigured.
1541af202f84SMarcel Holtmann 		 */
1542eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
15437fdf6c6aSMarcel Holtmann 		    invalid_bdaddr)
1544a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
1545f41c70c4SMarcel Holtmann 
15460ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
15470ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
15480ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
15490ebca7d6SMarcel Holtmann 		 *
15500ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
15510ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
15520ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
15530ebca7d6SMarcel Holtmann 		 */
1554d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
15550ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
155689bc22d2SMarcel Holtmann 	}
155789bc22d2SMarcel Holtmann 
1558d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_CONFIG)) {
15599713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
15609713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
15619713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
15629713c17bSMarcel Holtmann 		 * on procedure.
156324c457e2SMarcel Holtmann 		 */
15649713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
15659713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
156624c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
156724c457e2SMarcel Holtmann 		else
156824c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
156924c457e2SMarcel Holtmann 	}
157024c457e2SMarcel Holtmann 
1571f41c70c4SMarcel Holtmann 	if (!ret) {
1572d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
157398a63aafSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
15742177bab5SJohan Hedberg 			ret = __hci_init(hdev);
157598a63aafSMarcel Holtmann 			if (!ret && hdev->post_init)
157698a63aafSMarcel Holtmann 				ret = hdev->post_init(hdev);
157798a63aafSMarcel Holtmann 		}
15781da177e4SLinus Torvalds 	}
15791da177e4SLinus Torvalds 
15807e995b9eSMarcel Holtmann 	/* If the HCI Reset command is clearing all diagnostic settings,
15817e995b9eSMarcel Holtmann 	 * then they need to be reprogrammed after the init procedure
15827e995b9eSMarcel Holtmann 	 * completed.
15837e995b9eSMarcel Holtmann 	 */
15847e995b9eSMarcel Holtmann 	if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
1585b56c7b25SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
15867e995b9eSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
15877e995b9eSMarcel Holtmann 		ret = hdev->set_diag(hdev, true);
15887e995b9eSMarcel Holtmann 
1589145373cbSMiao-chen Chou 	msft_do_open(hdev);
1590f67743f9SMarcel Holtmann 	aosp_do_open(hdev);
1591145373cbSMiao-chen Chou 
1592f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1593f41c70c4SMarcel Holtmann 
15941da177e4SLinus Torvalds 	if (!ret) {
15951da177e4SLinus Torvalds 		hci_dev_hold(hdev);
1596a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
1597a73c046aSJaganath Kanakkassery 		hci_adv_instances_set_rpa_expired(hdev, true);
15981da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
159905fcd4c4SMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_UP);
16006d5d2ee6SHeiner Kallweit 		hci_leds_update_powered(hdev, true);
1601d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1602d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG) &&
1603d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1604d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
16052ff13894SJohan Hedberg 		    hci_dev_test_flag(hdev, HCI_MGMT) &&
1606ca8bee5dSMarcel Holtmann 		    hdev->dev_type == HCI_PRIMARY) {
16072ff13894SJohan Hedberg 			ret = __hci_req_hci_power_on(hdev);
16082ff13894SJohan Hedberg 			mgmt_power_on(hdev, ret);
160956e5cb86SJohan Hedberg 		}
16101da177e4SLinus Torvalds 	} else {
16111da177e4SLinus Torvalds 		/* Init failed, cleanup */
16123eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
16136a137caeSLin Ma 
16146a137caeSLin Ma 		/* Since hci_rx_work() is possible to awake new cmd_work
16156a137caeSLin Ma 		 * it should be flushed first to avoid unexpected call of
16166a137caeSLin Ma 		 * hci_cmd_work()
16176a137caeSLin Ma 		 */
1618b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
16196a137caeSLin Ma 		flush_work(&hdev->cmd_work);
16201da177e4SLinus Torvalds 
16211da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
16221da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
16231da177e4SLinus Torvalds 
16241da177e4SLinus Torvalds 		if (hdev->flush)
16251da177e4SLinus Torvalds 			hdev->flush(hdev);
16261da177e4SLinus Torvalds 
16271da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
16281da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
16291da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
16301da177e4SLinus Torvalds 		}
16311da177e4SLinus Torvalds 
1632e9ca8bf1SMarcel Holtmann 		clear_bit(HCI_RUNNING, &hdev->flags);
163305fcd4c4SMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
16344a3f95b7SMarcel Holtmann 
16351da177e4SLinus Torvalds 		hdev->close(hdev);
1636fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
16371da177e4SLinus Torvalds 	}
16381da177e4SLinus Torvalds 
16391da177e4SLinus Torvalds done:
1640b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
16411da177e4SLinus Torvalds 	return ret;
16421da177e4SLinus Torvalds }
16431da177e4SLinus Torvalds 
1644cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1645cbed0ca1SJohan Hedberg 
1646cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1647cbed0ca1SJohan Hedberg {
1648cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1649cbed0ca1SJohan Hedberg 	int err;
1650cbed0ca1SJohan Hedberg 
1651cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1652cbed0ca1SJohan Hedberg 	if (!hdev)
1653cbed0ca1SJohan Hedberg 		return -ENODEV;
1654cbed0ca1SJohan Hedberg 
16554a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
1656fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
1657fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
1658fee746b0SMarcel Holtmann 	 * possible.
1659fee746b0SMarcel Holtmann 	 *
1660fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
1661fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
1662fee746b0SMarcel Holtmann 	 * open the device.
1663fee746b0SMarcel Holtmann 	 */
1664d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1665d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1666fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1667fee746b0SMarcel Holtmann 		goto done;
1668fee746b0SMarcel Holtmann 	}
1669fee746b0SMarcel Holtmann 
1670e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
1671e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
1672e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
1673e1d08f40SJohan Hedberg 	 * completed.
1674e1d08f40SJohan Hedberg 	 */
1675a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
1676e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
1677e1d08f40SJohan Hedberg 
1678a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
1679a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
1680a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
1681a5c8f270SMarcel Holtmann 	 */
1682e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
1683e1d08f40SJohan Hedberg 
168412aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
1685b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
168612aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
168712aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
168812aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
168912aa4f0aSMarcel Holtmann 	 */
1690d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1691d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
1692a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
169312aa4f0aSMarcel Holtmann 
1694cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
1695cbed0ca1SJohan Hedberg 
1696fee746b0SMarcel Holtmann done:
1697cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
1698cbed0ca1SJohan Hedberg 	return err;
1699cbed0ca1SJohan Hedberg }
1700cbed0ca1SJohan Hedberg 
1701d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
1702d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
1703d7347f3cSJohan Hedberg {
1704d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
1705d7347f3cSJohan Hedberg 
1706f161dd41SJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list) {
1707f161dd41SJohan Hedberg 		if (p->conn) {
1708f161dd41SJohan Hedberg 			hci_conn_drop(p->conn);
1709f8aaf9b6SJohan Hedberg 			hci_conn_put(p->conn);
1710f161dd41SJohan Hedberg 			p->conn = NULL;
1711f161dd41SJohan Hedberg 		}
1712d7347f3cSJohan Hedberg 		list_del_init(&p->action);
1713f161dd41SJohan Hedberg 	}
1714d7347f3cSJohan Hedberg 
1715d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
1716d7347f3cSJohan Hedberg }
1717d7347f3cSJohan Hedberg 
17186b3cc1dbSSimon Fels int hci_dev_do_close(struct hci_dev *hdev)
17191da177e4SLinus Torvalds {
1720acc649c6SMarcel Holtmann 	bool auto_off;
1721acc649c6SMarcel Holtmann 
17221da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
17231da177e4SLinus Torvalds 
172478c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
1725de75cd0dSManish Mandlik 	cancel_delayed_work(&hdev->ncmd_timer);
172678c04c0bSVinicius Costa Gomes 
17277df0f73eSJohan Hedberg 	hci_request_cancel_all(hdev);
1728b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
17291da177e4SLinus Torvalds 
17301da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
173165cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
1732b504430cSJohan Hedberg 		hci_req_sync_unlock(hdev);
17331da177e4SLinus Torvalds 		return 0;
17341da177e4SLinus Torvalds 	}
17351da177e4SLinus Torvalds 
17366d5d2ee6SHeiner Kallweit 	hci_leds_update_powered(hdev, false);
17376d5d2ee6SHeiner Kallweit 
17383eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
17393eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1740b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
17411da177e4SLinus Torvalds 
174216ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
174316ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
1744a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
1745a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
174616ab91abSJohan Hedberg 	}
174716ab91abSJohan Hedberg 
1748a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
17497d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
17507d78525dSJohan Hedberg 
1751a73c046aSJaganath Kanakkassery 	if (hci_dev_test_flag(hdev, HCI_MGMT)) {
1752a73c046aSJaganath Kanakkassery 		struct adv_info *adv_instance;
1753a73c046aSJaganath Kanakkassery 
1754d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
17557ba8b4beSAndre Guedes 
1756a73c046aSJaganath Kanakkassery 		list_for_each_entry(adv_instance, &hdev->adv_instances, list)
1757a73c046aSJaganath Kanakkassery 			cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1758a73c046aSJaganath Kanakkassery 	}
1759a73c046aSJaganath Kanakkassery 
176076727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
176176727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
176276727c02SJohan Hedberg 	 */
176376727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
176476727c02SJohan Hedberg 
176509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
17661aeb9c65SJohan Hedberg 
17678f502f84SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
17688f502f84SJohan Hedberg 
1769acc649c6SMarcel Holtmann 	auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF);
1770acc649c6SMarcel Holtmann 
1771ca8bee5dSMarcel Holtmann 	if (!auto_off && hdev->dev_type == HCI_PRIMARY &&
1772baab7932SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
17732ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT))
17742ff13894SJohan Hedberg 		__mgmt_power_off(hdev);
17751aeb9c65SJohan Hedberg 
17761f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
1777d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
1778f161dd41SJohan Hedberg 	hci_conn_hash_flush(hdev);
177909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
17801da177e4SLinus Torvalds 
178164dae967SMarcel Holtmann 	smp_unregister(hdev);
178264dae967SMarcel Holtmann 
178305fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_DOWN);
17841da177e4SLinus Torvalds 
1785f67743f9SMarcel Holtmann 	aosp_do_close(hdev);
1786145373cbSMiao-chen Chou 	msft_do_close(hdev);
1787145373cbSMiao-chen Chou 
17881da177e4SLinus Torvalds 	if (hdev->flush)
17891da177e4SLinus Torvalds 		hdev->flush(hdev);
17901da177e4SLinus Torvalds 
17911da177e4SLinus Torvalds 	/* Reset device */
17921da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
17931da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
1794acc649c6SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) &&
1795acc649c6SMarcel Holtmann 	    !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
17961da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
17974ebeee2dSJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL);
17981da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
17991da177e4SLinus Torvalds 	}
18001da177e4SLinus Torvalds 
18010ea9fd00SKai-Heng Feng 	if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
18020ea9fd00SKai-Heng Feng 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
18030ea9fd00SKai-Heng Feng 	    test_bit(HCI_UP, &hdev->flags)) {
18040ea9fd00SKai-Heng Feng 		/* Execute vendor specific shutdown routine */
18050ea9fd00SKai-Heng Feng 		if (hdev->shutdown)
18060ea9fd00SKai-Heng Feng 			hdev->shutdown(hdev);
18070ea9fd00SKai-Heng Feng 	}
18080ea9fd00SKai-Heng Feng 
1809c347b765SGustavo F. Padovan 	/* flush cmd  work */
1810c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
18111da177e4SLinus Torvalds 
18121da177e4SLinus Torvalds 	/* Drop queues */
18131da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
18141da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
18151da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
18161da177e4SLinus Torvalds 
18171da177e4SLinus Torvalds 	/* Drop last sent command */
18181da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
181965cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
18201da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
18211da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
18221da177e4SLinus Torvalds 	}
18231da177e4SLinus Torvalds 
1824e9ca8bf1SMarcel Holtmann 	clear_bit(HCI_RUNNING, &hdev->flags);
182505fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
18264a3f95b7SMarcel Holtmann 
18279952d90eSAbhishek Pandit-Subedi 	if (test_and_clear_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks))
18289952d90eSAbhishek Pandit-Subedi 		wake_up(&hdev->suspend_wait_q);
18299952d90eSAbhishek Pandit-Subedi 
18301da177e4SLinus Torvalds 	/* After this point our queues are empty
18311da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
18321da177e4SLinus Torvalds 	hdev->close(hdev);
18331da177e4SLinus Torvalds 
183435b973c9SJohan Hedberg 	/* Clear flags */
1835fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
1836eacb44dfSMarcel Holtmann 	hci_dev_clear_volatile_flags(hdev);
183735b973c9SJohan Hedberg 
1838ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1839536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1840ced5c338SAndrei Emeltchenko 
1841e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
184209b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
18437a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
1844e59fda8dSJohan Hedberg 
1845b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
18461da177e4SLinus Torvalds 
18471da177e4SLinus Torvalds 	hci_dev_put(hdev);
18481da177e4SLinus Torvalds 	return 0;
18491da177e4SLinus Torvalds }
18501da177e4SLinus Torvalds 
18511da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
18521da177e4SLinus Torvalds {
18531da177e4SLinus Torvalds 	struct hci_dev *hdev;
18541da177e4SLinus Torvalds 	int err;
18551da177e4SLinus Torvalds 
185670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
185770f23020SAndrei Emeltchenko 	if (!hdev)
18581da177e4SLinus Torvalds 		return -ENODEV;
18598ee56540SMarcel Holtmann 
1860d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
18610736cfa8SMarcel Holtmann 		err = -EBUSY;
18620736cfa8SMarcel Holtmann 		goto done;
18630736cfa8SMarcel Holtmann 	}
18640736cfa8SMarcel Holtmann 
1865a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
18668ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
18678ee56540SMarcel Holtmann 
18681da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
18698ee56540SMarcel Holtmann 
18700736cfa8SMarcel Holtmann done:
18711da177e4SLinus Torvalds 	hci_dev_put(hdev);
18721da177e4SLinus Torvalds 	return err;
18731da177e4SLinus Torvalds }
18741da177e4SLinus Torvalds 
18755c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
18761da177e4SLinus Torvalds {
18775c912495SMarcel Holtmann 	int ret;
18781da177e4SLinus Torvalds 
18795c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
18801da177e4SLinus Torvalds 
1881b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
18821da177e4SLinus Torvalds 
18831da177e4SLinus Torvalds 	/* Drop queues */
18841da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
18851da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
18861da177e4SLinus Torvalds 
188776727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
188876727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
188976727c02SJohan Hedberg 	 */
189076727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
189176727c02SJohan Hedberg 
189209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
18931f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
18941da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
189509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
18961da177e4SLinus Torvalds 
18971da177e4SLinus Torvalds 	if (hdev->flush)
18981da177e4SLinus Torvalds 		hdev->flush(hdev);
18991da177e4SLinus Torvalds 
19001da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
19016ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
19021da177e4SLinus Torvalds 
19034ebeee2dSJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT, NULL);
19041da177e4SLinus Torvalds 
1905b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
19061da177e4SLinus Torvalds 	return ret;
19071da177e4SLinus Torvalds }
19081da177e4SLinus Torvalds 
19095c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
19105c912495SMarcel Holtmann {
19115c912495SMarcel Holtmann 	struct hci_dev *hdev;
19125c912495SMarcel Holtmann 	int err;
19135c912495SMarcel Holtmann 
19145c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
19155c912495SMarcel Holtmann 	if (!hdev)
19165c912495SMarcel Holtmann 		return -ENODEV;
19175c912495SMarcel Holtmann 
19185c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
19195c912495SMarcel Holtmann 		err = -ENETDOWN;
19205c912495SMarcel Holtmann 		goto done;
19215c912495SMarcel Holtmann 	}
19225c912495SMarcel Holtmann 
1923d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
19245c912495SMarcel Holtmann 		err = -EBUSY;
19255c912495SMarcel Holtmann 		goto done;
19265c912495SMarcel Holtmann 	}
19275c912495SMarcel Holtmann 
1928d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
19295c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
19305c912495SMarcel Holtmann 		goto done;
19315c912495SMarcel Holtmann 	}
19325c912495SMarcel Holtmann 
19335c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
19345c912495SMarcel Holtmann 
19355c912495SMarcel Holtmann done:
19365c912495SMarcel Holtmann 	hci_dev_put(hdev);
19375c912495SMarcel Holtmann 	return err;
19385c912495SMarcel Holtmann }
19395c912495SMarcel Holtmann 
19401da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
19411da177e4SLinus Torvalds {
19421da177e4SLinus Torvalds 	struct hci_dev *hdev;
19431da177e4SLinus Torvalds 	int ret = 0;
19441da177e4SLinus Torvalds 
194570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
194670f23020SAndrei Emeltchenko 	if (!hdev)
19471da177e4SLinus Torvalds 		return -ENODEV;
19481da177e4SLinus Torvalds 
1949d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
19500736cfa8SMarcel Holtmann 		ret = -EBUSY;
19510736cfa8SMarcel Holtmann 		goto done;
19520736cfa8SMarcel Holtmann 	}
19530736cfa8SMarcel Holtmann 
1954d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1955fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
1956fee746b0SMarcel Holtmann 		goto done;
1957fee746b0SMarcel Holtmann 	}
1958fee746b0SMarcel Holtmann 
19591da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
19601da177e4SLinus Torvalds 
19610736cfa8SMarcel Holtmann done:
19621da177e4SLinus Torvalds 	hci_dev_put(hdev);
19631da177e4SLinus Torvalds 	return ret;
19641da177e4SLinus Torvalds }
19651da177e4SLinus Torvalds 
1966123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
1967123abc08SJohan Hedberg {
1968bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
1969123abc08SJohan Hedberg 
1970123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
1971123abc08SJohan Hedberg 
1972123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
1973238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
1974238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
1975123abc08SJohan Hedberg 	else
1976a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
1977a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
1978123abc08SJohan Hedberg 
1979bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
1980238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
1981238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
1982bc6d2d04SJohan Hedberg 	} else {
1983a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1984a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
1985a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
1986bc6d2d04SJohan Hedberg 	}
1987bc6d2d04SJohan Hedberg 
1988d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
1989123abc08SJohan Hedberg 		return;
1990123abc08SJohan Hedberg 
1991bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
1992bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
1993a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
1994bc6d2d04SJohan Hedberg 
1995d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
1996cab054abSJohan Hedberg 			hci_req_update_adv_data(hdev, hdev->cur_adv_instance);
1997bc6d2d04SJohan Hedberg 
1998123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
1999123abc08SJohan Hedberg 	}
2000bc6d2d04SJohan Hedberg }
2001123abc08SJohan Hedberg 
20021da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
20031da177e4SLinus Torvalds {
20041da177e4SLinus Torvalds 	struct hci_dev *hdev;
20051da177e4SLinus Torvalds 	struct hci_dev_req dr;
20061da177e4SLinus Torvalds 	int err = 0;
20071da177e4SLinus Torvalds 
20081da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
20091da177e4SLinus Torvalds 		return -EFAULT;
20101da177e4SLinus Torvalds 
201170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
201270f23020SAndrei Emeltchenko 	if (!hdev)
20131da177e4SLinus Torvalds 		return -ENODEV;
20141da177e4SLinus Torvalds 
2015d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
20160736cfa8SMarcel Holtmann 		err = -EBUSY;
20170736cfa8SMarcel Holtmann 		goto done;
20180736cfa8SMarcel Holtmann 	}
20190736cfa8SMarcel Holtmann 
2020d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
2021fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2022fee746b0SMarcel Holtmann 		goto done;
2023fee746b0SMarcel Holtmann 	}
2024fee746b0SMarcel Holtmann 
2025ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
20265b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
20275b69bef5SMarcel Holtmann 		goto done;
20285b69bef5SMarcel Holtmann 	}
20295b69bef5SMarcel Holtmann 
2030d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
203156f87901SJohan Hedberg 		err = -EOPNOTSUPP;
203256f87901SJohan Hedberg 		goto done;
203356f87901SJohan Hedberg 	}
203456f87901SJohan Hedberg 
20351da177e4SLinus Torvalds 	switch (cmd) {
20361da177e4SLinus Torvalds 	case HCISETAUTH:
203701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
20384ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20391da177e4SLinus Torvalds 		break;
20401da177e4SLinus Torvalds 
20411da177e4SLinus Torvalds 	case HCISETENCRYPT:
20421da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
20431da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
20441da177e4SLinus Torvalds 			break;
20451da177e4SLinus Torvalds 		}
20461da177e4SLinus Torvalds 
20471da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
20481da177e4SLinus Torvalds 			/* Auth must be enabled first */
204901178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
20504ebeee2dSJohan Hedberg 					   HCI_INIT_TIMEOUT, NULL);
20511da177e4SLinus Torvalds 			if (err)
20521da177e4SLinus Torvalds 				break;
20531da177e4SLinus Torvalds 		}
20541da177e4SLinus Torvalds 
205501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
20564ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20571da177e4SLinus Torvalds 		break;
20581da177e4SLinus Torvalds 
20591da177e4SLinus Torvalds 	case HCISETSCAN:
206001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
20614ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
206291a668b0SJohan Hedberg 
2063bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
2064bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
206591a668b0SJohan Hedberg 		 */
2066123abc08SJohan Hedberg 		if (!err)
2067123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
20681da177e4SLinus Torvalds 		break;
20691da177e4SLinus Torvalds 
20701da177e4SLinus Torvalds 	case HCISETLINKPOL:
207101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
20724ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20731da177e4SLinus Torvalds 		break;
20741da177e4SLinus Torvalds 
20751da177e4SLinus Torvalds 	case HCISETLINKMODE:
2076e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2077e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2078e4e8e37cSMarcel Holtmann 		break;
2079e4e8e37cSMarcel Holtmann 
2080e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2081b7c23df8SJaganath Kanakkassery 		if (hdev->pkt_type == (__u16) dr.dev_opt)
2082b7c23df8SJaganath Kanakkassery 			break;
2083b7c23df8SJaganath Kanakkassery 
2084e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
2085b7c23df8SJaganath Kanakkassery 		mgmt_phy_configuration_changed(hdev, NULL);
20861da177e4SLinus Torvalds 		break;
20871da177e4SLinus Torvalds 
20881da177e4SLinus Torvalds 	case HCISETACLMTU:
20891da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
20901da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
20911da177e4SLinus Torvalds 		break;
20921da177e4SLinus Torvalds 
20931da177e4SLinus Torvalds 	case HCISETSCOMTU:
20941da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
20951da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
20961da177e4SLinus Torvalds 		break;
20971da177e4SLinus Torvalds 
20981da177e4SLinus Torvalds 	default:
20991da177e4SLinus Torvalds 		err = -EINVAL;
21001da177e4SLinus Torvalds 		break;
21011da177e4SLinus Torvalds 	}
2102e4e8e37cSMarcel Holtmann 
21030736cfa8SMarcel Holtmann done:
21041da177e4SLinus Torvalds 	hci_dev_put(hdev);
21051da177e4SLinus Torvalds 	return err;
21061da177e4SLinus Torvalds }
21071da177e4SLinus Torvalds 
21081da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
21091da177e4SLinus Torvalds {
21108035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
21111da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
21121da177e4SLinus Torvalds 	struct hci_dev_req *dr;
21131da177e4SLinus Torvalds 	int n = 0, size, err;
21141da177e4SLinus Torvalds 	__u16 dev_num;
21151da177e4SLinus Torvalds 
21161da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
21171da177e4SLinus Torvalds 		return -EFAULT;
21181da177e4SLinus Torvalds 
21191da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
21201da177e4SLinus Torvalds 		return -EINVAL;
21211da177e4SLinus Torvalds 
21221da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
21231da177e4SLinus Torvalds 
212470f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
212570f23020SAndrei Emeltchenko 	if (!dl)
21261da177e4SLinus Torvalds 		return -ENOMEM;
21271da177e4SLinus Torvalds 
21281da177e4SLinus Torvalds 	dr = dl->dev_req;
21291da177e4SLinus Torvalds 
2130f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
21318035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
21322e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
2133c542a06cSJohan Hedberg 
21342e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
21352e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
21362e84d8dbSMarcel Holtmann 		 * device is actually down.
21372e84d8dbSMarcel Holtmann 		 */
2138d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
21392e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
2140c542a06cSJohan Hedberg 
21411da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
21422e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
2143c542a06cSJohan Hedberg 
21441da177e4SLinus Torvalds 		if (++n >= dev_num)
21451da177e4SLinus Torvalds 			break;
21461da177e4SLinus Torvalds 	}
2147f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
21481da177e4SLinus Torvalds 
21491da177e4SLinus Torvalds 	dl->dev_num = n;
21501da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
21511da177e4SLinus Torvalds 
21521da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
21531da177e4SLinus Torvalds 	kfree(dl);
21541da177e4SLinus Torvalds 
21551da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
21561da177e4SLinus Torvalds }
21571da177e4SLinus Torvalds 
21581da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
21591da177e4SLinus Torvalds {
21601da177e4SLinus Torvalds 	struct hci_dev *hdev;
21611da177e4SLinus Torvalds 	struct hci_dev_info di;
21622e84d8dbSMarcel Holtmann 	unsigned long flags;
21631da177e4SLinus Torvalds 	int err = 0;
21641da177e4SLinus Torvalds 
21651da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
21661da177e4SLinus Torvalds 		return -EFAULT;
21671da177e4SLinus Torvalds 
216870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
216970f23020SAndrei Emeltchenko 	if (!hdev)
21701da177e4SLinus Torvalds 		return -ENODEV;
21711da177e4SLinus Torvalds 
21722e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
21732e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
21742e84d8dbSMarcel Holtmann 	 * device is actually down.
21752e84d8dbSMarcel Holtmann 	 */
2176d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
21772e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
21782e84d8dbSMarcel Holtmann 	else
21792e84d8dbSMarcel Holtmann 		flags = hdev->flags;
2180c542a06cSJohan Hedberg 
21811da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
21821da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
218360f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
21842e84d8dbSMarcel Holtmann 	di.flags    = flags;
21851da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2186572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
21871da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
21881da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
21891da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
21901da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2191572c7f84SJohan Hedberg 	} else {
2192572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2193572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2194572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2195572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2196572c7f84SJohan Hedberg 	}
21971da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
21981da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
21991da177e4SLinus Torvalds 
22001da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
22011da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
22021da177e4SLinus Torvalds 
22031da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
22041da177e4SLinus Torvalds 		err = -EFAULT;
22051da177e4SLinus Torvalds 
22061da177e4SLinus Torvalds 	hci_dev_put(hdev);
22071da177e4SLinus Torvalds 
22081da177e4SLinus Torvalds 	return err;
22091da177e4SLinus Torvalds }
22101da177e4SLinus Torvalds 
22111da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
22121da177e4SLinus Torvalds 
2213611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2214611b30f7SMarcel Holtmann {
2215611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2216611b30f7SMarcel Holtmann 
2217611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2218611b30f7SMarcel Holtmann 
2219d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
22200736cfa8SMarcel Holtmann 		return -EBUSY;
22210736cfa8SMarcel Holtmann 
22225e130367SJohan Hedberg 	if (blocked) {
2223a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
2224d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
2225d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
2226611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
22275e130367SJohan Hedberg 	} else {
2228a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
22295e130367SJohan Hedberg 	}
2230611b30f7SMarcel Holtmann 
2231611b30f7SMarcel Holtmann 	return 0;
2232611b30f7SMarcel Holtmann }
2233611b30f7SMarcel Holtmann 
2234611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2235611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2236611b30f7SMarcel Holtmann };
2237611b30f7SMarcel Holtmann 
2238ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2239ab81cbf9SJohan Hedberg {
2240ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
224196570ffcSJohan Hedberg 	int err;
2242ab81cbf9SJohan Hedberg 
2243ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2244ab81cbf9SJohan Hedberg 
22452ff13894SJohan Hedberg 	if (test_bit(HCI_UP, &hdev->flags) &&
22462ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT) &&
22472ff13894SJohan Hedberg 	    hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
2248d82142a8SWei-Ning Huang 		cancel_delayed_work(&hdev->power_off);
22492ff13894SJohan Hedberg 		hci_req_sync_lock(hdev);
22502ff13894SJohan Hedberg 		err = __hci_req_hci_power_on(hdev);
22512ff13894SJohan Hedberg 		hci_req_sync_unlock(hdev);
22522ff13894SJohan Hedberg 		mgmt_power_on(hdev, err);
22532ff13894SJohan Hedberg 		return;
22542ff13894SJohan Hedberg 	}
22552ff13894SJohan Hedberg 
2256cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
225796570ffcSJohan Hedberg 	if (err < 0) {
22583ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
225996570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
22603ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
2261ab81cbf9SJohan Hedberg 		return;
226296570ffcSJohan Hedberg 	}
2263ab81cbf9SJohan Hedberg 
2264a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2265a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2266a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2267a5c8f270SMarcel Holtmann 	 */
2268d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
2269d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
2270ca8bee5dSMarcel Holtmann 	    (hdev->dev_type == HCI_PRIMARY &&
2271a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2272a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2273a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
2274bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2275d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
227619202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
227719202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2278bf543036SJohan Hedberg 	}
2279ab81cbf9SJohan Hedberg 
2280a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
22814a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
22824a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
22834a964404SMarcel Holtmann 		 */
2284d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
22854a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
22860602a8adSMarcel Holtmann 
22870602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
22880602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
22890602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
22900602a8adSMarcel Holtmann 		 *
22910602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
22920602a8adSMarcel Holtmann 		 * and no event will be send.
22930602a8adSMarcel Holtmann 		 */
2294744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2295a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
22965ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
22975ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
22985ea234d3SMarcel Holtmann 		 */
2299d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
23005ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
23015ea234d3SMarcel Holtmann 
2302d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
2303d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
2304d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
2305d603b76bSMarcel Holtmann 		 */
2306d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
2307ab81cbf9SJohan Hedberg 	}
2308ab81cbf9SJohan Hedberg }
2309ab81cbf9SJohan Hedberg 
2310ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2311ab81cbf9SJohan Hedberg {
23123243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
23133243553fSJohan Hedberg 					    power_off.work);
2314ab81cbf9SJohan Hedberg 
2315ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2316ab81cbf9SJohan Hedberg 
23178ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2318ab81cbf9SJohan Hedberg }
2319ab81cbf9SJohan Hedberg 
2320c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
2321c7741d16SMarcel Holtmann {
2322c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
2323c7741d16SMarcel Holtmann 
2324c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2325c7741d16SMarcel Holtmann 
2326c7741d16SMarcel Holtmann 	if (hdev->hw_error)
2327c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
2328c7741d16SMarcel Holtmann 	else
23292064ee33SMarcel Holtmann 		bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
2330c7741d16SMarcel Holtmann 
2331c7741d16SMarcel Holtmann 	if (hci_dev_do_close(hdev))
2332c7741d16SMarcel Holtmann 		return;
2333c7741d16SMarcel Holtmann 
2334c7741d16SMarcel Holtmann 	hci_dev_do_open(hdev);
2335c7741d16SMarcel Holtmann }
2336c7741d16SMarcel Holtmann 
233735f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
23382aeb9a1aSJohan Hedberg {
23394821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
23402aeb9a1aSJohan Hedberg 
23414821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
23424821002cSJohan Hedberg 		list_del(&uuid->list);
23432aeb9a1aSJohan Hedberg 		kfree(uuid);
23442aeb9a1aSJohan Hedberg 	}
23452aeb9a1aSJohan Hedberg }
23462aeb9a1aSJohan Hedberg 
234735f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
234855ed8ca1SJohan Hedberg {
234955ed8ca1SJohan Hedberg 	struct link_key *key;
235055ed8ca1SJohan Hedberg 
2351d7d41682SMadhuparna Bhowmik 	list_for_each_entry(key, &hdev->link_keys, list) {
23520378b597SJohan Hedberg 		list_del_rcu(&key->list);
23530378b597SJohan Hedberg 		kfree_rcu(key, rcu);
235455ed8ca1SJohan Hedberg 	}
235555ed8ca1SJohan Hedberg }
235655ed8ca1SJohan Hedberg 
235735f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2358b899efafSVinicius Costa Gomes {
2359970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2360b899efafSVinicius Costa Gomes 
2361d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->long_term_keys, list) {
2362970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2363970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2364b899efafSVinicius Costa Gomes 	}
2365b899efafSVinicius Costa Gomes }
2366b899efafSVinicius Costa Gomes 
2367970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2368970c4e46SJohan Hedberg {
2369adae20cbSJohan Hedberg 	struct smp_irk *k;
2370970c4e46SJohan Hedberg 
2371d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->identity_resolving_keys, list) {
2372adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2373adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2374970c4e46SJohan Hedberg 	}
2375970c4e46SJohan Hedberg }
2376970c4e46SJohan Hedberg 
2377600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev)
2378600a8749SAlain Michaud {
2379600a8749SAlain Michaud 	struct blocked_key *b;
2380600a8749SAlain Michaud 
2381d7d41682SMadhuparna Bhowmik 	list_for_each_entry(b, &hdev->blocked_keys, list) {
2382600a8749SAlain Michaud 		list_del_rcu(&b->list);
2383600a8749SAlain Michaud 		kfree_rcu(b, rcu);
2384600a8749SAlain Michaud 	}
2385600a8749SAlain Michaud }
2386600a8749SAlain Michaud 
2387600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16])
2388600a8749SAlain Michaud {
2389600a8749SAlain Michaud 	bool blocked = false;
2390600a8749SAlain Michaud 	struct blocked_key *b;
2391600a8749SAlain Michaud 
2392600a8749SAlain Michaud 	rcu_read_lock();
23930c2ac7d4SMadhuparna Bhowmik 	list_for_each_entry_rcu(b, &hdev->blocked_keys, list) {
2394600a8749SAlain Michaud 		if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) {
2395600a8749SAlain Michaud 			blocked = true;
2396600a8749SAlain Michaud 			break;
2397600a8749SAlain Michaud 		}
2398600a8749SAlain Michaud 	}
2399600a8749SAlain Michaud 
2400600a8749SAlain Michaud 	rcu_read_unlock();
2401600a8749SAlain Michaud 	return blocked;
2402600a8749SAlain Michaud }
2403600a8749SAlain Michaud 
240455ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
240555ed8ca1SJohan Hedberg {
240655ed8ca1SJohan Hedberg 	struct link_key *k;
240755ed8ca1SJohan Hedberg 
24080378b597SJohan Hedberg 	rcu_read_lock();
24090378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
24100378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
24110378b597SJohan Hedberg 			rcu_read_unlock();
2412600a8749SAlain Michaud 
2413600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev,
2414600a8749SAlain Michaud 					       HCI_BLOCKED_KEY_TYPE_LINKKEY,
2415600a8749SAlain Michaud 					       k->val)) {
2416600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
2417600a8749SAlain Michaud 							"Link key blocked for %pMR",
2418600a8749SAlain Michaud 							&k->bdaddr);
2419600a8749SAlain Michaud 				return NULL;
2420600a8749SAlain Michaud 			}
2421600a8749SAlain Michaud 
242255ed8ca1SJohan Hedberg 			return k;
24230378b597SJohan Hedberg 		}
24240378b597SJohan Hedberg 	}
24250378b597SJohan Hedberg 	rcu_read_unlock();
242655ed8ca1SJohan Hedberg 
242755ed8ca1SJohan Hedberg 	return NULL;
242855ed8ca1SJohan Hedberg }
242955ed8ca1SJohan Hedberg 
2430745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2431d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2432d25e28abSJohan Hedberg {
2433d25e28abSJohan Hedberg 	/* Legacy key */
2434d25e28abSJohan Hedberg 	if (key_type < 0x03)
2435745c0ce3SVishal Agarwal 		return true;
2436d25e28abSJohan Hedberg 
2437d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2438d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2439745c0ce3SVishal Agarwal 		return false;
2440d25e28abSJohan Hedberg 
2441d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2442d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2443745c0ce3SVishal Agarwal 		return false;
2444d25e28abSJohan Hedberg 
2445d25e28abSJohan Hedberg 	/* Security mode 3 case */
2446d25e28abSJohan Hedberg 	if (!conn)
2447745c0ce3SVishal Agarwal 		return true;
2448d25e28abSJohan Hedberg 
2449e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
2450e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
2451e3befab9SJohan Hedberg 		return true;
2452e3befab9SJohan Hedberg 
2453d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2454d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2455745c0ce3SVishal Agarwal 		return true;
2456d25e28abSJohan Hedberg 
2457d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2458d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2459745c0ce3SVishal Agarwal 		return true;
2460d25e28abSJohan Hedberg 
2461d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2462d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2463745c0ce3SVishal Agarwal 		return true;
2464d25e28abSJohan Hedberg 
2465d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2466d25e28abSJohan Hedberg 	 * persistently */
2467745c0ce3SVishal Agarwal 	return false;
2468d25e28abSJohan Hedberg }
2469d25e28abSJohan Hedberg 
2470e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
247198a0b845SJohan Hedberg {
2472e804d25dSJohan Hedberg 	if (type == SMP_LTK)
2473e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
247498a0b845SJohan Hedberg 
2475e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
247698a0b845SJohan Hedberg }
247798a0b845SJohan Hedberg 
2478f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2479e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
248075d262c2SVinicius Costa Gomes {
2481c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
248275d262c2SVinicius Costa Gomes 
2483970d0f1bSJohan Hedberg 	rcu_read_lock();
2484970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
24855378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
24865378bc56SJohan Hedberg 			continue;
24875378bc56SJohan Hedberg 
2488923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
2489970d0f1bSJohan Hedberg 			rcu_read_unlock();
2490600a8749SAlain Michaud 
2491600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK,
2492600a8749SAlain Michaud 					       k->val)) {
2493600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
2494600a8749SAlain Michaud 							"LTK blocked for %pMR",
2495600a8749SAlain Michaud 							&k->bdaddr);
2496600a8749SAlain Michaud 				return NULL;
2497600a8749SAlain Michaud 			}
2498600a8749SAlain Michaud 
249975d262c2SVinicius Costa Gomes 			return k;
2500970d0f1bSJohan Hedberg 		}
2501970d0f1bSJohan Hedberg 	}
2502970d0f1bSJohan Hedberg 	rcu_read_unlock();
250375d262c2SVinicius Costa Gomes 
250475d262c2SVinicius Costa Gomes 	return NULL;
250575d262c2SVinicius Costa Gomes }
250675d262c2SVinicius Costa Gomes 
2507970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2508970c4e46SJohan Hedberg {
2509600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
2510970c4e46SJohan Hedberg 	struct smp_irk *irk;
2511970c4e46SJohan Hedberg 
2512adae20cbSJohan Hedberg 	rcu_read_lock();
2513adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2514adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
2515600a8749SAlain Michaud 			irk_to_return = irk;
2516600a8749SAlain Michaud 			goto done;
2517970c4e46SJohan Hedberg 		}
2518adae20cbSJohan Hedberg 	}
2519970c4e46SJohan Hedberg 
2520adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2521defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
2522970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
2523600a8749SAlain Michaud 			irk_to_return = irk;
2524600a8749SAlain Michaud 			goto done;
2525970c4e46SJohan Hedberg 		}
2526970c4e46SJohan Hedberg 	}
2527600a8749SAlain Michaud 
2528600a8749SAlain Michaud done:
2529600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
2530600a8749SAlain Michaud 						irk_to_return->val)) {
2531600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
2532600a8749SAlain Michaud 					&irk_to_return->bdaddr);
2533600a8749SAlain Michaud 		irk_to_return = NULL;
2534600a8749SAlain Michaud 	}
2535600a8749SAlain Michaud 
2536adae20cbSJohan Hedberg 	rcu_read_unlock();
2537970c4e46SJohan Hedberg 
2538600a8749SAlain Michaud 	return irk_to_return;
2539970c4e46SJohan Hedberg }
2540970c4e46SJohan Hedberg 
2541970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2542970c4e46SJohan Hedberg 				     u8 addr_type)
2543970c4e46SJohan Hedberg {
2544600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
2545970c4e46SJohan Hedberg 	struct smp_irk *irk;
2546970c4e46SJohan Hedberg 
25476cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
25486cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
25496cfc9988SJohan Hedberg 		return NULL;
25506cfc9988SJohan Hedberg 
2551adae20cbSJohan Hedberg 	rcu_read_lock();
2552adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2553970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
2554adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
2555600a8749SAlain Michaud 			irk_to_return = irk;
2556600a8749SAlain Michaud 			goto done;
2557970c4e46SJohan Hedberg 		}
2558adae20cbSJohan Hedberg 	}
2559600a8749SAlain Michaud 
2560600a8749SAlain Michaud done:
2561600a8749SAlain Michaud 
2562600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
2563600a8749SAlain Michaud 						irk_to_return->val)) {
2564600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
2565600a8749SAlain Michaud 					&irk_to_return->bdaddr);
2566600a8749SAlain Michaud 		irk_to_return = NULL;
2567600a8749SAlain Michaud 	}
2568600a8749SAlain Michaud 
2569adae20cbSJohan Hedberg 	rcu_read_unlock();
2570970c4e46SJohan Hedberg 
2571600a8749SAlain Michaud 	return irk_to_return;
2572970c4e46SJohan Hedberg }
2573970c4e46SJohan Hedberg 
2574567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
25757652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
25767652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
257755ed8ca1SJohan Hedberg {
257855ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2579745c0ce3SVishal Agarwal 	u8 old_key_type;
258055ed8ca1SJohan Hedberg 
258155ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
258255ed8ca1SJohan Hedberg 	if (old_key) {
258355ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
258455ed8ca1SJohan Hedberg 		key = old_key;
258555ed8ca1SJohan Hedberg 	} else {
258612adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
25870a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
258855ed8ca1SJohan Hedberg 		if (!key)
2589567fa2aaSJohan Hedberg 			return NULL;
25900378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
259155ed8ca1SJohan Hedberg 	}
259255ed8ca1SJohan Hedberg 
25936ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
259455ed8ca1SJohan Hedberg 
2595d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2596d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2597d25e28abSJohan Hedberg 	 * previous key */
2598d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2599a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2600d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2601655fe6ecSJohan Hedberg 		if (conn)
2602655fe6ecSJohan Hedberg 			conn->key_type = type;
2603655fe6ecSJohan Hedberg 	}
2604d25e28abSJohan Hedberg 
260555ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
26069b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
260755ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
260855ed8ca1SJohan Hedberg 
2609b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
261055ed8ca1SJohan Hedberg 		key->type = old_key_type;
26114748fed2SJohan Hedberg 	else
26124748fed2SJohan Hedberg 		key->type = type;
26134748fed2SJohan Hedberg 
26147652ff6aSJohan Hedberg 	if (persistent)
26157652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
26167652ff6aSJohan Hedberg 						 old_key_type);
26174df378a1SJohan Hedberg 
2618567fa2aaSJohan Hedberg 	return key;
261955ed8ca1SJohan Hedberg }
262055ed8ca1SJohan Hedberg 
2621ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
262235d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
2623fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
262475d262c2SVinicius Costa Gomes {
2625c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
2626e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
262775d262c2SVinicius Costa Gomes 
2628f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
2629c9839a11SVinicius Costa Gomes 	if (old_key)
263075d262c2SVinicius Costa Gomes 		key = old_key;
2631c9839a11SVinicius Costa Gomes 	else {
26320a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
263375d262c2SVinicius Costa Gomes 		if (!key)
2634ca9142b8SJohan Hedberg 			return NULL;
2635970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
263675d262c2SVinicius Costa Gomes 	}
263775d262c2SVinicius Costa Gomes 
263875d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2639c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2640c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2641c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2642c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2643fe39c7b2SMarcel Holtmann 	key->rand = rand;
2644c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2645c9839a11SVinicius Costa Gomes 	key->type = type;
264675d262c2SVinicius Costa Gomes 
2647ca9142b8SJohan Hedberg 	return key;
264875d262c2SVinicius Costa Gomes }
264975d262c2SVinicius Costa Gomes 
2650ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2651ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
2652970c4e46SJohan Hedberg {
2653970c4e46SJohan Hedberg 	struct smp_irk *irk;
2654970c4e46SJohan Hedberg 
2655970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2656970c4e46SJohan Hedberg 	if (!irk) {
2657970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
2658970c4e46SJohan Hedberg 		if (!irk)
2659ca9142b8SJohan Hedberg 			return NULL;
2660970c4e46SJohan Hedberg 
2661970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
2662970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
2663970c4e46SJohan Hedberg 
2664adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
2665970c4e46SJohan Hedberg 	}
2666970c4e46SJohan Hedberg 
2667970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
2668970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
2669970c4e46SJohan Hedberg 
2670ca9142b8SJohan Hedberg 	return irk;
2671970c4e46SJohan Hedberg }
2672970c4e46SJohan Hedberg 
267355ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
267455ed8ca1SJohan Hedberg {
267555ed8ca1SJohan Hedberg 	struct link_key *key;
267655ed8ca1SJohan Hedberg 
267755ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
267855ed8ca1SJohan Hedberg 	if (!key)
267955ed8ca1SJohan Hedberg 		return -ENOENT;
268055ed8ca1SJohan Hedberg 
26816ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
268255ed8ca1SJohan Hedberg 
26830378b597SJohan Hedberg 	list_del_rcu(&key->list);
26840378b597SJohan Hedberg 	kfree_rcu(key, rcu);
268555ed8ca1SJohan Hedberg 
268655ed8ca1SJohan Hedberg 	return 0;
268755ed8ca1SJohan Hedberg }
268855ed8ca1SJohan Hedberg 
2689e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2690b899efafSVinicius Costa Gomes {
2691970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2692c51ffa0bSJohan Hedberg 	int removed = 0;
2693b899efafSVinicius Costa Gomes 
2694970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2695e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2696b899efafSVinicius Costa Gomes 			continue;
2697b899efafSVinicius Costa Gomes 
26986ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2699b899efafSVinicius Costa Gomes 
2700970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2701970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2702c51ffa0bSJohan Hedberg 		removed++;
2703b899efafSVinicius Costa Gomes 	}
2704b899efafSVinicius Costa Gomes 
2705c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
2706b899efafSVinicius Costa Gomes }
2707b899efafSVinicius Costa Gomes 
2708a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
2709a7ec7338SJohan Hedberg {
2710adae20cbSJohan Hedberg 	struct smp_irk *k;
2711a7ec7338SJohan Hedberg 
2712adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2713a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
2714a7ec7338SJohan Hedberg 			continue;
2715a7ec7338SJohan Hedberg 
2716a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2717a7ec7338SJohan Hedberg 
2718adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2719adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2720a7ec7338SJohan Hedberg 	}
2721a7ec7338SJohan Hedberg }
2722a7ec7338SJohan Hedberg 
272355e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
272455e76b38SJohan Hedberg {
272555e76b38SJohan Hedberg 	struct smp_ltk *k;
27264ba9faf3SJohan Hedberg 	struct smp_irk *irk;
272755e76b38SJohan Hedberg 	u8 addr_type;
272855e76b38SJohan Hedberg 
272955e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
273055e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
273155e76b38SJohan Hedberg 			return true;
273255e76b38SJohan Hedberg 		return false;
273355e76b38SJohan Hedberg 	}
273455e76b38SJohan Hedberg 
273555e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
273655e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
273755e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
273855e76b38SJohan Hedberg 	else
273955e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
274055e76b38SJohan Hedberg 
27414ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
27424ba9faf3SJohan Hedberg 	if (irk) {
27434ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
27444ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
27454ba9faf3SJohan Hedberg 	}
27464ba9faf3SJohan Hedberg 
274755e76b38SJohan Hedberg 	rcu_read_lock();
274855e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
274987c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
275087c8b28dSJohan Hedberg 			rcu_read_unlock();
275155e76b38SJohan Hedberg 			return true;
275255e76b38SJohan Hedberg 		}
275387c8b28dSJohan Hedberg 	}
275455e76b38SJohan Hedberg 	rcu_read_unlock();
275555e76b38SJohan Hedberg 
275655e76b38SJohan Hedberg 	return false;
275755e76b38SJohan Hedberg }
275855e76b38SJohan Hedberg 
27596bd32326SVille Tervo /* HCI command timer function */
276065cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
27616bd32326SVille Tervo {
276265cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
276365cc2b49SMarcel Holtmann 					    cmd_timer.work);
27646bd32326SVille Tervo 
2765bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2766bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2767bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2768bda4f23aSAndrei Emeltchenko 
27692064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
2770bda4f23aSAndrei Emeltchenko 	} else {
27712064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command tx timeout");
2772bda4f23aSAndrei Emeltchenko 	}
2773bda4f23aSAndrei Emeltchenko 
2774e2bef384SRajat Jain 	if (hdev->cmd_timeout)
2775e2bef384SRajat Jain 		hdev->cmd_timeout(hdev);
2776e2bef384SRajat Jain 
27776bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2778c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
27796bd32326SVille Tervo }
27806bd32326SVille Tervo 
2781de75cd0dSManish Mandlik /* HCI ncmd timer function */
2782de75cd0dSManish Mandlik static void hci_ncmd_timeout(struct work_struct *work)
2783de75cd0dSManish Mandlik {
2784de75cd0dSManish Mandlik 	struct hci_dev *hdev = container_of(work, struct hci_dev,
2785de75cd0dSManish Mandlik 					    ncmd_timer.work);
2786de75cd0dSManish Mandlik 
2787de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Controller not accepting commands anymore: ncmd = 0");
2788de75cd0dSManish Mandlik 
2789de75cd0dSManish Mandlik 	/* During HCI_INIT phase no events can be injected if the ncmd timer
2790de75cd0dSManish Mandlik 	 * triggers since the procedure has its own timeout handling.
2791de75cd0dSManish Mandlik 	 */
2792de75cd0dSManish Mandlik 	if (test_bit(HCI_INIT, &hdev->flags))
2793de75cd0dSManish Mandlik 		return;
2794de75cd0dSManish Mandlik 
2795de75cd0dSManish Mandlik 	/* This is an irrecoverable state, inject hardware error event */
2796de75cd0dSManish Mandlik 	hci_reset_dev(hdev);
2797de75cd0dSManish Mandlik }
2798de75cd0dSManish Mandlik 
27992763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
28006928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
28012763eda6SSzymon Janc {
28022763eda6SSzymon Janc 	struct oob_data *data;
28032763eda6SSzymon Janc 
28046928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
28056928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
28066928a924SJohan Hedberg 			continue;
28076928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
28086928a924SJohan Hedberg 			continue;
28092763eda6SSzymon Janc 		return data;
28106928a924SJohan Hedberg 	}
28112763eda6SSzymon Janc 
28122763eda6SSzymon Janc 	return NULL;
28132763eda6SSzymon Janc }
28142763eda6SSzymon Janc 
28156928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
28166928a924SJohan Hedberg 			       u8 bdaddr_type)
28172763eda6SSzymon Janc {
28182763eda6SSzymon Janc 	struct oob_data *data;
28192763eda6SSzymon Janc 
28206928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
28212763eda6SSzymon Janc 	if (!data)
28222763eda6SSzymon Janc 		return -ENOENT;
28232763eda6SSzymon Janc 
28246928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
28252763eda6SSzymon Janc 
28262763eda6SSzymon Janc 	list_del(&data->list);
28272763eda6SSzymon Janc 	kfree(data);
28282763eda6SSzymon Janc 
28292763eda6SSzymon Janc 	return 0;
28302763eda6SSzymon Janc }
28312763eda6SSzymon Janc 
283235f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
28332763eda6SSzymon Janc {
28342763eda6SSzymon Janc 	struct oob_data *data, *n;
28352763eda6SSzymon Janc 
28362763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
28372763eda6SSzymon Janc 		list_del(&data->list);
28382763eda6SSzymon Janc 		kfree(data);
28392763eda6SSzymon Janc 	}
28402763eda6SSzymon Janc }
28412763eda6SSzymon Janc 
28420798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
28436928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
284438da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
28450798872eSMarcel Holtmann {
28460798872eSMarcel Holtmann 	struct oob_data *data;
28470798872eSMarcel Holtmann 
28486928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
28490798872eSMarcel Holtmann 	if (!data) {
28500a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
28510798872eSMarcel Holtmann 		if (!data)
28520798872eSMarcel Holtmann 			return -ENOMEM;
28530798872eSMarcel Holtmann 
28540798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
28556928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
28560798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
28570798872eSMarcel Holtmann 	}
28580798872eSMarcel Holtmann 
285981328d5cSJohan Hedberg 	if (hash192 && rand192) {
28600798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
286138da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
2862f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2863f7697b16SMarcel Holtmann 			data->present = 0x03;
286481328d5cSJohan Hedberg 	} else {
286581328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
286681328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
2867f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2868f7697b16SMarcel Holtmann 			data->present = 0x02;
2869f7697b16SMarcel Holtmann 		else
2870f7697b16SMarcel Holtmann 			data->present = 0x00;
287181328d5cSJohan Hedberg 	}
28720798872eSMarcel Holtmann 
287381328d5cSJohan Hedberg 	if (hash256 && rand256) {
28740798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
287538da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
287681328d5cSJohan Hedberg 	} else {
287781328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
287881328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
2879f7697b16SMarcel Holtmann 		if (hash192 && rand192)
2880f7697b16SMarcel Holtmann 			data->present = 0x01;
288181328d5cSJohan Hedberg 	}
28820798872eSMarcel Holtmann 
28836ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
28842763eda6SSzymon Janc 
28852763eda6SSzymon Janc 	return 0;
28862763eda6SSzymon Janc }
28872763eda6SSzymon Janc 
2888d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2889d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
2890d2609b34SFlorian Grandel {
2891d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2892d2609b34SFlorian Grandel 
2893d2609b34SFlorian Grandel 	list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
2894d2609b34SFlorian Grandel 		if (adv_instance->instance == instance)
2895d2609b34SFlorian Grandel 			return adv_instance;
2896d2609b34SFlorian Grandel 	}
2897d2609b34SFlorian Grandel 
2898d2609b34SFlorian Grandel 	return NULL;
2899d2609b34SFlorian Grandel }
2900d2609b34SFlorian Grandel 
2901d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
290274b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
290374b93e9fSPrasanna Karthik {
2904d2609b34SFlorian Grandel 	struct adv_info *cur_instance;
2905d2609b34SFlorian Grandel 
2906d2609b34SFlorian Grandel 	cur_instance = hci_find_adv_instance(hdev, instance);
2907d2609b34SFlorian Grandel 	if (!cur_instance)
2908d2609b34SFlorian Grandel 		return NULL;
2909d2609b34SFlorian Grandel 
2910d2609b34SFlorian Grandel 	if (cur_instance == list_last_entry(&hdev->adv_instances,
2911d2609b34SFlorian Grandel 					    struct adv_info, list))
2912d2609b34SFlorian Grandel 		return list_first_entry(&hdev->adv_instances,
2913d2609b34SFlorian Grandel 						 struct adv_info, list);
2914d2609b34SFlorian Grandel 	else
2915d2609b34SFlorian Grandel 		return list_next_entry(cur_instance, list);
2916d2609b34SFlorian Grandel }
2917d2609b34SFlorian Grandel 
2918d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2919d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
2920d2609b34SFlorian Grandel {
2921d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2922d2609b34SFlorian Grandel 
2923d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
2924d2609b34SFlorian Grandel 	if (!adv_instance)
2925d2609b34SFlorian Grandel 		return -ENOENT;
2926d2609b34SFlorian Grandel 
2927d2609b34SFlorian Grandel 	BT_DBG("%s removing %dMR", hdev->name, instance);
2928d2609b34SFlorian Grandel 
2929cab054abSJohan Hedberg 	if (hdev->cur_adv_instance == instance) {
2930cab054abSJohan Hedberg 		if (hdev->adv_instance_timeout) {
29315d900e46SFlorian Grandel 			cancel_delayed_work(&hdev->adv_instance_expire);
29325d900e46SFlorian Grandel 			hdev->adv_instance_timeout = 0;
29335d900e46SFlorian Grandel 		}
2934cab054abSJohan Hedberg 		hdev->cur_adv_instance = 0x00;
2935cab054abSJohan Hedberg 	}
29365d900e46SFlorian Grandel 
2937a73c046aSJaganath Kanakkassery 	cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
2938a73c046aSJaganath Kanakkassery 
2939d2609b34SFlorian Grandel 	list_del(&adv_instance->list);
2940d2609b34SFlorian Grandel 	kfree(adv_instance);
2941d2609b34SFlorian Grandel 
2942d2609b34SFlorian Grandel 	hdev->adv_instance_cnt--;
2943d2609b34SFlorian Grandel 
2944d2609b34SFlorian Grandel 	return 0;
2945d2609b34SFlorian Grandel }
2946d2609b34SFlorian Grandel 
2947a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired)
2948a73c046aSJaganath Kanakkassery {
2949a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance, *n;
2950a73c046aSJaganath Kanakkassery 
2951a73c046aSJaganath Kanakkassery 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list)
2952a73c046aSJaganath Kanakkassery 		adv_instance->rpa_expired = rpa_expired;
2953a73c046aSJaganath Kanakkassery }
2954a73c046aSJaganath Kanakkassery 
2955d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2956d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev)
2957d2609b34SFlorian Grandel {
2958d2609b34SFlorian Grandel 	struct adv_info *adv_instance, *n;
2959d2609b34SFlorian Grandel 
29605d900e46SFlorian Grandel 	if (hdev->adv_instance_timeout) {
29615d900e46SFlorian Grandel 		cancel_delayed_work(&hdev->adv_instance_expire);
29625d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
29635d900e46SFlorian Grandel 	}
29645d900e46SFlorian Grandel 
2965d2609b34SFlorian Grandel 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
2966a73c046aSJaganath Kanakkassery 		cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
2967d2609b34SFlorian Grandel 		list_del(&adv_instance->list);
2968d2609b34SFlorian Grandel 		kfree(adv_instance);
2969d2609b34SFlorian Grandel 	}
2970d2609b34SFlorian Grandel 
2971d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
2972cab054abSJohan Hedberg 	hdev->cur_adv_instance = 0x00;
2973d2609b34SFlorian Grandel }
2974d2609b34SFlorian Grandel 
2975a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work)
2976a73c046aSJaganath Kanakkassery {
2977a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance = container_of(work, struct adv_info,
2978a73c046aSJaganath Kanakkassery 						     rpa_expired_cb.work);
2979a73c046aSJaganath Kanakkassery 
2980a73c046aSJaganath Kanakkassery 	BT_DBG("");
2981a73c046aSJaganath Kanakkassery 
2982a73c046aSJaganath Kanakkassery 	adv_instance->rpa_expired = true;
2983a73c046aSJaganath Kanakkassery }
2984a73c046aSJaganath Kanakkassery 
2985d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2986d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
2987d2609b34SFlorian Grandel 			 u16 adv_data_len, u8 *adv_data,
2988d2609b34SFlorian Grandel 			 u16 scan_rsp_len, u8 *scan_rsp_data,
29899bf9f4b6SDaniel Winkler 			 u16 timeout, u16 duration, s8 tx_power,
29909bf9f4b6SDaniel Winkler 			 u32 min_interval, u32 max_interval)
2991d2609b34SFlorian Grandel {
2992d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2993d2609b34SFlorian Grandel 
2994d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
2995d2609b34SFlorian Grandel 	if (adv_instance) {
2996d2609b34SFlorian Grandel 		memset(adv_instance->adv_data, 0,
2997d2609b34SFlorian Grandel 		       sizeof(adv_instance->adv_data));
2998d2609b34SFlorian Grandel 		memset(adv_instance->scan_rsp_data, 0,
2999d2609b34SFlorian Grandel 		       sizeof(adv_instance->scan_rsp_data));
3000d2609b34SFlorian Grandel 	} else {
30011d0fac2cSLuiz Augusto von Dentz 		if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
300287597482SDaniel Winkler 		    instance < 1 || instance > hdev->le_num_of_adv_sets)
3003d2609b34SFlorian Grandel 			return -EOVERFLOW;
3004d2609b34SFlorian Grandel 
300539ecfad6SJohan Hedberg 		adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL);
3006d2609b34SFlorian Grandel 		if (!adv_instance)
3007d2609b34SFlorian Grandel 			return -ENOMEM;
3008d2609b34SFlorian Grandel 
3009fffd38bcSFlorian Grandel 		adv_instance->pending = true;
3010d2609b34SFlorian Grandel 		adv_instance->instance = instance;
3011d2609b34SFlorian Grandel 		list_add(&adv_instance->list, &hdev->adv_instances);
3012d2609b34SFlorian Grandel 		hdev->adv_instance_cnt++;
3013d2609b34SFlorian Grandel 	}
3014d2609b34SFlorian Grandel 
3015d2609b34SFlorian Grandel 	adv_instance->flags = flags;
3016d2609b34SFlorian Grandel 	adv_instance->adv_data_len = adv_data_len;
3017d2609b34SFlorian Grandel 	adv_instance->scan_rsp_len = scan_rsp_len;
30189bf9f4b6SDaniel Winkler 	adv_instance->min_interval = min_interval;
30199bf9f4b6SDaniel Winkler 	adv_instance->max_interval = max_interval;
30209bf9f4b6SDaniel Winkler 	adv_instance->tx_power = tx_power;
3021d2609b34SFlorian Grandel 
3022d2609b34SFlorian Grandel 	if (adv_data_len)
3023d2609b34SFlorian Grandel 		memcpy(adv_instance->adv_data, adv_data, adv_data_len);
3024d2609b34SFlorian Grandel 
3025d2609b34SFlorian Grandel 	if (scan_rsp_len)
3026d2609b34SFlorian Grandel 		memcpy(adv_instance->scan_rsp_data,
3027d2609b34SFlorian Grandel 		       scan_rsp_data, scan_rsp_len);
3028d2609b34SFlorian Grandel 
3029d2609b34SFlorian Grandel 	adv_instance->timeout = timeout;
30305d900e46SFlorian Grandel 	adv_instance->remaining_time = timeout;
3031d2609b34SFlorian Grandel 
3032d2609b34SFlorian Grandel 	if (duration == 0)
303310873f99SAlain Michaud 		adv_instance->duration = hdev->def_multi_adv_rotation_duration;
3034d2609b34SFlorian Grandel 	else
3035d2609b34SFlorian Grandel 		adv_instance->duration = duration;
3036d2609b34SFlorian Grandel 
3037a73c046aSJaganath Kanakkassery 	INIT_DELAYED_WORK(&adv_instance->rpa_expired_cb,
3038a73c046aSJaganath Kanakkassery 			  adv_instance_rpa_expired);
3039a73c046aSJaganath Kanakkassery 
3040d2609b34SFlorian Grandel 	BT_DBG("%s for %dMR", hdev->name, instance);
3041d2609b34SFlorian Grandel 
3042d2609b34SFlorian Grandel 	return 0;
3043d2609b34SFlorian Grandel }
3044d2609b34SFlorian Grandel 
3045e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */
304631aab5c2SDaniel Winkler int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,
304731aab5c2SDaniel Winkler 			      u16 adv_data_len, u8 *adv_data,
304831aab5c2SDaniel Winkler 			      u16 scan_rsp_len, u8 *scan_rsp_data)
304931aab5c2SDaniel Winkler {
305031aab5c2SDaniel Winkler 	struct adv_info *adv_instance;
305131aab5c2SDaniel Winkler 
305231aab5c2SDaniel Winkler 	adv_instance = hci_find_adv_instance(hdev, instance);
305331aab5c2SDaniel Winkler 
305431aab5c2SDaniel Winkler 	/* If advertisement doesn't exist, we can't modify its data */
305531aab5c2SDaniel Winkler 	if (!adv_instance)
305631aab5c2SDaniel Winkler 		return -ENOENT;
305731aab5c2SDaniel Winkler 
305831aab5c2SDaniel Winkler 	if (adv_data_len) {
305931aab5c2SDaniel Winkler 		memset(adv_instance->adv_data, 0,
306031aab5c2SDaniel Winkler 		       sizeof(adv_instance->adv_data));
306131aab5c2SDaniel Winkler 		memcpy(adv_instance->adv_data, adv_data, adv_data_len);
306231aab5c2SDaniel Winkler 		adv_instance->adv_data_len = adv_data_len;
306331aab5c2SDaniel Winkler 	}
306431aab5c2SDaniel Winkler 
306531aab5c2SDaniel Winkler 	if (scan_rsp_len) {
306631aab5c2SDaniel Winkler 		memset(adv_instance->scan_rsp_data, 0,
306731aab5c2SDaniel Winkler 		       sizeof(adv_instance->scan_rsp_data));
306831aab5c2SDaniel Winkler 		memcpy(adv_instance->scan_rsp_data,
306931aab5c2SDaniel Winkler 		       scan_rsp_data, scan_rsp_len);
307031aab5c2SDaniel Winkler 		adv_instance->scan_rsp_len = scan_rsp_len;
307131aab5c2SDaniel Winkler 	}
307231aab5c2SDaniel Winkler 
307331aab5c2SDaniel Winkler 	return 0;
307431aab5c2SDaniel Winkler }
307531aab5c2SDaniel Winkler 
307631aab5c2SDaniel Winkler /* This function requires the caller holds hdev->lock */
3077e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev)
3078e5e1e7fdSMiao-chen Chou {
3079b139553dSMiao-chen Chou 	struct adv_monitor *monitor;
3080b139553dSMiao-chen Chou 	int handle;
3081b139553dSMiao-chen Chou 
3082b139553dSMiao-chen Chou 	idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
308366bd095aSArchie Pusaka 		hci_free_adv_monitor(hdev, monitor);
3084b139553dSMiao-chen Chou 
3085e5e1e7fdSMiao-chen Chou 	idr_destroy(&hdev->adv_monitors_idr);
3086e5e1e7fdSMiao-chen Chou }
3087e5e1e7fdSMiao-chen Chou 
308866bd095aSArchie Pusaka /* Frees the monitor structure and do some bookkeepings.
308966bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
309066bd095aSArchie Pusaka  */
309166bd095aSArchie Pusaka void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
3092b139553dSMiao-chen Chou {
3093b139553dSMiao-chen Chou 	struct adv_pattern *pattern;
3094b139553dSMiao-chen Chou 	struct adv_pattern *tmp;
3095b139553dSMiao-chen Chou 
3096b139553dSMiao-chen Chou 	if (!monitor)
3097b139553dSMiao-chen Chou 		return;
3098b139553dSMiao-chen Chou 
309966bd095aSArchie Pusaka 	list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) {
310066bd095aSArchie Pusaka 		list_del(&pattern->list);
3101b139553dSMiao-chen Chou 		kfree(pattern);
310266bd095aSArchie Pusaka 	}
310366bd095aSArchie Pusaka 
310466bd095aSArchie Pusaka 	if (monitor->handle)
310566bd095aSArchie Pusaka 		idr_remove(&hdev->adv_monitors_idr, monitor->handle);
310666bd095aSArchie Pusaka 
310766bd095aSArchie Pusaka 	if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) {
310866bd095aSArchie Pusaka 		hdev->adv_monitors_cnt--;
310966bd095aSArchie Pusaka 		mgmt_adv_monitor_removed(hdev, monitor->handle);
311066bd095aSArchie Pusaka 	}
3111b139553dSMiao-chen Chou 
3112b139553dSMiao-chen Chou 	kfree(monitor);
3113b139553dSMiao-chen Chou }
3114b139553dSMiao-chen Chou 
3115a2a4dedfSArchie Pusaka int hci_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status)
3116a2a4dedfSArchie Pusaka {
3117a2a4dedfSArchie Pusaka 	return mgmt_add_adv_patterns_monitor_complete(hdev, status);
3118a2a4dedfSArchie Pusaka }
3119a2a4dedfSArchie Pusaka 
312066bd095aSArchie Pusaka int hci_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status)
312166bd095aSArchie Pusaka {
312266bd095aSArchie Pusaka 	return mgmt_remove_adv_monitor_complete(hdev, status);
312366bd095aSArchie Pusaka }
312466bd095aSArchie Pusaka 
3125a2a4dedfSArchie Pusaka /* Assigns handle to a monitor, and if offloading is supported and power is on,
3126a2a4dedfSArchie Pusaka  * also attempts to forward the request to the controller.
3127a2a4dedfSArchie Pusaka  * Returns true if request is forwarded (result is pending), false otherwise.
3128a2a4dedfSArchie Pusaka  * This function requires the caller holds hdev->lock.
3129a2a4dedfSArchie Pusaka  */
3130a2a4dedfSArchie Pusaka bool hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor,
3131a2a4dedfSArchie Pusaka 			 int *err)
3132b139553dSMiao-chen Chou {
3133b139553dSMiao-chen Chou 	int min, max, handle;
3134b139553dSMiao-chen Chou 
3135a2a4dedfSArchie Pusaka 	*err = 0;
3136a2a4dedfSArchie Pusaka 
3137a2a4dedfSArchie Pusaka 	if (!monitor) {
3138a2a4dedfSArchie Pusaka 		*err = -EINVAL;
3139a2a4dedfSArchie Pusaka 		return false;
3140a2a4dedfSArchie Pusaka 	}
3141b139553dSMiao-chen Chou 
3142b139553dSMiao-chen Chou 	min = HCI_MIN_ADV_MONITOR_HANDLE;
3143b139553dSMiao-chen Chou 	max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES;
3144b139553dSMiao-chen Chou 	handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max,
3145b139553dSMiao-chen Chou 			   GFP_KERNEL);
3146a2a4dedfSArchie Pusaka 	if (handle < 0) {
3147a2a4dedfSArchie Pusaka 		*err = handle;
3148a2a4dedfSArchie Pusaka 		return false;
3149a2a4dedfSArchie Pusaka 	}
3150b139553dSMiao-chen Chou 
3151b139553dSMiao-chen Chou 	monitor->handle = handle;
31528208f5a9SMiao-chen Chou 
3153a2a4dedfSArchie Pusaka 	if (!hdev_is_powered(hdev))
3154a2a4dedfSArchie Pusaka 		return false;
31558208f5a9SMiao-chen Chou 
3156a2a4dedfSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
3157a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE:
3158a2a4dedfSArchie Pusaka 		hci_update_background_scan(hdev);
3159a2a4dedfSArchie Pusaka 		bt_dev_dbg(hdev, "%s add monitor status %d", hdev->name, *err);
3160a2a4dedfSArchie Pusaka 		/* Message was not forwarded to controller - not an error */
3161a2a4dedfSArchie Pusaka 		return false;
3162a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
3163a2a4dedfSArchie Pusaka 		*err = msft_add_monitor_pattern(hdev, monitor);
3164a2a4dedfSArchie Pusaka 		bt_dev_dbg(hdev, "%s add monitor msft status %d", hdev->name,
3165a2a4dedfSArchie Pusaka 			   *err);
3166a2a4dedfSArchie Pusaka 		break;
3167a2a4dedfSArchie Pusaka 	}
3168a2a4dedfSArchie Pusaka 
3169a2a4dedfSArchie Pusaka 	return (*err == 0);
3170b139553dSMiao-chen Chou }
3171b139553dSMiao-chen Chou 
317266bd095aSArchie Pusaka /* Attempts to tell the controller and free the monitor. If somehow the
317366bd095aSArchie Pusaka  * controller doesn't have a corresponding handle, remove anyway.
317466bd095aSArchie Pusaka  * Returns true if request is forwarded (result is pending), false otherwise.
317566bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
317666bd095aSArchie Pusaka  */
317766bd095aSArchie Pusaka static bool hci_remove_adv_monitor(struct hci_dev *hdev,
317866bd095aSArchie Pusaka 				   struct adv_monitor *monitor,
317966bd095aSArchie Pusaka 				   u16 handle, int *err)
3180bd2fbc6cSMiao-chen Chou {
318166bd095aSArchie Pusaka 	*err = 0;
3182bd2fbc6cSMiao-chen Chou 
318366bd095aSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
318466bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */
318566bd095aSArchie Pusaka 		goto free_monitor;
318666bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
318766bd095aSArchie Pusaka 		*err = msft_remove_monitor(hdev, monitor, handle);
318866bd095aSArchie Pusaka 		break;
3189bd2fbc6cSMiao-chen Chou 	}
3190bd2fbc6cSMiao-chen Chou 
319166bd095aSArchie Pusaka 	/* In case no matching handle registered, just free the monitor */
319266bd095aSArchie Pusaka 	if (*err == -ENOENT)
319366bd095aSArchie Pusaka 		goto free_monitor;
3194bd2fbc6cSMiao-chen Chou 
319566bd095aSArchie Pusaka 	return (*err == 0);
3196bd2fbc6cSMiao-chen Chou 
319766bd095aSArchie Pusaka free_monitor:
319866bd095aSArchie Pusaka 	if (*err == -ENOENT)
319966bd095aSArchie Pusaka 		bt_dev_warn(hdev, "Removing monitor with no matching handle %d",
320066bd095aSArchie Pusaka 			    monitor->handle);
320166bd095aSArchie Pusaka 	hci_free_adv_monitor(hdev, monitor);
320266bd095aSArchie Pusaka 
320366bd095aSArchie Pusaka 	*err = 0;
320466bd095aSArchie Pusaka 	return false;
3205bd2fbc6cSMiao-chen Chou }
3206bd2fbc6cSMiao-chen Chou 
320766bd095aSArchie Pusaka /* Returns true if request is forwarded (result is pending), false otherwise.
320866bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
320966bd095aSArchie Pusaka  */
321066bd095aSArchie Pusaka bool hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle, int *err)
321166bd095aSArchie Pusaka {
321266bd095aSArchie Pusaka 	struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle);
321366bd095aSArchie Pusaka 	bool pending;
321466bd095aSArchie Pusaka 
321566bd095aSArchie Pusaka 	if (!monitor) {
321666bd095aSArchie Pusaka 		*err = -EINVAL;
321766bd095aSArchie Pusaka 		return false;
321866bd095aSArchie Pusaka 	}
321966bd095aSArchie Pusaka 
322066bd095aSArchie Pusaka 	pending = hci_remove_adv_monitor(hdev, monitor, handle, err);
322166bd095aSArchie Pusaka 	if (!*err && !pending)
32228208f5a9SMiao-chen Chou 		hci_update_background_scan(hdev);
32238208f5a9SMiao-chen Chou 
322466bd095aSArchie Pusaka 	bt_dev_dbg(hdev, "%s remove monitor handle %d, status %d, %spending",
322566bd095aSArchie Pusaka 		   hdev->name, handle, *err, pending ? "" : "not ");
322666bd095aSArchie Pusaka 
322766bd095aSArchie Pusaka 	return pending;
322866bd095aSArchie Pusaka }
322966bd095aSArchie Pusaka 
323066bd095aSArchie Pusaka /* Returns true if request is forwarded (result is pending), false otherwise.
323166bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
323266bd095aSArchie Pusaka  */
323366bd095aSArchie Pusaka bool hci_remove_all_adv_monitor(struct hci_dev *hdev, int *err)
323466bd095aSArchie Pusaka {
323566bd095aSArchie Pusaka 	struct adv_monitor *monitor;
323666bd095aSArchie Pusaka 	int idr_next_id = 0;
323766bd095aSArchie Pusaka 	bool pending = false;
323866bd095aSArchie Pusaka 	bool update = false;
323966bd095aSArchie Pusaka 
324066bd095aSArchie Pusaka 	*err = 0;
324166bd095aSArchie Pusaka 
324266bd095aSArchie Pusaka 	while (!*err && !pending) {
324366bd095aSArchie Pusaka 		monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id);
324466bd095aSArchie Pusaka 		if (!monitor)
324566bd095aSArchie Pusaka 			break;
324666bd095aSArchie Pusaka 
324766bd095aSArchie Pusaka 		pending = hci_remove_adv_monitor(hdev, monitor, 0, err);
324866bd095aSArchie Pusaka 
324966bd095aSArchie Pusaka 		if (!*err && !pending)
325066bd095aSArchie Pusaka 			update = true;
325166bd095aSArchie Pusaka 	}
325266bd095aSArchie Pusaka 
325366bd095aSArchie Pusaka 	if (update)
325466bd095aSArchie Pusaka 		hci_update_background_scan(hdev);
325566bd095aSArchie Pusaka 
325666bd095aSArchie Pusaka 	bt_dev_dbg(hdev, "%s remove all monitors status %d, %spending",
325766bd095aSArchie Pusaka 		   hdev->name, *err, pending ? "" : "not ");
325866bd095aSArchie Pusaka 
325966bd095aSArchie Pusaka 	return pending;
3260bd2fbc6cSMiao-chen Chou }
3261bd2fbc6cSMiao-chen Chou 
32628208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */
32638208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev)
32648208f5a9SMiao-chen Chou {
32658208f5a9SMiao-chen Chou 	return !idr_is_empty(&hdev->adv_monitors_idr);
32668208f5a9SMiao-chen Chou }
32678208f5a9SMiao-chen Chou 
3268a2a4dedfSArchie Pusaka int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev)
3269a2a4dedfSArchie Pusaka {
3270a2a4dedfSArchie Pusaka 	if (msft_monitor_supported(hdev))
3271a2a4dedfSArchie Pusaka 		return HCI_ADV_MONITOR_EXT_MSFT;
3272a2a4dedfSArchie Pusaka 
3273a2a4dedfSArchie Pusaka 	return HCI_ADV_MONITOR_EXT_NONE;
3274a2a4dedfSArchie Pusaka }
3275a2a4dedfSArchie Pusaka 
3276dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
3277b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
3278b2a66aadSAntti Julku {
3279b2a66aadSAntti Julku 	struct bdaddr_list *b;
3280b2a66aadSAntti Julku 
3281dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
3282b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3283b2a66aadSAntti Julku 			return b;
3284b9ee0a78SMarcel Holtmann 	}
3285b2a66aadSAntti Julku 
3286b2a66aadSAntti Julku 	return NULL;
3287b2a66aadSAntti Julku }
3288b2a66aadSAntti Julku 
3289b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
3290b950aa88SAnkit Navik 				struct list_head *bdaddr_list, bdaddr_t *bdaddr,
3291b950aa88SAnkit Navik 				u8 type)
3292b950aa88SAnkit Navik {
3293b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *b;
3294b950aa88SAnkit Navik 
3295b950aa88SAnkit Navik 	list_for_each_entry(b, bdaddr_list, list) {
3296b950aa88SAnkit Navik 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3297b950aa88SAnkit Navik 			return b;
3298b950aa88SAnkit Navik 	}
3299b950aa88SAnkit Navik 
3300b950aa88SAnkit Navik 	return NULL;
3301b950aa88SAnkit Navik }
3302b950aa88SAnkit Navik 
33038baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *
33048baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
33058baaa403SAbhishek Pandit-Subedi 				  bdaddr_t *bdaddr, u8 type)
33068baaa403SAbhishek Pandit-Subedi {
33078baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *b;
33088baaa403SAbhishek Pandit-Subedi 
33098baaa403SAbhishek Pandit-Subedi 	list_for_each_entry(b, bdaddr_list, list) {
33108baaa403SAbhishek Pandit-Subedi 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
33118baaa403SAbhishek Pandit-Subedi 			return b;
33128baaa403SAbhishek Pandit-Subedi 	}
33138baaa403SAbhishek Pandit-Subedi 
33148baaa403SAbhishek Pandit-Subedi 	return NULL;
33158baaa403SAbhishek Pandit-Subedi }
33168baaa403SAbhishek Pandit-Subedi 
3317dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
3318b2a66aadSAntti Julku {
33197eb7404fSGeliang Tang 	struct bdaddr_list *b, *n;
3320b2a66aadSAntti Julku 
33217eb7404fSGeliang Tang 	list_for_each_entry_safe(b, n, bdaddr_list, list) {
33227eb7404fSGeliang Tang 		list_del(&b->list);
3323b2a66aadSAntti Julku 		kfree(b);
3324b2a66aadSAntti Julku 	}
3325b2a66aadSAntti Julku }
3326b2a66aadSAntti Julku 
3327dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3328b2a66aadSAntti Julku {
3329b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3330b2a66aadSAntti Julku 
3331b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3332b2a66aadSAntti Julku 		return -EBADF;
3333b2a66aadSAntti Julku 
3334dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
33355e762444SAntti Julku 		return -EEXIST;
3336b2a66aadSAntti Julku 
333727f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
33385e762444SAntti Julku 	if (!entry)
33395e762444SAntti Julku 		return -ENOMEM;
3340b2a66aadSAntti Julku 
3341b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3342b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3343b2a66aadSAntti Julku 
3344dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
3345b2a66aadSAntti Julku 
33462a8357f2SJohan Hedberg 	return 0;
3347b2a66aadSAntti Julku }
3348b2a66aadSAntti Julku 
3349b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
3350b950aa88SAnkit Navik 					u8 type, u8 *peer_irk, u8 *local_irk)
3351b950aa88SAnkit Navik {
3352b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
3353b950aa88SAnkit Navik 
3354b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY))
3355b950aa88SAnkit Navik 		return -EBADF;
3356b950aa88SAnkit Navik 
3357b950aa88SAnkit Navik 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
3358b950aa88SAnkit Navik 		return -EEXIST;
3359b950aa88SAnkit Navik 
3360b950aa88SAnkit Navik 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
3361b950aa88SAnkit Navik 	if (!entry)
3362b950aa88SAnkit Navik 		return -ENOMEM;
3363b950aa88SAnkit Navik 
3364b950aa88SAnkit Navik 	bacpy(&entry->bdaddr, bdaddr);
3365b950aa88SAnkit Navik 	entry->bdaddr_type = type;
3366b950aa88SAnkit Navik 
3367b950aa88SAnkit Navik 	if (peer_irk)
3368b950aa88SAnkit Navik 		memcpy(entry->peer_irk, peer_irk, 16);
3369b950aa88SAnkit Navik 
3370b950aa88SAnkit Navik 	if (local_irk)
3371b950aa88SAnkit Navik 		memcpy(entry->local_irk, local_irk, 16);
3372b950aa88SAnkit Navik 
3373b950aa88SAnkit Navik 	list_add(&entry->list, list);
3374b950aa88SAnkit Navik 
3375b950aa88SAnkit Navik 	return 0;
3376b950aa88SAnkit Navik }
3377b950aa88SAnkit Navik 
33788baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
33798baaa403SAbhishek Pandit-Subedi 				   u8 type, u32 flags)
33808baaa403SAbhishek Pandit-Subedi {
33818baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
33828baaa403SAbhishek Pandit-Subedi 
33838baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY))
33848baaa403SAbhishek Pandit-Subedi 		return -EBADF;
33858baaa403SAbhishek Pandit-Subedi 
33868baaa403SAbhishek Pandit-Subedi 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
33878baaa403SAbhishek Pandit-Subedi 		return -EEXIST;
33888baaa403SAbhishek Pandit-Subedi 
33898baaa403SAbhishek Pandit-Subedi 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
33908baaa403SAbhishek Pandit-Subedi 	if (!entry)
33918baaa403SAbhishek Pandit-Subedi 		return -ENOMEM;
33928baaa403SAbhishek Pandit-Subedi 
33938baaa403SAbhishek Pandit-Subedi 	bacpy(&entry->bdaddr, bdaddr);
33948baaa403SAbhishek Pandit-Subedi 	entry->bdaddr_type = type;
33958baaa403SAbhishek Pandit-Subedi 	entry->current_flags = flags;
33968baaa403SAbhishek Pandit-Subedi 
33978baaa403SAbhishek Pandit-Subedi 	list_add(&entry->list, list);
33988baaa403SAbhishek Pandit-Subedi 
33998baaa403SAbhishek Pandit-Subedi 	return 0;
34008baaa403SAbhishek Pandit-Subedi }
34018baaa403SAbhishek Pandit-Subedi 
3402dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3403b2a66aadSAntti Julku {
3404b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3405b2a66aadSAntti Julku 
340635f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3407dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
340835f7498aSJohan Hedberg 		return 0;
340935f7498aSJohan Hedberg 	}
3410b2a66aadSAntti Julku 
3411dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
3412d2ab0ac1SMarcel Holtmann 	if (!entry)
3413d2ab0ac1SMarcel Holtmann 		return -ENOENT;
3414d2ab0ac1SMarcel Holtmann 
3415d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
3416d2ab0ac1SMarcel Holtmann 	kfree(entry);
3417d2ab0ac1SMarcel Holtmann 
3418d2ab0ac1SMarcel Holtmann 	return 0;
3419d2ab0ac1SMarcel Holtmann }
3420d2ab0ac1SMarcel Holtmann 
3421b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
3422b950aa88SAnkit Navik 							u8 type)
3423b950aa88SAnkit Navik {
3424b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
3425b950aa88SAnkit Navik 
3426b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3427b950aa88SAnkit Navik 		hci_bdaddr_list_clear(list);
3428b950aa88SAnkit Navik 		return 0;
3429b950aa88SAnkit Navik 	}
3430b950aa88SAnkit Navik 
3431b950aa88SAnkit Navik 	entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
3432b950aa88SAnkit Navik 	if (!entry)
3433b950aa88SAnkit Navik 		return -ENOENT;
3434b950aa88SAnkit Navik 
3435b950aa88SAnkit Navik 	list_del(&entry->list);
3436b950aa88SAnkit Navik 	kfree(entry);
3437b950aa88SAnkit Navik 
3438b950aa88SAnkit Navik 	return 0;
3439b950aa88SAnkit Navik }
3440b950aa88SAnkit Navik 
34418baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
34428baaa403SAbhishek Pandit-Subedi 				   u8 type)
34438baaa403SAbhishek Pandit-Subedi {
34448baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
34458baaa403SAbhishek Pandit-Subedi 
34468baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY)) {
34478baaa403SAbhishek Pandit-Subedi 		hci_bdaddr_list_clear(list);
34488baaa403SAbhishek Pandit-Subedi 		return 0;
34498baaa403SAbhishek Pandit-Subedi 	}
34508baaa403SAbhishek Pandit-Subedi 
34518baaa403SAbhishek Pandit-Subedi 	entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
34528baaa403SAbhishek Pandit-Subedi 	if (!entry)
34538baaa403SAbhishek Pandit-Subedi 		return -ENOENT;
34548baaa403SAbhishek Pandit-Subedi 
34558baaa403SAbhishek Pandit-Subedi 	list_del(&entry->list);
34568baaa403SAbhishek Pandit-Subedi 	kfree(entry);
34578baaa403SAbhishek Pandit-Subedi 
34588baaa403SAbhishek Pandit-Subedi 	return 0;
34598baaa403SAbhishek Pandit-Subedi }
34608baaa403SAbhishek Pandit-Subedi 
346115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
346215819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
346315819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
346415819a70SAndre Guedes {
346515819a70SAndre Guedes 	struct hci_conn_params *params;
346615819a70SAndre Guedes 
346715819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
346815819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
346915819a70SAndre Guedes 		    params->addr_type == addr_type) {
347015819a70SAndre Guedes 			return params;
347115819a70SAndre Guedes 		}
347215819a70SAndre Guedes 	}
347315819a70SAndre Guedes 
347415819a70SAndre Guedes 	return NULL;
347515819a70SAndre Guedes }
347615819a70SAndre Guedes 
347715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
3478501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
34794b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
348015819a70SAndre Guedes {
3481912b42efSJohan Hedberg 	struct hci_conn_params *param;
348215819a70SAndre Guedes 
34836540351eSMarcel Holtmann 	switch (addr_type) {
34846540351eSMarcel Holtmann 	case ADDR_LE_DEV_PUBLIC_RESOLVED:
34856540351eSMarcel Holtmann 		addr_type = ADDR_LE_DEV_PUBLIC;
34866540351eSMarcel Holtmann 		break;
34876540351eSMarcel Holtmann 	case ADDR_LE_DEV_RANDOM_RESOLVED:
34886540351eSMarcel Holtmann 		addr_type = ADDR_LE_DEV_RANDOM;
34896540351eSMarcel Holtmann 		break;
34906540351eSMarcel Holtmann 	}
34916540351eSMarcel Holtmann 
3492501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
3493912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
3494912b42efSJohan Hedberg 		    param->addr_type == addr_type)
3495912b42efSJohan Hedberg 			return param;
34964b10966fSMarcel Holtmann 	}
34974b10966fSMarcel Holtmann 
34984b10966fSMarcel Holtmann 	return NULL;
349915819a70SAndre Guedes }
350015819a70SAndre Guedes 
350115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
350251d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
350351d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
350415819a70SAndre Guedes {
350515819a70SAndre Guedes 	struct hci_conn_params *params;
350615819a70SAndre Guedes 
350715819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
3508cef952ceSAndre Guedes 	if (params)
350951d167c0SMarcel Holtmann 		return params;
351015819a70SAndre Guedes 
351115819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
351215819a70SAndre Guedes 	if (!params) {
35132064ee33SMarcel Holtmann 		bt_dev_err(hdev, "out of memory");
351451d167c0SMarcel Holtmann 		return NULL;
351515819a70SAndre Guedes 	}
351615819a70SAndre Guedes 
351715819a70SAndre Guedes 	bacpy(&params->addr, addr);
351815819a70SAndre Guedes 	params->addr_type = addr_type;
3519cef952ceSAndre Guedes 
3520cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
352193450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
3522cef952ceSAndre Guedes 
3523bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
3524bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
3525bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
3526bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
3527bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
3528bf5b3c8bSMarcel Holtmann 
3529bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
3530bf5b3c8bSMarcel Holtmann 
353151d167c0SMarcel Holtmann 	return params;
3532bf5b3c8bSMarcel Holtmann }
3533bf5b3c8bSMarcel Holtmann 
3534f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
3535f6c63249SJohan Hedberg {
3536f6c63249SJohan Hedberg 	if (params->conn) {
3537f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
3538f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
3539f6c63249SJohan Hedberg 	}
3540f6c63249SJohan Hedberg 
3541f6c63249SJohan Hedberg 	list_del(&params->action);
3542f6c63249SJohan Hedberg 	list_del(&params->list);
3543f6c63249SJohan Hedberg 	kfree(params);
3544f6c63249SJohan Hedberg }
3545f6c63249SJohan Hedberg 
354615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
354715819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
354815819a70SAndre Guedes {
354915819a70SAndre Guedes 	struct hci_conn_params *params;
355015819a70SAndre Guedes 
355115819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
355215819a70SAndre Guedes 	if (!params)
355315819a70SAndre Guedes 		return;
355415819a70SAndre Guedes 
3555f6c63249SJohan Hedberg 	hci_conn_params_free(params);
355615819a70SAndre Guedes 
355795305baaSJohan Hedberg 	hci_update_background_scan(hdev);
355895305baaSJohan Hedberg 
355915819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
356015819a70SAndre Guedes }
356115819a70SAndre Guedes 
356215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
356355af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
356415819a70SAndre Guedes {
356515819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
356615819a70SAndre Guedes 
356715819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
356855af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
356955af49a8SJohan Hedberg 			continue;
3570f75113a2SJakub Pawlowski 
357191641b79SZheng Yongjun 		/* If trying to establish one time connection to disabled
3572f75113a2SJakub Pawlowski 		 * device, leave the params, but mark them as just once.
3573f75113a2SJakub Pawlowski 		 */
3574f75113a2SJakub Pawlowski 		if (params->explicit_connect) {
3575f75113a2SJakub Pawlowski 			params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
3576f75113a2SJakub Pawlowski 			continue;
3577f75113a2SJakub Pawlowski 		}
3578f75113a2SJakub Pawlowski 
357915819a70SAndre Guedes 		list_del(&params->list);
358015819a70SAndre Guedes 		kfree(params);
358115819a70SAndre Guedes 	}
358215819a70SAndre Guedes 
358355af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
358455af49a8SJohan Hedberg }
358555af49a8SJohan Hedberg 
358655af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
3587030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev)
358815819a70SAndre Guedes {
358915819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
359015819a70SAndre Guedes 
3591f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
3592f6c63249SJohan Hedberg 		hci_conn_params_free(params);
359315819a70SAndre Guedes 
359415819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
359515819a70SAndre Guedes }
359615819a70SAndre Guedes 
3597a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
3598a1f4c318SJohan Hedberg  *
3599a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
3600a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
3601a1f4c318SJohan Hedberg  * the static random address.
3602a1f4c318SJohan Hedberg  *
3603a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
3604a1f4c318SJohan Hedberg  * public address to use the static random address instead.
360550b5b952SMarcel Holtmann  *
360650b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
360750b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
360850b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
3609a1f4c318SJohan Hedberg  */
3610a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3611a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
3612a1f4c318SJohan Hedberg {
3613b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
361450b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
3615d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
361650b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
3617a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
3618a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
3619a1f4c318SJohan Hedberg 	} else {
3620a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
3621a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
3622a1f4c318SJohan Hedberg 	}
3623a1f4c318SJohan Hedberg }
3624a1f4c318SJohan Hedberg 
36250e995280SAbhishek Pandit-Subedi static void hci_suspend_clear_tasks(struct hci_dev *hdev)
36260e995280SAbhishek Pandit-Subedi {
36270e995280SAbhishek Pandit-Subedi 	int i;
36280e995280SAbhishek Pandit-Subedi 
36290e995280SAbhishek Pandit-Subedi 	for (i = 0; i < __SUSPEND_NUM_TASKS; i++)
36300e995280SAbhishek Pandit-Subedi 		clear_bit(i, hdev->suspend_tasks);
36310e995280SAbhishek Pandit-Subedi 
36320e995280SAbhishek Pandit-Subedi 	wake_up(&hdev->suspend_wait_q);
36330e995280SAbhishek Pandit-Subedi }
36340e995280SAbhishek Pandit-Subedi 
36359952d90eSAbhishek Pandit-Subedi static int hci_suspend_wait_event(struct hci_dev *hdev)
36369952d90eSAbhishek Pandit-Subedi {
36379952d90eSAbhishek Pandit-Subedi #define WAKE_COND                                                              \
36389952d90eSAbhishek Pandit-Subedi 	(find_first_bit(hdev->suspend_tasks, __SUSPEND_NUM_TASKS) ==           \
36399952d90eSAbhishek Pandit-Subedi 	 __SUSPEND_NUM_TASKS)
36409952d90eSAbhishek Pandit-Subedi 
36419952d90eSAbhishek Pandit-Subedi 	int i;
36429952d90eSAbhishek Pandit-Subedi 	int ret = wait_event_timeout(hdev->suspend_wait_q,
36439952d90eSAbhishek Pandit-Subedi 				     WAKE_COND, SUSPEND_NOTIFIER_TIMEOUT);
36449952d90eSAbhishek Pandit-Subedi 
36459952d90eSAbhishek Pandit-Subedi 	if (ret == 0) {
3646a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Timed out waiting for suspend events");
36479952d90eSAbhishek Pandit-Subedi 		for (i = 0; i < __SUSPEND_NUM_TASKS; ++i) {
36489952d90eSAbhishek Pandit-Subedi 			if (test_bit(i, hdev->suspend_tasks))
3649a9ec8423SAbhishek Pandit-Subedi 				bt_dev_err(hdev, "Suspend timeout bit: %d", i);
36509952d90eSAbhishek Pandit-Subedi 			clear_bit(i, hdev->suspend_tasks);
36519952d90eSAbhishek Pandit-Subedi 		}
36529952d90eSAbhishek Pandit-Subedi 
36539952d90eSAbhishek Pandit-Subedi 		ret = -ETIMEDOUT;
36549952d90eSAbhishek Pandit-Subedi 	} else {
36559952d90eSAbhishek Pandit-Subedi 		ret = 0;
36569952d90eSAbhishek Pandit-Subedi 	}
36579952d90eSAbhishek Pandit-Subedi 
36589952d90eSAbhishek Pandit-Subedi 	return ret;
36599952d90eSAbhishek Pandit-Subedi }
36609952d90eSAbhishek Pandit-Subedi 
36619952d90eSAbhishek Pandit-Subedi static void hci_prepare_suspend(struct work_struct *work)
36629952d90eSAbhishek Pandit-Subedi {
36639952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
36649952d90eSAbhishek Pandit-Subedi 		container_of(work, struct hci_dev, suspend_prepare);
36659952d90eSAbhishek Pandit-Subedi 
36669952d90eSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
36679952d90eSAbhishek Pandit-Subedi 	hci_req_prepare_suspend(hdev, hdev->suspend_state_next);
36689952d90eSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
36699952d90eSAbhishek Pandit-Subedi }
36709952d90eSAbhishek Pandit-Subedi 
36718731840aSAbhishek Pandit-Subedi static int hci_change_suspend_state(struct hci_dev *hdev,
36728731840aSAbhishek Pandit-Subedi 				    enum suspended_state next)
36738731840aSAbhishek Pandit-Subedi {
36748731840aSAbhishek Pandit-Subedi 	hdev->suspend_state_next = next;
36758731840aSAbhishek Pandit-Subedi 	set_bit(SUSPEND_PREPARE_NOTIFIER, hdev->suspend_tasks);
36768731840aSAbhishek Pandit-Subedi 	queue_work(hdev->req_workqueue, &hdev->suspend_prepare);
36778731840aSAbhishek Pandit-Subedi 	return hci_suspend_wait_event(hdev);
36788731840aSAbhishek Pandit-Subedi }
36798731840aSAbhishek Pandit-Subedi 
36802f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev)
36812f20216cSAbhishek Pandit-Subedi {
36822f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
36832f20216cSAbhishek Pandit-Subedi 
36842f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = 0;
36852f20216cSAbhishek Pandit-Subedi 	bacpy(&hdev->wake_addr, BDADDR_ANY);
36862f20216cSAbhishek Pandit-Subedi 	hdev->wake_addr_type = 0;
36872f20216cSAbhishek Pandit-Subedi 
36882f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
36892f20216cSAbhishek Pandit-Subedi }
36902f20216cSAbhishek Pandit-Subedi 
36919952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
36929952d90eSAbhishek Pandit-Subedi 				void *data)
36939952d90eSAbhishek Pandit-Subedi {
36949952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
36959952d90eSAbhishek Pandit-Subedi 		container_of(nb, struct hci_dev, suspend_notifier);
36969952d90eSAbhishek Pandit-Subedi 	int ret = 0;
36972f20216cSAbhishek Pandit-Subedi 	u8 state = BT_RUNNING;
36989952d90eSAbhishek Pandit-Subedi 
36999952d90eSAbhishek Pandit-Subedi 	/* If powering down, wait for completion. */
37009952d90eSAbhishek Pandit-Subedi 	if (mgmt_powering_down(hdev)) {
37019952d90eSAbhishek Pandit-Subedi 		set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks);
37029952d90eSAbhishek Pandit-Subedi 		ret = hci_suspend_wait_event(hdev);
37039952d90eSAbhishek Pandit-Subedi 		if (ret)
37049952d90eSAbhishek Pandit-Subedi 			goto done;
37059952d90eSAbhishek Pandit-Subedi 	}
37069952d90eSAbhishek Pandit-Subedi 
37079952d90eSAbhishek Pandit-Subedi 	/* Suspend notifier should only act on events when powered. */
37085ff20cbeSVamshi K Sthambamkadi 	if (!hdev_is_powered(hdev) ||
37095ff20cbeSVamshi K Sthambamkadi 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
37109952d90eSAbhishek Pandit-Subedi 		goto done;
37119952d90eSAbhishek Pandit-Subedi 
37129952d90eSAbhishek Pandit-Subedi 	if (action == PM_SUSPEND_PREPARE) {
37134f40afc6SAbhishek Pandit-Subedi 		/* Suspend consists of two actions:
37144f40afc6SAbhishek Pandit-Subedi 		 *  - First, disconnect everything and make the controller not
37154f40afc6SAbhishek Pandit-Subedi 		 *    connectable (disabling scanning)
37163d4f9c00SArchie Pusaka 		 *  - Second, program event filter/accept list and enable scan
37174f40afc6SAbhishek Pandit-Subedi 		 */
37188731840aSAbhishek Pandit-Subedi 		ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT);
37192f20216cSAbhishek Pandit-Subedi 		if (!ret)
37202f20216cSAbhishek Pandit-Subedi 			state = BT_SUSPEND_DISCONNECT;
37214f40afc6SAbhishek Pandit-Subedi 
37223d4f9c00SArchie Pusaka 		/* Only configure accept list if disconnect succeeded and wake
372381dafad5SAbhishek Pandit-Subedi 		 * isn't being prevented.
372481dafad5SAbhishek Pandit-Subedi 		 */
37252f20216cSAbhishek Pandit-Subedi 		if (!ret && !(hdev->prevent_wake && hdev->prevent_wake(hdev))) {
37268731840aSAbhishek Pandit-Subedi 			ret = hci_change_suspend_state(hdev,
37270d2c9825SAbhishek Pandit-Subedi 						BT_SUSPEND_CONFIGURE_WAKE);
37282f20216cSAbhishek Pandit-Subedi 			if (!ret)
37292f20216cSAbhishek Pandit-Subedi 				state = BT_SUSPEND_CONFIGURE_WAKE;
37302f20216cSAbhishek Pandit-Subedi 		}
37312f20216cSAbhishek Pandit-Subedi 
37322f20216cSAbhishek Pandit-Subedi 		hci_clear_wake_reason(hdev);
37332f20216cSAbhishek Pandit-Subedi 		mgmt_suspending(hdev, state);
37342f20216cSAbhishek Pandit-Subedi 
37359952d90eSAbhishek Pandit-Subedi 	} else if (action == PM_POST_SUSPEND) {
37368731840aSAbhishek Pandit-Subedi 		ret = hci_change_suspend_state(hdev, BT_RUNNING);
37372f20216cSAbhishek Pandit-Subedi 
37382f20216cSAbhishek Pandit-Subedi 		mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
37392f20216cSAbhishek Pandit-Subedi 			      hdev->wake_addr_type);
37409952d90eSAbhishek Pandit-Subedi 	}
37419952d90eSAbhishek Pandit-Subedi 
37429952d90eSAbhishek Pandit-Subedi done:
3743a9ec8423SAbhishek Pandit-Subedi 	/* We always allow suspend even if suspend preparation failed and
3744a9ec8423SAbhishek Pandit-Subedi 	 * attempt to recover in resume.
3745a9ec8423SAbhishek Pandit-Subedi 	 */
3746a9ec8423SAbhishek Pandit-Subedi 	if (ret)
3747a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
3748a9ec8423SAbhishek Pandit-Subedi 			   action, ret);
3749a9ec8423SAbhishek Pandit-Subedi 
375024b06572SMax Chou 	return NOTIFY_DONE;
37519952d90eSAbhishek Pandit-Subedi }
37528731840aSAbhishek Pandit-Subedi 
37539be0dab7SDavid Herrmann /* Alloc HCI device */
37549be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
37559be0dab7SDavid Herrmann {
37569be0dab7SDavid Herrmann 	struct hci_dev *hdev;
37579be0dab7SDavid Herrmann 
375827f70f3eSJohan Hedberg 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
37599be0dab7SDavid Herrmann 	if (!hdev)
37609be0dab7SDavid Herrmann 		return NULL;
37619be0dab7SDavid Herrmann 
3762b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3763b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3764b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3765b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3766b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
376796c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
3768bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3769bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3770d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
3771d2609b34SFlorian Grandel 	hdev->cur_adv_instance = 0x00;
37725d900e46SFlorian Grandel 	hdev->adv_instance_timeout = 0;
3773b1b813d4SDavid Herrmann 
3774c4f1f408SHoward Chung 	hdev->advmon_allowlist_duration = 300;
3775c4f1f408SHoward Chung 	hdev->advmon_no_filter_duration = 500;
377680af16a3SHoward Chung 	hdev->enable_advmon_interleave_scan = 0x00;	/* Default to disable */
3777c4f1f408SHoward Chung 
3778b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3779b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3780b1b813d4SDavid Herrmann 
37813f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3782628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
3783628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
3784bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3785bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
378610873f99SAlain Michaud 	hdev->le_scan_int_suspend = 0x0400;
378710873f99SAlain Michaud 	hdev->le_scan_window_suspend = 0x0012;
378810873f99SAlain Michaud 	hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
378910873f99SAlain Michaud 	hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
3790ba29d036SMarcel Holtmann 	hdev->le_scan_int_adv_monitor = 0x0060;
3791ba29d036SMarcel Holtmann 	hdev->le_scan_window_adv_monitor = 0x0030;
379210873f99SAlain Michaud 	hdev->le_scan_int_connect = 0x0060;
379310873f99SAlain Michaud 	hdev->le_scan_window_connect = 0x0060;
3794b48c3b59SJonas Holmberg 	hdev->le_conn_min_interval = 0x0018;
3795b48c3b59SJonas Holmberg 	hdev->le_conn_max_interval = 0x0028;
379604fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
379704fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
3798a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
3799a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
3800a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
3801a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
3802a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
3803a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
380430d65e08SMatias Karhumaa 	hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
380530d65e08SMatias Karhumaa 	hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
38066decb5b4SJaganath Kanakkassery 	hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
38076decb5b4SJaganath Kanakkassery 	hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
38081d0fac2cSLuiz Augusto von Dentz 	hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
380910873f99SAlain Michaud 	hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
381049b020c1SAlain Michaud 	hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT;
38117c395ea5SDaniel Winkler 	hdev->min_le_tx_power = HCI_TX_POWER_INVALID;
38127c395ea5SDaniel Winkler 	hdev->max_le_tx_power = HCI_TX_POWER_INVALID;
3813bef64738SMarcel Holtmann 
3814d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3815b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
381631ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
381731ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
3818302975cbSSpoorthi Ravishankar Koppad 	hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
381958a96fc3SMarcel Holtmann 	hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
3820d6bfd59cSJohan Hedberg 
382110873f99SAlain Michaud 	/* default 1.28 sec page scan */
382210873f99SAlain Michaud 	hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
382310873f99SAlain Michaud 	hdev->def_page_scan_int = 0x0800;
382410873f99SAlain Michaud 	hdev->def_page_scan_window = 0x0012;
382510873f99SAlain Michaud 
3826b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3827b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3828b1b813d4SDavid Herrmann 
3829b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
38303d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->reject_list);
38313d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->accept_list);
3832b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3833b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3834b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3835970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3836b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
38373d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->le_accept_list);
3838cfdb0c2dSAnkit Navik 	INIT_LIST_HEAD(&hdev->le_resolv_list);
383915819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
384077a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
384166f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
38426b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3843d2609b34SFlorian Grandel 	INIT_LIST_HEAD(&hdev->adv_instances);
3844600a8749SAlain Michaud 	INIT_LIST_HEAD(&hdev->blocked_keys);
3845b1b813d4SDavid Herrmann 
3846b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3847b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3848b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3849b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3850c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
38519952d90eSAbhishek Pandit-Subedi 	INIT_WORK(&hdev->suspend_prepare, hci_prepare_suspend);
3852b1b813d4SDavid Herrmann 
3853b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3854b1b813d4SDavid Herrmann 
3855b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3856b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3857b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3858b1b813d4SDavid Herrmann 
3859b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
38609952d90eSAbhishek Pandit-Subedi 	init_waitqueue_head(&hdev->suspend_wait_q);
3861b1b813d4SDavid Herrmann 
386265cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
3863de75cd0dSManish Mandlik 	INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout);
3864b1b813d4SDavid Herrmann 
38655fc16cc4SJohan Hedberg 	hci_request_setup(hdev);
38665fc16cc4SJohan Hedberg 
3867b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3868b1b813d4SDavid Herrmann 	discovery_init(hdev);
38699be0dab7SDavid Herrmann 
38709be0dab7SDavid Herrmann 	return hdev;
38719be0dab7SDavid Herrmann }
38729be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
38739be0dab7SDavid Herrmann 
38749be0dab7SDavid Herrmann /* Free HCI device */
38759be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
38769be0dab7SDavid Herrmann {
38779be0dab7SDavid Herrmann 	/* will free via device release */
38789be0dab7SDavid Herrmann 	put_device(&hdev->dev);
38799be0dab7SDavid Herrmann }
38809be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
38819be0dab7SDavid Herrmann 
38821da177e4SLinus Torvalds /* Register HCI device */
38831da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
38841da177e4SLinus Torvalds {
3885b1b813d4SDavid Herrmann 	int id, error;
38861da177e4SLinus Torvalds 
388774292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
38881da177e4SLinus Torvalds 		return -EINVAL;
38891da177e4SLinus Torvalds 
389008add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
389108add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
389208add513SMat Martineau 	 */
38933df92b31SSasha Levin 	switch (hdev->dev_type) {
3894ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
38953df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
38961da177e4SLinus Torvalds 		break;
38973df92b31SSasha Levin 	case HCI_AMP:
38983df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
38993df92b31SSasha Levin 		break;
39003df92b31SSasha Levin 	default:
39013df92b31SSasha Levin 		return -EINVAL;
39021da177e4SLinus Torvalds 	}
39031da177e4SLinus Torvalds 
39043df92b31SSasha Levin 	if (id < 0)
39053df92b31SSasha Levin 		return id;
39063df92b31SSasha Levin 
39071da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
39081da177e4SLinus Torvalds 	hdev->id = id;
39092d8b3a11SAndrei Emeltchenko 
39102d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
39112d8b3a11SAndrei Emeltchenko 
391229e2dd0dSTejun Heo 	hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
391333ca954dSDavid Herrmann 	if (!hdev->workqueue) {
391433ca954dSDavid Herrmann 		error = -ENOMEM;
391533ca954dSDavid Herrmann 		goto err;
391633ca954dSDavid Herrmann 	}
3917f48fd9c8SMarcel Holtmann 
391829e2dd0dSTejun Heo 	hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
391929e2dd0dSTejun Heo 						      hdev->name);
39206ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
39216ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
39226ead1bbcSJohan Hedberg 		error = -ENOMEM;
39236ead1bbcSJohan Hedberg 		goto err;
39246ead1bbcSJohan Hedberg 	}
39256ead1bbcSJohan Hedberg 
39260153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
39270153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
39280153e2ecSMarcel Holtmann 
3929bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3930bdc3e0f1SMarcel Holtmann 
3931bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
393233ca954dSDavid Herrmann 	if (error < 0)
393354506918SJohan Hedberg 		goto err_wqueue;
39341da177e4SLinus Torvalds 
39356d5d2ee6SHeiner Kallweit 	hci_leds_init(hdev);
39366d5d2ee6SHeiner Kallweit 
3937611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3938a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3939a8c5fb1aSGustavo Padovan 				    hdev);
3940611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3941611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3942611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3943611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3944611b30f7SMarcel Holtmann 		}
3945611b30f7SMarcel Holtmann 	}
3946611b30f7SMarcel Holtmann 
39475e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
3948a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
39495e130367SJohan Hedberg 
3950a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
3951a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
3952ce2be9acSAndrei Emeltchenko 
3953ca8bee5dSMarcel Holtmann 	if (hdev->dev_type == HCI_PRIMARY) {
395456f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
395556f87901SJohan Hedberg 		 * through reading supported features during init.
395656f87901SJohan Hedberg 		 */
3957a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
395856f87901SJohan Hedberg 	}
3959ce2be9acSAndrei Emeltchenko 
3960fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3961fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3962fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3963fcee3377SGustavo Padovan 
39644a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
39654a964404SMarcel Holtmann 	 * and should not be included in normal operation.
3966fee746b0SMarcel Holtmann 	 */
3967fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
3968a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
3969fee746b0SMarcel Holtmann 
397005fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_REG);
3971dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
39721da177e4SLinus Torvalds 
3973219991e6SHans de Goede 	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
39749952d90eSAbhishek Pandit-Subedi 		hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
39759952d90eSAbhishek Pandit-Subedi 		error = register_pm_notifier(&hdev->suspend_notifier);
39769952d90eSAbhishek Pandit-Subedi 		if (error)
39779952d90eSAbhishek Pandit-Subedi 			goto err_wqueue;
3978219991e6SHans de Goede 	}
39799952d90eSAbhishek Pandit-Subedi 
398019202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3981fbe96d6fSMarcel Holtmann 
3982e5e1e7fdSMiao-chen Chou 	idr_init(&hdev->adv_monitors_idr);
3983e5e1e7fdSMiao-chen Chou 
39841da177e4SLinus Torvalds 	return id;
3985f48fd9c8SMarcel Holtmann 
398633ca954dSDavid Herrmann err_wqueue:
398733ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
39886ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
398933ca954dSDavid Herrmann err:
39903df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
3991f48fd9c8SMarcel Holtmann 
399233ca954dSDavid Herrmann 	return error;
39931da177e4SLinus Torvalds }
39941da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
39951da177e4SLinus Torvalds 
39961da177e4SLinus Torvalds /* Unregister HCI device */
399759735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
39981da177e4SLinus Torvalds {
3999c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
40001da177e4SLinus Torvalds 
4001a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
400294324962SJohan Hovold 
4003f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
40041da177e4SLinus Torvalds 	list_del(&hdev->list);
4005f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
40061da177e4SLinus Torvalds 
4007b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
4008b9b5ef18SGustavo Padovan 
4009219991e6SHans de Goede 	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
40100e995280SAbhishek Pandit-Subedi 		hci_suspend_clear_tasks(hdev);
40119952d90eSAbhishek Pandit-Subedi 		unregister_pm_notifier(&hdev->suspend_notifier);
40124e8c36c3SAbhishek Pandit-Subedi 		cancel_work_sync(&hdev->suspend_prepare);
4013219991e6SHans de Goede 	}
40144e8c36c3SAbhishek Pandit-Subedi 
40154e8c36c3SAbhishek Pandit-Subedi 	hci_dev_do_close(hdev);
40169952d90eSAbhishek Pandit-Subedi 
4017ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
4018d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
4019d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
402009fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
4021744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
402209fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
402356e5cb86SJohan Hedberg 	}
4024ab81cbf9SJohan Hedberg 
40252e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
40262e58ef3eSJohan Hedberg 	 * pending list */
40272e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
40282e58ef3eSJohan Hedberg 
402905fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_UNREG);
40301da177e4SLinus Torvalds 
4031611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
4032611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
4033611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
4034611b30f7SMarcel Holtmann 	}
4035611b30f7SMarcel Holtmann 
4036bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
4037*e0448092STetsuo Handa 	/* Actual cleanup is deferred until hci_cleanup_dev(). */
4038*e0448092STetsuo Handa 	hci_dev_put(hdev);
4039*e0448092STetsuo Handa }
4040*e0448092STetsuo Handa EXPORT_SYMBOL(hci_unregister_dev);
4041147e2d59SDave Young 
4042*e0448092STetsuo Handa /* Cleanup HCI device */
4043*e0448092STetsuo Handa void hci_cleanup_dev(struct hci_dev *hdev)
4044*e0448092STetsuo Handa {
40450153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
40465177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
40475177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
40480153e2ecSMarcel Holtmann 
4049f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
40506ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
4051f48fd9c8SMarcel Holtmann 
405209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
40533d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->reject_list);
40543d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->accept_list);
40552aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
405655ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
4057b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
4058970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
40592763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
4060d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
4061e5e1e7fdSMiao-chen Chou 	hci_adv_monitors_clear(hdev);
40623d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
4063cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
4064373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
406522078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
4066600a8749SAlain Michaud 	hci_blocked_keys_clear(hdev);
406709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4068e2e0cacbSJohan Hedberg 
4069*e0448092STetsuo Handa 	ida_simple_remove(&hci_index_ida, hdev->id);
40701da177e4SLinus Torvalds }
40711da177e4SLinus Torvalds 
40721da177e4SLinus Torvalds /* Suspend HCI device */
40731da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
40741da177e4SLinus Torvalds {
407505fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
40761da177e4SLinus Torvalds 	return 0;
40771da177e4SLinus Torvalds }
40781da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
40791da177e4SLinus Torvalds 
40801da177e4SLinus Torvalds /* Resume HCI device */
40811da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
40821da177e4SLinus Torvalds {
408305fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_RESUME);
40841da177e4SLinus Torvalds 	return 0;
40851da177e4SLinus Torvalds }
40861da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
40871da177e4SLinus Torvalds 
408875e0569fSMarcel Holtmann /* Reset HCI device */
408975e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
409075e0569fSMarcel Holtmann {
40911e4b6e91SColin Ian King 	static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
409275e0569fSMarcel Holtmann 	struct sk_buff *skb;
409375e0569fSMarcel Holtmann 
409475e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
409575e0569fSMarcel Holtmann 	if (!skb)
409675e0569fSMarcel Holtmann 		return -ENOMEM;
409775e0569fSMarcel Holtmann 
4098d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
409959ae1d12SJohannes Berg 	skb_put_data(skb, hw_err, 3);
410075e0569fSMarcel Holtmann 
4101de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Injecting HCI hardware error event");
4102de75cd0dSManish Mandlik 
410375e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
410475e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
410575e0569fSMarcel Holtmann }
410675e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
410775e0569fSMarcel Holtmann 
410876bca880SMarcel Holtmann /* Receive frame from HCI drivers */
4109e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
411076bca880SMarcel Holtmann {
411176bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
411276bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
411376bca880SMarcel Holtmann 		kfree_skb(skb);
411476bca880SMarcel Holtmann 		return -ENXIO;
411576bca880SMarcel Holtmann 	}
411676bca880SMarcel Holtmann 
4117d79f34e3SMarcel Holtmann 	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
4118d79f34e3SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
4119cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT &&
4120cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) {
4121fe806dceSMarcel Holtmann 		kfree_skb(skb);
4122fe806dceSMarcel Holtmann 		return -EINVAL;
4123fe806dceSMarcel Holtmann 	}
4124fe806dceSMarcel Holtmann 
4125d82603c6SJorrit Schippers 	/* Incoming skb */
412676bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
412776bca880SMarcel Holtmann 
412876bca880SMarcel Holtmann 	/* Time stamp */
412976bca880SMarcel Holtmann 	__net_timestamp(skb);
413076bca880SMarcel Holtmann 
413176bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
4132b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
4133c78ae283SMarcel Holtmann 
413476bca880SMarcel Holtmann 	return 0;
413576bca880SMarcel Holtmann }
413676bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
413776bca880SMarcel Holtmann 
4138e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
4139e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
4140e875ff84SMarcel Holtmann {
4141581d6fd6SMarcel Holtmann 	/* Mark as diagnostic packet */
4142d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
4143581d6fd6SMarcel Holtmann 
4144e875ff84SMarcel Holtmann 	/* Time stamp */
4145e875ff84SMarcel Holtmann 	__net_timestamp(skb);
4146e875ff84SMarcel Holtmann 
4147581d6fd6SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
4148581d6fd6SMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
4149e875ff84SMarcel Holtmann 
4150e875ff84SMarcel Holtmann 	return 0;
4151e875ff84SMarcel Holtmann }
4152e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
4153e875ff84SMarcel Holtmann 
41545177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
41555177a838SMarcel Holtmann {
41565177a838SMarcel Holtmann 	va_list vargs;
41575177a838SMarcel Holtmann 
41585177a838SMarcel Holtmann 	va_start(vargs, fmt);
41595177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
41605177a838SMarcel Holtmann 	hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
41615177a838SMarcel Holtmann 	va_end(vargs);
41625177a838SMarcel Holtmann }
41635177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
41645177a838SMarcel Holtmann 
41655177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
41665177a838SMarcel Holtmann {
41675177a838SMarcel Holtmann 	va_list vargs;
41685177a838SMarcel Holtmann 
41695177a838SMarcel Holtmann 	va_start(vargs, fmt);
41705177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
41715177a838SMarcel Holtmann 	hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
41725177a838SMarcel Holtmann 	va_end(vargs);
41735177a838SMarcel Holtmann }
41745177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
41755177a838SMarcel Holtmann 
41761da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
41771da177e4SLinus Torvalds 
41781da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
41791da177e4SLinus Torvalds {
41801da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
41811da177e4SLinus Torvalds 
4182fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
418300629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
4184fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
41851da177e4SLinus Torvalds 
41861da177e4SLinus Torvalds 	return 0;
41871da177e4SLinus Torvalds }
41881da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
41891da177e4SLinus Torvalds 
41901da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
41911da177e4SLinus Torvalds {
41921da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
41931da177e4SLinus Torvalds 
4194fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
41951da177e4SLinus Torvalds 	list_del(&cb->list);
4196fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
41971da177e4SLinus Torvalds 
41981da177e4SLinus Torvalds 	return 0;
41991da177e4SLinus Torvalds }
42001da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
42011da177e4SLinus Torvalds 
420251086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
42031da177e4SLinus Torvalds {
4204cdc52faaSMarcel Holtmann 	int err;
4205cdc52faaSMarcel Holtmann 
4206d79f34e3SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
4207d79f34e3SMarcel Holtmann 	       skb->len);
42081da177e4SLinus Torvalds 
42091da177e4SLinus Torvalds 	/* Time stamp */
4210a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
42111da177e4SLinus Torvalds 
4212cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
4213cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
4214cd82e61cSMarcel Holtmann 
4215cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
4216cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
4217470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
42181da177e4SLinus Torvalds 	}
42191da177e4SLinus Torvalds 
42201da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
42211da177e4SLinus Torvalds 	skb_orphan(skb);
42221da177e4SLinus Torvalds 
422373d0d3c8SMarcel Holtmann 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
422473d0d3c8SMarcel Holtmann 		kfree_skb(skb);
422573d0d3c8SMarcel Holtmann 		return;
422673d0d3c8SMarcel Holtmann 	}
422773d0d3c8SMarcel Holtmann 
4228cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
4229cdc52faaSMarcel Holtmann 	if (err < 0) {
42302064ee33SMarcel Holtmann 		bt_dev_err(hdev, "sending frame failed (%d)", err);
4231cdc52faaSMarcel Holtmann 		kfree_skb(skb);
4232cdc52faaSMarcel Holtmann 	}
42331da177e4SLinus Torvalds }
42341da177e4SLinus Torvalds 
42351ca3a9d0SJohan Hedberg /* Send HCI command */
423607dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
423707dc93ddSJohan Hedberg 		 const void *param)
42381ca3a9d0SJohan Hedberg {
42391ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
42401ca3a9d0SJohan Hedberg 
42411ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
42421ca3a9d0SJohan Hedberg 
42431ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
42441ca3a9d0SJohan Hedberg 	if (!skb) {
42452064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no memory for command");
42461ca3a9d0SJohan Hedberg 		return -ENOMEM;
42471ca3a9d0SJohan Hedberg 	}
42481ca3a9d0SJohan Hedberg 
424949c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
425011714b3dSJohan Hedberg 	 * single-command requests.
425111714b3dSJohan Hedberg 	 */
425244d27137SJohan Hedberg 	bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
425311714b3dSJohan Hedberg 
42541da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
4255c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
42561da177e4SLinus Torvalds 
42571da177e4SLinus Torvalds 	return 0;
42581da177e4SLinus Torvalds }
42591da177e4SLinus Torvalds 
4260d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
4261d6ee6ad7SLoic Poulain 		   const void *param)
4262d6ee6ad7SLoic Poulain {
4263d6ee6ad7SLoic Poulain 	struct sk_buff *skb;
4264d6ee6ad7SLoic Poulain 
4265d6ee6ad7SLoic Poulain 	if (hci_opcode_ogf(opcode) != 0x3f) {
4266d6ee6ad7SLoic Poulain 		/* A controller receiving a command shall respond with either
4267d6ee6ad7SLoic Poulain 		 * a Command Status Event or a Command Complete Event.
4268d6ee6ad7SLoic Poulain 		 * Therefore, all standard HCI commands must be sent via the
4269d6ee6ad7SLoic Poulain 		 * standard API, using hci_send_cmd or hci_cmd_sync helpers.
4270d6ee6ad7SLoic Poulain 		 * Some vendors do not comply with this rule for vendor-specific
4271d6ee6ad7SLoic Poulain 		 * commands and do not return any event. We want to support
4272d6ee6ad7SLoic Poulain 		 * unresponded commands for such cases only.
4273d6ee6ad7SLoic Poulain 		 */
4274d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "unresponded command not supported");
4275d6ee6ad7SLoic Poulain 		return -EINVAL;
4276d6ee6ad7SLoic Poulain 	}
4277d6ee6ad7SLoic Poulain 
4278d6ee6ad7SLoic Poulain 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
4279d6ee6ad7SLoic Poulain 	if (!skb) {
4280d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
4281d6ee6ad7SLoic Poulain 			   opcode);
4282d6ee6ad7SLoic Poulain 		return -ENOMEM;
4283d6ee6ad7SLoic Poulain 	}
4284d6ee6ad7SLoic Poulain 
4285d6ee6ad7SLoic Poulain 	hci_send_frame(hdev, skb);
4286d6ee6ad7SLoic Poulain 
4287d6ee6ad7SLoic Poulain 	return 0;
4288d6ee6ad7SLoic Poulain }
4289d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
4290d6ee6ad7SLoic Poulain 
42911da177e4SLinus Torvalds /* Get data from the previously sent command */
4292a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
42931da177e4SLinus Torvalds {
42941da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
42951da177e4SLinus Torvalds 
42961da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
42971da177e4SLinus Torvalds 		return NULL;
42981da177e4SLinus Torvalds 
42991da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
43001da177e4SLinus Torvalds 
4301a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
43021da177e4SLinus Torvalds 		return NULL;
43031da177e4SLinus Torvalds 
4304f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
43051da177e4SLinus Torvalds 
43061da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
43071da177e4SLinus Torvalds }
43081da177e4SLinus Torvalds 
430991641b79SZheng Yongjun /* Send HCI command and wait for command complete event */
4310fbef168fSLoic Poulain struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
4311fbef168fSLoic Poulain 			     const void *param, u32 timeout)
4312fbef168fSLoic Poulain {
4313fbef168fSLoic Poulain 	struct sk_buff *skb;
4314fbef168fSLoic Poulain 
4315fbef168fSLoic Poulain 	if (!test_bit(HCI_UP, &hdev->flags))
4316fbef168fSLoic Poulain 		return ERR_PTR(-ENETDOWN);
4317fbef168fSLoic Poulain 
4318fbef168fSLoic Poulain 	bt_dev_dbg(hdev, "opcode 0x%4.4x plen %d", opcode, plen);
4319fbef168fSLoic Poulain 
4320b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
4321fbef168fSLoic Poulain 	skb = __hci_cmd_sync(hdev, opcode, plen, param, timeout);
4322b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
4323fbef168fSLoic Poulain 
4324fbef168fSLoic Poulain 	return skb;
4325fbef168fSLoic Poulain }
4326fbef168fSLoic Poulain EXPORT_SYMBOL(hci_cmd_sync);
4327fbef168fSLoic Poulain 
43281da177e4SLinus Torvalds /* Send ACL data */
43291da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
43301da177e4SLinus Torvalds {
43311da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
43321da177e4SLinus Torvalds 	int len = skb->len;
43331da177e4SLinus Torvalds 
4334badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
4335badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
43369c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
4337aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
4338aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
43391da177e4SLinus Torvalds }
43401da177e4SLinus Torvalds 
4341ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
434273d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
43431da177e4SLinus Torvalds {
4344ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
43451da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
43461da177e4SLinus Torvalds 	struct sk_buff *list;
43471da177e4SLinus Torvalds 
4348087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
4349087bfd99SGustavo Padovan 	skb->data_len = 0;
4350087bfd99SGustavo Padovan 
4351d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
4352204a6e54SAndrei Emeltchenko 
4353204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
4354ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
4355087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
4356204a6e54SAndrei Emeltchenko 		break;
4357204a6e54SAndrei Emeltchenko 	case HCI_AMP:
4358204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
4359204a6e54SAndrei Emeltchenko 		break;
4360204a6e54SAndrei Emeltchenko 	default:
43612064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
4362204a6e54SAndrei Emeltchenko 		return;
4363204a6e54SAndrei Emeltchenko 	}
4364087bfd99SGustavo Padovan 
436570f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
436670f23020SAndrei Emeltchenko 	if (!list) {
43671da177e4SLinus Torvalds 		/* Non fragmented */
43681da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
43691da177e4SLinus Torvalds 
437073d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
43711da177e4SLinus Torvalds 	} else {
43721da177e4SLinus Torvalds 		/* Fragmented */
43731da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
43741da177e4SLinus Torvalds 
43751da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
43761da177e4SLinus Torvalds 
43779cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
43789cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
43799cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
43809cfd5a23SJukka Rissanen 		 * deadlocks.
43819cfd5a23SJukka Rissanen 		 */
43829cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
43831da177e4SLinus Torvalds 
438473d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
4385e702112fSAndrei Emeltchenko 
4386e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
4387e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
43881da177e4SLinus Torvalds 		do {
43891da177e4SLinus Torvalds 			skb = list; list = list->next;
43901da177e4SLinus Torvalds 
4391d79f34e3SMarcel Holtmann 			hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
4392e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
43931da177e4SLinus Torvalds 
43941da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
43951da177e4SLinus Torvalds 
439673d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
43971da177e4SLinus Torvalds 		} while (list);
43981da177e4SLinus Torvalds 
43999cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
44001da177e4SLinus Torvalds 	}
440173d80debSLuiz Augusto von Dentz }
440273d80debSLuiz Augusto von Dentz 
440373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
440473d80debSLuiz Augusto von Dentz {
4405ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
440673d80debSLuiz Augusto von Dentz 
4407f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
440873d80debSLuiz Augusto von Dentz 
4409ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
44101da177e4SLinus Torvalds 
44113eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
44121da177e4SLinus Torvalds }
44131da177e4SLinus Torvalds 
44141da177e4SLinus Torvalds /* Send SCO data */
44150d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
44161da177e4SLinus Torvalds {
44171da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
44181da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
44191da177e4SLinus Torvalds 
44201da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
44211da177e4SLinus Torvalds 
4422aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
44231da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
44241da177e4SLinus Torvalds 
4425badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
4426badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
44279c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
44281da177e4SLinus Torvalds 
4429d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
4430c78ae283SMarcel Holtmann 
44311da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
44323eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
44331da177e4SLinus Torvalds }
44341da177e4SLinus Torvalds 
44351da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
44361da177e4SLinus Torvalds 
44371da177e4SLinus Torvalds /* HCI Connection scheduler */
44386039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
4439a8c5fb1aSGustavo Padovan 				     int *quote)
44401da177e4SLinus Torvalds {
44411da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
44428035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
4443abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
44441da177e4SLinus Torvalds 
44451da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
44461da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
4447bf4c6325SGustavo F. Padovan 
4448bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4449bf4c6325SGustavo F. Padovan 
4450bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4451769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
44521da177e4SLinus Torvalds 			continue;
4453769be974SMarcel Holtmann 
4454769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
4455769be974SMarcel Holtmann 			continue;
4456769be974SMarcel Holtmann 
44571da177e4SLinus Torvalds 		num++;
44581da177e4SLinus Torvalds 
44591da177e4SLinus Torvalds 		if (c->sent < min) {
44601da177e4SLinus Torvalds 			min  = c->sent;
44611da177e4SLinus Torvalds 			conn = c;
44621da177e4SLinus Torvalds 		}
446352087a79SLuiz Augusto von Dentz 
446452087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
446552087a79SLuiz Augusto von Dentz 			break;
44661da177e4SLinus Torvalds 	}
44671da177e4SLinus Torvalds 
4468bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4469bf4c6325SGustavo F. Padovan 
44701da177e4SLinus Torvalds 	if (conn) {
44716ed58ec5SVille Tervo 		int cnt, q;
44726ed58ec5SVille Tervo 
44736ed58ec5SVille Tervo 		switch (conn->type) {
44746ed58ec5SVille Tervo 		case ACL_LINK:
44756ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
44766ed58ec5SVille Tervo 			break;
44776ed58ec5SVille Tervo 		case SCO_LINK:
44786ed58ec5SVille Tervo 		case ESCO_LINK:
44796ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
44806ed58ec5SVille Tervo 			break;
44816ed58ec5SVille Tervo 		case LE_LINK:
44826ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
44836ed58ec5SVille Tervo 			break;
44846ed58ec5SVille Tervo 		default:
44856ed58ec5SVille Tervo 			cnt = 0;
44862064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown link type %d", conn->type);
44876ed58ec5SVille Tervo 		}
44886ed58ec5SVille Tervo 
44896ed58ec5SVille Tervo 		q = cnt / num;
44901da177e4SLinus Torvalds 		*quote = q ? q : 1;
44911da177e4SLinus Torvalds 	} else
44921da177e4SLinus Torvalds 		*quote = 0;
44931da177e4SLinus Torvalds 
44941da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
44951da177e4SLinus Torvalds 	return conn;
44961da177e4SLinus Torvalds }
44971da177e4SLinus Torvalds 
44986039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
44991da177e4SLinus Torvalds {
45001da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
45011da177e4SLinus Torvalds 	struct hci_conn *c;
45021da177e4SLinus Torvalds 
45032064ee33SMarcel Holtmann 	bt_dev_err(hdev, "link tx timeout");
45041da177e4SLinus Torvalds 
4505bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4506bf4c6325SGustavo F. Padovan 
45071da177e4SLinus Torvalds 	/* Kill stalled connections */
4508bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4509bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
45102064ee33SMarcel Holtmann 			bt_dev_err(hdev, "killing stalled connection %pMR",
45112064ee33SMarcel Holtmann 				   &c->dst);
4512bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
45131da177e4SLinus Torvalds 		}
45141da177e4SLinus Torvalds 	}
4515bf4c6325SGustavo F. Padovan 
4516bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
45171da177e4SLinus Torvalds }
45181da177e4SLinus Torvalds 
45196039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
452073d80debSLuiz Augusto von Dentz 				      int *quote)
452173d80debSLuiz Augusto von Dentz {
452273d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
452373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4524abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
452573d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
452673d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
452773d80debSLuiz Augusto von Dentz 
452873d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
452973d80debSLuiz Augusto von Dentz 
4530bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4531bf4c6325SGustavo F. Padovan 
4532bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
453373d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
453473d80debSLuiz Augusto von Dentz 
453573d80debSLuiz Augusto von Dentz 		if (conn->type != type)
453673d80debSLuiz Augusto von Dentz 			continue;
453773d80debSLuiz Augusto von Dentz 
453873d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
453973d80debSLuiz Augusto von Dentz 			continue;
454073d80debSLuiz Augusto von Dentz 
454173d80debSLuiz Augusto von Dentz 		conn_num++;
454273d80debSLuiz Augusto von Dentz 
45438192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
454473d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
454573d80debSLuiz Augusto von Dentz 
454673d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
454773d80debSLuiz Augusto von Dentz 				continue;
454873d80debSLuiz Augusto von Dentz 
454973d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
455073d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
455173d80debSLuiz Augusto von Dentz 				continue;
455273d80debSLuiz Augusto von Dentz 
455373d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
455473d80debSLuiz Augusto von Dentz 				num = 0;
455573d80debSLuiz Augusto von Dentz 				min = ~0;
455673d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
455773d80debSLuiz Augusto von Dentz 			}
455873d80debSLuiz Augusto von Dentz 
455973d80debSLuiz Augusto von Dentz 			num++;
456073d80debSLuiz Augusto von Dentz 
456173d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
456273d80debSLuiz Augusto von Dentz 				min  = conn->sent;
456373d80debSLuiz Augusto von Dentz 				chan = tmp;
456473d80debSLuiz Augusto von Dentz 			}
456573d80debSLuiz Augusto von Dentz 		}
456673d80debSLuiz Augusto von Dentz 
456773d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
456873d80debSLuiz Augusto von Dentz 			break;
456973d80debSLuiz Augusto von Dentz 	}
457073d80debSLuiz Augusto von Dentz 
4571bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4572bf4c6325SGustavo F. Padovan 
457373d80debSLuiz Augusto von Dentz 	if (!chan)
457473d80debSLuiz Augusto von Dentz 		return NULL;
457573d80debSLuiz Augusto von Dentz 
457673d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
457773d80debSLuiz Augusto von Dentz 	case ACL_LINK:
457873d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
457973d80debSLuiz Augusto von Dentz 		break;
4580bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4581bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4582bd1eb66bSAndrei Emeltchenko 		break;
458373d80debSLuiz Augusto von Dentz 	case SCO_LINK:
458473d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
458573d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
458673d80debSLuiz Augusto von Dentz 		break;
458773d80debSLuiz Augusto von Dentz 	case LE_LINK:
458873d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
458973d80debSLuiz Augusto von Dentz 		break;
459073d80debSLuiz Augusto von Dentz 	default:
459173d80debSLuiz Augusto von Dentz 		cnt = 0;
45922064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown link type %d", chan->conn->type);
459373d80debSLuiz Augusto von Dentz 	}
459473d80debSLuiz Augusto von Dentz 
459573d80debSLuiz Augusto von Dentz 	q = cnt / num;
459673d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
459773d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
459873d80debSLuiz Augusto von Dentz 	return chan;
459973d80debSLuiz Augusto von Dentz }
460073d80debSLuiz Augusto von Dentz 
460102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
460202b20f0bSLuiz Augusto von Dentz {
460302b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
460402b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
460502b20f0bSLuiz Augusto von Dentz 	int num = 0;
460602b20f0bSLuiz Augusto von Dentz 
460702b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
460802b20f0bSLuiz Augusto von Dentz 
4609bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4610bf4c6325SGustavo F. Padovan 
4611bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
461202b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
461302b20f0bSLuiz Augusto von Dentz 
461402b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
461502b20f0bSLuiz Augusto von Dentz 			continue;
461602b20f0bSLuiz Augusto von Dentz 
461702b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
461802b20f0bSLuiz Augusto von Dentz 			continue;
461902b20f0bSLuiz Augusto von Dentz 
462002b20f0bSLuiz Augusto von Dentz 		num++;
462102b20f0bSLuiz Augusto von Dentz 
46228192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
462302b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
462402b20f0bSLuiz Augusto von Dentz 
462502b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
462602b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
462702b20f0bSLuiz Augusto von Dentz 				continue;
462802b20f0bSLuiz Augusto von Dentz 			}
462902b20f0bSLuiz Augusto von Dentz 
463002b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
463102b20f0bSLuiz Augusto von Dentz 				continue;
463202b20f0bSLuiz Augusto von Dentz 
463302b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
463402b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
463502b20f0bSLuiz Augusto von Dentz 				continue;
463602b20f0bSLuiz Augusto von Dentz 
463702b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
463802b20f0bSLuiz Augusto von Dentz 
463902b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
464002b20f0bSLuiz Augusto von Dentz 			       skb->priority);
464102b20f0bSLuiz Augusto von Dentz 		}
464202b20f0bSLuiz Augusto von Dentz 
464302b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
464402b20f0bSLuiz Augusto von Dentz 			break;
464502b20f0bSLuiz Augusto von Dentz 	}
4646bf4c6325SGustavo F. Padovan 
4647bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4648bf4c6325SGustavo F. Padovan 
464902b20f0bSLuiz Augusto von Dentz }
465002b20f0bSLuiz Augusto von Dentz 
4651b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4652b71d385aSAndrei Emeltchenko {
4653b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4654b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4655b71d385aSAndrei Emeltchenko }
4656b71d385aSAndrei Emeltchenko 
46576039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
46581da177e4SLinus Torvalds {
4659d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
46601da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
46611da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
466263d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
46635f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4664bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
46651da177e4SLinus Torvalds 	}
466663d2bc1bSAndrei Emeltchenko }
46671da177e4SLinus Torvalds 
46687fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
46697fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
46707fedd3bbSAbhishek Pandit-Subedi {
46717fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
46727fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
46737fedd3bbSAbhishek Pandit-Subedi 	int quote;
46747fedd3bbSAbhishek Pandit-Subedi 
46757fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
46767fedd3bbSAbhishek Pandit-Subedi 
46777fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, SCO_LINK))
46787fedd3bbSAbhishek Pandit-Subedi 		return;
46797fedd3bbSAbhishek Pandit-Subedi 
46807fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
46817fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
46827fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
46837fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
46847fedd3bbSAbhishek Pandit-Subedi 
46857fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
46867fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
46877fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
46887fedd3bbSAbhishek Pandit-Subedi 		}
46897fedd3bbSAbhishek Pandit-Subedi 	}
46907fedd3bbSAbhishek Pandit-Subedi }
46917fedd3bbSAbhishek Pandit-Subedi 
46927fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
46937fedd3bbSAbhishek Pandit-Subedi {
46947fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
46957fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
46967fedd3bbSAbhishek Pandit-Subedi 	int quote;
46977fedd3bbSAbhishek Pandit-Subedi 
46987fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
46997fedd3bbSAbhishek Pandit-Subedi 
47007fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, ESCO_LINK))
47017fedd3bbSAbhishek Pandit-Subedi 		return;
47027fedd3bbSAbhishek Pandit-Subedi 
47037fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
47047fedd3bbSAbhishek Pandit-Subedi 						     &quote))) {
47057fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
47067fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
47077fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
47087fedd3bbSAbhishek Pandit-Subedi 
47097fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
47107fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
47117fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
47127fedd3bbSAbhishek Pandit-Subedi 		}
47137fedd3bbSAbhishek Pandit-Subedi 	}
47147fedd3bbSAbhishek Pandit-Subedi }
47157fedd3bbSAbhishek Pandit-Subedi 
47166039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
471763d2bc1bSAndrei Emeltchenko {
471863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
471963d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
472063d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
472163d2bc1bSAndrei Emeltchenko 	int quote;
472263d2bc1bSAndrei Emeltchenko 
472363d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
472404837f64SMarcel Holtmann 
472573d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
472673d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4727ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4728ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
472973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
473073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
473173d80debSLuiz Augusto von Dentz 
4732ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4733ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4734ec1cce24SLuiz Augusto von Dentz 				break;
4735ec1cce24SLuiz Augusto von Dentz 
4736ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4737ec1cce24SLuiz Augusto von Dentz 
473873d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
473973d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
474004837f64SMarcel Holtmann 
474157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
47421da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
47431da177e4SLinus Torvalds 
47441da177e4SLinus Torvalds 			hdev->acl_cnt--;
474573d80debSLuiz Augusto von Dentz 			chan->sent++;
474673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
47477fedd3bbSAbhishek Pandit-Subedi 
47487fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
47497fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
47507fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
47511da177e4SLinus Torvalds 		}
47521da177e4SLinus Torvalds 	}
475302b20f0bSLuiz Augusto von Dentz 
475402b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
475502b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
47561da177e4SLinus Torvalds }
47571da177e4SLinus Torvalds 
47586039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4759b71d385aSAndrei Emeltchenko {
476063d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4761b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4762b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4763b71d385aSAndrei Emeltchenko 	int quote;
4764bd1eb66bSAndrei Emeltchenko 	u8 type;
4765b71d385aSAndrei Emeltchenko 
476663d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
4767b71d385aSAndrei Emeltchenko 
4768bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4769bd1eb66bSAndrei Emeltchenko 
4770bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
4771bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
4772bd1eb66bSAndrei Emeltchenko 	else
4773bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
4774bd1eb66bSAndrei Emeltchenko 
4775b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
4776bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
4777b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
4778b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
4779b71d385aSAndrei Emeltchenko 			int blocks;
4780b71d385aSAndrei Emeltchenko 
4781b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
4782b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
4783b71d385aSAndrei Emeltchenko 
4784b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
4785b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
4786b71d385aSAndrei Emeltchenko 				break;
4787b71d385aSAndrei Emeltchenko 
4788b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
4789b71d385aSAndrei Emeltchenko 
4790b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
4791b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
4792b71d385aSAndrei Emeltchenko 				return;
4793b71d385aSAndrei Emeltchenko 
4794b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
4795b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
4796b71d385aSAndrei Emeltchenko 
479757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4798b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4799b71d385aSAndrei Emeltchenko 
4800b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4801b71d385aSAndrei Emeltchenko 			quote -= blocks;
4802b71d385aSAndrei Emeltchenko 
4803b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4804b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4805b71d385aSAndrei Emeltchenko 		}
4806b71d385aSAndrei Emeltchenko 	}
4807b71d385aSAndrei Emeltchenko 
4808b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4809bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4810b71d385aSAndrei Emeltchenko }
4811b71d385aSAndrei Emeltchenko 
48126039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4813b71d385aSAndrei Emeltchenko {
4814b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4815b71d385aSAndrei Emeltchenko 
4816bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4817ca8bee5dSMarcel Holtmann 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY)
4818bd1eb66bSAndrei Emeltchenko 		return;
4819bd1eb66bSAndrei Emeltchenko 
4820bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4821bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4822b71d385aSAndrei Emeltchenko 		return;
4823b71d385aSAndrei Emeltchenko 
4824b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4825b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4826b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4827b71d385aSAndrei Emeltchenko 		break;
4828b71d385aSAndrei Emeltchenko 
4829b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4830b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4831b71d385aSAndrei Emeltchenko 		break;
4832b71d385aSAndrei Emeltchenko 	}
4833b71d385aSAndrei Emeltchenko }
4834b71d385aSAndrei Emeltchenko 
48356039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
48366ed58ec5SVille Tervo {
483773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
48386ed58ec5SVille Tervo 	struct sk_buff *skb;
483902b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
48406ed58ec5SVille Tervo 
48416ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
48426ed58ec5SVille Tervo 
484352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
484452087a79SLuiz Augusto von Dentz 		return;
484552087a79SLuiz Augusto von Dentz 
48466ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
48471b1d29e5SLuiz Augusto von Dentz 
48481b1d29e5SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt);
48491b1d29e5SLuiz Augusto von Dentz 
485002b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
485173d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4852ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4853ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
485473d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
485573d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
48566ed58ec5SVille Tervo 
4857ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4858ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4859ec1cce24SLuiz Augusto von Dentz 				break;
4860ec1cce24SLuiz Augusto von Dentz 
4861ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4862ec1cce24SLuiz Augusto von Dentz 
486357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
48646ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
48656ed58ec5SVille Tervo 
48666ed58ec5SVille Tervo 			cnt--;
486773d80debSLuiz Augusto von Dentz 			chan->sent++;
486873d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
48697fedd3bbSAbhishek Pandit-Subedi 
48707fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
48717fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
48727fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
48736ed58ec5SVille Tervo 		}
48746ed58ec5SVille Tervo 	}
487573d80debSLuiz Augusto von Dentz 
48766ed58ec5SVille Tervo 	if (hdev->le_pkts)
48776ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
48786ed58ec5SVille Tervo 	else
48796ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
488002b20f0bSLuiz Augusto von Dentz 
488102b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
488202b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
48836ed58ec5SVille Tervo }
48846ed58ec5SVille Tervo 
48853eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
48861da177e4SLinus Torvalds {
48873eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
48881da177e4SLinus Torvalds 	struct sk_buff *skb;
48891da177e4SLinus Torvalds 
48906ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
48916ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
48921da177e4SLinus Torvalds 
4893d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
48941da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
48951da177e4SLinus Torvalds 		hci_sched_sco(hdev);
4896b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
48977fedd3bbSAbhishek Pandit-Subedi 		hci_sched_acl(hdev);
48986ed58ec5SVille Tervo 		hci_sched_le(hdev);
489952de599eSMarcel Holtmann 	}
49006ed58ec5SVille Tervo 
49011da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
49021da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
490357d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
49041da177e4SLinus Torvalds }
49051da177e4SLinus Torvalds 
490625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
49071da177e4SLinus Torvalds 
49081da177e4SLinus Torvalds /* ACL data packet */
49096039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
49101da177e4SLinus Torvalds {
49111da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
49121da177e4SLinus Torvalds 	struct hci_conn *conn;
49131da177e4SLinus Torvalds 	__u16 handle, flags;
49141da177e4SLinus Torvalds 
49151da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
49161da177e4SLinus Torvalds 
49171da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
49181da177e4SLinus Torvalds 	flags  = hci_flags(handle);
49191da177e4SLinus Torvalds 	handle = hci_handle(handle);
49201da177e4SLinus Torvalds 
4921f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4922a8c5fb1aSGustavo Padovan 	       handle, flags);
49231da177e4SLinus Torvalds 
49241da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
49251da177e4SLinus Torvalds 
49261da177e4SLinus Torvalds 	hci_dev_lock(hdev);
49271da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
49281da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
49291da177e4SLinus Torvalds 
49301da177e4SLinus Torvalds 	if (conn) {
493165983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
493204837f64SMarcel Holtmann 
49331da177e4SLinus Torvalds 		/* Send to upper protocol */
4934686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
49351da177e4SLinus Torvalds 		return;
49361da177e4SLinus Torvalds 	} else {
49372064ee33SMarcel Holtmann 		bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
49382064ee33SMarcel Holtmann 			   handle);
49391da177e4SLinus Torvalds 	}
49401da177e4SLinus Torvalds 
49411da177e4SLinus Torvalds 	kfree_skb(skb);
49421da177e4SLinus Torvalds }
49431da177e4SLinus Torvalds 
49441da177e4SLinus Torvalds /* SCO data packet */
49456039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
49461da177e4SLinus Torvalds {
49471da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
49481da177e4SLinus Torvalds 	struct hci_conn *conn;
4949debdedf2SMarcel Holtmann 	__u16 handle, flags;
49501da177e4SLinus Torvalds 
49511da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
49521da177e4SLinus Torvalds 
49531da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
4954debdedf2SMarcel Holtmann 	flags  = hci_flags(handle);
4955debdedf2SMarcel Holtmann 	handle = hci_handle(handle);
49561da177e4SLinus Torvalds 
4957debdedf2SMarcel Holtmann 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4958debdedf2SMarcel Holtmann 	       handle, flags);
49591da177e4SLinus Torvalds 
49601da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
49611da177e4SLinus Torvalds 
49621da177e4SLinus Torvalds 	hci_dev_lock(hdev);
49631da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
49641da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
49651da177e4SLinus Torvalds 
49661da177e4SLinus Torvalds 	if (conn) {
49671da177e4SLinus Torvalds 		/* Send to upper protocol */
496800398e1dSAlain Michaud 		bt_cb(skb)->sco.pkt_status = flags & 0x03;
4969686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
49701da177e4SLinus Torvalds 		return;
49711da177e4SLinus Torvalds 	} else {
49722064ee33SMarcel Holtmann 		bt_dev_err(hdev, "SCO packet for unknown connection handle %d",
49732064ee33SMarcel Holtmann 			   handle);
49741da177e4SLinus Torvalds 	}
49751da177e4SLinus Torvalds 
49761da177e4SLinus Torvalds 	kfree_skb(skb);
49771da177e4SLinus Torvalds }
49781da177e4SLinus Torvalds 
49799238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
49809238f36aSJohan Hedberg {
49819238f36aSJohan Hedberg 	struct sk_buff *skb;
49829238f36aSJohan Hedberg 
49839238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
49849238f36aSJohan Hedberg 	if (!skb)
49859238f36aSJohan Hedberg 		return true;
49869238f36aSJohan Hedberg 
498744d27137SJohan Hedberg 	return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
49889238f36aSJohan Hedberg }
49899238f36aSJohan Hedberg 
499042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
499142c6b129SJohan Hedberg {
499242c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
499342c6b129SJohan Hedberg 	struct sk_buff *skb;
499442c6b129SJohan Hedberg 	u16 opcode;
499542c6b129SJohan Hedberg 
499642c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
499742c6b129SJohan Hedberg 		return;
499842c6b129SJohan Hedberg 
499942c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
500042c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
500142c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
500242c6b129SJohan Hedberg 		return;
500342c6b129SJohan Hedberg 
500442c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
500542c6b129SJohan Hedberg 	if (!skb)
500642c6b129SJohan Hedberg 		return;
500742c6b129SJohan Hedberg 
500842c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
500942c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
501042c6b129SJohan Hedberg }
501142c6b129SJohan Hedberg 
5012e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
5013e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
5014e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
50159238f36aSJohan Hedberg {
50169238f36aSJohan Hedberg 	struct sk_buff *skb;
50179238f36aSJohan Hedberg 	unsigned long flags;
50189238f36aSJohan Hedberg 
50199238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
50209238f36aSJohan Hedberg 
502142c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
502242c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
50239238f36aSJohan Hedberg 	 */
502442c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
502542c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
502642c6b129SJohan Hedberg 		 * reset complete event during init and any pending
502742c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
502842c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
502942c6b129SJohan Hedberg 		 * command.
503042c6b129SJohan Hedberg 		 */
503142c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
503242c6b129SJohan Hedberg 			hci_resend_last(hdev);
503342c6b129SJohan Hedberg 
50349238f36aSJohan Hedberg 		return;
503542c6b129SJohan Hedberg 	}
50369238f36aSJohan Hedberg 
5037f80c5dadSJoão Paulo Rechi Vita 	/* If we reach this point this event matches the last command sent */
5038f80c5dadSJoão Paulo Rechi Vita 	hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
5039f80c5dadSJoão Paulo Rechi Vita 
50409238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
50419238f36aSJohan Hedberg 	 * this request the request is not yet complete.
50429238f36aSJohan Hedberg 	 */
50439238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
50449238f36aSJohan Hedberg 		return;
50459238f36aSJohan Hedberg 
50469238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
50479238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
50489238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
50499238f36aSJohan Hedberg 	 */
505044d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) {
505144d27137SJohan Hedberg 		*req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb;
5052e6214487SJohan Hedberg 		return;
50539238f36aSJohan Hedberg 	}
5054e6214487SJohan Hedberg 
505544d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_complete) {
505644d27137SJohan Hedberg 		*req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete;
5057e6214487SJohan Hedberg 		return;
505853e21fbcSJohan Hedberg 	}
50599238f36aSJohan Hedberg 
50609238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
50619238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
50629238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
506344d27137SJohan Hedberg 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
50649238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
50659238f36aSJohan Hedberg 			break;
50669238f36aSJohan Hedberg 		}
50679238f36aSJohan Hedberg 
50683bd7594eSDouglas Anderson 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
5069242c0ebdSMarcel Holtmann 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
50703bd7594eSDouglas Anderson 		else
50713bd7594eSDouglas Anderson 			*req_complete = bt_cb(skb)->hci.req_complete;
50729238f36aSJohan Hedberg 		kfree_skb(skb);
50739238f36aSJohan Hedberg 	}
50749238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
50759238f36aSJohan Hedberg }
50769238f36aSJohan Hedberg 
5077b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
50781da177e4SLinus Torvalds {
5079b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
50801da177e4SLinus Torvalds 	struct sk_buff *skb;
50811da177e4SLinus Torvalds 
50821da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
50831da177e4SLinus Torvalds 
50841da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
5085cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
5086cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
5087cd82e61cSMarcel Holtmann 
50881da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
50891da177e4SLinus Torvalds 			/* Send copy to the sockets */
5090470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
50911da177e4SLinus Torvalds 		}
50921da177e4SLinus Torvalds 
5093eb8c101eSMattijs Korpershoek 		/* If the device has been opened in HCI_USER_CHANNEL,
5094eb8c101eSMattijs Korpershoek 		 * the userspace has exclusive access to device.
5095eb8c101eSMattijs Korpershoek 		 * When device is HCI_INIT, we still need to process
5096eb8c101eSMattijs Korpershoek 		 * the data packets to the driver in order
5097eb8c101eSMattijs Korpershoek 		 * to complete its setup().
5098eb8c101eSMattijs Korpershoek 		 */
5099eb8c101eSMattijs Korpershoek 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
5100eb8c101eSMattijs Korpershoek 		    !test_bit(HCI_INIT, &hdev->flags)) {
51011da177e4SLinus Torvalds 			kfree_skb(skb);
51021da177e4SLinus Torvalds 			continue;
51031da177e4SLinus Torvalds 		}
51041da177e4SLinus Torvalds 
51051da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
51061da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
5107d79f34e3SMarcel Holtmann 			switch (hci_skb_pkt_type(skb)) {
51081da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
51091da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
5110cc974003SMarcel Holtmann 			case HCI_ISODATA_PKT:
51111da177e4SLinus Torvalds 				kfree_skb(skb);
51121da177e4SLinus Torvalds 				continue;
51133ff50b79SStephen Hemminger 			}
51141da177e4SLinus Torvalds 		}
51151da177e4SLinus Torvalds 
51161da177e4SLinus Torvalds 		/* Process frame */
5117d79f34e3SMarcel Holtmann 		switch (hci_skb_pkt_type(skb)) {
51181da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
5119b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
51201da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
51211da177e4SLinus Torvalds 			break;
51221da177e4SLinus Torvalds 
51231da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
51241da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
51251da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
51261da177e4SLinus Torvalds 			break;
51271da177e4SLinus Torvalds 
51281da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
51291da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
51301da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
51311da177e4SLinus Torvalds 			break;
51321da177e4SLinus Torvalds 
51331da177e4SLinus Torvalds 		default:
51341da177e4SLinus Torvalds 			kfree_skb(skb);
51351da177e4SLinus Torvalds 			break;
51361da177e4SLinus Torvalds 		}
51371da177e4SLinus Torvalds 	}
51381da177e4SLinus Torvalds }
51391da177e4SLinus Torvalds 
5140c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
51411da177e4SLinus Torvalds {
5142c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
51431da177e4SLinus Torvalds 	struct sk_buff *skb;
51441da177e4SLinus Torvalds 
51452104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
51462104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
51471da177e4SLinus Torvalds 
51481da177e4SLinus Torvalds 	/* Send queued commands */
51495a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
51505a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
51515a08ecceSAndrei Emeltchenko 		if (!skb)
51525a08ecceSAndrei Emeltchenko 			return;
51535a08ecceSAndrei Emeltchenko 
51541da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
51551da177e4SLinus Torvalds 
5156a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
515770f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
5158f80c5dadSJoão Paulo Rechi Vita 			if (hci_req_status_pend(hdev))
5159f80c5dadSJoão Paulo Rechi Vita 				hci_dev_set_flag(hdev, HCI_CMD_PENDING);
51601da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
516157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
51627bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
516365cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
51647bdb8a5cSSzymon Janc 			else
516565cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
516665cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
51671da177e4SLinus Torvalds 		} else {
51681da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
5169c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
51701da177e4SLinus Torvalds 		}
51711da177e4SLinus Torvalds 	}
51721da177e4SLinus Torvalds }
5173