xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 80af16a3)
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"
47970c4e46SJohan Hedberg 
48b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
49c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
503eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds /* HCI device list */
531da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
541da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds /* HCI callback list */
571da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
58fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock);
591da177e4SLinus Torvalds 
603df92b31SSasha Levin /* HCI ID Numbering */
613df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
623df92b31SSasha Levin 
63baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
64baf27f6eSMarcel Holtmann 
654b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
664b4148e9SMarcel Holtmann 			     size_t count, loff_t *ppos)
674b4148e9SMarcel Holtmann {
684b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
694b4148e9SMarcel Holtmann 	char buf[3];
704b4148e9SMarcel Holtmann 
71b7cb93e5SMarcel Holtmann 	buf[0] = hci_dev_test_flag(hdev, HCI_DUT_MODE) ? 'Y' : 'N';
724b4148e9SMarcel Holtmann 	buf[1] = '\n';
734b4148e9SMarcel Holtmann 	buf[2] = '\0';
744b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
754b4148e9SMarcel Holtmann }
764b4148e9SMarcel Holtmann 
774b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
784b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
794b4148e9SMarcel Holtmann {
804b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
814b4148e9SMarcel Holtmann 	struct sk_buff *skb;
824b4148e9SMarcel Holtmann 	bool enable;
833bf5e97dSAndy Shevchenko 	int err;
844b4148e9SMarcel Holtmann 
854b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
864b4148e9SMarcel Holtmann 		return -ENETDOWN;
874b4148e9SMarcel Holtmann 
883bf5e97dSAndy Shevchenko 	err = kstrtobool_from_user(user_buf, count, &enable);
893bf5e97dSAndy Shevchenko 	if (err)
903bf5e97dSAndy Shevchenko 		return err;
914b4148e9SMarcel Holtmann 
92b7cb93e5SMarcel Holtmann 	if (enable == hci_dev_test_flag(hdev, HCI_DUT_MODE))
934b4148e9SMarcel Holtmann 		return -EALREADY;
944b4148e9SMarcel Holtmann 
95b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
964b4148e9SMarcel Holtmann 	if (enable)
974b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
984b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
994b4148e9SMarcel Holtmann 	else
1004b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1014b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
102b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
1034b4148e9SMarcel Holtmann 
1044b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1054b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1064b4148e9SMarcel Holtmann 
1074b4148e9SMarcel Holtmann 	kfree_skb(skb);
1084b4148e9SMarcel Holtmann 
109b7cb93e5SMarcel Holtmann 	hci_dev_change_flag(hdev, HCI_DUT_MODE);
1104b4148e9SMarcel Holtmann 
1114b4148e9SMarcel Holtmann 	return count;
1124b4148e9SMarcel Holtmann }
1134b4148e9SMarcel Holtmann 
1144b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1154b4148e9SMarcel Holtmann 	.open		= simple_open,
1164b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1174b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1184b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1194b4148e9SMarcel Holtmann };
1204b4148e9SMarcel Holtmann 
1214b4113d6SMarcel Holtmann static ssize_t vendor_diag_read(struct file *file, char __user *user_buf,
1224b4113d6SMarcel Holtmann 				size_t count, loff_t *ppos)
1234b4113d6SMarcel Holtmann {
1244b4113d6SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
1254b4113d6SMarcel Holtmann 	char buf[3];
1264b4113d6SMarcel Holtmann 
1274b4113d6SMarcel Holtmann 	buf[0] = hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) ? 'Y' : 'N';
1284b4113d6SMarcel Holtmann 	buf[1] = '\n';
1294b4113d6SMarcel Holtmann 	buf[2] = '\0';
1304b4113d6SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
1314b4113d6SMarcel Holtmann }
1324b4113d6SMarcel Holtmann 
1334b4113d6SMarcel Holtmann static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf,
1344b4113d6SMarcel Holtmann 				 size_t count, loff_t *ppos)
1354b4113d6SMarcel Holtmann {
1364b4113d6SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
1374b4113d6SMarcel Holtmann 	bool enable;
1384b4113d6SMarcel Holtmann 	int err;
1394b4113d6SMarcel Holtmann 
1403bf5e97dSAndy Shevchenko 	err = kstrtobool_from_user(user_buf, count, &enable);
1413bf5e97dSAndy Shevchenko 	if (err)
1423bf5e97dSAndy Shevchenko 		return err;
1434b4113d6SMarcel Holtmann 
1447e995b9eSMarcel Holtmann 	/* When the diagnostic flags are not persistent and the transport
145b56c7b25SMarcel Holtmann 	 * is not active or in user channel operation, then there is no need
146b56c7b25SMarcel Holtmann 	 * for the vendor callback. Instead just store the desired value and
147b56c7b25SMarcel Holtmann 	 * the setting will be programmed when the controller gets powered on.
1487e995b9eSMarcel Holtmann 	 */
1497e995b9eSMarcel Holtmann 	if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
150b56c7b25SMarcel Holtmann 	    (!test_bit(HCI_RUNNING, &hdev->flags) ||
151b56c7b25SMarcel Holtmann 	     hci_dev_test_flag(hdev, HCI_USER_CHANNEL)))
1527e995b9eSMarcel Holtmann 		goto done;
1537e995b9eSMarcel Holtmann 
154b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
1554b4113d6SMarcel Holtmann 	err = hdev->set_diag(hdev, enable);
156b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
1574b4113d6SMarcel Holtmann 
1584b4113d6SMarcel Holtmann 	if (err < 0)
1594b4113d6SMarcel Holtmann 		return err;
1604b4113d6SMarcel Holtmann 
1617e995b9eSMarcel Holtmann done:
1624b4113d6SMarcel Holtmann 	if (enable)
1634b4113d6SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_VENDOR_DIAG);
1644b4113d6SMarcel Holtmann 	else
1654b4113d6SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_VENDOR_DIAG);
1664b4113d6SMarcel Holtmann 
1674b4113d6SMarcel Holtmann 	return count;
1684b4113d6SMarcel Holtmann }
1694b4113d6SMarcel Holtmann 
1704b4113d6SMarcel Holtmann static const struct file_operations vendor_diag_fops = {
1714b4113d6SMarcel Holtmann 	.open		= simple_open,
1724b4113d6SMarcel Holtmann 	.read		= vendor_diag_read,
1734b4113d6SMarcel Holtmann 	.write		= vendor_diag_write,
1744b4113d6SMarcel Holtmann 	.llseek		= default_llseek,
1754b4113d6SMarcel Holtmann };
1764b4113d6SMarcel Holtmann 
177f640ee98SMarcel Holtmann static void hci_debugfs_create_basic(struct hci_dev *hdev)
178f640ee98SMarcel Holtmann {
179f640ee98SMarcel Holtmann 	debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
180f640ee98SMarcel Holtmann 			    &dut_mode_fops);
181f640ee98SMarcel Holtmann 
182f640ee98SMarcel Holtmann 	if (hdev->set_diag)
183f640ee98SMarcel Holtmann 		debugfs_create_file("vendor_diag", 0644, hdev->debugfs, hdev,
184f640ee98SMarcel Holtmann 				    &vendor_diag_fops);
185f640ee98SMarcel Holtmann }
186f640ee98SMarcel Holtmann 
187a1d01db1SJohan Hedberg static int hci_reset_req(struct hci_request *req, unsigned long opt)
1881da177e4SLinus Torvalds {
18942c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
1901da177e4SLinus Torvalds 
1911da177e4SLinus Torvalds 	/* Reset device */
19242c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
19342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
194a1d01db1SJohan Hedberg 	return 0;
1951da177e4SLinus Torvalds }
1961da177e4SLinus Torvalds 
19742c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
1981da177e4SLinus Torvalds {
19942c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
2002455a3eaSAndrei Emeltchenko 
2011da177e4SLinus Torvalds 	/* Read Local Supported Features */
20242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
2031da177e4SLinus Torvalds 
2041143e5a6SMarcel Holtmann 	/* Read Local Version */
20542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2062177bab5SJohan Hedberg 
2072177bab5SJohan Hedberg 	/* Read BD Address */
20842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
2091da177e4SLinus Torvalds }
2101da177e4SLinus Torvalds 
2110af801b9SJohan Hedberg static void amp_init1(struct hci_request *req)
212e61ef499SAndrei Emeltchenko {
21342c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
2142455a3eaSAndrei Emeltchenko 
215e61ef499SAndrei Emeltchenko 	/* Read Local Version */
21642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2176bcbc489SAndrei Emeltchenko 
218f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
219f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
220f6996cfeSMarcel Holtmann 
2216bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
22242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
223e71dfabaSAndrei Emeltchenko 
224e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
22542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
2267528ca1cSMarcel Holtmann 
227f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
228f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
229f38ba941SMarcel Holtmann 
2307528ca1cSMarcel Holtmann 	/* Read Location Data */
2317528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
232e61ef499SAndrei Emeltchenko }
233e61ef499SAndrei Emeltchenko 
234a1d01db1SJohan Hedberg static int amp_init2(struct hci_request *req)
2350af801b9SJohan Hedberg {
2360af801b9SJohan Hedberg 	/* Read Local Supported Features. Not all AMP controllers
2370af801b9SJohan Hedberg 	 * support this so it's placed conditionally in the second
2380af801b9SJohan Hedberg 	 * stage init.
2390af801b9SJohan Hedberg 	 */
2400af801b9SJohan Hedberg 	if (req->hdev->commands[14] & 0x20)
2410af801b9SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
242a1d01db1SJohan Hedberg 
243a1d01db1SJohan Hedberg 	return 0;
2440af801b9SJohan Hedberg }
2450af801b9SJohan Hedberg 
246a1d01db1SJohan Hedberg static int hci_init1_req(struct hci_request *req, unsigned long opt)
247e61ef499SAndrei Emeltchenko {
24842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
249e61ef499SAndrei Emeltchenko 
250e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
251e61ef499SAndrei Emeltchenko 
25211778716SAndrei Emeltchenko 	/* Reset */
25311778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
25442c6b129SJohan Hedberg 		hci_reset_req(req, 0);
25511778716SAndrei Emeltchenko 
256e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
257ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
25842c6b129SJohan Hedberg 		bredr_init(req);
259e61ef499SAndrei Emeltchenko 		break;
260e61ef499SAndrei Emeltchenko 	case HCI_AMP:
2610af801b9SJohan Hedberg 		amp_init1(req);
262e61ef499SAndrei Emeltchenko 		break;
263e61ef499SAndrei Emeltchenko 	default:
2642064ee33SMarcel Holtmann 		bt_dev_err(hdev, "Unknown device type %d", hdev->dev_type);
265e61ef499SAndrei Emeltchenko 		break;
266e61ef499SAndrei Emeltchenko 	}
267a1d01db1SJohan Hedberg 
268a1d01db1SJohan Hedberg 	return 0;
269e61ef499SAndrei Emeltchenko }
270e61ef499SAndrei Emeltchenko 
27142c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
2722177bab5SJohan Hedberg {
2732177bab5SJohan Hedberg 	__le16 param;
2742177bab5SJohan Hedberg 	__u8 flt_type;
2752177bab5SJohan Hedberg 
2762177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
27742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
2782177bab5SJohan Hedberg 
2792177bab5SJohan Hedberg 	/* Read Class of Device */
28042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
2812177bab5SJohan Hedberg 
2822177bab5SJohan Hedberg 	/* Read Local Name */
28342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2842177bab5SJohan Hedberg 
2852177bab5SJohan Hedberg 	/* Read Voice Setting */
28642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2872177bab5SJohan Hedberg 
288b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
289b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
290b4cb9fb2SMarcel Holtmann 
2914b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
2924b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
2934b836f39SMarcel Holtmann 
2942177bab5SJohan Hedberg 	/* Clear Event Filters */
2952177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
29642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2972177bab5SJohan Hedberg 
2982177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
299dcf4adbfSJoe Perches 	param = cpu_to_le16(0x7d00);
30042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
3012177bab5SJohan Hedberg }
3022177bab5SJohan Hedberg 
30342c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
3042177bab5SJohan Hedberg {
305c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
306c73eee91SJohan Hedberg 
3072177bab5SJohan Hedberg 	/* Read LE Buffer Size */
30842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
3092177bab5SJohan Hedberg 
3102177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
31142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
3122177bab5SJohan Hedberg 
313747d3f03SMarcel Holtmann 	/* Read LE Supported States */
314747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
315747d3f03SMarcel Holtmann 
316c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
317c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
318a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ENABLED);
3192177bab5SJohan Hedberg }
3202177bab5SJohan Hedberg 
32142c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
3222177bab5SJohan Hedberg {
32342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
32442c6b129SJohan Hedberg 
3252177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
3262177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
3272177bab5SJohan Hedberg 	 * command otherwise.
3282177bab5SJohan Hedberg 	 */
3292177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
3302177bab5SJohan Hedberg 
3312177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
3322177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
3332177bab5SJohan Hedberg 	 */
3342177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
3352177bab5SJohan Hedberg 		return;
3362177bab5SJohan Hedberg 
3372177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
3382177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
339c7882cbdSMarcel Holtmann 	} else {
340c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
341c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
342c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
343c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
344c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
3455c3d3b4cSMarcel Holtmann 
3465c3d3b4cSMarcel Holtmann 		/* If the controller supports the Disconnect command, enable
3475c3d3b4cSMarcel Holtmann 		 * the corresponding event. In addition enable packet flow
3485c3d3b4cSMarcel Holtmann 		 * control related events.
3495c3d3b4cSMarcel Holtmann 		 */
3505c3d3b4cSMarcel Holtmann 		if (hdev->commands[0] & 0x20) {
3515c3d3b4cSMarcel Holtmann 			events[0] |= 0x10; /* Disconnection Complete */
352c7882cbdSMarcel Holtmann 			events[2] |= 0x04; /* Number of Completed Packets */
353c7882cbdSMarcel Holtmann 			events[3] |= 0x02; /* Data Buffer Overflow */
3545c3d3b4cSMarcel Holtmann 		}
3555c3d3b4cSMarcel Holtmann 
3565c3d3b4cSMarcel Holtmann 		/* If the controller supports the Read Remote Version
3575c3d3b4cSMarcel Holtmann 		 * Information command, enable the corresponding event.
3585c3d3b4cSMarcel Holtmann 		 */
3595c3d3b4cSMarcel Holtmann 		if (hdev->commands[2] & 0x80)
3605c3d3b4cSMarcel Holtmann 			events[1] |= 0x08; /* Read Remote Version Information
3615c3d3b4cSMarcel Holtmann 					    * Complete
3625c3d3b4cSMarcel Holtmann 					    */
3630da71f1bSMarcel Holtmann 
3640da71f1bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION) {
3650da71f1bSMarcel Holtmann 			events[0] |= 0x80; /* Encryption Change */
366c7882cbdSMarcel Holtmann 			events[5] |= 0x80; /* Encryption Key Refresh Complete */
3672177bab5SJohan Hedberg 		}
3680da71f1bSMarcel Holtmann 	}
3692177bab5SJohan Hedberg 
3709fe759ceSMarcel Holtmann 	if (lmp_inq_rssi_capable(hdev) ||
3719fe759ceSMarcel Holtmann 	    test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks))
3722177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
3732177bab5SJohan Hedberg 
37470f56aa2SMarcel Holtmann 	if (lmp_ext_feat_capable(hdev))
37570f56aa2SMarcel Holtmann 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
37670f56aa2SMarcel Holtmann 
37770f56aa2SMarcel Holtmann 	if (lmp_esco_capable(hdev)) {
37870f56aa2SMarcel Holtmann 		events[5] |= 0x08; /* Synchronous Connection Complete */
37970f56aa2SMarcel Holtmann 		events[5] |= 0x10; /* Synchronous Connection Changed */
38070f56aa2SMarcel Holtmann 	}
38170f56aa2SMarcel Holtmann 
3822177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
3832177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
3842177bab5SJohan Hedberg 
3852177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
3862177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
3872177bab5SJohan Hedberg 
3882177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
3892177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
3902177bab5SJohan Hedberg 
3912177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
3922177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
3932177bab5SJohan Hedberg 
3942177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
3952177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
3962177bab5SJohan Hedberg 
3972177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
3982177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
3992177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
4002177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
4012177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
4022177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
4032177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
4042177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
4052177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
4062177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
4072177bab5SJohan Hedberg 					 * Features Notification
4082177bab5SJohan Hedberg 					 */
4092177bab5SJohan Hedberg 	}
4102177bab5SJohan Hedberg 
4112177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
4122177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
4132177bab5SJohan Hedberg 
41442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
4152177bab5SJohan Hedberg }
4162177bab5SJohan Hedberg 
417a1d01db1SJohan Hedberg static int hci_init2_req(struct hci_request *req, unsigned long opt)
4182177bab5SJohan Hedberg {
41942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
42042c6b129SJohan Hedberg 
4210af801b9SJohan Hedberg 	if (hdev->dev_type == HCI_AMP)
4220af801b9SJohan Hedberg 		return amp_init2(req);
4230af801b9SJohan Hedberg 
4242177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
42542c6b129SJohan Hedberg 		bredr_setup(req);
42656f87901SJohan Hedberg 	else
427a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED);
4282177bab5SJohan Hedberg 
4292177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
43042c6b129SJohan Hedberg 		le_setup(req);
4312177bab5SJohan Hedberg 
4320f3adeaeSMarcel Holtmann 	/* All Bluetooth 1.2 and later controllers should support the
4330f3adeaeSMarcel Holtmann 	 * HCI command for reading the local supported commands.
4340f3adeaeSMarcel Holtmann 	 *
4350f3adeaeSMarcel Holtmann 	 * Unfortunately some controllers indicate Bluetooth 1.2 support,
4360f3adeaeSMarcel Holtmann 	 * but do not have support for this command. If that is the case,
4370f3adeaeSMarcel Holtmann 	 * the driver can quirk the behavior and skip reading the local
4380f3adeaeSMarcel Holtmann 	 * supported commands.
4393f8e2d75SJohan Hedberg 	 */
4400f3adeaeSMarcel Holtmann 	if (hdev->hci_ver > BLUETOOTH_VER_1_1 &&
4410f3adeaeSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks))
44242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
4432177bab5SJohan Hedberg 
4442177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
44557af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
44657af75a8SMarcel Holtmann 		 * should also be available as well. However some
44757af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
44857af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
44957af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
45057af75a8SMarcel Holtmann 		 */
45157af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
45257af75a8SMarcel Holtmann 
453d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
4542177bab5SJohan Hedberg 			u8 mode = 0x01;
455574ea3c7SMarcel Holtmann 
45642c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
4572177bab5SJohan Hedberg 				    sizeof(mode), &mode);
4582177bab5SJohan Hedberg 		} else {
4592177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
4602177bab5SJohan Hedberg 
4612177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
4622177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
4632177bab5SJohan Hedberg 
46442c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
4652177bab5SJohan Hedberg 		}
4662177bab5SJohan Hedberg 	}
4672177bab5SJohan Hedberg 
468043ec9bfSMarcel Holtmann 	if (lmp_inq_rssi_capable(hdev) ||
469043ec9bfSMarcel Holtmann 	    test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) {
47004422da9SMarcel Holtmann 		u8 mode;
47104422da9SMarcel Holtmann 
47204422da9SMarcel Holtmann 		/* If Extended Inquiry Result events are supported, then
47304422da9SMarcel Holtmann 		 * they are clearly preferred over Inquiry Result with RSSI
47404422da9SMarcel Holtmann 		 * events.
47504422da9SMarcel Holtmann 		 */
47604422da9SMarcel Holtmann 		mode = lmp_ext_inq_capable(hdev) ? 0x02 : 0x01;
47704422da9SMarcel Holtmann 
47804422da9SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
47904422da9SMarcel Holtmann 	}
4802177bab5SJohan Hedberg 
4812177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
48242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
4832177bab5SJohan Hedberg 
4842177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
4852177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
4862177bab5SJohan Hedberg 
4872177bab5SJohan Hedberg 		cp.page = 0x01;
48842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
48942c6b129SJohan Hedberg 			    sizeof(cp), &cp);
4902177bab5SJohan Hedberg 	}
4912177bab5SJohan Hedberg 
492d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_LINK_SECURITY)) {
4932177bab5SJohan Hedberg 		u8 enable = 1;
49442c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
4952177bab5SJohan Hedberg 			    &enable);
4962177bab5SJohan Hedberg 	}
497a1d01db1SJohan Hedberg 
498a1d01db1SJohan Hedberg 	return 0;
4992177bab5SJohan Hedberg }
5002177bab5SJohan Hedberg 
50142c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
5022177bab5SJohan Hedberg {
50342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5042177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
5052177bab5SJohan Hedberg 	u16 link_policy = 0;
5062177bab5SJohan Hedberg 
5072177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
5082177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
5092177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
5102177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
5112177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
5122177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
5132177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
5142177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
5152177bab5SJohan Hedberg 
5162177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
51742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
5182177bab5SJohan Hedberg }
5192177bab5SJohan Hedberg 
52042c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
5212177bab5SJohan Hedberg {
52242c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5232177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
5242177bab5SJohan Hedberg 
525c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
526c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
527c73eee91SJohan Hedberg 		return;
528c73eee91SJohan Hedberg 
5292177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
5302177bab5SJohan Hedberg 
531d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
5322177bab5SJohan Hedberg 		cp.le = 0x01;
53332226e4fSMarcel Holtmann 		cp.simul = 0x00;
5342177bab5SJohan Hedberg 	}
5352177bab5SJohan Hedberg 
5362177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
53742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
5382177bab5SJohan Hedberg 			    &cp);
5392177bab5SJohan Hedberg }
5402177bab5SJohan Hedberg 
541d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
542d62e6d67SJohan Hedberg {
543d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
544d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
545313f6888SMarcel Holtmann 	bool changed = false;
546d62e6d67SJohan Hedberg 
547d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
548d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
549d62e6d67SJohan Hedberg 	 */
55053b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
551d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
552d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
553d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
554d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
555313f6888SMarcel Holtmann 		changed = true;
556d62e6d67SJohan Hedberg 	}
557d62e6d67SJohan Hedberg 
558d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
559d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
560d62e6d67SJohan Hedberg 	 */
56153b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
562d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
563d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
564d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
565d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
566313f6888SMarcel Holtmann 		changed = true;
567d62e6d67SJohan Hedberg 	}
568d62e6d67SJohan Hedberg 
56940c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
570313f6888SMarcel Holtmann 	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) {
57140c59fcbSMarcel Holtmann 		events[2] |= 0x80;
572313f6888SMarcel Holtmann 		changed = true;
573313f6888SMarcel Holtmann 	}
57440c59fcbSMarcel Holtmann 
575313f6888SMarcel Holtmann 	/* Some Broadcom based controllers indicate support for Set Event
576313f6888SMarcel Holtmann 	 * Mask Page 2 command, but then actually do not support it. Since
577313f6888SMarcel Holtmann 	 * the default value is all bits set to zero, the command is only
578313f6888SMarcel Holtmann 	 * required if the event mask has to be changed. In case no change
579313f6888SMarcel Holtmann 	 * to the event mask is needed, skip this command.
580313f6888SMarcel Holtmann 	 */
581313f6888SMarcel Holtmann 	if (changed)
582313f6888SMarcel Holtmann 		hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2,
583313f6888SMarcel Holtmann 			    sizeof(events), events);
584d62e6d67SJohan Hedberg }
585d62e6d67SJohan Hedberg 
586a1d01db1SJohan Hedberg static int hci_init3_req(struct hci_request *req, unsigned long opt)
5872177bab5SJohan Hedberg {
58842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
589d2c5d77fSJohan Hedberg 	u8 p;
59042c6b129SJohan Hedberg 
5910da71f1bSMarcel Holtmann 	hci_setup_event_mask(req);
5920da71f1bSMarcel Holtmann 
593e81be90bSJohan Hedberg 	if (hdev->commands[6] & 0x20 &&
594e81be90bSJohan Hedberg 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
59548ce62c4SMarcel Holtmann 		struct hci_cp_read_stored_link_key cp;
59648ce62c4SMarcel Holtmann 
59748ce62c4SMarcel Holtmann 		bacpy(&cp.bdaddr, BDADDR_ANY);
59848ce62c4SMarcel Holtmann 		cp.read_all = 0x01;
59948ce62c4SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_STORED_LINK_KEY, sizeof(cp), &cp);
60048ce62c4SMarcel Holtmann 	}
60148ce62c4SMarcel Holtmann 
6022177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
60342c6b129SJohan Hedberg 		hci_setup_link_policy(req);
6042177bab5SJohan Hedberg 
605417287deSMarcel Holtmann 	if (hdev->commands[8] & 0x01)
606417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
607417287deSMarcel Holtmann 
608cde1a8a9SIsmael Ferreras Morezuelas 	if (hdev->commands[18] & 0x04 &&
609cde1a8a9SIsmael Ferreras Morezuelas 	    !test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
61000bce3fbSAlain Michaud 		hci_req_add(req, HCI_OP_READ_DEF_ERR_DATA_REPORTING, 0, NULL);
61100bce3fbSAlain Michaud 
612417287deSMarcel Holtmann 	/* Some older Broadcom based Bluetooth 1.2 controllers do not
613417287deSMarcel Holtmann 	 * support the Read Page Scan Type command. Check support for
614417287deSMarcel Holtmann 	 * this command in the bit mask of supported commands.
615417287deSMarcel Holtmann 	 */
616417287deSMarcel Holtmann 	if (hdev->commands[13] & 0x01)
617417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
618417287deSMarcel Holtmann 
6199193c6e8SAndre Guedes 	if (lmp_le_capable(hdev)) {
6209193c6e8SAndre Guedes 		u8 events[8];
6219193c6e8SAndre Guedes 
6229193c6e8SAndre Guedes 		memset(events, 0, sizeof(events));
6234d6c705bSMarcel Holtmann 
6244d6c705bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
6254d6c705bSMarcel Holtmann 			events[0] |= 0x10;	/* LE Long Term Key Request */
626662bc2e6SAndre Guedes 
627662bc2e6SAndre Guedes 		/* If controller supports the Connection Parameters Request
628662bc2e6SAndre Guedes 		 * Link Layer Procedure, enable the corresponding event.
629662bc2e6SAndre Guedes 		 */
630662bc2e6SAndre Guedes 		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
631662bc2e6SAndre Guedes 			events[0] |= 0x20;	/* LE Remote Connection
632662bc2e6SAndre Guedes 						 * Parameter Request
633662bc2e6SAndre Guedes 						 */
634662bc2e6SAndre Guedes 
635a9f6068eSMarcel Holtmann 		/* If the controller supports the Data Length Extension
636a9f6068eSMarcel Holtmann 		 * feature, enable the corresponding event.
637a9f6068eSMarcel Holtmann 		 */
638a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
639a9f6068eSMarcel Holtmann 			events[0] |= 0x40;	/* LE Data Length Change */
640a9f6068eSMarcel Holtmann 
641ff3b8df2SMarcel Holtmann 		/* If the controller supports LL Privacy feature, enable
642ff3b8df2SMarcel Holtmann 		 * the corresponding event.
643ff3b8df2SMarcel Holtmann 		 */
644ff3b8df2SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_LL_PRIVACY)
645ff3b8df2SMarcel Holtmann 			events[1] |= 0x02;	/* LE Enhanced Connection
646ff3b8df2SMarcel Holtmann 						 * Complete
647ff3b8df2SMarcel Holtmann 						 */
648ff3b8df2SMarcel Holtmann 
6494b71bba4SMarcel Holtmann 		/* If the controller supports Extended Scanner Filter
6504b71bba4SMarcel Holtmann 		 * Policies, enable the correspondig event.
6514b71bba4SMarcel Holtmann 		 */
6524b71bba4SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)
6534b71bba4SMarcel Holtmann 			events[1] |= 0x04;	/* LE Direct Advertising
6544b71bba4SMarcel Holtmann 						 * Report
6554b71bba4SMarcel Holtmann 						 */
6564b71bba4SMarcel Holtmann 
6579756d33bSMarcel Holtmann 		/* If the controller supports Channel Selection Algorithm #2
6589756d33bSMarcel Holtmann 		 * feature, enable the corresponding event.
6599756d33bSMarcel Holtmann 		 */
6609756d33bSMarcel Holtmann 		if (hdev->le_features[1] & HCI_LE_CHAN_SEL_ALG2)
6619756d33bSMarcel Holtmann 			events[2] |= 0x08;	/* LE Channel Selection
6629756d33bSMarcel Holtmann 						 * Algorithm
6639756d33bSMarcel Holtmann 						 */
6649756d33bSMarcel Holtmann 
6657d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Set Scan Enable command,
6667d26f5c4SMarcel Holtmann 		 * enable the corresponding advertising report event.
6677d26f5c4SMarcel Holtmann 		 */
6687d26f5c4SMarcel Holtmann 		if (hdev->commands[26] & 0x08)
6697d26f5c4SMarcel Holtmann 			events[0] |= 0x02;	/* LE Advertising Report */
6707d26f5c4SMarcel Holtmann 
6717d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Create Connection
6727d26f5c4SMarcel Holtmann 		 * command, enable the corresponding event.
6737d26f5c4SMarcel Holtmann 		 */
6747d26f5c4SMarcel Holtmann 		if (hdev->commands[26] & 0x10)
6757d26f5c4SMarcel Holtmann 			events[0] |= 0x01;	/* LE Connection Complete */
6767d26f5c4SMarcel Holtmann 
6777d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Connection Update
6787d26f5c4SMarcel Holtmann 		 * command, enable the corresponding event.
6797d26f5c4SMarcel Holtmann 		 */
6807d26f5c4SMarcel Holtmann 		if (hdev->commands[27] & 0x04)
6817d26f5c4SMarcel Holtmann 			events[0] |= 0x04;	/* LE Connection Update
6827d26f5c4SMarcel Holtmann 						 * Complete
6837d26f5c4SMarcel Holtmann 						 */
6847d26f5c4SMarcel Holtmann 
6857d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Read Remote Used Features
6867d26f5c4SMarcel Holtmann 		 * command, enable the corresponding event.
6877d26f5c4SMarcel Holtmann 		 */
6887d26f5c4SMarcel Holtmann 		if (hdev->commands[27] & 0x20)
6897d26f5c4SMarcel Holtmann 			events[0] |= 0x08;	/* LE Read Remote Used
6907d26f5c4SMarcel Holtmann 						 * Features Complete
6917d26f5c4SMarcel Holtmann 						 */
6927d26f5c4SMarcel Holtmann 
6935a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Read Local P-256
6945a34bd5fSMarcel Holtmann 		 * Public Key command, enable the corresponding event.
6955a34bd5fSMarcel Holtmann 		 */
6965a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x02)
6975a34bd5fSMarcel Holtmann 			events[0] |= 0x80;	/* LE Read Local P-256
6985a34bd5fSMarcel Holtmann 						 * Public Key Complete
6995a34bd5fSMarcel Holtmann 						 */
7005a34bd5fSMarcel Holtmann 
7015a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Generate DHKey
7025a34bd5fSMarcel Holtmann 		 * command, enable the corresponding event.
7035a34bd5fSMarcel Holtmann 		 */
7045a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x04)
7055a34bd5fSMarcel Holtmann 			events[1] |= 0x01;	/* LE Generate DHKey Complete */
7065a34bd5fSMarcel Holtmann 
70727bbca44SMarcel Holtmann 		/* If the controller supports the LE Set Default PHY or
70827bbca44SMarcel Holtmann 		 * LE Set PHY commands, enable the corresponding event.
70927bbca44SMarcel Holtmann 		 */
71027bbca44SMarcel Holtmann 		if (hdev->commands[35] & (0x20 | 0x40))
71127bbca44SMarcel Holtmann 			events[1] |= 0x08;        /* LE PHY Update Complete */
71227bbca44SMarcel Holtmann 
713c215e939SJaganath Kanakkassery 		/* If the controller supports LE Set Extended Scan Parameters
714c215e939SJaganath Kanakkassery 		 * and LE Set Extended Scan Enable commands, enable the
715c215e939SJaganath Kanakkassery 		 * corresponding event.
716c215e939SJaganath Kanakkassery 		 */
717c215e939SJaganath Kanakkassery 		if (use_ext_scan(hdev))
718c215e939SJaganath Kanakkassery 			events[1] |= 0x10;	/* LE Extended Advertising
719c215e939SJaganath Kanakkassery 						 * Report
720c215e939SJaganath Kanakkassery 						 */
721c215e939SJaganath Kanakkassery 
722acf0aeaeSJaganath Kanakkassery 		/* If the controller supports the LE Extended Advertising
723acf0aeaeSJaganath Kanakkassery 		 * command, enable the corresponding event.
724acf0aeaeSJaganath Kanakkassery 		 */
725acf0aeaeSJaganath Kanakkassery 		if (ext_adv_capable(hdev))
726acf0aeaeSJaganath Kanakkassery 			events[2] |= 0x02;	/* LE Advertising Set
727acf0aeaeSJaganath Kanakkassery 						 * Terminated
728acf0aeaeSJaganath Kanakkassery 						 */
729acf0aeaeSJaganath Kanakkassery 
7309193c6e8SAndre Guedes 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
7319193c6e8SAndre Guedes 			    events);
7329193c6e8SAndre Guedes 
73315a49ccaSMarcel Holtmann 		/* Read LE Advertising Channel TX Power */
7346b49bcb4SJaganath Kanakkassery 		if ((hdev->commands[25] & 0x40) && !ext_adv_capable(hdev)) {
7356b49bcb4SJaganath Kanakkassery 			/* HCI TS spec forbids mixing of legacy and extended
7366b49bcb4SJaganath Kanakkassery 			 * advertising commands wherein READ_ADV_TX_POWER is
7376b49bcb4SJaganath Kanakkassery 			 * also included. So do not call it if extended adv
7386b49bcb4SJaganath Kanakkassery 			 * is supported otherwise controller will return
7396b49bcb4SJaganath Kanakkassery 			 * COMMAND_DISALLOWED for extended commands.
7406b49bcb4SJaganath Kanakkassery 			 */
74115a49ccaSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
74215a49ccaSMarcel Holtmann 		}
74315a49ccaSMarcel Holtmann 
7442ab216a7SMarcel Holtmann 		if (hdev->commands[26] & 0x40) {
7452ab216a7SMarcel Holtmann 			/* Read LE White List Size */
7462ab216a7SMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE,
7472ab216a7SMarcel Holtmann 				    0, NULL);
7482ab216a7SMarcel Holtmann 		}
7492ab216a7SMarcel Holtmann 
7502ab216a7SMarcel Holtmann 		if (hdev->commands[26] & 0x80) {
7512ab216a7SMarcel Holtmann 			/* Clear LE White List */
7522ab216a7SMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
7532ab216a7SMarcel Holtmann 		}
7542ab216a7SMarcel Holtmann 
755cfdb0c2dSAnkit Navik 		if (hdev->commands[34] & 0x40) {
756cfdb0c2dSAnkit Navik 			/* Read LE Resolving List Size */
757cfdb0c2dSAnkit Navik 			hci_req_add(req, HCI_OP_LE_READ_RESOLV_LIST_SIZE,
758cfdb0c2dSAnkit Navik 				    0, NULL);
759cfdb0c2dSAnkit Navik 		}
760cfdb0c2dSAnkit Navik 
761545f2596SAnkit Navik 		if (hdev->commands[34] & 0x20) {
762545f2596SAnkit Navik 			/* Clear LE Resolving List */
763545f2596SAnkit Navik 			hci_req_add(req, HCI_OP_LE_CLEAR_RESOLV_LIST, 0, NULL);
764545f2596SAnkit Navik 		}
765545f2596SAnkit Navik 
766a31489d2SEdward Vear 		if (hdev->commands[35] & 0x04) {
767b2cc2339SSathish Narasimman 			__le16 rpa_timeout = cpu_to_le16(hdev->rpa_timeout);
768b2cc2339SSathish Narasimman 
769b2cc2339SSathish Narasimman 			/* Set RPA timeout */
770b2cc2339SSathish Narasimman 			hci_req_add(req, HCI_OP_LE_SET_RPA_TIMEOUT, 2,
771b2cc2339SSathish Narasimman 				    &rpa_timeout);
772b2cc2339SSathish Narasimman 		}
773b2cc2339SSathish Narasimman 
774a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
775a9f6068eSMarcel Holtmann 			/* Read LE Maximum Data Length */
776a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL);
777a9f6068eSMarcel Holtmann 
778a9f6068eSMarcel Holtmann 			/* Read LE Suggested Default Data Length */
779a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL);
780a9f6068eSMarcel Holtmann 		}
781a9f6068eSMarcel Holtmann 
7826b49bcb4SJaganath Kanakkassery 		if (ext_adv_capable(hdev)) {
7836b49bcb4SJaganath Kanakkassery 			/* Read LE Number of Supported Advertising Sets */
7846b49bcb4SJaganath Kanakkassery 			hci_req_add(req, HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS,
7856b49bcb4SJaganath Kanakkassery 				    0, NULL);
7866b49bcb4SJaganath Kanakkassery 		}
7876b49bcb4SJaganath Kanakkassery 
78842c6b129SJohan Hedberg 		hci_set_le_support(req);
7899193c6e8SAndre Guedes 	}
790d2c5d77fSJohan Hedberg 
791d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
792d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
793d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
794d2c5d77fSJohan Hedberg 
795d2c5d77fSJohan Hedberg 		cp.page = p;
796d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
797d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
798d2c5d77fSJohan Hedberg 	}
799a1d01db1SJohan Hedberg 
800a1d01db1SJohan Hedberg 	return 0;
8012177bab5SJohan Hedberg }
8022177bab5SJohan Hedberg 
803a1d01db1SJohan Hedberg static int hci_init4_req(struct hci_request *req, unsigned long opt)
8045d4e7e8dSJohan Hedberg {
8055d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
8065d4e7e8dSJohan Hedberg 
80736f260ceSMarcel Holtmann 	/* Some Broadcom based Bluetooth controllers do not support the
80836f260ceSMarcel Holtmann 	 * Delete Stored Link Key command. They are clearly indicating its
80936f260ceSMarcel Holtmann 	 * absence in the bit mask of supported commands.
81036f260ceSMarcel Holtmann 	 *
811bb6d6895SRandy Dunlap 	 * Check the supported commands and only if the command is marked
81236f260ceSMarcel Holtmann 	 * as supported send it. If not supported assume that the controller
81336f260ceSMarcel Holtmann 	 * does not have actual support for stored link keys which makes this
81436f260ceSMarcel Holtmann 	 * command redundant anyway.
81536f260ceSMarcel Holtmann 	 *
81636f260ceSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
81736f260ceSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
81836f260ceSMarcel Holtmann 	 * just disable this command.
81936f260ceSMarcel Holtmann 	 */
82036f260ceSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
82136f260ceSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
82236f260ceSMarcel Holtmann 		struct hci_cp_delete_stored_link_key cp;
82336f260ceSMarcel Holtmann 
82436f260ceSMarcel Holtmann 		bacpy(&cp.bdaddr, BDADDR_ANY);
82536f260ceSMarcel Holtmann 		cp.delete_all = 0x01;
82636f260ceSMarcel Holtmann 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
82736f260ceSMarcel Holtmann 			    sizeof(cp), &cp);
82836f260ceSMarcel Holtmann 	}
82936f260ceSMarcel Holtmann 
830d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
831d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
832d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
833d62e6d67SJohan Hedberg 
834109e3191SMarcel Holtmann 	/* Read local codec list if the HCI command is supported */
835109e3191SMarcel Holtmann 	if (hdev->commands[29] & 0x20)
836109e3191SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
837109e3191SMarcel Holtmann 
838a4790360SMarcel Holtmann 	/* Read local pairing options if the HCI command is supported */
839a4790360SMarcel Holtmann 	if (hdev->commands[41] & 0x08)
840a4790360SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_PAIRING_OPTS, 0, NULL);
841a4790360SMarcel Holtmann 
842f4fe73edSMarcel Holtmann 	/* Get MWS transport configuration if the HCI command is supported */
843f4fe73edSMarcel Holtmann 	if (hdev->commands[30] & 0x08)
844f4fe73edSMarcel Holtmann 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
845f4fe73edSMarcel Holtmann 
8465d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
84753b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
8485d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
849a6d0d690SMarcel Holtmann 
850a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
851d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) &&
852574ea3c7SMarcel Holtmann 	    bredr_sc_enabled(hdev)) {
853a6d0d690SMarcel Holtmann 		u8 support = 0x01;
854574ea3c7SMarcel Holtmann 
855a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
856a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
857a6d0d690SMarcel Holtmann 	}
858a1d01db1SJohan Hedberg 
85900bce3fbSAlain Michaud 	/* Set erroneous data reporting if supported to the wideband speech
86000bce3fbSAlain Michaud 	 * setting value
86100bce3fbSAlain Michaud 	 */
862cde1a8a9SIsmael Ferreras Morezuelas 	if (hdev->commands[18] & 0x08 &&
863cde1a8a9SIsmael Ferreras Morezuelas 	    !test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks)) {
86400bce3fbSAlain Michaud 		bool enabled = hci_dev_test_flag(hdev,
86500bce3fbSAlain Michaud 						 HCI_WIDEBAND_SPEECH_ENABLED);
86600bce3fbSAlain Michaud 
86700bce3fbSAlain Michaud 		if (enabled !=
86800bce3fbSAlain Michaud 		    (hdev->err_data_reporting == ERR_DATA_REPORTING_ENABLED)) {
86900bce3fbSAlain Michaud 			struct hci_cp_write_def_err_data_reporting cp;
87000bce3fbSAlain Michaud 
87100bce3fbSAlain Michaud 			cp.err_data_reporting = enabled ?
87200bce3fbSAlain Michaud 						ERR_DATA_REPORTING_ENABLED :
87300bce3fbSAlain Michaud 						ERR_DATA_REPORTING_DISABLED;
87400bce3fbSAlain Michaud 
87500bce3fbSAlain Michaud 			hci_req_add(req, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING,
87600bce3fbSAlain Michaud 				    sizeof(cp), &cp);
87700bce3fbSAlain Michaud 		}
87800bce3fbSAlain Michaud 	}
87900bce3fbSAlain Michaud 
88012204875SMarcel Holtmann 	/* Set Suggested Default Data Length to maximum if supported */
88112204875SMarcel Holtmann 	if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
88212204875SMarcel Holtmann 		struct hci_cp_le_write_def_data_len cp;
88312204875SMarcel Holtmann 
884727ea61aSBen Dooks (Codethink) 		cp.tx_len = cpu_to_le16(hdev->le_max_tx_len);
885727ea61aSBen Dooks (Codethink) 		cp.tx_time = cpu_to_le16(hdev->le_max_tx_time);
88612204875SMarcel Holtmann 		hci_req_add(req, HCI_OP_LE_WRITE_DEF_DATA_LEN, sizeof(cp), &cp);
88712204875SMarcel Holtmann 	}
88812204875SMarcel Holtmann 
889de2ba303SMarcel Holtmann 	/* Set Default PHY parameters if command is supported */
890de2ba303SMarcel Holtmann 	if (hdev->commands[35] & 0x20) {
891de2ba303SMarcel Holtmann 		struct hci_cp_le_set_default_phy cp;
892de2ba303SMarcel Holtmann 
8936decb5b4SJaganath Kanakkassery 		cp.all_phys = 0x00;
8946decb5b4SJaganath Kanakkassery 		cp.tx_phys = hdev->le_tx_def_phys;
8956decb5b4SJaganath Kanakkassery 		cp.rx_phys = hdev->le_rx_def_phys;
896de2ba303SMarcel Holtmann 
897de2ba303SMarcel Holtmann 		hci_req_add(req, HCI_OP_LE_SET_DEFAULT_PHY, sizeof(cp), &cp);
898de2ba303SMarcel Holtmann 	}
899de2ba303SMarcel Holtmann 
900a1d01db1SJohan Hedberg 	return 0;
9015d4e7e8dSJohan Hedberg }
9025d4e7e8dSJohan Hedberg 
9032177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
9042177bab5SJohan Hedberg {
9052177bab5SJohan Hedberg 	int err;
9062177bab5SJohan Hedberg 
9074ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT, NULL);
9082177bab5SJohan Hedberg 	if (err < 0)
9092177bab5SJohan Hedberg 		return err;
9102177bab5SJohan Hedberg 
911f640ee98SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP))
912f640ee98SMarcel Holtmann 		hci_debugfs_create_basic(hdev);
9134b4148e9SMarcel Holtmann 
9144ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT, NULL);
9152177bab5SJohan Hedberg 	if (err < 0)
9162177bab5SJohan Hedberg 		return err;
9172177bab5SJohan Hedberg 
918ca8bee5dSMarcel Holtmann 	/* HCI_PRIMARY covers both single-mode LE, BR/EDR and dual-mode
9190af801b9SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
9200af801b9SJohan Hedberg 	 * first two stages of init.
9210af801b9SJohan Hedberg 	 */
922ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY)
9230af801b9SJohan Hedberg 		return 0;
9240af801b9SJohan Hedberg 
9254ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT, NULL);
9265d4e7e8dSJohan Hedberg 	if (err < 0)
9275d4e7e8dSJohan Hedberg 		return err;
9285d4e7e8dSJohan Hedberg 
9294ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT, NULL);
930baf27f6eSMarcel Holtmann 	if (err < 0)
931baf27f6eSMarcel Holtmann 		return err;
932baf27f6eSMarcel Holtmann 
933ec6cef9cSMarcel Holtmann 	/* This function is only called when the controller is actually in
934ec6cef9cSMarcel Holtmann 	 * configured state. When the controller is marked as unconfigured,
935ec6cef9cSMarcel Holtmann 	 * this initialization procedure is not run.
936ec6cef9cSMarcel Holtmann 	 *
937ec6cef9cSMarcel Holtmann 	 * It means that it is possible that a controller runs through its
938ec6cef9cSMarcel Holtmann 	 * setup phase and then discovers missing settings. If that is the
939ec6cef9cSMarcel Holtmann 	 * case, then this function will not be called. It then will only
940ec6cef9cSMarcel Holtmann 	 * be called during the config phase.
941ec6cef9cSMarcel Holtmann 	 *
942ec6cef9cSMarcel Holtmann 	 * So only when in setup phase or config phase, create the debugfs
943ec6cef9cSMarcel Holtmann 	 * entries and register the SMP channels.
944baf27f6eSMarcel Holtmann 	 */
945d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
946d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG))
947baf27f6eSMarcel Holtmann 		return 0;
948baf27f6eSMarcel Holtmann 
94960c5f5fbSMarcel Holtmann 	hci_debugfs_create_common(hdev);
95060c5f5fbSMarcel Holtmann 
95171c3b60eSMarcel Holtmann 	if (lmp_bredr_capable(hdev))
95260c5f5fbSMarcel Holtmann 		hci_debugfs_create_bredr(hdev);
9532bfa3531SMarcel Holtmann 
954162a3bacSMarcel Holtmann 	if (lmp_le_capable(hdev))
95560c5f5fbSMarcel Holtmann 		hci_debugfs_create_le(hdev);
956e7b8fc92SMarcel Holtmann 
957baf27f6eSMarcel Holtmann 	return 0;
9582177bab5SJohan Hedberg }
9592177bab5SJohan Hedberg 
960a1d01db1SJohan Hedberg static int hci_init0_req(struct hci_request *req, unsigned long opt)
9610ebca7d6SMarcel Holtmann {
9620ebca7d6SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
9630ebca7d6SMarcel Holtmann 
9640ebca7d6SMarcel Holtmann 	BT_DBG("%s %ld", hdev->name, opt);
9650ebca7d6SMarcel Holtmann 
9660ebca7d6SMarcel Holtmann 	/* Reset */
9670ebca7d6SMarcel Holtmann 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
9680ebca7d6SMarcel Holtmann 		hci_reset_req(req, 0);
9690ebca7d6SMarcel Holtmann 
9700ebca7d6SMarcel Holtmann 	/* Read Local Version */
9710ebca7d6SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
9720ebca7d6SMarcel Holtmann 
9730ebca7d6SMarcel Holtmann 	/* Read BD Address */
9740ebca7d6SMarcel Holtmann 	if (hdev->set_bdaddr)
9750ebca7d6SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
976a1d01db1SJohan Hedberg 
977a1d01db1SJohan Hedberg 	return 0;
9780ebca7d6SMarcel Holtmann }
9790ebca7d6SMarcel Holtmann 
9800ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev)
9810ebca7d6SMarcel Holtmann {
9820ebca7d6SMarcel Holtmann 	int err;
9830ebca7d6SMarcel Holtmann 
984cc78b44bSMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
985cc78b44bSMarcel Holtmann 		return 0;
986cc78b44bSMarcel Holtmann 
9874ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT, NULL);
9880ebca7d6SMarcel Holtmann 	if (err < 0)
9890ebca7d6SMarcel Holtmann 		return err;
9900ebca7d6SMarcel Holtmann 
991f640ee98SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP))
992f640ee98SMarcel Holtmann 		hci_debugfs_create_basic(hdev);
993f640ee98SMarcel Holtmann 
9940ebca7d6SMarcel Holtmann 	return 0;
9950ebca7d6SMarcel Holtmann }
9960ebca7d6SMarcel Holtmann 
997a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt)
9981da177e4SLinus Torvalds {
9991da177e4SLinus Torvalds 	__u8 scan = opt;
10001da177e4SLinus Torvalds 
100142c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
10021da177e4SLinus Torvalds 
10031da177e4SLinus Torvalds 	/* Inquiry and Page scans */
100442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
1005a1d01db1SJohan Hedberg 	return 0;
10061da177e4SLinus Torvalds }
10071da177e4SLinus Torvalds 
1008a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt)
10091da177e4SLinus Torvalds {
10101da177e4SLinus Torvalds 	__u8 auth = opt;
10111da177e4SLinus Torvalds 
101242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
10131da177e4SLinus Torvalds 
10141da177e4SLinus Torvalds 	/* Authentication */
101542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
1016a1d01db1SJohan Hedberg 	return 0;
10171da177e4SLinus Torvalds }
10181da177e4SLinus Torvalds 
1019a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt)
10201da177e4SLinus Torvalds {
10211da177e4SLinus Torvalds 	__u8 encrypt = opt;
10221da177e4SLinus Torvalds 
102342c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
10241da177e4SLinus Torvalds 
1025e4e8e37cSMarcel Holtmann 	/* Encryption */
102642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
1027a1d01db1SJohan Hedberg 	return 0;
10281da177e4SLinus Torvalds }
10291da177e4SLinus Torvalds 
1030a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt)
1031e4e8e37cSMarcel Holtmann {
1032e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
1033e4e8e37cSMarcel Holtmann 
103442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
1035e4e8e37cSMarcel Holtmann 
1036e4e8e37cSMarcel Holtmann 	/* Default link policy */
103742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
1038a1d01db1SJohan Hedberg 	return 0;
1039e4e8e37cSMarcel Holtmann }
1040e4e8e37cSMarcel Holtmann 
10411da177e4SLinus Torvalds /* Get HCI device by index.
10421da177e4SLinus Torvalds  * Device is held on return. */
10431da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
10441da177e4SLinus Torvalds {
10458035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
10461da177e4SLinus Torvalds 
10471da177e4SLinus Torvalds 	BT_DBG("%d", index);
10481da177e4SLinus Torvalds 
10491da177e4SLinus Torvalds 	if (index < 0)
10501da177e4SLinus Torvalds 		return NULL;
10511da177e4SLinus Torvalds 
10521da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
10538035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
10541da177e4SLinus Torvalds 		if (d->id == index) {
10551da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
10561da177e4SLinus Torvalds 			break;
10571da177e4SLinus Torvalds 		}
10581da177e4SLinus Torvalds 	}
10591da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
10601da177e4SLinus Torvalds 	return hdev;
10611da177e4SLinus Torvalds }
10621da177e4SLinus Torvalds 
10631da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1064ff9ef578SJohan Hedberg 
106530dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
106630dc78e1SJohan Hedberg {
106730dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
106830dc78e1SJohan Hedberg 
10696fbe195dSAndre Guedes 	switch (discov->state) {
1070343f935bSAndre Guedes 	case DISCOVERY_FINDING:
10716fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
107230dc78e1SJohan Hedberg 		return true;
107330dc78e1SJohan Hedberg 
10746fbe195dSAndre Guedes 	default:
107530dc78e1SJohan Hedberg 		return false;
107630dc78e1SJohan Hedberg 	}
10776fbe195dSAndre Guedes }
107830dc78e1SJohan Hedberg 
1079ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1080ff9ef578SJohan Hedberg {
1081bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
1082bb3e0a33SJohan Hedberg 
1083ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1084ff9ef578SJohan Hedberg 
1085bb3e0a33SJohan Hedberg 	if (old_state == state)
1086ff9ef578SJohan Hedberg 		return;
1087ff9ef578SJohan Hedberg 
1088bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
1089bb3e0a33SJohan Hedberg 
1090ff9ef578SJohan Hedberg 	switch (state) {
1091ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1092c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
1093c54c3860SAndre Guedes 
1094bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
1095ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1096ff9ef578SJohan Hedberg 		break;
1097ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1098ff9ef578SJohan Hedberg 		break;
1099343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1100ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1101ff9ef578SJohan Hedberg 		break;
110230dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
110330dc78e1SJohan Hedberg 		break;
1104ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1105ff9ef578SJohan Hedberg 		break;
1106ff9ef578SJohan Hedberg 	}
1107ff9ef578SJohan Hedberg }
1108ff9ef578SJohan Hedberg 
11091f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
11101da177e4SLinus Torvalds {
111130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1112b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
11131da177e4SLinus Torvalds 
1114561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
1115561aafbcSJohan Hedberg 		list_del(&p->all);
1116b57c1a56SJohan Hedberg 		kfree(p);
11171da177e4SLinus Torvalds 	}
1118561aafbcSJohan Hedberg 
1119561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
1120561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
11211da177e4SLinus Torvalds }
11221da177e4SLinus Torvalds 
1123a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
1124a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
11251da177e4SLinus Torvalds {
112630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
11271da177e4SLinus Torvalds 	struct inquiry_entry *e;
11281da177e4SLinus Torvalds 
11296ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
11301da177e4SLinus Torvalds 
1131561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
11321da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
11331da177e4SLinus Torvalds 			return e;
11341da177e4SLinus Torvalds 	}
11351da177e4SLinus Torvalds 
1136b57c1a56SJohan Hedberg 	return NULL;
1137b57c1a56SJohan Hedberg }
1138b57c1a56SJohan Hedberg 
1139561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
1140561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
1141561aafbcSJohan Hedberg {
114230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1143561aafbcSJohan Hedberg 	struct inquiry_entry *e;
1144561aafbcSJohan Hedberg 
11456ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1146561aafbcSJohan Hedberg 
1147561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
1148561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
1149561aafbcSJohan Hedberg 			return e;
1150561aafbcSJohan Hedberg 	}
1151561aafbcSJohan Hedberg 
1152561aafbcSJohan Hedberg 	return NULL;
1153561aafbcSJohan Hedberg }
1154561aafbcSJohan Hedberg 
115530dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
115630dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
115730dc78e1SJohan Hedberg 						       int state)
115830dc78e1SJohan Hedberg {
115930dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
116030dc78e1SJohan Hedberg 	struct inquiry_entry *e;
116130dc78e1SJohan Hedberg 
11626ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
116330dc78e1SJohan Hedberg 
116430dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
116530dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
116630dc78e1SJohan Hedberg 			return e;
116730dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
116830dc78e1SJohan Hedberg 			return e;
116930dc78e1SJohan Hedberg 	}
117030dc78e1SJohan Hedberg 
117130dc78e1SJohan Hedberg 	return NULL;
117230dc78e1SJohan Hedberg }
117330dc78e1SJohan Hedberg 
1174a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
1175a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
1176a3d4e20aSJohan Hedberg {
1177a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1178a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
1179a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
1180a3d4e20aSJohan Hedberg 
1181a3d4e20aSJohan Hedberg 	list_del(&ie->list);
1182a3d4e20aSJohan Hedberg 
1183a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
1184a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
1185a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
1186a3d4e20aSJohan Hedberg 			break;
1187a3d4e20aSJohan Hedberg 		pos = &p->list;
1188a3d4e20aSJohan Hedberg 	}
1189a3d4e20aSJohan Hedberg 
1190a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
1191a3d4e20aSJohan Hedberg }
1192a3d4e20aSJohan Hedberg 
1193af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
1194af58925cSMarcel Holtmann 			     bool name_known)
11951da177e4SLinus Torvalds {
119630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
119770f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
1198af58925cSMarcel Holtmann 	u32 flags = 0;
11991da177e4SLinus Torvalds 
12006ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
12011da177e4SLinus Torvalds 
12026928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
12032b2fec4dSSzymon Janc 
1204af58925cSMarcel Holtmann 	if (!data->ssp_mode)
1205af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1206388fc8faSJohan Hedberg 
120770f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
1208a3d4e20aSJohan Hedberg 	if (ie) {
1209af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
1210af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1211388fc8faSJohan Hedberg 
1212a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
1213a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
1214a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
1215a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
1216a3d4e20aSJohan Hedberg 		}
1217a3d4e20aSJohan Hedberg 
1218561aafbcSJohan Hedberg 		goto update;
1219a3d4e20aSJohan Hedberg 	}
1220561aafbcSJohan Hedberg 
12211da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
122227f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
1223af58925cSMarcel Holtmann 	if (!ie) {
1224af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
1225af58925cSMarcel Holtmann 		goto done;
1226af58925cSMarcel Holtmann 	}
122770f23020SAndrei Emeltchenko 
1228561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
1229561aafbcSJohan Hedberg 
1230561aafbcSJohan Hedberg 	if (name_known) {
1231561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1232561aafbcSJohan Hedberg 	} else {
1233561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
1234561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
1235561aafbcSJohan Hedberg 	}
1236561aafbcSJohan Hedberg 
1237561aafbcSJohan Hedberg update:
1238561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
1239561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
1240561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1241561aafbcSJohan Hedberg 		list_del(&ie->list);
12421da177e4SLinus Torvalds 	}
12431da177e4SLinus Torvalds 
124470f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
124570f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
12461da177e4SLinus Torvalds 	cache->timestamp = jiffies;
12473175405bSJohan Hedberg 
12483175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
1249af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
12503175405bSJohan Hedberg 
1251af58925cSMarcel Holtmann done:
1252af58925cSMarcel Holtmann 	return flags;
12531da177e4SLinus Torvalds }
12541da177e4SLinus Torvalds 
12551da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
12561da177e4SLinus Torvalds {
125730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
12581da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
12591da177e4SLinus Torvalds 	struct inquiry_entry *e;
12601da177e4SLinus Torvalds 	int copied = 0;
12611da177e4SLinus Torvalds 
1262561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
12631da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
1264b57c1a56SJohan Hedberg 
1265b57c1a56SJohan Hedberg 		if (copied >= num)
1266b57c1a56SJohan Hedberg 			break;
1267b57c1a56SJohan Hedberg 
12681da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
12691da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
12701da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
12711da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
12721da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
12731da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1274b57c1a56SJohan Hedberg 
12751da177e4SLinus Torvalds 		info++;
1276b57c1a56SJohan Hedberg 		copied++;
12771da177e4SLinus Torvalds 	}
12781da177e4SLinus Torvalds 
12791da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
12801da177e4SLinus Torvalds 	return copied;
12811da177e4SLinus Torvalds }
12821da177e4SLinus Torvalds 
1283a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt)
12841da177e4SLinus Torvalds {
12851da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
128642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
12871da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
12881da177e4SLinus Torvalds 
12891da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
12901da177e4SLinus Torvalds 
12911da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
1292a1d01db1SJohan Hedberg 		return 0;
12931da177e4SLinus Torvalds 
12941da177e4SLinus Torvalds 	/* Start Inquiry */
12951da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
12961da177e4SLinus Torvalds 	cp.length  = ir->length;
12971da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
129842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
1299a1d01db1SJohan Hedberg 
1300a1d01db1SJohan Hedberg 	return 0;
13011da177e4SLinus Torvalds }
13021da177e4SLinus Torvalds 
13031da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
13041da177e4SLinus Torvalds {
13051da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
13061da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
13071da177e4SLinus Torvalds 	struct hci_dev *hdev;
13081da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
13091da177e4SLinus Torvalds 	long timeo;
13101da177e4SLinus Torvalds 	__u8 *buf;
13111da177e4SLinus Torvalds 
13121da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
13131da177e4SLinus Torvalds 		return -EFAULT;
13141da177e4SLinus Torvalds 
13155a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
13165a08ecceSAndrei Emeltchenko 	if (!hdev)
13171da177e4SLinus Torvalds 		return -ENODEV;
13181da177e4SLinus Torvalds 
1319d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
13200736cfa8SMarcel Holtmann 		err = -EBUSY;
13210736cfa8SMarcel Holtmann 		goto done;
13220736cfa8SMarcel Holtmann 	}
13230736cfa8SMarcel Holtmann 
1324d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1325fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1326fee746b0SMarcel Holtmann 		goto done;
1327fee746b0SMarcel Holtmann 	}
1328fee746b0SMarcel Holtmann 
1329ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
13305b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
13315b69bef5SMarcel Holtmann 		goto done;
13325b69bef5SMarcel Holtmann 	}
13335b69bef5SMarcel Holtmann 
1334d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
133556f87901SJohan Hedberg 		err = -EOPNOTSUPP;
133656f87901SJohan Hedberg 		goto done;
133756f87901SJohan Hedberg 	}
133856f87901SJohan Hedberg 
133909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13401da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1341a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
13421f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
13431da177e4SLinus Torvalds 		do_inquiry = 1;
13441da177e4SLinus Torvalds 	}
134509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13461da177e4SLinus Torvalds 
134704837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
134870f23020SAndrei Emeltchenko 
134970f23020SAndrei Emeltchenko 	if (do_inquiry) {
135001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
13514ebeee2dSJohan Hedberg 				   timeo, NULL);
135270f23020SAndrei Emeltchenko 		if (err < 0)
13531da177e4SLinus Torvalds 			goto done;
13543e13fa1eSAndre Guedes 
13553e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
13563e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
13573e13fa1eSAndre Guedes 		 */
135874316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
13593e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
13603e13fa1eSAndre Guedes 			return -EINTR;
136170f23020SAndrei Emeltchenko 	}
13621da177e4SLinus Torvalds 
13638fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
13648fc9ced3SGustavo Padovan 	 * 255 entries
13658fc9ced3SGustavo Padovan 	 */
13661da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
13671da177e4SLinus Torvalds 
13681da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
13691da177e4SLinus Torvalds 	 * copy it to the user space.
13701da177e4SLinus Torvalds 	 */
13716da2ec56SKees Cook 	buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL);
137270f23020SAndrei Emeltchenko 	if (!buf) {
13731da177e4SLinus Torvalds 		err = -ENOMEM;
13741da177e4SLinus Torvalds 		goto done;
13751da177e4SLinus Torvalds 	}
13761da177e4SLinus Torvalds 
137709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13781da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
137909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13801da177e4SLinus Torvalds 
13811da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
13821da177e4SLinus Torvalds 
13831da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
13841da177e4SLinus Torvalds 		ptr += sizeof(ir);
13851da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
13861da177e4SLinus Torvalds 				 ir.num_rsp))
13871da177e4SLinus Torvalds 			err = -EFAULT;
13881da177e4SLinus Torvalds 	} else
13891da177e4SLinus Torvalds 		err = -EFAULT;
13901da177e4SLinus Torvalds 
13911da177e4SLinus Torvalds 	kfree(buf);
13921da177e4SLinus Torvalds 
13931da177e4SLinus Torvalds done:
13941da177e4SLinus Torvalds 	hci_dev_put(hdev);
13951da177e4SLinus Torvalds 	return err;
13961da177e4SLinus Torvalds }
13971da177e4SLinus Torvalds 
13987a0e5b15SMatthias Kaehlcke /**
13997a0e5b15SMatthias Kaehlcke  * hci_dev_get_bd_addr_from_property - Get the Bluetooth Device Address
14007a0e5b15SMatthias Kaehlcke  *				       (BD_ADDR) for a HCI device from
14017a0e5b15SMatthias Kaehlcke  *				       a firmware node property.
14027a0e5b15SMatthias Kaehlcke  * @hdev:	The HCI device
14037a0e5b15SMatthias Kaehlcke  *
14047a0e5b15SMatthias Kaehlcke  * Search the firmware node for 'local-bd-address'.
14057a0e5b15SMatthias Kaehlcke  *
14067a0e5b15SMatthias Kaehlcke  * All-zero BD addresses are rejected, because those could be properties
14077a0e5b15SMatthias Kaehlcke  * that exist in the firmware tables, but were not updated by the firmware. For
14087a0e5b15SMatthias Kaehlcke  * example, the DTS could define 'local-bd-address', with zero BD addresses.
14097a0e5b15SMatthias Kaehlcke  */
14107a0e5b15SMatthias Kaehlcke static void hci_dev_get_bd_addr_from_property(struct hci_dev *hdev)
14117a0e5b15SMatthias Kaehlcke {
14127a0e5b15SMatthias Kaehlcke 	struct fwnode_handle *fwnode = dev_fwnode(hdev->dev.parent);
14137a0e5b15SMatthias Kaehlcke 	bdaddr_t ba;
14147a0e5b15SMatthias Kaehlcke 	int ret;
14157a0e5b15SMatthias Kaehlcke 
14167a0e5b15SMatthias Kaehlcke 	ret = fwnode_property_read_u8_array(fwnode, "local-bd-address",
14177a0e5b15SMatthias Kaehlcke 					    (u8 *)&ba, sizeof(ba));
14187a0e5b15SMatthias Kaehlcke 	if (ret < 0 || !bacmp(&ba, BDADDR_ANY))
14197a0e5b15SMatthias Kaehlcke 		return;
14207a0e5b15SMatthias Kaehlcke 
14217a0e5b15SMatthias Kaehlcke 	bacpy(&hdev->public_addr, &ba);
14227a0e5b15SMatthias Kaehlcke }
14237a0e5b15SMatthias Kaehlcke 
1424cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
14251da177e4SLinus Torvalds {
14261da177e4SLinus Torvalds 	int ret = 0;
14271da177e4SLinus Torvalds 
14281da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
14291da177e4SLinus Torvalds 
1430b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
14311da177e4SLinus Torvalds 
1432d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
143394324962SJohan Hovold 		ret = -ENODEV;
143494324962SJohan Hovold 		goto done;
143594324962SJohan Hovold 	}
143694324962SJohan Hovold 
1437d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1438d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
1439a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1440a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1441bf543036SJohan Hedberg 		 */
1442d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
1443611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1444611b30f7SMarcel Holtmann 			goto done;
1445611b30f7SMarcel Holtmann 		}
1446611b30f7SMarcel Holtmann 
1447a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1448a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1449a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1450a5c8f270SMarcel Holtmann 		 * or not.
1451a5c8f270SMarcel Holtmann 		 *
1452c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
1453c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
1454c6beca0eSMarcel Holtmann 		 * available.
1455c6beca0eSMarcel Holtmann 		 *
1456a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1457a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1458a5c8f270SMarcel Holtmann 		 */
1459d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1460ca8bee5dSMarcel Holtmann 		    hdev->dev_type == HCI_PRIMARY &&
1461a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1462a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1463a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1464a5c8f270SMarcel Holtmann 			goto done;
1465a5c8f270SMarcel Holtmann 		}
1466a5c8f270SMarcel Holtmann 	}
1467a5c8f270SMarcel Holtmann 
14681da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
14691da177e4SLinus Torvalds 		ret = -EALREADY;
14701da177e4SLinus Torvalds 		goto done;
14711da177e4SLinus Torvalds 	}
14721da177e4SLinus Torvalds 
14731da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
14741da177e4SLinus Torvalds 		ret = -EIO;
14751da177e4SLinus Torvalds 		goto done;
14761da177e4SLinus Torvalds 	}
14771da177e4SLinus Torvalds 
1478e9ca8bf1SMarcel Holtmann 	set_bit(HCI_RUNNING, &hdev->flags);
147905fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_OPEN);
14804a3f95b7SMarcel Holtmann 
14811da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
14821da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1483f41c70c4SMarcel Holtmann 
1484740011cfSSean Wang 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
1485740011cfSSean Wang 	    test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
14867fdf6c6aSMarcel Holtmann 		bool invalid_bdaddr;
14877fdf6c6aSMarcel Holtmann 
1488e131d74aSMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_SETUP);
1489e131d74aSMarcel Holtmann 
1490af202f84SMarcel Holtmann 		if (hdev->setup)
1491f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
1492f41c70c4SMarcel Holtmann 
14937fdf6c6aSMarcel Holtmann 		/* The transport driver can set the quirk to mark the
14947fdf6c6aSMarcel Holtmann 		 * BD_ADDR invalid before creating the HCI device or in
14957fdf6c6aSMarcel Holtmann 		 * its setup callback.
14967fdf6c6aSMarcel Holtmann 		 */
14977fdf6c6aSMarcel Holtmann 		invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR,
14987fdf6c6aSMarcel Holtmann 					  &hdev->quirks);
14997fdf6c6aSMarcel Holtmann 
15007a0e5b15SMatthias Kaehlcke 		if (ret)
15017a0e5b15SMatthias Kaehlcke 			goto setup_failed;
15027a0e5b15SMatthias Kaehlcke 
15037a0e5b15SMatthias Kaehlcke 		if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) {
15047a0e5b15SMatthias Kaehlcke 			if (!bacmp(&hdev->public_addr, BDADDR_ANY))
15057a0e5b15SMatthias Kaehlcke 				hci_dev_get_bd_addr_from_property(hdev);
15067a0e5b15SMatthias Kaehlcke 
15077a0e5b15SMatthias Kaehlcke 			if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
15087fdf6c6aSMarcel Holtmann 			    hdev->set_bdaddr) {
15097a0e5b15SMatthias Kaehlcke 				ret = hdev->set_bdaddr(hdev,
15107a0e5b15SMatthias Kaehlcke 						       &hdev->public_addr);
15117fdf6c6aSMarcel Holtmann 
15127fdf6c6aSMarcel Holtmann 				/* If setting of the BD_ADDR from the device
15137fdf6c6aSMarcel Holtmann 				 * property succeeds, then treat the address
15147fdf6c6aSMarcel Holtmann 				 * as valid even if the invalid BD_ADDR
15157fdf6c6aSMarcel Holtmann 				 * quirk indicates otherwise.
15167fdf6c6aSMarcel Holtmann 				 */
15177fdf6c6aSMarcel Holtmann 				if (!ret)
15187fdf6c6aSMarcel Holtmann 					invalid_bdaddr = false;
15197fdf6c6aSMarcel Holtmann 			}
15207a0e5b15SMatthias Kaehlcke 		}
15217a0e5b15SMatthias Kaehlcke 
15227a0e5b15SMatthias Kaehlcke setup_failed:
1523af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
1524af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
1525af202f84SMarcel Holtmann 		 *
15267fdf6c6aSMarcel Holtmann 		 * For the invalid BD_ADDR quirk it is possible that
15277fdf6c6aSMarcel Holtmann 		 * it becomes a valid address if the bootloader does
15287fdf6c6aSMarcel Holtmann 		 * provide it (see above).
15297fdf6c6aSMarcel Holtmann 		 *
1530af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
1531af202f84SMarcel Holtmann 		 * start up as unconfigured.
1532af202f84SMarcel Holtmann 		 */
1533eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
15347fdf6c6aSMarcel Holtmann 		    invalid_bdaddr)
1535a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
1536f41c70c4SMarcel Holtmann 
15370ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
15380ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
15390ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
15400ebca7d6SMarcel Holtmann 		 *
15410ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
15420ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
15430ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
15440ebca7d6SMarcel Holtmann 		 */
1545d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
15460ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
154789bc22d2SMarcel Holtmann 	}
154889bc22d2SMarcel Holtmann 
1549d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_CONFIG)) {
15509713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
15519713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
15529713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
15539713c17bSMarcel Holtmann 		 * on procedure.
155424c457e2SMarcel Holtmann 		 */
15559713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
15569713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
155724c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
155824c457e2SMarcel Holtmann 		else
155924c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
156024c457e2SMarcel Holtmann 	}
156124c457e2SMarcel Holtmann 
1562f41c70c4SMarcel Holtmann 	if (!ret) {
1563d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
156498a63aafSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
15652177bab5SJohan Hedberg 			ret = __hci_init(hdev);
156698a63aafSMarcel Holtmann 			if (!ret && hdev->post_init)
156798a63aafSMarcel Holtmann 				ret = hdev->post_init(hdev);
156898a63aafSMarcel Holtmann 		}
15691da177e4SLinus Torvalds 	}
15701da177e4SLinus Torvalds 
15717e995b9eSMarcel Holtmann 	/* If the HCI Reset command is clearing all diagnostic settings,
15727e995b9eSMarcel Holtmann 	 * then they need to be reprogrammed after the init procedure
15737e995b9eSMarcel Holtmann 	 * completed.
15747e995b9eSMarcel Holtmann 	 */
15757e995b9eSMarcel Holtmann 	if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
1576b56c7b25SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
15777e995b9eSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
15787e995b9eSMarcel Holtmann 		ret = hdev->set_diag(hdev, true);
15797e995b9eSMarcel Holtmann 
1580145373cbSMiao-chen Chou 	msft_do_open(hdev);
1581145373cbSMiao-chen Chou 
1582f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1583f41c70c4SMarcel Holtmann 
15841da177e4SLinus Torvalds 	if (!ret) {
15851da177e4SLinus Torvalds 		hci_dev_hold(hdev);
1586a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
1587a73c046aSJaganath Kanakkassery 		hci_adv_instances_set_rpa_expired(hdev, true);
15881da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
158905fcd4c4SMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_UP);
15906d5d2ee6SHeiner Kallweit 		hci_leds_update_powered(hdev, true);
1591d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1592d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG) &&
1593d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1594d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
15952ff13894SJohan Hedberg 		    hci_dev_test_flag(hdev, HCI_MGMT) &&
1596ca8bee5dSMarcel Holtmann 		    hdev->dev_type == HCI_PRIMARY) {
15972ff13894SJohan Hedberg 			ret = __hci_req_hci_power_on(hdev);
15982ff13894SJohan Hedberg 			mgmt_power_on(hdev, ret);
159956e5cb86SJohan Hedberg 		}
16001da177e4SLinus Torvalds 	} else {
16011da177e4SLinus Torvalds 		/* Init failed, cleanup */
16023eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1603c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1604b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
16051da177e4SLinus Torvalds 
16061da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
16071da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
16081da177e4SLinus Torvalds 
16091da177e4SLinus Torvalds 		if (hdev->flush)
16101da177e4SLinus Torvalds 			hdev->flush(hdev);
16111da177e4SLinus Torvalds 
16121da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
16131da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
16141da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
16151da177e4SLinus Torvalds 		}
16161da177e4SLinus Torvalds 
1617e9ca8bf1SMarcel Holtmann 		clear_bit(HCI_RUNNING, &hdev->flags);
161805fcd4c4SMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
16194a3f95b7SMarcel Holtmann 
16201da177e4SLinus Torvalds 		hdev->close(hdev);
1621fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
16221da177e4SLinus Torvalds 	}
16231da177e4SLinus Torvalds 
16241da177e4SLinus Torvalds done:
1625b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
16261da177e4SLinus Torvalds 	return ret;
16271da177e4SLinus Torvalds }
16281da177e4SLinus Torvalds 
1629cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1630cbed0ca1SJohan Hedberg 
1631cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1632cbed0ca1SJohan Hedberg {
1633cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1634cbed0ca1SJohan Hedberg 	int err;
1635cbed0ca1SJohan Hedberg 
1636cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1637cbed0ca1SJohan Hedberg 	if (!hdev)
1638cbed0ca1SJohan Hedberg 		return -ENODEV;
1639cbed0ca1SJohan Hedberg 
16404a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
1641fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
1642fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
1643fee746b0SMarcel Holtmann 	 * possible.
1644fee746b0SMarcel Holtmann 	 *
1645fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
1646fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
1647fee746b0SMarcel Holtmann 	 * open the device.
1648fee746b0SMarcel Holtmann 	 */
1649d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1650d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1651fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1652fee746b0SMarcel Holtmann 		goto done;
1653fee746b0SMarcel Holtmann 	}
1654fee746b0SMarcel Holtmann 
1655e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
1656e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
1657e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
1658e1d08f40SJohan Hedberg 	 * completed.
1659e1d08f40SJohan Hedberg 	 */
1660a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
1661e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
1662e1d08f40SJohan Hedberg 
1663a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
1664a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
1665a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
1666a5c8f270SMarcel Holtmann 	 */
1667e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
1668e1d08f40SJohan Hedberg 
166912aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
1670b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
167112aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
167212aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
167312aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
167412aa4f0aSMarcel Holtmann 	 */
1675d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1676d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
1677a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
167812aa4f0aSMarcel Holtmann 
1679cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
1680cbed0ca1SJohan Hedberg 
1681fee746b0SMarcel Holtmann done:
1682cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
1683cbed0ca1SJohan Hedberg 	return err;
1684cbed0ca1SJohan Hedberg }
1685cbed0ca1SJohan Hedberg 
1686d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
1687d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
1688d7347f3cSJohan Hedberg {
1689d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
1690d7347f3cSJohan Hedberg 
1691f161dd41SJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list) {
1692f161dd41SJohan Hedberg 		if (p->conn) {
1693f161dd41SJohan Hedberg 			hci_conn_drop(p->conn);
1694f8aaf9b6SJohan Hedberg 			hci_conn_put(p->conn);
1695f161dd41SJohan Hedberg 			p->conn = NULL;
1696f161dd41SJohan Hedberg 		}
1697d7347f3cSJohan Hedberg 		list_del_init(&p->action);
1698f161dd41SJohan Hedberg 	}
1699d7347f3cSJohan Hedberg 
1700d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
1701d7347f3cSJohan Hedberg }
1702d7347f3cSJohan Hedberg 
17036b3cc1dbSSimon Fels int hci_dev_do_close(struct hci_dev *hdev)
17041da177e4SLinus Torvalds {
1705acc649c6SMarcel Holtmann 	bool auto_off;
1706acc649c6SMarcel Holtmann 
17071da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
17081da177e4SLinus Torvalds 
1709d24d8144SGabriele Mazzotta 	if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
1710867146a0SLoic Poulain 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1711d24d8144SGabriele Mazzotta 	    test_bit(HCI_UP, &hdev->flags)) {
1712a44fecbdSTedd Ho-Jeong An 		/* Execute vendor specific shutdown routine */
1713a44fecbdSTedd Ho-Jeong An 		if (hdev->shutdown)
1714a44fecbdSTedd Ho-Jeong An 			hdev->shutdown(hdev);
1715a44fecbdSTedd Ho-Jeong An 	}
1716a44fecbdSTedd Ho-Jeong An 
171778c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
171878c04c0bSVinicius Costa Gomes 
17197df0f73eSJohan Hedberg 	hci_request_cancel_all(hdev);
1720b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
17211da177e4SLinus Torvalds 
17221da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
172365cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
1724b504430cSJohan Hedberg 		hci_req_sync_unlock(hdev);
17251da177e4SLinus Torvalds 		return 0;
17261da177e4SLinus Torvalds 	}
17271da177e4SLinus Torvalds 
17286d5d2ee6SHeiner Kallweit 	hci_leds_update_powered(hdev, false);
17296d5d2ee6SHeiner Kallweit 
17303eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
17313eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1732b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
17331da177e4SLinus Torvalds 
173416ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
173516ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
1736a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
1737a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
173816ab91abSJohan Hedberg 	}
173916ab91abSJohan Hedberg 
1740a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
17417d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
17427d78525dSJohan Hedberg 
1743a73c046aSJaganath Kanakkassery 	if (hci_dev_test_flag(hdev, HCI_MGMT)) {
1744a73c046aSJaganath Kanakkassery 		struct adv_info *adv_instance;
1745a73c046aSJaganath Kanakkassery 
1746d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
17477ba8b4beSAndre Guedes 
1748a73c046aSJaganath Kanakkassery 		list_for_each_entry(adv_instance, &hdev->adv_instances, list)
1749a73c046aSJaganath Kanakkassery 			cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1750a73c046aSJaganath Kanakkassery 	}
1751a73c046aSJaganath Kanakkassery 
175276727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
175376727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
175476727c02SJohan Hedberg 	 */
175576727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
175676727c02SJohan Hedberg 
175709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
17581aeb9c65SJohan Hedberg 
17598f502f84SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
17608f502f84SJohan Hedberg 
1761acc649c6SMarcel Holtmann 	auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF);
1762acc649c6SMarcel Holtmann 
1763ca8bee5dSMarcel Holtmann 	if (!auto_off && hdev->dev_type == HCI_PRIMARY &&
1764baab7932SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
17652ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT))
17662ff13894SJohan Hedberg 		__mgmt_power_off(hdev);
17671aeb9c65SJohan Hedberg 
17681f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
1769d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
1770f161dd41SJohan Hedberg 	hci_conn_hash_flush(hdev);
177109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
17721da177e4SLinus Torvalds 
177364dae967SMarcel Holtmann 	smp_unregister(hdev);
177464dae967SMarcel Holtmann 
177505fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_DOWN);
17761da177e4SLinus Torvalds 
1777145373cbSMiao-chen Chou 	msft_do_close(hdev);
1778145373cbSMiao-chen Chou 
17791da177e4SLinus Torvalds 	if (hdev->flush)
17801da177e4SLinus Torvalds 		hdev->flush(hdev);
17811da177e4SLinus Torvalds 
17821da177e4SLinus Torvalds 	/* Reset device */
17831da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
17841da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
1785acc649c6SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) &&
1786acc649c6SMarcel Holtmann 	    !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
17871da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
17884ebeee2dSJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL);
17891da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
17901da177e4SLinus Torvalds 	}
17911da177e4SLinus Torvalds 
1792c347b765SGustavo F. Padovan 	/* flush cmd  work */
1793c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
17941da177e4SLinus Torvalds 
17951da177e4SLinus Torvalds 	/* Drop queues */
17961da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
17971da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
17981da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
17991da177e4SLinus Torvalds 
18001da177e4SLinus Torvalds 	/* Drop last sent command */
18011da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
180265cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
18031da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
18041da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
18051da177e4SLinus Torvalds 	}
18061da177e4SLinus Torvalds 
1807e9ca8bf1SMarcel Holtmann 	clear_bit(HCI_RUNNING, &hdev->flags);
180805fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
18094a3f95b7SMarcel Holtmann 
18109952d90eSAbhishek Pandit-Subedi 	if (test_and_clear_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks))
18119952d90eSAbhishek Pandit-Subedi 		wake_up(&hdev->suspend_wait_q);
18129952d90eSAbhishek Pandit-Subedi 
18131da177e4SLinus Torvalds 	/* After this point our queues are empty
18141da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
18151da177e4SLinus Torvalds 	hdev->close(hdev);
18161da177e4SLinus Torvalds 
181735b973c9SJohan Hedberg 	/* Clear flags */
1818fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
1819eacb44dfSMarcel Holtmann 	hci_dev_clear_volatile_flags(hdev);
182035b973c9SJohan Hedberg 
1821ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1822536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1823ced5c338SAndrei Emeltchenko 
1824e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
182509b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
18267a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
1827e59fda8dSJohan Hedberg 
1828b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
18291da177e4SLinus Torvalds 
18301da177e4SLinus Torvalds 	hci_dev_put(hdev);
18311da177e4SLinus Torvalds 	return 0;
18321da177e4SLinus Torvalds }
18331da177e4SLinus Torvalds 
18341da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
18351da177e4SLinus Torvalds {
18361da177e4SLinus Torvalds 	struct hci_dev *hdev;
18371da177e4SLinus Torvalds 	int err;
18381da177e4SLinus Torvalds 
183970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
184070f23020SAndrei Emeltchenko 	if (!hdev)
18411da177e4SLinus Torvalds 		return -ENODEV;
18428ee56540SMarcel Holtmann 
1843d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
18440736cfa8SMarcel Holtmann 		err = -EBUSY;
18450736cfa8SMarcel Holtmann 		goto done;
18460736cfa8SMarcel Holtmann 	}
18470736cfa8SMarcel Holtmann 
1848a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
18498ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
18508ee56540SMarcel Holtmann 
18511da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
18528ee56540SMarcel Holtmann 
18530736cfa8SMarcel Holtmann done:
18541da177e4SLinus Torvalds 	hci_dev_put(hdev);
18551da177e4SLinus Torvalds 	return err;
18561da177e4SLinus Torvalds }
18571da177e4SLinus Torvalds 
18585c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
18591da177e4SLinus Torvalds {
18605c912495SMarcel Holtmann 	int ret;
18611da177e4SLinus Torvalds 
18625c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
18631da177e4SLinus Torvalds 
1864b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
18651da177e4SLinus Torvalds 
18661da177e4SLinus Torvalds 	/* Drop queues */
18671da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
18681da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
18691da177e4SLinus Torvalds 
187076727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
187176727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
187276727c02SJohan Hedberg 	 */
187376727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
187476727c02SJohan Hedberg 
187509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
18761f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
18771da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
187809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
18791da177e4SLinus Torvalds 
18801da177e4SLinus Torvalds 	if (hdev->flush)
18811da177e4SLinus Torvalds 		hdev->flush(hdev);
18821da177e4SLinus Torvalds 
18831da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
18846ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
18851da177e4SLinus Torvalds 
18864ebeee2dSJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT, NULL);
18871da177e4SLinus Torvalds 
1888b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
18891da177e4SLinus Torvalds 	return ret;
18901da177e4SLinus Torvalds }
18911da177e4SLinus Torvalds 
18925c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
18935c912495SMarcel Holtmann {
18945c912495SMarcel Holtmann 	struct hci_dev *hdev;
18955c912495SMarcel Holtmann 	int err;
18965c912495SMarcel Holtmann 
18975c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
18985c912495SMarcel Holtmann 	if (!hdev)
18995c912495SMarcel Holtmann 		return -ENODEV;
19005c912495SMarcel Holtmann 
19015c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
19025c912495SMarcel Holtmann 		err = -ENETDOWN;
19035c912495SMarcel Holtmann 		goto done;
19045c912495SMarcel Holtmann 	}
19055c912495SMarcel Holtmann 
1906d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
19075c912495SMarcel Holtmann 		err = -EBUSY;
19085c912495SMarcel Holtmann 		goto done;
19095c912495SMarcel Holtmann 	}
19105c912495SMarcel Holtmann 
1911d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
19125c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
19135c912495SMarcel Holtmann 		goto done;
19145c912495SMarcel Holtmann 	}
19155c912495SMarcel Holtmann 
19165c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
19175c912495SMarcel Holtmann 
19185c912495SMarcel Holtmann done:
19195c912495SMarcel Holtmann 	hci_dev_put(hdev);
19205c912495SMarcel Holtmann 	return err;
19215c912495SMarcel Holtmann }
19225c912495SMarcel Holtmann 
19231da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
19241da177e4SLinus Torvalds {
19251da177e4SLinus Torvalds 	struct hci_dev *hdev;
19261da177e4SLinus Torvalds 	int ret = 0;
19271da177e4SLinus Torvalds 
192870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
192970f23020SAndrei Emeltchenko 	if (!hdev)
19301da177e4SLinus Torvalds 		return -ENODEV;
19311da177e4SLinus Torvalds 
1932d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
19330736cfa8SMarcel Holtmann 		ret = -EBUSY;
19340736cfa8SMarcel Holtmann 		goto done;
19350736cfa8SMarcel Holtmann 	}
19360736cfa8SMarcel Holtmann 
1937d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1938fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
1939fee746b0SMarcel Holtmann 		goto done;
1940fee746b0SMarcel Holtmann 	}
1941fee746b0SMarcel Holtmann 
19421da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
19431da177e4SLinus Torvalds 
19440736cfa8SMarcel Holtmann done:
19451da177e4SLinus Torvalds 	hci_dev_put(hdev);
19461da177e4SLinus Torvalds 	return ret;
19471da177e4SLinus Torvalds }
19481da177e4SLinus Torvalds 
1949123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
1950123abc08SJohan Hedberg {
1951bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
1952123abc08SJohan Hedberg 
1953123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
1954123abc08SJohan Hedberg 
1955123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
1956238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
1957238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
1958123abc08SJohan Hedberg 	else
1959a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
1960a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
1961123abc08SJohan Hedberg 
1962bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
1963238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
1964238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
1965bc6d2d04SJohan Hedberg 	} else {
1966a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1967a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
1968a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
1969bc6d2d04SJohan Hedberg 	}
1970bc6d2d04SJohan Hedberg 
1971d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
1972123abc08SJohan Hedberg 		return;
1973123abc08SJohan Hedberg 
1974bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
1975bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
1976a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
1977bc6d2d04SJohan Hedberg 
1978d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
1979cab054abSJohan Hedberg 			hci_req_update_adv_data(hdev, hdev->cur_adv_instance);
1980bc6d2d04SJohan Hedberg 
1981123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
1982123abc08SJohan Hedberg 	}
1983bc6d2d04SJohan Hedberg }
1984123abc08SJohan Hedberg 
19851da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
19861da177e4SLinus Torvalds {
19871da177e4SLinus Torvalds 	struct hci_dev *hdev;
19881da177e4SLinus Torvalds 	struct hci_dev_req dr;
19891da177e4SLinus Torvalds 	int err = 0;
19901da177e4SLinus Torvalds 
19911da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
19921da177e4SLinus Torvalds 		return -EFAULT;
19931da177e4SLinus Torvalds 
199470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
199570f23020SAndrei Emeltchenko 	if (!hdev)
19961da177e4SLinus Torvalds 		return -ENODEV;
19971da177e4SLinus Torvalds 
1998d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
19990736cfa8SMarcel Holtmann 		err = -EBUSY;
20000736cfa8SMarcel Holtmann 		goto done;
20010736cfa8SMarcel Holtmann 	}
20020736cfa8SMarcel Holtmann 
2003d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
2004fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2005fee746b0SMarcel Holtmann 		goto done;
2006fee746b0SMarcel Holtmann 	}
2007fee746b0SMarcel Holtmann 
2008ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
20095b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
20105b69bef5SMarcel Holtmann 		goto done;
20115b69bef5SMarcel Holtmann 	}
20125b69bef5SMarcel Holtmann 
2013d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
201456f87901SJohan Hedberg 		err = -EOPNOTSUPP;
201556f87901SJohan Hedberg 		goto done;
201656f87901SJohan Hedberg 	}
201756f87901SJohan Hedberg 
20181da177e4SLinus Torvalds 	switch (cmd) {
20191da177e4SLinus Torvalds 	case HCISETAUTH:
202001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
20214ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20221da177e4SLinus Torvalds 		break;
20231da177e4SLinus Torvalds 
20241da177e4SLinus Torvalds 	case HCISETENCRYPT:
20251da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
20261da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
20271da177e4SLinus Torvalds 			break;
20281da177e4SLinus Torvalds 		}
20291da177e4SLinus Torvalds 
20301da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
20311da177e4SLinus Torvalds 			/* Auth must be enabled first */
203201178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
20334ebeee2dSJohan Hedberg 					   HCI_INIT_TIMEOUT, NULL);
20341da177e4SLinus Torvalds 			if (err)
20351da177e4SLinus Torvalds 				break;
20361da177e4SLinus Torvalds 		}
20371da177e4SLinus Torvalds 
203801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
20394ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20401da177e4SLinus Torvalds 		break;
20411da177e4SLinus Torvalds 
20421da177e4SLinus Torvalds 	case HCISETSCAN:
204301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
20444ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
204591a668b0SJohan Hedberg 
2046bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
2047bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
204891a668b0SJohan Hedberg 		 */
2049123abc08SJohan Hedberg 		if (!err)
2050123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
20511da177e4SLinus Torvalds 		break;
20521da177e4SLinus Torvalds 
20531da177e4SLinus Torvalds 	case HCISETLINKPOL:
205401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
20554ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20561da177e4SLinus Torvalds 		break;
20571da177e4SLinus Torvalds 
20581da177e4SLinus Torvalds 	case HCISETLINKMODE:
2059e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2060e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2061e4e8e37cSMarcel Holtmann 		break;
2062e4e8e37cSMarcel Holtmann 
2063e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2064b7c23df8SJaganath Kanakkassery 		if (hdev->pkt_type == (__u16) dr.dev_opt)
2065b7c23df8SJaganath Kanakkassery 			break;
2066b7c23df8SJaganath Kanakkassery 
2067e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
2068b7c23df8SJaganath Kanakkassery 		mgmt_phy_configuration_changed(hdev, NULL);
20691da177e4SLinus Torvalds 		break;
20701da177e4SLinus Torvalds 
20711da177e4SLinus Torvalds 	case HCISETACLMTU:
20721da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
20731da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
20741da177e4SLinus Torvalds 		break;
20751da177e4SLinus Torvalds 
20761da177e4SLinus Torvalds 	case HCISETSCOMTU:
20771da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
20781da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
20791da177e4SLinus Torvalds 		break;
20801da177e4SLinus Torvalds 
20811da177e4SLinus Torvalds 	default:
20821da177e4SLinus Torvalds 		err = -EINVAL;
20831da177e4SLinus Torvalds 		break;
20841da177e4SLinus Torvalds 	}
2085e4e8e37cSMarcel Holtmann 
20860736cfa8SMarcel Holtmann done:
20871da177e4SLinus Torvalds 	hci_dev_put(hdev);
20881da177e4SLinus Torvalds 	return err;
20891da177e4SLinus Torvalds }
20901da177e4SLinus Torvalds 
20911da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
20921da177e4SLinus Torvalds {
20938035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
20941da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
20951da177e4SLinus Torvalds 	struct hci_dev_req *dr;
20961da177e4SLinus Torvalds 	int n = 0, size, err;
20971da177e4SLinus Torvalds 	__u16 dev_num;
20981da177e4SLinus Torvalds 
20991da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
21001da177e4SLinus Torvalds 		return -EFAULT;
21011da177e4SLinus Torvalds 
21021da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
21031da177e4SLinus Torvalds 		return -EINVAL;
21041da177e4SLinus Torvalds 
21051da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
21061da177e4SLinus Torvalds 
210770f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
210870f23020SAndrei Emeltchenko 	if (!dl)
21091da177e4SLinus Torvalds 		return -ENOMEM;
21101da177e4SLinus Torvalds 
21111da177e4SLinus Torvalds 	dr = dl->dev_req;
21121da177e4SLinus Torvalds 
2113f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
21148035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
21152e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
2116c542a06cSJohan Hedberg 
21172e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
21182e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
21192e84d8dbSMarcel Holtmann 		 * device is actually down.
21202e84d8dbSMarcel Holtmann 		 */
2121d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
21222e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
2123c542a06cSJohan Hedberg 
21241da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
21252e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
2126c542a06cSJohan Hedberg 
21271da177e4SLinus Torvalds 		if (++n >= dev_num)
21281da177e4SLinus Torvalds 			break;
21291da177e4SLinus Torvalds 	}
2130f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
21311da177e4SLinus Torvalds 
21321da177e4SLinus Torvalds 	dl->dev_num = n;
21331da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
21341da177e4SLinus Torvalds 
21351da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
21361da177e4SLinus Torvalds 	kfree(dl);
21371da177e4SLinus Torvalds 
21381da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
21391da177e4SLinus Torvalds }
21401da177e4SLinus Torvalds 
21411da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
21421da177e4SLinus Torvalds {
21431da177e4SLinus Torvalds 	struct hci_dev *hdev;
21441da177e4SLinus Torvalds 	struct hci_dev_info di;
21452e84d8dbSMarcel Holtmann 	unsigned long flags;
21461da177e4SLinus Torvalds 	int err = 0;
21471da177e4SLinus Torvalds 
21481da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
21491da177e4SLinus Torvalds 		return -EFAULT;
21501da177e4SLinus Torvalds 
215170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
215270f23020SAndrei Emeltchenko 	if (!hdev)
21531da177e4SLinus Torvalds 		return -ENODEV;
21541da177e4SLinus Torvalds 
21552e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
21562e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
21572e84d8dbSMarcel Holtmann 	 * device is actually down.
21582e84d8dbSMarcel Holtmann 	 */
2159d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
21602e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
21612e84d8dbSMarcel Holtmann 	else
21622e84d8dbSMarcel Holtmann 		flags = hdev->flags;
2163c542a06cSJohan Hedberg 
21641da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
21651da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
216660f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
21672e84d8dbSMarcel Holtmann 	di.flags    = flags;
21681da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2169572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
21701da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
21711da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
21721da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
21731da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2174572c7f84SJohan Hedberg 	} else {
2175572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2176572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2177572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2178572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2179572c7f84SJohan Hedberg 	}
21801da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
21811da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
21821da177e4SLinus Torvalds 
21831da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
21841da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
21851da177e4SLinus Torvalds 
21861da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
21871da177e4SLinus Torvalds 		err = -EFAULT;
21881da177e4SLinus Torvalds 
21891da177e4SLinus Torvalds 	hci_dev_put(hdev);
21901da177e4SLinus Torvalds 
21911da177e4SLinus Torvalds 	return err;
21921da177e4SLinus Torvalds }
21931da177e4SLinus Torvalds 
21941da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
21951da177e4SLinus Torvalds 
2196611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2197611b30f7SMarcel Holtmann {
2198611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2199611b30f7SMarcel Holtmann 
2200611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2201611b30f7SMarcel Holtmann 
2202d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
22030736cfa8SMarcel Holtmann 		return -EBUSY;
22040736cfa8SMarcel Holtmann 
22055e130367SJohan Hedberg 	if (blocked) {
2206a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
2207d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
2208d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
2209611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
22105e130367SJohan Hedberg 	} else {
2211a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
22125e130367SJohan Hedberg 	}
2213611b30f7SMarcel Holtmann 
2214611b30f7SMarcel Holtmann 	return 0;
2215611b30f7SMarcel Holtmann }
2216611b30f7SMarcel Holtmann 
2217611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2218611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2219611b30f7SMarcel Holtmann };
2220611b30f7SMarcel Holtmann 
2221ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2222ab81cbf9SJohan Hedberg {
2223ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
222496570ffcSJohan Hedberg 	int err;
2225ab81cbf9SJohan Hedberg 
2226ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2227ab81cbf9SJohan Hedberg 
22282ff13894SJohan Hedberg 	if (test_bit(HCI_UP, &hdev->flags) &&
22292ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT) &&
22302ff13894SJohan Hedberg 	    hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
2231d82142a8SWei-Ning Huang 		cancel_delayed_work(&hdev->power_off);
22322ff13894SJohan Hedberg 		hci_req_sync_lock(hdev);
22332ff13894SJohan Hedberg 		err = __hci_req_hci_power_on(hdev);
22342ff13894SJohan Hedberg 		hci_req_sync_unlock(hdev);
22352ff13894SJohan Hedberg 		mgmt_power_on(hdev, err);
22362ff13894SJohan Hedberg 		return;
22372ff13894SJohan Hedberg 	}
22382ff13894SJohan Hedberg 
2239cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
224096570ffcSJohan Hedberg 	if (err < 0) {
22413ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
224296570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
22433ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
2244ab81cbf9SJohan Hedberg 		return;
224596570ffcSJohan Hedberg 	}
2246ab81cbf9SJohan Hedberg 
2247a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2248a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2249a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2250a5c8f270SMarcel Holtmann 	 */
2251d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
2252d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
2253ca8bee5dSMarcel Holtmann 	    (hdev->dev_type == HCI_PRIMARY &&
2254a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2255a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2256a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
2257bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2258d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
225919202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
226019202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2261bf543036SJohan Hedberg 	}
2262ab81cbf9SJohan Hedberg 
2263a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
22644a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
22654a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
22664a964404SMarcel Holtmann 		 */
2267d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
22684a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
22690602a8adSMarcel Holtmann 
22700602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
22710602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
22720602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
22730602a8adSMarcel Holtmann 		 *
22740602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
22750602a8adSMarcel Holtmann 		 * and no event will be send.
22760602a8adSMarcel Holtmann 		 */
2277744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2278a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
22795ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
22805ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
22815ea234d3SMarcel Holtmann 		 */
2282d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
22835ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
22845ea234d3SMarcel Holtmann 
2285d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
2286d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
2287d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
2288d603b76bSMarcel Holtmann 		 */
2289d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
2290ab81cbf9SJohan Hedberg 	}
2291ab81cbf9SJohan Hedberg }
2292ab81cbf9SJohan Hedberg 
2293ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2294ab81cbf9SJohan Hedberg {
22953243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
22963243553fSJohan Hedberg 					    power_off.work);
2297ab81cbf9SJohan Hedberg 
2298ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2299ab81cbf9SJohan Hedberg 
23008ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2301ab81cbf9SJohan Hedberg }
2302ab81cbf9SJohan Hedberg 
2303c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
2304c7741d16SMarcel Holtmann {
2305c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
2306c7741d16SMarcel Holtmann 
2307c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2308c7741d16SMarcel Holtmann 
2309c7741d16SMarcel Holtmann 	if (hdev->hw_error)
2310c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
2311c7741d16SMarcel Holtmann 	else
23122064ee33SMarcel Holtmann 		bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
2313c7741d16SMarcel Holtmann 
2314c7741d16SMarcel Holtmann 	if (hci_dev_do_close(hdev))
2315c7741d16SMarcel Holtmann 		return;
2316c7741d16SMarcel Holtmann 
2317c7741d16SMarcel Holtmann 	hci_dev_do_open(hdev);
2318c7741d16SMarcel Holtmann }
2319c7741d16SMarcel Holtmann 
232035f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
23212aeb9a1aSJohan Hedberg {
23224821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
23232aeb9a1aSJohan Hedberg 
23244821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
23254821002cSJohan Hedberg 		list_del(&uuid->list);
23262aeb9a1aSJohan Hedberg 		kfree(uuid);
23272aeb9a1aSJohan Hedberg 	}
23282aeb9a1aSJohan Hedberg }
23292aeb9a1aSJohan Hedberg 
233035f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
233155ed8ca1SJohan Hedberg {
233255ed8ca1SJohan Hedberg 	struct link_key *key;
233355ed8ca1SJohan Hedberg 
2334d7d41682SMadhuparna Bhowmik 	list_for_each_entry(key, &hdev->link_keys, list) {
23350378b597SJohan Hedberg 		list_del_rcu(&key->list);
23360378b597SJohan Hedberg 		kfree_rcu(key, rcu);
233755ed8ca1SJohan Hedberg 	}
233855ed8ca1SJohan Hedberg }
233955ed8ca1SJohan Hedberg 
234035f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2341b899efafSVinicius Costa Gomes {
2342970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2343b899efafSVinicius Costa Gomes 
2344d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->long_term_keys, list) {
2345970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2346970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2347b899efafSVinicius Costa Gomes 	}
2348b899efafSVinicius Costa Gomes }
2349b899efafSVinicius Costa Gomes 
2350970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2351970c4e46SJohan Hedberg {
2352adae20cbSJohan Hedberg 	struct smp_irk *k;
2353970c4e46SJohan Hedberg 
2354d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->identity_resolving_keys, list) {
2355adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2356adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2357970c4e46SJohan Hedberg 	}
2358970c4e46SJohan Hedberg }
2359970c4e46SJohan Hedberg 
2360600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev)
2361600a8749SAlain Michaud {
2362600a8749SAlain Michaud 	struct blocked_key *b;
2363600a8749SAlain Michaud 
2364d7d41682SMadhuparna Bhowmik 	list_for_each_entry(b, &hdev->blocked_keys, list) {
2365600a8749SAlain Michaud 		list_del_rcu(&b->list);
2366600a8749SAlain Michaud 		kfree_rcu(b, rcu);
2367600a8749SAlain Michaud 	}
2368600a8749SAlain Michaud }
2369600a8749SAlain Michaud 
2370600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16])
2371600a8749SAlain Michaud {
2372600a8749SAlain Michaud 	bool blocked = false;
2373600a8749SAlain Michaud 	struct blocked_key *b;
2374600a8749SAlain Michaud 
2375600a8749SAlain Michaud 	rcu_read_lock();
23760c2ac7d4SMadhuparna Bhowmik 	list_for_each_entry_rcu(b, &hdev->blocked_keys, list) {
2377600a8749SAlain Michaud 		if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) {
2378600a8749SAlain Michaud 			blocked = true;
2379600a8749SAlain Michaud 			break;
2380600a8749SAlain Michaud 		}
2381600a8749SAlain Michaud 	}
2382600a8749SAlain Michaud 
2383600a8749SAlain Michaud 	rcu_read_unlock();
2384600a8749SAlain Michaud 	return blocked;
2385600a8749SAlain Michaud }
2386600a8749SAlain Michaud 
238755ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
238855ed8ca1SJohan Hedberg {
238955ed8ca1SJohan Hedberg 	struct link_key *k;
239055ed8ca1SJohan Hedberg 
23910378b597SJohan Hedberg 	rcu_read_lock();
23920378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
23930378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
23940378b597SJohan Hedberg 			rcu_read_unlock();
2395600a8749SAlain Michaud 
2396600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev,
2397600a8749SAlain Michaud 					       HCI_BLOCKED_KEY_TYPE_LINKKEY,
2398600a8749SAlain Michaud 					       k->val)) {
2399600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
2400600a8749SAlain Michaud 							"Link key blocked for %pMR",
2401600a8749SAlain Michaud 							&k->bdaddr);
2402600a8749SAlain Michaud 				return NULL;
2403600a8749SAlain Michaud 			}
2404600a8749SAlain Michaud 
240555ed8ca1SJohan Hedberg 			return k;
24060378b597SJohan Hedberg 		}
24070378b597SJohan Hedberg 	}
24080378b597SJohan Hedberg 	rcu_read_unlock();
240955ed8ca1SJohan Hedberg 
241055ed8ca1SJohan Hedberg 	return NULL;
241155ed8ca1SJohan Hedberg }
241255ed8ca1SJohan Hedberg 
2413745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2414d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2415d25e28abSJohan Hedberg {
2416d25e28abSJohan Hedberg 	/* Legacy key */
2417d25e28abSJohan Hedberg 	if (key_type < 0x03)
2418745c0ce3SVishal Agarwal 		return true;
2419d25e28abSJohan Hedberg 
2420d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2421d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2422745c0ce3SVishal Agarwal 		return false;
2423d25e28abSJohan Hedberg 
2424d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2425d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2426745c0ce3SVishal Agarwal 		return false;
2427d25e28abSJohan Hedberg 
2428d25e28abSJohan Hedberg 	/* Security mode 3 case */
2429d25e28abSJohan Hedberg 	if (!conn)
2430745c0ce3SVishal Agarwal 		return true;
2431d25e28abSJohan Hedberg 
2432e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
2433e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
2434e3befab9SJohan Hedberg 		return true;
2435e3befab9SJohan Hedberg 
2436d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2437d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2438745c0ce3SVishal Agarwal 		return true;
2439d25e28abSJohan Hedberg 
2440d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2441d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2442745c0ce3SVishal Agarwal 		return true;
2443d25e28abSJohan Hedberg 
2444d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2445d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2446745c0ce3SVishal Agarwal 		return true;
2447d25e28abSJohan Hedberg 
2448d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2449d25e28abSJohan Hedberg 	 * persistently */
2450745c0ce3SVishal Agarwal 	return false;
2451d25e28abSJohan Hedberg }
2452d25e28abSJohan Hedberg 
2453e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
245498a0b845SJohan Hedberg {
2455e804d25dSJohan Hedberg 	if (type == SMP_LTK)
2456e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
245798a0b845SJohan Hedberg 
2458e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
245998a0b845SJohan Hedberg }
246098a0b845SJohan Hedberg 
2461f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2462e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
246375d262c2SVinicius Costa Gomes {
2464c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
246575d262c2SVinicius Costa Gomes 
2466970d0f1bSJohan Hedberg 	rcu_read_lock();
2467970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
24685378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
24695378bc56SJohan Hedberg 			continue;
24705378bc56SJohan Hedberg 
2471923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
2472970d0f1bSJohan Hedberg 			rcu_read_unlock();
2473600a8749SAlain Michaud 
2474600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK,
2475600a8749SAlain Michaud 					       k->val)) {
2476600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
2477600a8749SAlain Michaud 							"LTK blocked for %pMR",
2478600a8749SAlain Michaud 							&k->bdaddr);
2479600a8749SAlain Michaud 				return NULL;
2480600a8749SAlain Michaud 			}
2481600a8749SAlain Michaud 
248275d262c2SVinicius Costa Gomes 			return k;
2483970d0f1bSJohan Hedberg 		}
2484970d0f1bSJohan Hedberg 	}
2485970d0f1bSJohan Hedberg 	rcu_read_unlock();
248675d262c2SVinicius Costa Gomes 
248775d262c2SVinicius Costa Gomes 	return NULL;
248875d262c2SVinicius Costa Gomes }
248975d262c2SVinicius Costa Gomes 
2490970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2491970c4e46SJohan Hedberg {
2492600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
2493970c4e46SJohan Hedberg 	struct smp_irk *irk;
2494970c4e46SJohan Hedberg 
2495adae20cbSJohan Hedberg 	rcu_read_lock();
2496adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2497adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
2498600a8749SAlain Michaud 			irk_to_return = irk;
2499600a8749SAlain Michaud 			goto done;
2500970c4e46SJohan Hedberg 		}
2501adae20cbSJohan Hedberg 	}
2502970c4e46SJohan Hedberg 
2503adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2504defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
2505970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
2506600a8749SAlain Michaud 			irk_to_return = irk;
2507600a8749SAlain Michaud 			goto done;
2508970c4e46SJohan Hedberg 		}
2509970c4e46SJohan Hedberg 	}
2510600a8749SAlain Michaud 
2511600a8749SAlain Michaud done:
2512600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
2513600a8749SAlain Michaud 						irk_to_return->val)) {
2514600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
2515600a8749SAlain Michaud 					&irk_to_return->bdaddr);
2516600a8749SAlain Michaud 		irk_to_return = NULL;
2517600a8749SAlain Michaud 	}
2518600a8749SAlain Michaud 
2519adae20cbSJohan Hedberg 	rcu_read_unlock();
2520970c4e46SJohan Hedberg 
2521600a8749SAlain Michaud 	return irk_to_return;
2522970c4e46SJohan Hedberg }
2523970c4e46SJohan Hedberg 
2524970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2525970c4e46SJohan Hedberg 				     u8 addr_type)
2526970c4e46SJohan Hedberg {
2527600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
2528970c4e46SJohan Hedberg 	struct smp_irk *irk;
2529970c4e46SJohan Hedberg 
25306cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
25316cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
25326cfc9988SJohan Hedberg 		return NULL;
25336cfc9988SJohan Hedberg 
2534adae20cbSJohan Hedberg 	rcu_read_lock();
2535adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2536970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
2537adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
2538600a8749SAlain Michaud 			irk_to_return = irk;
2539600a8749SAlain Michaud 			goto done;
2540970c4e46SJohan Hedberg 		}
2541adae20cbSJohan Hedberg 	}
2542600a8749SAlain Michaud 
2543600a8749SAlain Michaud done:
2544600a8749SAlain Michaud 
2545600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
2546600a8749SAlain Michaud 						irk_to_return->val)) {
2547600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
2548600a8749SAlain Michaud 					&irk_to_return->bdaddr);
2549600a8749SAlain Michaud 		irk_to_return = NULL;
2550600a8749SAlain Michaud 	}
2551600a8749SAlain Michaud 
2552adae20cbSJohan Hedberg 	rcu_read_unlock();
2553970c4e46SJohan Hedberg 
2554600a8749SAlain Michaud 	return irk_to_return;
2555970c4e46SJohan Hedberg }
2556970c4e46SJohan Hedberg 
2557567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
25587652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
25597652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
256055ed8ca1SJohan Hedberg {
256155ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2562745c0ce3SVishal Agarwal 	u8 old_key_type;
256355ed8ca1SJohan Hedberg 
256455ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
256555ed8ca1SJohan Hedberg 	if (old_key) {
256655ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
256755ed8ca1SJohan Hedberg 		key = old_key;
256855ed8ca1SJohan Hedberg 	} else {
256912adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
25700a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
257155ed8ca1SJohan Hedberg 		if (!key)
2572567fa2aaSJohan Hedberg 			return NULL;
25730378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
257455ed8ca1SJohan Hedberg 	}
257555ed8ca1SJohan Hedberg 
25766ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
257755ed8ca1SJohan Hedberg 
2578d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2579d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2580d25e28abSJohan Hedberg 	 * previous key */
2581d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2582a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2583d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2584655fe6ecSJohan Hedberg 		if (conn)
2585655fe6ecSJohan Hedberg 			conn->key_type = type;
2586655fe6ecSJohan Hedberg 	}
2587d25e28abSJohan Hedberg 
258855ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
25899b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
259055ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
259155ed8ca1SJohan Hedberg 
2592b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
259355ed8ca1SJohan Hedberg 		key->type = old_key_type;
25944748fed2SJohan Hedberg 	else
25954748fed2SJohan Hedberg 		key->type = type;
25964748fed2SJohan Hedberg 
25977652ff6aSJohan Hedberg 	if (persistent)
25987652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
25997652ff6aSJohan Hedberg 						 old_key_type);
26004df378a1SJohan Hedberg 
2601567fa2aaSJohan Hedberg 	return key;
260255ed8ca1SJohan Hedberg }
260355ed8ca1SJohan Hedberg 
2604ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
260535d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
2606fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
260775d262c2SVinicius Costa Gomes {
2608c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
2609e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
261075d262c2SVinicius Costa Gomes 
2611f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
2612c9839a11SVinicius Costa Gomes 	if (old_key)
261375d262c2SVinicius Costa Gomes 		key = old_key;
2614c9839a11SVinicius Costa Gomes 	else {
26150a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
261675d262c2SVinicius Costa Gomes 		if (!key)
2617ca9142b8SJohan Hedberg 			return NULL;
2618970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
261975d262c2SVinicius Costa Gomes 	}
262075d262c2SVinicius Costa Gomes 
262175d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2622c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2623c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2624c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2625c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2626fe39c7b2SMarcel Holtmann 	key->rand = rand;
2627c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2628c9839a11SVinicius Costa Gomes 	key->type = type;
262975d262c2SVinicius Costa Gomes 
2630ca9142b8SJohan Hedberg 	return key;
263175d262c2SVinicius Costa Gomes }
263275d262c2SVinicius Costa Gomes 
2633ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2634ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
2635970c4e46SJohan Hedberg {
2636970c4e46SJohan Hedberg 	struct smp_irk *irk;
2637970c4e46SJohan Hedberg 
2638970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2639970c4e46SJohan Hedberg 	if (!irk) {
2640970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
2641970c4e46SJohan Hedberg 		if (!irk)
2642ca9142b8SJohan Hedberg 			return NULL;
2643970c4e46SJohan Hedberg 
2644970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
2645970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
2646970c4e46SJohan Hedberg 
2647adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
2648970c4e46SJohan Hedberg 	}
2649970c4e46SJohan Hedberg 
2650970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
2651970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
2652970c4e46SJohan Hedberg 
2653ca9142b8SJohan Hedberg 	return irk;
2654970c4e46SJohan Hedberg }
2655970c4e46SJohan Hedberg 
265655ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
265755ed8ca1SJohan Hedberg {
265855ed8ca1SJohan Hedberg 	struct link_key *key;
265955ed8ca1SJohan Hedberg 
266055ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
266155ed8ca1SJohan Hedberg 	if (!key)
266255ed8ca1SJohan Hedberg 		return -ENOENT;
266355ed8ca1SJohan Hedberg 
26646ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
266555ed8ca1SJohan Hedberg 
26660378b597SJohan Hedberg 	list_del_rcu(&key->list);
26670378b597SJohan Hedberg 	kfree_rcu(key, rcu);
266855ed8ca1SJohan Hedberg 
266955ed8ca1SJohan Hedberg 	return 0;
267055ed8ca1SJohan Hedberg }
267155ed8ca1SJohan Hedberg 
2672e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2673b899efafSVinicius Costa Gomes {
2674970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2675c51ffa0bSJohan Hedberg 	int removed = 0;
2676b899efafSVinicius Costa Gomes 
2677970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2678e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2679b899efafSVinicius Costa Gomes 			continue;
2680b899efafSVinicius Costa Gomes 
26816ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2682b899efafSVinicius Costa Gomes 
2683970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2684970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2685c51ffa0bSJohan Hedberg 		removed++;
2686b899efafSVinicius Costa Gomes 	}
2687b899efafSVinicius Costa Gomes 
2688c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
2689b899efafSVinicius Costa Gomes }
2690b899efafSVinicius Costa Gomes 
2691a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
2692a7ec7338SJohan Hedberg {
2693adae20cbSJohan Hedberg 	struct smp_irk *k;
2694a7ec7338SJohan Hedberg 
2695adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2696a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
2697a7ec7338SJohan Hedberg 			continue;
2698a7ec7338SJohan Hedberg 
2699a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2700a7ec7338SJohan Hedberg 
2701adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2702adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2703a7ec7338SJohan Hedberg 	}
2704a7ec7338SJohan Hedberg }
2705a7ec7338SJohan Hedberg 
270655e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
270755e76b38SJohan Hedberg {
270855e76b38SJohan Hedberg 	struct smp_ltk *k;
27094ba9faf3SJohan Hedberg 	struct smp_irk *irk;
271055e76b38SJohan Hedberg 	u8 addr_type;
271155e76b38SJohan Hedberg 
271255e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
271355e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
271455e76b38SJohan Hedberg 			return true;
271555e76b38SJohan Hedberg 		return false;
271655e76b38SJohan Hedberg 	}
271755e76b38SJohan Hedberg 
271855e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
271955e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
272055e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
272155e76b38SJohan Hedberg 	else
272255e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
272355e76b38SJohan Hedberg 
27244ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
27254ba9faf3SJohan Hedberg 	if (irk) {
27264ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
27274ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
27284ba9faf3SJohan Hedberg 	}
27294ba9faf3SJohan Hedberg 
273055e76b38SJohan Hedberg 	rcu_read_lock();
273155e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
273287c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
273387c8b28dSJohan Hedberg 			rcu_read_unlock();
273455e76b38SJohan Hedberg 			return true;
273555e76b38SJohan Hedberg 		}
273687c8b28dSJohan Hedberg 	}
273755e76b38SJohan Hedberg 	rcu_read_unlock();
273855e76b38SJohan Hedberg 
273955e76b38SJohan Hedberg 	return false;
274055e76b38SJohan Hedberg }
274155e76b38SJohan Hedberg 
27426bd32326SVille Tervo /* HCI command timer function */
274365cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
27446bd32326SVille Tervo {
274565cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
274665cc2b49SMarcel Holtmann 					    cmd_timer.work);
27476bd32326SVille Tervo 
2748bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2749bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2750bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2751bda4f23aSAndrei Emeltchenko 
27522064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
2753bda4f23aSAndrei Emeltchenko 	} else {
27542064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command tx timeout");
2755bda4f23aSAndrei Emeltchenko 	}
2756bda4f23aSAndrei Emeltchenko 
2757e2bef384SRajat Jain 	if (hdev->cmd_timeout)
2758e2bef384SRajat Jain 		hdev->cmd_timeout(hdev);
2759e2bef384SRajat Jain 
27606bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2761c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
27626bd32326SVille Tervo }
27636bd32326SVille Tervo 
27642763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
27656928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
27662763eda6SSzymon Janc {
27672763eda6SSzymon Janc 	struct oob_data *data;
27682763eda6SSzymon Janc 
27696928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
27706928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
27716928a924SJohan Hedberg 			continue;
27726928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
27736928a924SJohan Hedberg 			continue;
27742763eda6SSzymon Janc 		return data;
27756928a924SJohan Hedberg 	}
27762763eda6SSzymon Janc 
27772763eda6SSzymon Janc 	return NULL;
27782763eda6SSzymon Janc }
27792763eda6SSzymon Janc 
27806928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
27816928a924SJohan Hedberg 			       u8 bdaddr_type)
27822763eda6SSzymon Janc {
27832763eda6SSzymon Janc 	struct oob_data *data;
27842763eda6SSzymon Janc 
27856928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
27862763eda6SSzymon Janc 	if (!data)
27872763eda6SSzymon Janc 		return -ENOENT;
27882763eda6SSzymon Janc 
27896928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
27902763eda6SSzymon Janc 
27912763eda6SSzymon Janc 	list_del(&data->list);
27922763eda6SSzymon Janc 	kfree(data);
27932763eda6SSzymon Janc 
27942763eda6SSzymon Janc 	return 0;
27952763eda6SSzymon Janc }
27962763eda6SSzymon Janc 
279735f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
27982763eda6SSzymon Janc {
27992763eda6SSzymon Janc 	struct oob_data *data, *n;
28002763eda6SSzymon Janc 
28012763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
28022763eda6SSzymon Janc 		list_del(&data->list);
28032763eda6SSzymon Janc 		kfree(data);
28042763eda6SSzymon Janc 	}
28052763eda6SSzymon Janc }
28062763eda6SSzymon Janc 
28070798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
28086928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
280938da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
28100798872eSMarcel Holtmann {
28110798872eSMarcel Holtmann 	struct oob_data *data;
28120798872eSMarcel Holtmann 
28136928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
28140798872eSMarcel Holtmann 	if (!data) {
28150a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
28160798872eSMarcel Holtmann 		if (!data)
28170798872eSMarcel Holtmann 			return -ENOMEM;
28180798872eSMarcel Holtmann 
28190798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
28206928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
28210798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
28220798872eSMarcel Holtmann 	}
28230798872eSMarcel Holtmann 
282481328d5cSJohan Hedberg 	if (hash192 && rand192) {
28250798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
282638da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
2827f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2828f7697b16SMarcel Holtmann 			data->present = 0x03;
282981328d5cSJohan Hedberg 	} else {
283081328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
283181328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
2832f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2833f7697b16SMarcel Holtmann 			data->present = 0x02;
2834f7697b16SMarcel Holtmann 		else
2835f7697b16SMarcel Holtmann 			data->present = 0x00;
283681328d5cSJohan Hedberg 	}
28370798872eSMarcel Holtmann 
283881328d5cSJohan Hedberg 	if (hash256 && rand256) {
28390798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
284038da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
284181328d5cSJohan Hedberg 	} else {
284281328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
284381328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
2844f7697b16SMarcel Holtmann 		if (hash192 && rand192)
2845f7697b16SMarcel Holtmann 			data->present = 0x01;
284681328d5cSJohan Hedberg 	}
28470798872eSMarcel Holtmann 
28486ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
28492763eda6SSzymon Janc 
28502763eda6SSzymon Janc 	return 0;
28512763eda6SSzymon Janc }
28522763eda6SSzymon Janc 
2853d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2854d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
2855d2609b34SFlorian Grandel {
2856d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2857d2609b34SFlorian Grandel 
2858d2609b34SFlorian Grandel 	list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
2859d2609b34SFlorian Grandel 		if (adv_instance->instance == instance)
2860d2609b34SFlorian Grandel 			return adv_instance;
2861d2609b34SFlorian Grandel 	}
2862d2609b34SFlorian Grandel 
2863d2609b34SFlorian Grandel 	return NULL;
2864d2609b34SFlorian Grandel }
2865d2609b34SFlorian Grandel 
2866d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
286774b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
286874b93e9fSPrasanna Karthik {
2869d2609b34SFlorian Grandel 	struct adv_info *cur_instance;
2870d2609b34SFlorian Grandel 
2871d2609b34SFlorian Grandel 	cur_instance = hci_find_adv_instance(hdev, instance);
2872d2609b34SFlorian Grandel 	if (!cur_instance)
2873d2609b34SFlorian Grandel 		return NULL;
2874d2609b34SFlorian Grandel 
2875d2609b34SFlorian Grandel 	if (cur_instance == list_last_entry(&hdev->adv_instances,
2876d2609b34SFlorian Grandel 					    struct adv_info, list))
2877d2609b34SFlorian Grandel 		return list_first_entry(&hdev->adv_instances,
2878d2609b34SFlorian Grandel 						 struct adv_info, list);
2879d2609b34SFlorian Grandel 	else
2880d2609b34SFlorian Grandel 		return list_next_entry(cur_instance, list);
2881d2609b34SFlorian Grandel }
2882d2609b34SFlorian Grandel 
2883d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2884d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
2885d2609b34SFlorian Grandel {
2886d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2887d2609b34SFlorian Grandel 
2888d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
2889d2609b34SFlorian Grandel 	if (!adv_instance)
2890d2609b34SFlorian Grandel 		return -ENOENT;
2891d2609b34SFlorian Grandel 
2892d2609b34SFlorian Grandel 	BT_DBG("%s removing %dMR", hdev->name, instance);
2893d2609b34SFlorian Grandel 
2894cab054abSJohan Hedberg 	if (hdev->cur_adv_instance == instance) {
2895cab054abSJohan Hedberg 		if (hdev->adv_instance_timeout) {
28965d900e46SFlorian Grandel 			cancel_delayed_work(&hdev->adv_instance_expire);
28975d900e46SFlorian Grandel 			hdev->adv_instance_timeout = 0;
28985d900e46SFlorian Grandel 		}
2899cab054abSJohan Hedberg 		hdev->cur_adv_instance = 0x00;
2900cab054abSJohan Hedberg 	}
29015d900e46SFlorian Grandel 
2902a73c046aSJaganath Kanakkassery 	cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
2903a73c046aSJaganath Kanakkassery 
2904d2609b34SFlorian Grandel 	list_del(&adv_instance->list);
2905d2609b34SFlorian Grandel 	kfree(adv_instance);
2906d2609b34SFlorian Grandel 
2907d2609b34SFlorian Grandel 	hdev->adv_instance_cnt--;
2908d2609b34SFlorian Grandel 
2909d2609b34SFlorian Grandel 	return 0;
2910d2609b34SFlorian Grandel }
2911d2609b34SFlorian Grandel 
2912a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired)
2913a73c046aSJaganath Kanakkassery {
2914a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance, *n;
2915a73c046aSJaganath Kanakkassery 
2916a73c046aSJaganath Kanakkassery 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list)
2917a73c046aSJaganath Kanakkassery 		adv_instance->rpa_expired = rpa_expired;
2918a73c046aSJaganath Kanakkassery }
2919a73c046aSJaganath Kanakkassery 
2920d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2921d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev)
2922d2609b34SFlorian Grandel {
2923d2609b34SFlorian Grandel 	struct adv_info *adv_instance, *n;
2924d2609b34SFlorian Grandel 
29255d900e46SFlorian Grandel 	if (hdev->adv_instance_timeout) {
29265d900e46SFlorian Grandel 		cancel_delayed_work(&hdev->adv_instance_expire);
29275d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
29285d900e46SFlorian Grandel 	}
29295d900e46SFlorian Grandel 
2930d2609b34SFlorian Grandel 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
2931a73c046aSJaganath Kanakkassery 		cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
2932d2609b34SFlorian Grandel 		list_del(&adv_instance->list);
2933d2609b34SFlorian Grandel 		kfree(adv_instance);
2934d2609b34SFlorian Grandel 	}
2935d2609b34SFlorian Grandel 
2936d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
2937cab054abSJohan Hedberg 	hdev->cur_adv_instance = 0x00;
2938d2609b34SFlorian Grandel }
2939d2609b34SFlorian Grandel 
2940a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work)
2941a73c046aSJaganath Kanakkassery {
2942a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance = container_of(work, struct adv_info,
2943a73c046aSJaganath Kanakkassery 						     rpa_expired_cb.work);
2944a73c046aSJaganath Kanakkassery 
2945a73c046aSJaganath Kanakkassery 	BT_DBG("");
2946a73c046aSJaganath Kanakkassery 
2947a73c046aSJaganath Kanakkassery 	adv_instance->rpa_expired = true;
2948a73c046aSJaganath Kanakkassery }
2949a73c046aSJaganath Kanakkassery 
2950d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2951d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
2952d2609b34SFlorian Grandel 			 u16 adv_data_len, u8 *adv_data,
2953d2609b34SFlorian Grandel 			 u16 scan_rsp_len, u8 *scan_rsp_data,
2954d2609b34SFlorian Grandel 			 u16 timeout, u16 duration)
2955d2609b34SFlorian Grandel {
2956d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2957d2609b34SFlorian Grandel 
2958d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
2959d2609b34SFlorian Grandel 	if (adv_instance) {
2960d2609b34SFlorian Grandel 		memset(adv_instance->adv_data, 0,
2961d2609b34SFlorian Grandel 		       sizeof(adv_instance->adv_data));
2962d2609b34SFlorian Grandel 		memset(adv_instance->scan_rsp_data, 0,
2963d2609b34SFlorian Grandel 		       sizeof(adv_instance->scan_rsp_data));
2964d2609b34SFlorian Grandel 	} else {
29651d0fac2cSLuiz Augusto von Dentz 		if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
296687597482SDaniel Winkler 		    instance < 1 || instance > hdev->le_num_of_adv_sets)
2967d2609b34SFlorian Grandel 			return -EOVERFLOW;
2968d2609b34SFlorian Grandel 
296939ecfad6SJohan Hedberg 		adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL);
2970d2609b34SFlorian Grandel 		if (!adv_instance)
2971d2609b34SFlorian Grandel 			return -ENOMEM;
2972d2609b34SFlorian Grandel 
2973fffd38bcSFlorian Grandel 		adv_instance->pending = true;
2974d2609b34SFlorian Grandel 		adv_instance->instance = instance;
2975d2609b34SFlorian Grandel 		list_add(&adv_instance->list, &hdev->adv_instances);
2976d2609b34SFlorian Grandel 		hdev->adv_instance_cnt++;
2977d2609b34SFlorian Grandel 	}
2978d2609b34SFlorian Grandel 
2979d2609b34SFlorian Grandel 	adv_instance->flags = flags;
2980d2609b34SFlorian Grandel 	adv_instance->adv_data_len = adv_data_len;
2981d2609b34SFlorian Grandel 	adv_instance->scan_rsp_len = scan_rsp_len;
2982d2609b34SFlorian Grandel 
2983d2609b34SFlorian Grandel 	if (adv_data_len)
2984d2609b34SFlorian Grandel 		memcpy(adv_instance->adv_data, adv_data, adv_data_len);
2985d2609b34SFlorian Grandel 
2986d2609b34SFlorian Grandel 	if (scan_rsp_len)
2987d2609b34SFlorian Grandel 		memcpy(adv_instance->scan_rsp_data,
2988d2609b34SFlorian Grandel 		       scan_rsp_data, scan_rsp_len);
2989d2609b34SFlorian Grandel 
2990d2609b34SFlorian Grandel 	adv_instance->timeout = timeout;
29915d900e46SFlorian Grandel 	adv_instance->remaining_time = timeout;
2992d2609b34SFlorian Grandel 
2993d2609b34SFlorian Grandel 	if (duration == 0)
299410873f99SAlain Michaud 		adv_instance->duration = hdev->def_multi_adv_rotation_duration;
2995d2609b34SFlorian Grandel 	else
2996d2609b34SFlorian Grandel 		adv_instance->duration = duration;
2997d2609b34SFlorian Grandel 
2998de181e88SJaganath Kanakkassery 	adv_instance->tx_power = HCI_TX_POWER_INVALID;
2999de181e88SJaganath Kanakkassery 
3000a73c046aSJaganath Kanakkassery 	INIT_DELAYED_WORK(&adv_instance->rpa_expired_cb,
3001a73c046aSJaganath Kanakkassery 			  adv_instance_rpa_expired);
3002a73c046aSJaganath Kanakkassery 
3003d2609b34SFlorian Grandel 	BT_DBG("%s for %dMR", hdev->name, instance);
3004d2609b34SFlorian Grandel 
3005d2609b34SFlorian Grandel 	return 0;
3006d2609b34SFlorian Grandel }
3007d2609b34SFlorian Grandel 
3008e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */
3009e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev)
3010e5e1e7fdSMiao-chen Chou {
3011b139553dSMiao-chen Chou 	struct adv_monitor *monitor;
3012b139553dSMiao-chen Chou 	int handle;
3013b139553dSMiao-chen Chou 
3014b139553dSMiao-chen Chou 	idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
3015b139553dSMiao-chen Chou 		hci_free_adv_monitor(monitor);
3016b139553dSMiao-chen Chou 
3017e5e1e7fdSMiao-chen Chou 	idr_destroy(&hdev->adv_monitors_idr);
3018e5e1e7fdSMiao-chen Chou }
3019e5e1e7fdSMiao-chen Chou 
3020b139553dSMiao-chen Chou void hci_free_adv_monitor(struct adv_monitor *monitor)
3021b139553dSMiao-chen Chou {
3022b139553dSMiao-chen Chou 	struct adv_pattern *pattern;
3023b139553dSMiao-chen Chou 	struct adv_pattern *tmp;
3024b139553dSMiao-chen Chou 
3025b139553dSMiao-chen Chou 	if (!monitor)
3026b139553dSMiao-chen Chou 		return;
3027b139553dSMiao-chen Chou 
3028b139553dSMiao-chen Chou 	list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list)
3029b139553dSMiao-chen Chou 		kfree(pattern);
3030b139553dSMiao-chen Chou 
3031b139553dSMiao-chen Chou 	kfree(monitor);
3032b139553dSMiao-chen Chou }
3033b139553dSMiao-chen Chou 
3034b139553dSMiao-chen Chou /* This function requires the caller holds hdev->lock */
3035b139553dSMiao-chen Chou int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
3036b139553dSMiao-chen Chou {
3037b139553dSMiao-chen Chou 	int min, max, handle;
3038b139553dSMiao-chen Chou 
3039b139553dSMiao-chen Chou 	if (!monitor)
3040b139553dSMiao-chen Chou 		return -EINVAL;
3041b139553dSMiao-chen Chou 
3042b139553dSMiao-chen Chou 	min = HCI_MIN_ADV_MONITOR_HANDLE;
3043b139553dSMiao-chen Chou 	max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES;
3044b139553dSMiao-chen Chou 	handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max,
3045b139553dSMiao-chen Chou 			   GFP_KERNEL);
3046b139553dSMiao-chen Chou 	if (handle < 0)
3047b139553dSMiao-chen Chou 		return handle;
3048b139553dSMiao-chen Chou 
3049b139553dSMiao-chen Chou 	hdev->adv_monitors_cnt++;
3050b139553dSMiao-chen Chou 	monitor->handle = handle;
30518208f5a9SMiao-chen Chou 
30528208f5a9SMiao-chen Chou 	hci_update_background_scan(hdev);
30538208f5a9SMiao-chen Chou 
3054b139553dSMiao-chen Chou 	return 0;
3055b139553dSMiao-chen Chou }
3056b139553dSMiao-chen Chou 
3057bd2fbc6cSMiao-chen Chou static int free_adv_monitor(int id, void *ptr, void *data)
3058bd2fbc6cSMiao-chen Chou {
3059bd2fbc6cSMiao-chen Chou 	struct hci_dev *hdev = data;
3060bd2fbc6cSMiao-chen Chou 	struct adv_monitor *monitor = ptr;
3061bd2fbc6cSMiao-chen Chou 
3062bd2fbc6cSMiao-chen Chou 	idr_remove(&hdev->adv_monitors_idr, monitor->handle);
3063bd2fbc6cSMiao-chen Chou 	hci_free_adv_monitor(monitor);
3064c88e3979SMiao-chen Chou 	hdev->adv_monitors_cnt--;
3065bd2fbc6cSMiao-chen Chou 
3066bd2fbc6cSMiao-chen Chou 	return 0;
3067bd2fbc6cSMiao-chen Chou }
3068bd2fbc6cSMiao-chen Chou 
3069bd2fbc6cSMiao-chen Chou /* This function requires the caller holds hdev->lock */
3070bd2fbc6cSMiao-chen Chou int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle)
3071bd2fbc6cSMiao-chen Chou {
3072bd2fbc6cSMiao-chen Chou 	struct adv_monitor *monitor;
3073bd2fbc6cSMiao-chen Chou 
3074bd2fbc6cSMiao-chen Chou 	if (handle) {
3075bd2fbc6cSMiao-chen Chou 		monitor = idr_find(&hdev->adv_monitors_idr, handle);
3076bd2fbc6cSMiao-chen Chou 		if (!monitor)
3077bd2fbc6cSMiao-chen Chou 			return -ENOENT;
3078bd2fbc6cSMiao-chen Chou 
3079bd2fbc6cSMiao-chen Chou 		idr_remove(&hdev->adv_monitors_idr, monitor->handle);
3080bd2fbc6cSMiao-chen Chou 		hci_free_adv_monitor(monitor);
3081c88e3979SMiao-chen Chou 		hdev->adv_monitors_cnt--;
3082bd2fbc6cSMiao-chen Chou 	} else {
3083bd2fbc6cSMiao-chen Chou 		/* Remove all monitors if handle is 0. */
3084bd2fbc6cSMiao-chen Chou 		idr_for_each(&hdev->adv_monitors_idr, &free_adv_monitor, hdev);
3085bd2fbc6cSMiao-chen Chou 	}
3086bd2fbc6cSMiao-chen Chou 
30878208f5a9SMiao-chen Chou 	hci_update_background_scan(hdev);
30888208f5a9SMiao-chen Chou 
3089bd2fbc6cSMiao-chen Chou 	return 0;
3090bd2fbc6cSMiao-chen Chou }
3091bd2fbc6cSMiao-chen Chou 
30928208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */
30938208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev)
30948208f5a9SMiao-chen Chou {
30958208f5a9SMiao-chen Chou 	return !idr_is_empty(&hdev->adv_monitors_idr);
30968208f5a9SMiao-chen Chou }
30978208f5a9SMiao-chen Chou 
3098dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
3099b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
3100b2a66aadSAntti Julku {
3101b2a66aadSAntti Julku 	struct bdaddr_list *b;
3102b2a66aadSAntti Julku 
3103dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
3104b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3105b2a66aadSAntti Julku 			return b;
3106b9ee0a78SMarcel Holtmann 	}
3107b2a66aadSAntti Julku 
3108b2a66aadSAntti Julku 	return NULL;
3109b2a66aadSAntti Julku }
3110b2a66aadSAntti Julku 
3111b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
3112b950aa88SAnkit Navik 				struct list_head *bdaddr_list, bdaddr_t *bdaddr,
3113b950aa88SAnkit Navik 				u8 type)
3114b950aa88SAnkit Navik {
3115b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *b;
3116b950aa88SAnkit Navik 
3117b950aa88SAnkit Navik 	list_for_each_entry(b, bdaddr_list, list) {
3118b950aa88SAnkit Navik 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3119b950aa88SAnkit Navik 			return b;
3120b950aa88SAnkit Navik 	}
3121b950aa88SAnkit Navik 
3122b950aa88SAnkit Navik 	return NULL;
3123b950aa88SAnkit Navik }
3124b950aa88SAnkit Navik 
31258baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *
31268baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
31278baaa403SAbhishek Pandit-Subedi 				  bdaddr_t *bdaddr, u8 type)
31288baaa403SAbhishek Pandit-Subedi {
31298baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *b;
31308baaa403SAbhishek Pandit-Subedi 
31318baaa403SAbhishek Pandit-Subedi 	list_for_each_entry(b, bdaddr_list, list) {
31328baaa403SAbhishek Pandit-Subedi 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
31338baaa403SAbhishek Pandit-Subedi 			return b;
31348baaa403SAbhishek Pandit-Subedi 	}
31358baaa403SAbhishek Pandit-Subedi 
31368baaa403SAbhishek Pandit-Subedi 	return NULL;
31378baaa403SAbhishek Pandit-Subedi }
31388baaa403SAbhishek Pandit-Subedi 
3139dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
3140b2a66aadSAntti Julku {
31417eb7404fSGeliang Tang 	struct bdaddr_list *b, *n;
3142b2a66aadSAntti Julku 
31437eb7404fSGeliang Tang 	list_for_each_entry_safe(b, n, bdaddr_list, list) {
31447eb7404fSGeliang Tang 		list_del(&b->list);
3145b2a66aadSAntti Julku 		kfree(b);
3146b2a66aadSAntti Julku 	}
3147b2a66aadSAntti Julku }
3148b2a66aadSAntti Julku 
3149dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3150b2a66aadSAntti Julku {
3151b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3152b2a66aadSAntti Julku 
3153b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3154b2a66aadSAntti Julku 		return -EBADF;
3155b2a66aadSAntti Julku 
3156dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
31575e762444SAntti Julku 		return -EEXIST;
3158b2a66aadSAntti Julku 
315927f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
31605e762444SAntti Julku 	if (!entry)
31615e762444SAntti Julku 		return -ENOMEM;
3162b2a66aadSAntti Julku 
3163b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3164b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3165b2a66aadSAntti Julku 
3166dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
3167b2a66aadSAntti Julku 
31682a8357f2SJohan Hedberg 	return 0;
3169b2a66aadSAntti Julku }
3170b2a66aadSAntti Julku 
3171b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
3172b950aa88SAnkit Navik 					u8 type, u8 *peer_irk, u8 *local_irk)
3173b950aa88SAnkit Navik {
3174b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
3175b950aa88SAnkit Navik 
3176b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY))
3177b950aa88SAnkit Navik 		return -EBADF;
3178b950aa88SAnkit Navik 
3179b950aa88SAnkit Navik 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
3180b950aa88SAnkit Navik 		return -EEXIST;
3181b950aa88SAnkit Navik 
3182b950aa88SAnkit Navik 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
3183b950aa88SAnkit Navik 	if (!entry)
3184b950aa88SAnkit Navik 		return -ENOMEM;
3185b950aa88SAnkit Navik 
3186b950aa88SAnkit Navik 	bacpy(&entry->bdaddr, bdaddr);
3187b950aa88SAnkit Navik 	entry->bdaddr_type = type;
3188b950aa88SAnkit Navik 
3189b950aa88SAnkit Navik 	if (peer_irk)
3190b950aa88SAnkit Navik 		memcpy(entry->peer_irk, peer_irk, 16);
3191b950aa88SAnkit Navik 
3192b950aa88SAnkit Navik 	if (local_irk)
3193b950aa88SAnkit Navik 		memcpy(entry->local_irk, local_irk, 16);
3194b950aa88SAnkit Navik 
3195b950aa88SAnkit Navik 	list_add(&entry->list, list);
3196b950aa88SAnkit Navik 
3197b950aa88SAnkit Navik 	return 0;
3198b950aa88SAnkit Navik }
3199b950aa88SAnkit Navik 
32008baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
32018baaa403SAbhishek Pandit-Subedi 				   u8 type, u32 flags)
32028baaa403SAbhishek Pandit-Subedi {
32038baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
32048baaa403SAbhishek Pandit-Subedi 
32058baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY))
32068baaa403SAbhishek Pandit-Subedi 		return -EBADF;
32078baaa403SAbhishek Pandit-Subedi 
32088baaa403SAbhishek Pandit-Subedi 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
32098baaa403SAbhishek Pandit-Subedi 		return -EEXIST;
32108baaa403SAbhishek Pandit-Subedi 
32118baaa403SAbhishek Pandit-Subedi 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
32128baaa403SAbhishek Pandit-Subedi 	if (!entry)
32138baaa403SAbhishek Pandit-Subedi 		return -ENOMEM;
32148baaa403SAbhishek Pandit-Subedi 
32158baaa403SAbhishek Pandit-Subedi 	bacpy(&entry->bdaddr, bdaddr);
32168baaa403SAbhishek Pandit-Subedi 	entry->bdaddr_type = type;
32178baaa403SAbhishek Pandit-Subedi 	entry->current_flags = flags;
32188baaa403SAbhishek Pandit-Subedi 
32198baaa403SAbhishek Pandit-Subedi 	list_add(&entry->list, list);
32208baaa403SAbhishek Pandit-Subedi 
32218baaa403SAbhishek Pandit-Subedi 	return 0;
32228baaa403SAbhishek Pandit-Subedi }
32238baaa403SAbhishek Pandit-Subedi 
3224dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3225b2a66aadSAntti Julku {
3226b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3227b2a66aadSAntti Julku 
322835f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3229dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
323035f7498aSJohan Hedberg 		return 0;
323135f7498aSJohan Hedberg 	}
3232b2a66aadSAntti Julku 
3233dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
3234d2ab0ac1SMarcel Holtmann 	if (!entry)
3235d2ab0ac1SMarcel Holtmann 		return -ENOENT;
3236d2ab0ac1SMarcel Holtmann 
3237d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
3238d2ab0ac1SMarcel Holtmann 	kfree(entry);
3239d2ab0ac1SMarcel Holtmann 
3240d2ab0ac1SMarcel Holtmann 	return 0;
3241d2ab0ac1SMarcel Holtmann }
3242d2ab0ac1SMarcel Holtmann 
3243b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
3244b950aa88SAnkit Navik 							u8 type)
3245b950aa88SAnkit Navik {
3246b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
3247b950aa88SAnkit Navik 
3248b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3249b950aa88SAnkit Navik 		hci_bdaddr_list_clear(list);
3250b950aa88SAnkit Navik 		return 0;
3251b950aa88SAnkit Navik 	}
3252b950aa88SAnkit Navik 
3253b950aa88SAnkit Navik 	entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
3254b950aa88SAnkit Navik 	if (!entry)
3255b950aa88SAnkit Navik 		return -ENOENT;
3256b950aa88SAnkit Navik 
3257b950aa88SAnkit Navik 	list_del(&entry->list);
3258b950aa88SAnkit Navik 	kfree(entry);
3259b950aa88SAnkit Navik 
3260b950aa88SAnkit Navik 	return 0;
3261b950aa88SAnkit Navik }
3262b950aa88SAnkit Navik 
32638baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
32648baaa403SAbhishek Pandit-Subedi 				   u8 type)
32658baaa403SAbhishek Pandit-Subedi {
32668baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
32678baaa403SAbhishek Pandit-Subedi 
32688baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY)) {
32698baaa403SAbhishek Pandit-Subedi 		hci_bdaddr_list_clear(list);
32708baaa403SAbhishek Pandit-Subedi 		return 0;
32718baaa403SAbhishek Pandit-Subedi 	}
32728baaa403SAbhishek Pandit-Subedi 
32738baaa403SAbhishek Pandit-Subedi 	entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
32748baaa403SAbhishek Pandit-Subedi 	if (!entry)
32758baaa403SAbhishek Pandit-Subedi 		return -ENOENT;
32768baaa403SAbhishek Pandit-Subedi 
32778baaa403SAbhishek Pandit-Subedi 	list_del(&entry->list);
32788baaa403SAbhishek Pandit-Subedi 	kfree(entry);
32798baaa403SAbhishek Pandit-Subedi 
32808baaa403SAbhishek Pandit-Subedi 	return 0;
32818baaa403SAbhishek Pandit-Subedi }
32828baaa403SAbhishek Pandit-Subedi 
328315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
328415819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
328515819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
328615819a70SAndre Guedes {
328715819a70SAndre Guedes 	struct hci_conn_params *params;
328815819a70SAndre Guedes 
328915819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
329015819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
329115819a70SAndre Guedes 		    params->addr_type == addr_type) {
329215819a70SAndre Guedes 			return params;
329315819a70SAndre Guedes 		}
329415819a70SAndre Guedes 	}
329515819a70SAndre Guedes 
329615819a70SAndre Guedes 	return NULL;
329715819a70SAndre Guedes }
329815819a70SAndre Guedes 
329915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
3300501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
33014b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
330215819a70SAndre Guedes {
3303912b42efSJohan Hedberg 	struct hci_conn_params *param;
330415819a70SAndre Guedes 
33056540351eSMarcel Holtmann 	switch (addr_type) {
33066540351eSMarcel Holtmann 	case ADDR_LE_DEV_PUBLIC_RESOLVED:
33076540351eSMarcel Holtmann 		addr_type = ADDR_LE_DEV_PUBLIC;
33086540351eSMarcel Holtmann 		break;
33096540351eSMarcel Holtmann 	case ADDR_LE_DEV_RANDOM_RESOLVED:
33106540351eSMarcel Holtmann 		addr_type = ADDR_LE_DEV_RANDOM;
33116540351eSMarcel Holtmann 		break;
33126540351eSMarcel Holtmann 	}
33136540351eSMarcel Holtmann 
3314501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
3315912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
3316912b42efSJohan Hedberg 		    param->addr_type == addr_type)
3317912b42efSJohan Hedberg 			return param;
33184b10966fSMarcel Holtmann 	}
33194b10966fSMarcel Holtmann 
33204b10966fSMarcel Holtmann 	return NULL;
332115819a70SAndre Guedes }
332215819a70SAndre Guedes 
332315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
332451d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
332551d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
332615819a70SAndre Guedes {
332715819a70SAndre Guedes 	struct hci_conn_params *params;
332815819a70SAndre Guedes 
332915819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
3330cef952ceSAndre Guedes 	if (params)
333151d167c0SMarcel Holtmann 		return params;
333215819a70SAndre Guedes 
333315819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
333415819a70SAndre Guedes 	if (!params) {
33352064ee33SMarcel Holtmann 		bt_dev_err(hdev, "out of memory");
333651d167c0SMarcel Holtmann 		return NULL;
333715819a70SAndre Guedes 	}
333815819a70SAndre Guedes 
333915819a70SAndre Guedes 	bacpy(&params->addr, addr);
334015819a70SAndre Guedes 	params->addr_type = addr_type;
3341cef952ceSAndre Guedes 
3342cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
334393450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
3344cef952ceSAndre Guedes 
3345bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
3346bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
3347bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
3348bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
3349bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
3350bf5b3c8bSMarcel Holtmann 
3351bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
3352bf5b3c8bSMarcel Holtmann 
335351d167c0SMarcel Holtmann 	return params;
3354bf5b3c8bSMarcel Holtmann }
3355bf5b3c8bSMarcel Holtmann 
3356f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
3357f6c63249SJohan Hedberg {
3358f6c63249SJohan Hedberg 	if (params->conn) {
3359f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
3360f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
3361f6c63249SJohan Hedberg 	}
3362f6c63249SJohan Hedberg 
3363f6c63249SJohan Hedberg 	list_del(&params->action);
3364f6c63249SJohan Hedberg 	list_del(&params->list);
3365f6c63249SJohan Hedberg 	kfree(params);
3366f6c63249SJohan Hedberg }
3367f6c63249SJohan Hedberg 
336815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
336915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
337015819a70SAndre Guedes {
337115819a70SAndre Guedes 	struct hci_conn_params *params;
337215819a70SAndre Guedes 
337315819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
337415819a70SAndre Guedes 	if (!params)
337515819a70SAndre Guedes 		return;
337615819a70SAndre Guedes 
3377f6c63249SJohan Hedberg 	hci_conn_params_free(params);
337815819a70SAndre Guedes 
337995305baaSJohan Hedberg 	hci_update_background_scan(hdev);
338095305baaSJohan Hedberg 
338115819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
338215819a70SAndre Guedes }
338315819a70SAndre Guedes 
338415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
338555af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
338615819a70SAndre Guedes {
338715819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
338815819a70SAndre Guedes 
338915819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
339055af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
339155af49a8SJohan Hedberg 			continue;
3392f75113a2SJakub Pawlowski 
3393f75113a2SJakub Pawlowski 		/* If trying to estabilish one time connection to disabled
3394f75113a2SJakub Pawlowski 		 * device, leave the params, but mark them as just once.
3395f75113a2SJakub Pawlowski 		 */
3396f75113a2SJakub Pawlowski 		if (params->explicit_connect) {
3397f75113a2SJakub Pawlowski 			params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
3398f75113a2SJakub Pawlowski 			continue;
3399f75113a2SJakub Pawlowski 		}
3400f75113a2SJakub Pawlowski 
340115819a70SAndre Guedes 		list_del(&params->list);
340215819a70SAndre Guedes 		kfree(params);
340315819a70SAndre Guedes 	}
340415819a70SAndre Guedes 
340555af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
340655af49a8SJohan Hedberg }
340755af49a8SJohan Hedberg 
340855af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
3409030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev)
341015819a70SAndre Guedes {
341115819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
341215819a70SAndre Guedes 
3413f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
3414f6c63249SJohan Hedberg 		hci_conn_params_free(params);
341515819a70SAndre Guedes 
341615819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
341715819a70SAndre Guedes }
341815819a70SAndre Guedes 
3419a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
3420a1f4c318SJohan Hedberg  *
3421a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
3422a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
3423a1f4c318SJohan Hedberg  * the static random address.
3424a1f4c318SJohan Hedberg  *
3425a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
3426a1f4c318SJohan Hedberg  * public address to use the static random address instead.
342750b5b952SMarcel Holtmann  *
342850b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
342950b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
343050b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
3431a1f4c318SJohan Hedberg  */
3432a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3433a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
3434a1f4c318SJohan Hedberg {
3435b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
343650b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
3437d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
343850b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
3439a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
3440a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
3441a1f4c318SJohan Hedberg 	} else {
3442a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
3443a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
3444a1f4c318SJohan Hedberg 	}
3445a1f4c318SJohan Hedberg }
3446a1f4c318SJohan Hedberg 
34470e995280SAbhishek Pandit-Subedi static void hci_suspend_clear_tasks(struct hci_dev *hdev)
34480e995280SAbhishek Pandit-Subedi {
34490e995280SAbhishek Pandit-Subedi 	int i;
34500e995280SAbhishek Pandit-Subedi 
34510e995280SAbhishek Pandit-Subedi 	for (i = 0; i < __SUSPEND_NUM_TASKS; i++)
34520e995280SAbhishek Pandit-Subedi 		clear_bit(i, hdev->suspend_tasks);
34530e995280SAbhishek Pandit-Subedi 
34540e995280SAbhishek Pandit-Subedi 	wake_up(&hdev->suspend_wait_q);
34550e995280SAbhishek Pandit-Subedi }
34560e995280SAbhishek Pandit-Subedi 
34579952d90eSAbhishek Pandit-Subedi static int hci_suspend_wait_event(struct hci_dev *hdev)
34589952d90eSAbhishek Pandit-Subedi {
34599952d90eSAbhishek Pandit-Subedi #define WAKE_COND                                                              \
34609952d90eSAbhishek Pandit-Subedi 	(find_first_bit(hdev->suspend_tasks, __SUSPEND_NUM_TASKS) ==           \
34619952d90eSAbhishek Pandit-Subedi 	 __SUSPEND_NUM_TASKS)
34629952d90eSAbhishek Pandit-Subedi 
34639952d90eSAbhishek Pandit-Subedi 	int i;
34649952d90eSAbhishek Pandit-Subedi 	int ret = wait_event_timeout(hdev->suspend_wait_q,
34659952d90eSAbhishek Pandit-Subedi 				     WAKE_COND, SUSPEND_NOTIFIER_TIMEOUT);
34669952d90eSAbhishek Pandit-Subedi 
34679952d90eSAbhishek Pandit-Subedi 	if (ret == 0) {
3468a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Timed out waiting for suspend events");
34699952d90eSAbhishek Pandit-Subedi 		for (i = 0; i < __SUSPEND_NUM_TASKS; ++i) {
34709952d90eSAbhishek Pandit-Subedi 			if (test_bit(i, hdev->suspend_tasks))
3471a9ec8423SAbhishek Pandit-Subedi 				bt_dev_err(hdev, "Suspend timeout bit: %d", i);
34729952d90eSAbhishek Pandit-Subedi 			clear_bit(i, hdev->suspend_tasks);
34739952d90eSAbhishek Pandit-Subedi 		}
34749952d90eSAbhishek Pandit-Subedi 
34759952d90eSAbhishek Pandit-Subedi 		ret = -ETIMEDOUT;
34769952d90eSAbhishek Pandit-Subedi 	} else {
34779952d90eSAbhishek Pandit-Subedi 		ret = 0;
34789952d90eSAbhishek Pandit-Subedi 	}
34799952d90eSAbhishek Pandit-Subedi 
34809952d90eSAbhishek Pandit-Subedi 	return ret;
34819952d90eSAbhishek Pandit-Subedi }
34829952d90eSAbhishek Pandit-Subedi 
34839952d90eSAbhishek Pandit-Subedi static void hci_prepare_suspend(struct work_struct *work)
34849952d90eSAbhishek Pandit-Subedi {
34859952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
34869952d90eSAbhishek Pandit-Subedi 		container_of(work, struct hci_dev, suspend_prepare);
34879952d90eSAbhishek Pandit-Subedi 
34889952d90eSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
34899952d90eSAbhishek Pandit-Subedi 	hci_req_prepare_suspend(hdev, hdev->suspend_state_next);
34909952d90eSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
34919952d90eSAbhishek Pandit-Subedi }
34929952d90eSAbhishek Pandit-Subedi 
34938731840aSAbhishek Pandit-Subedi static int hci_change_suspend_state(struct hci_dev *hdev,
34948731840aSAbhishek Pandit-Subedi 				    enum suspended_state next)
34958731840aSAbhishek Pandit-Subedi {
34968731840aSAbhishek Pandit-Subedi 	hdev->suspend_state_next = next;
34978731840aSAbhishek Pandit-Subedi 	set_bit(SUSPEND_PREPARE_NOTIFIER, hdev->suspend_tasks);
34988731840aSAbhishek Pandit-Subedi 	queue_work(hdev->req_workqueue, &hdev->suspend_prepare);
34998731840aSAbhishek Pandit-Subedi 	return hci_suspend_wait_event(hdev);
35008731840aSAbhishek Pandit-Subedi }
35018731840aSAbhishek Pandit-Subedi 
35022f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev)
35032f20216cSAbhishek Pandit-Subedi {
35042f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
35052f20216cSAbhishek Pandit-Subedi 
35062f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = 0;
35072f20216cSAbhishek Pandit-Subedi 	bacpy(&hdev->wake_addr, BDADDR_ANY);
35082f20216cSAbhishek Pandit-Subedi 	hdev->wake_addr_type = 0;
35092f20216cSAbhishek Pandit-Subedi 
35102f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
35112f20216cSAbhishek Pandit-Subedi }
35122f20216cSAbhishek Pandit-Subedi 
35139952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
35149952d90eSAbhishek Pandit-Subedi 				void *data)
35159952d90eSAbhishek Pandit-Subedi {
35169952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
35179952d90eSAbhishek Pandit-Subedi 		container_of(nb, struct hci_dev, suspend_notifier);
35189952d90eSAbhishek Pandit-Subedi 	int ret = 0;
35192f20216cSAbhishek Pandit-Subedi 	u8 state = BT_RUNNING;
35209952d90eSAbhishek Pandit-Subedi 
35219952d90eSAbhishek Pandit-Subedi 	/* If powering down, wait for completion. */
35229952d90eSAbhishek Pandit-Subedi 	if (mgmt_powering_down(hdev)) {
35239952d90eSAbhishek Pandit-Subedi 		set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks);
35249952d90eSAbhishek Pandit-Subedi 		ret = hci_suspend_wait_event(hdev);
35259952d90eSAbhishek Pandit-Subedi 		if (ret)
35269952d90eSAbhishek Pandit-Subedi 			goto done;
35279952d90eSAbhishek Pandit-Subedi 	}
35289952d90eSAbhishek Pandit-Subedi 
35299952d90eSAbhishek Pandit-Subedi 	/* Suspend notifier should only act on events when powered. */
35309952d90eSAbhishek Pandit-Subedi 	if (!hdev_is_powered(hdev))
35319952d90eSAbhishek Pandit-Subedi 		goto done;
35329952d90eSAbhishek Pandit-Subedi 
35339952d90eSAbhishek Pandit-Subedi 	if (action == PM_SUSPEND_PREPARE) {
35344f40afc6SAbhishek Pandit-Subedi 		/* Suspend consists of two actions:
35354f40afc6SAbhishek Pandit-Subedi 		 *  - First, disconnect everything and make the controller not
35364f40afc6SAbhishek Pandit-Subedi 		 *    connectable (disabling scanning)
35374f40afc6SAbhishek Pandit-Subedi 		 *  - Second, program event filter/whitelist and enable scan
35384f40afc6SAbhishek Pandit-Subedi 		 */
35398731840aSAbhishek Pandit-Subedi 		ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT);
35402f20216cSAbhishek Pandit-Subedi 		if (!ret)
35412f20216cSAbhishek Pandit-Subedi 			state = BT_SUSPEND_DISCONNECT;
35424f40afc6SAbhishek Pandit-Subedi 
354381dafad5SAbhishek Pandit-Subedi 		/* Only configure whitelist if disconnect succeeded and wake
354481dafad5SAbhishek Pandit-Subedi 		 * isn't being prevented.
354581dafad5SAbhishek Pandit-Subedi 		 */
35462f20216cSAbhishek Pandit-Subedi 		if (!ret && !(hdev->prevent_wake && hdev->prevent_wake(hdev))) {
35478731840aSAbhishek Pandit-Subedi 			ret = hci_change_suspend_state(hdev,
35480d2c9825SAbhishek Pandit-Subedi 						BT_SUSPEND_CONFIGURE_WAKE);
35492f20216cSAbhishek Pandit-Subedi 			if (!ret)
35502f20216cSAbhishek Pandit-Subedi 				state = BT_SUSPEND_CONFIGURE_WAKE;
35512f20216cSAbhishek Pandit-Subedi 		}
35522f20216cSAbhishek Pandit-Subedi 
35532f20216cSAbhishek Pandit-Subedi 		hci_clear_wake_reason(hdev);
35542f20216cSAbhishek Pandit-Subedi 		mgmt_suspending(hdev, state);
35552f20216cSAbhishek Pandit-Subedi 
35569952d90eSAbhishek Pandit-Subedi 	} else if (action == PM_POST_SUSPEND) {
35578731840aSAbhishek Pandit-Subedi 		ret = hci_change_suspend_state(hdev, BT_RUNNING);
35582f20216cSAbhishek Pandit-Subedi 
35592f20216cSAbhishek Pandit-Subedi 		mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
35602f20216cSAbhishek Pandit-Subedi 			      hdev->wake_addr_type);
35619952d90eSAbhishek Pandit-Subedi 	}
35629952d90eSAbhishek Pandit-Subedi 
35639952d90eSAbhishek Pandit-Subedi done:
3564a9ec8423SAbhishek Pandit-Subedi 	/* We always allow suspend even if suspend preparation failed and
3565a9ec8423SAbhishek Pandit-Subedi 	 * attempt to recover in resume.
3566a9ec8423SAbhishek Pandit-Subedi 	 */
3567a9ec8423SAbhishek Pandit-Subedi 	if (ret)
3568a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
3569a9ec8423SAbhishek Pandit-Subedi 			   action, ret);
3570a9ec8423SAbhishek Pandit-Subedi 
357124b06572SMax Chou 	return NOTIFY_DONE;
35729952d90eSAbhishek Pandit-Subedi }
35738731840aSAbhishek Pandit-Subedi 
35749be0dab7SDavid Herrmann /* Alloc HCI device */
35759be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
35769be0dab7SDavid Herrmann {
35779be0dab7SDavid Herrmann 	struct hci_dev *hdev;
35789be0dab7SDavid Herrmann 
357927f70f3eSJohan Hedberg 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
35809be0dab7SDavid Herrmann 	if (!hdev)
35819be0dab7SDavid Herrmann 		return NULL;
35829be0dab7SDavid Herrmann 
3583b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3584b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3585b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3586b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3587b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
358896c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
3589bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3590bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3591d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
3592d2609b34SFlorian Grandel 	hdev->cur_adv_instance = 0x00;
35935d900e46SFlorian Grandel 	hdev->adv_instance_timeout = 0;
3594b1b813d4SDavid Herrmann 
3595c4f1f408SHoward Chung 	hdev->advmon_allowlist_duration = 300;
3596c4f1f408SHoward Chung 	hdev->advmon_no_filter_duration = 500;
3597*80af16a3SHoward Chung 	hdev->enable_advmon_interleave_scan = 0x00;	/* Default to disable */
3598c4f1f408SHoward Chung 
3599b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3600b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3601b1b813d4SDavid Herrmann 
36023f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3603628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
3604628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
3605bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3606bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
360710873f99SAlain Michaud 	hdev->le_scan_int_suspend = 0x0400;
360810873f99SAlain Michaud 	hdev->le_scan_window_suspend = 0x0012;
360910873f99SAlain Michaud 	hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
361010873f99SAlain Michaud 	hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
361110873f99SAlain Michaud 	hdev->le_scan_int_connect = 0x0060;
361210873f99SAlain Michaud 	hdev->le_scan_window_connect = 0x0060;
3613b48c3b59SJonas Holmberg 	hdev->le_conn_min_interval = 0x0018;
3614b48c3b59SJonas Holmberg 	hdev->le_conn_max_interval = 0x0028;
361504fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
361604fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
3617a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
3618a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
3619a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
3620a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
3621a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
3622a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
362330d65e08SMatias Karhumaa 	hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
362430d65e08SMatias Karhumaa 	hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
36256decb5b4SJaganath Kanakkassery 	hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
36266decb5b4SJaganath Kanakkassery 	hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
36271d0fac2cSLuiz Augusto von Dentz 	hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
362810873f99SAlain Michaud 	hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
362949b020c1SAlain Michaud 	hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT;
3630bef64738SMarcel Holtmann 
3631d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3632b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
363331ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
363431ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
3635302975cbSSpoorthi Ravishankar Koppad 	hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
363658a96fc3SMarcel Holtmann 	hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
3637d6bfd59cSJohan Hedberg 
363810873f99SAlain Michaud 	/* default 1.28 sec page scan */
363910873f99SAlain Michaud 	hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
364010873f99SAlain Michaud 	hdev->def_page_scan_int = 0x0800;
364110873f99SAlain Michaud 	hdev->def_page_scan_window = 0x0012;
364210873f99SAlain Michaud 
3643b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3644b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3645b1b813d4SDavid Herrmann 
3646b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3647b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
36486659358eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->whitelist);
3649b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3650b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3651b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3652970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3653b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
3654d2ab0ac1SMarcel Holtmann 	INIT_LIST_HEAD(&hdev->le_white_list);
3655cfdb0c2dSAnkit Navik 	INIT_LIST_HEAD(&hdev->le_resolv_list);
365615819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
365777a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
365866f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
36596b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3660d2609b34SFlorian Grandel 	INIT_LIST_HEAD(&hdev->adv_instances);
3661600a8749SAlain Michaud 	INIT_LIST_HEAD(&hdev->blocked_keys);
3662b1b813d4SDavid Herrmann 
3663b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3664b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3665b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3666b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3667c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
36689952d90eSAbhishek Pandit-Subedi 	INIT_WORK(&hdev->suspend_prepare, hci_prepare_suspend);
3669b1b813d4SDavid Herrmann 
3670b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3671b1b813d4SDavid Herrmann 
3672b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3673b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3674b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3675b1b813d4SDavid Herrmann 
3676b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
36779952d90eSAbhishek Pandit-Subedi 	init_waitqueue_head(&hdev->suspend_wait_q);
3678b1b813d4SDavid Herrmann 
367965cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
3680b1b813d4SDavid Herrmann 
36815fc16cc4SJohan Hedberg 	hci_request_setup(hdev);
36825fc16cc4SJohan Hedberg 
3683b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3684b1b813d4SDavid Herrmann 	discovery_init(hdev);
36859be0dab7SDavid Herrmann 
36869be0dab7SDavid Herrmann 	return hdev;
36879be0dab7SDavid Herrmann }
36889be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
36899be0dab7SDavid Herrmann 
36909be0dab7SDavid Herrmann /* Free HCI device */
36919be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
36929be0dab7SDavid Herrmann {
36939be0dab7SDavid Herrmann 	/* will free via device release */
36949be0dab7SDavid Herrmann 	put_device(&hdev->dev);
36959be0dab7SDavid Herrmann }
36969be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
36979be0dab7SDavid Herrmann 
36981da177e4SLinus Torvalds /* Register HCI device */
36991da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
37001da177e4SLinus Torvalds {
3701b1b813d4SDavid Herrmann 	int id, error;
37021da177e4SLinus Torvalds 
370374292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
37041da177e4SLinus Torvalds 		return -EINVAL;
37051da177e4SLinus Torvalds 
370608add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
370708add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
370808add513SMat Martineau 	 */
37093df92b31SSasha Levin 	switch (hdev->dev_type) {
3710ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
37113df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
37121da177e4SLinus Torvalds 		break;
37133df92b31SSasha Levin 	case HCI_AMP:
37143df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
37153df92b31SSasha Levin 		break;
37163df92b31SSasha Levin 	default:
37173df92b31SSasha Levin 		return -EINVAL;
37181da177e4SLinus Torvalds 	}
37191da177e4SLinus Torvalds 
37203df92b31SSasha Levin 	if (id < 0)
37213df92b31SSasha Levin 		return id;
37223df92b31SSasha Levin 
37231da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
37241da177e4SLinus Torvalds 	hdev->id = id;
37252d8b3a11SAndrei Emeltchenko 
37262d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
37272d8b3a11SAndrei Emeltchenko 
372829e2dd0dSTejun Heo 	hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
372933ca954dSDavid Herrmann 	if (!hdev->workqueue) {
373033ca954dSDavid Herrmann 		error = -ENOMEM;
373133ca954dSDavid Herrmann 		goto err;
373233ca954dSDavid Herrmann 	}
3733f48fd9c8SMarcel Holtmann 
373429e2dd0dSTejun Heo 	hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
373529e2dd0dSTejun Heo 						      hdev->name);
37366ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
37376ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
37386ead1bbcSJohan Hedberg 		error = -ENOMEM;
37396ead1bbcSJohan Hedberg 		goto err;
37406ead1bbcSJohan Hedberg 	}
37416ead1bbcSJohan Hedberg 
37420153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
37430153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
37440153e2ecSMarcel Holtmann 
3745bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3746bdc3e0f1SMarcel Holtmann 
3747bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
374833ca954dSDavid Herrmann 	if (error < 0)
374954506918SJohan Hedberg 		goto err_wqueue;
37501da177e4SLinus Torvalds 
37516d5d2ee6SHeiner Kallweit 	hci_leds_init(hdev);
37526d5d2ee6SHeiner Kallweit 
3753611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3754a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3755a8c5fb1aSGustavo Padovan 				    hdev);
3756611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3757611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3758611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3759611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3760611b30f7SMarcel Holtmann 		}
3761611b30f7SMarcel Holtmann 	}
3762611b30f7SMarcel Holtmann 
37635e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
3764a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
37655e130367SJohan Hedberg 
3766a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
3767a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
3768ce2be9acSAndrei Emeltchenko 
3769ca8bee5dSMarcel Holtmann 	if (hdev->dev_type == HCI_PRIMARY) {
377056f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
377156f87901SJohan Hedberg 		 * through reading supported features during init.
377256f87901SJohan Hedberg 		 */
3773a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
377456f87901SJohan Hedberg 	}
3775ce2be9acSAndrei Emeltchenko 
3776fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3777fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3778fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3779fcee3377SGustavo Padovan 
37804a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
37814a964404SMarcel Holtmann 	 * and should not be included in normal operation.
3782fee746b0SMarcel Holtmann 	 */
3783fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
3784a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
3785fee746b0SMarcel Holtmann 
378605fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_REG);
3787dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
37881da177e4SLinus Torvalds 
37899952d90eSAbhishek Pandit-Subedi 	hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
37909952d90eSAbhishek Pandit-Subedi 	error = register_pm_notifier(&hdev->suspend_notifier);
37919952d90eSAbhishek Pandit-Subedi 	if (error)
37929952d90eSAbhishek Pandit-Subedi 		goto err_wqueue;
37939952d90eSAbhishek Pandit-Subedi 
379419202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3795fbe96d6fSMarcel Holtmann 
3796e5e1e7fdSMiao-chen Chou 	idr_init(&hdev->adv_monitors_idr);
3797e5e1e7fdSMiao-chen Chou 
37981da177e4SLinus Torvalds 	return id;
3799f48fd9c8SMarcel Holtmann 
380033ca954dSDavid Herrmann err_wqueue:
380133ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
38026ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
380333ca954dSDavid Herrmann err:
38043df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
3805f48fd9c8SMarcel Holtmann 
380633ca954dSDavid Herrmann 	return error;
38071da177e4SLinus Torvalds }
38081da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
38091da177e4SLinus Torvalds 
38101da177e4SLinus Torvalds /* Unregister HCI device */
381159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
38121da177e4SLinus Torvalds {
38132d7cc19eSMarcel Holtmann 	int id;
3814ef222013SMarcel Holtmann 
3815c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
38161da177e4SLinus Torvalds 
3817a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
381894324962SJohan Hovold 
38193df92b31SSasha Levin 	id = hdev->id;
38203df92b31SSasha Levin 
3821f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
38221da177e4SLinus Torvalds 	list_del(&hdev->list);
3823f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
38241da177e4SLinus Torvalds 
3825b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
3826b9b5ef18SGustavo Padovan 
38270e995280SAbhishek Pandit-Subedi 	hci_suspend_clear_tasks(hdev);
38289952d90eSAbhishek Pandit-Subedi 	unregister_pm_notifier(&hdev->suspend_notifier);
38294e8c36c3SAbhishek Pandit-Subedi 	cancel_work_sync(&hdev->suspend_prepare);
38304e8c36c3SAbhishek Pandit-Subedi 
38314e8c36c3SAbhishek Pandit-Subedi 	hci_dev_do_close(hdev);
38329952d90eSAbhishek Pandit-Subedi 
3833ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
3834d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
3835d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
383609fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
3837744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
383809fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
383956e5cb86SJohan Hedberg 	}
3840ab81cbf9SJohan Hedberg 
38412e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
38422e58ef3eSJohan Hedberg 	 * pending list */
38432e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
38442e58ef3eSJohan Hedberg 
384505fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_UNREG);
38461da177e4SLinus Torvalds 
3847611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3848611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
3849611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
3850611b30f7SMarcel Holtmann 	}
3851611b30f7SMarcel Holtmann 
3852bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
3853147e2d59SDave Young 
38540153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
38555177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
38565177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
38570153e2ecSMarcel Holtmann 
3858f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
38596ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
3860f48fd9c8SMarcel Holtmann 
386109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
3862dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->blacklist);
38636659358eSJohan Hedberg 	hci_bdaddr_list_clear(&hdev->whitelist);
38642aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
386555ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
3866b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
3867970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
38682763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
3869d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
3870e5e1e7fdSMiao-chen Chou 	hci_adv_monitors_clear(hdev);
3871dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->le_white_list);
3872cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
3873373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
387422078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
3875600a8749SAlain Michaud 	hci_blocked_keys_clear(hdev);
387609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
3877e2e0cacbSJohan Hedberg 
3878dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
38793df92b31SSasha Levin 
38803df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
38811da177e4SLinus Torvalds }
38821da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
38831da177e4SLinus Torvalds 
38841da177e4SLinus Torvalds /* Suspend HCI device */
38851da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
38861da177e4SLinus Torvalds {
388705fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
38881da177e4SLinus Torvalds 	return 0;
38891da177e4SLinus Torvalds }
38901da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
38911da177e4SLinus Torvalds 
38921da177e4SLinus Torvalds /* Resume HCI device */
38931da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
38941da177e4SLinus Torvalds {
389505fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_RESUME);
38961da177e4SLinus Torvalds 	return 0;
38971da177e4SLinus Torvalds }
38981da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
38991da177e4SLinus Torvalds 
390075e0569fSMarcel Holtmann /* Reset HCI device */
390175e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
390275e0569fSMarcel Holtmann {
39031e4b6e91SColin Ian King 	static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
390475e0569fSMarcel Holtmann 	struct sk_buff *skb;
390575e0569fSMarcel Holtmann 
390675e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
390775e0569fSMarcel Holtmann 	if (!skb)
390875e0569fSMarcel Holtmann 		return -ENOMEM;
390975e0569fSMarcel Holtmann 
3910d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
391159ae1d12SJohannes Berg 	skb_put_data(skb, hw_err, 3);
391275e0569fSMarcel Holtmann 
391375e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
391475e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
391575e0569fSMarcel Holtmann }
391675e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
391775e0569fSMarcel Holtmann 
391876bca880SMarcel Holtmann /* Receive frame from HCI drivers */
3919e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
392076bca880SMarcel Holtmann {
392176bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
392276bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
392376bca880SMarcel Holtmann 		kfree_skb(skb);
392476bca880SMarcel Holtmann 		return -ENXIO;
392576bca880SMarcel Holtmann 	}
392676bca880SMarcel Holtmann 
3927d79f34e3SMarcel Holtmann 	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
3928d79f34e3SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
3929cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT &&
3930cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) {
3931fe806dceSMarcel Holtmann 		kfree_skb(skb);
3932fe806dceSMarcel Holtmann 		return -EINVAL;
3933fe806dceSMarcel Holtmann 	}
3934fe806dceSMarcel Holtmann 
3935d82603c6SJorrit Schippers 	/* Incoming skb */
393676bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
393776bca880SMarcel Holtmann 
393876bca880SMarcel Holtmann 	/* Time stamp */
393976bca880SMarcel Holtmann 	__net_timestamp(skb);
394076bca880SMarcel Holtmann 
394176bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3942b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3943c78ae283SMarcel Holtmann 
394476bca880SMarcel Holtmann 	return 0;
394576bca880SMarcel Holtmann }
394676bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
394776bca880SMarcel Holtmann 
3948e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
3949e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
3950e875ff84SMarcel Holtmann {
3951581d6fd6SMarcel Holtmann 	/* Mark as diagnostic packet */
3952d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
3953581d6fd6SMarcel Holtmann 
3954e875ff84SMarcel Holtmann 	/* Time stamp */
3955e875ff84SMarcel Holtmann 	__net_timestamp(skb);
3956e875ff84SMarcel Holtmann 
3957581d6fd6SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3958581d6fd6SMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3959e875ff84SMarcel Holtmann 
3960e875ff84SMarcel Holtmann 	return 0;
3961e875ff84SMarcel Holtmann }
3962e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
3963e875ff84SMarcel Holtmann 
39645177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
39655177a838SMarcel Holtmann {
39665177a838SMarcel Holtmann 	va_list vargs;
39675177a838SMarcel Holtmann 
39685177a838SMarcel Holtmann 	va_start(vargs, fmt);
39695177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
39705177a838SMarcel Holtmann 	hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
39715177a838SMarcel Holtmann 	va_end(vargs);
39725177a838SMarcel Holtmann }
39735177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
39745177a838SMarcel Holtmann 
39755177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
39765177a838SMarcel Holtmann {
39775177a838SMarcel Holtmann 	va_list vargs;
39785177a838SMarcel Holtmann 
39795177a838SMarcel Holtmann 	va_start(vargs, fmt);
39805177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
39815177a838SMarcel Holtmann 	hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
39825177a838SMarcel Holtmann 	va_end(vargs);
39835177a838SMarcel Holtmann }
39845177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
39855177a838SMarcel Holtmann 
39861da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
39871da177e4SLinus Torvalds 
39881da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
39891da177e4SLinus Torvalds {
39901da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
39911da177e4SLinus Torvalds 
3992fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
399300629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
3994fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
39951da177e4SLinus Torvalds 
39961da177e4SLinus Torvalds 	return 0;
39971da177e4SLinus Torvalds }
39981da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
39991da177e4SLinus Torvalds 
40001da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
40011da177e4SLinus Torvalds {
40021da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
40031da177e4SLinus Torvalds 
4004fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
40051da177e4SLinus Torvalds 	list_del(&cb->list);
4006fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
40071da177e4SLinus Torvalds 
40081da177e4SLinus Torvalds 	return 0;
40091da177e4SLinus Torvalds }
40101da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
40111da177e4SLinus Torvalds 
401251086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
40131da177e4SLinus Torvalds {
4014cdc52faaSMarcel Holtmann 	int err;
4015cdc52faaSMarcel Holtmann 
4016d79f34e3SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
4017d79f34e3SMarcel Holtmann 	       skb->len);
40181da177e4SLinus Torvalds 
40191da177e4SLinus Torvalds 	/* Time stamp */
4020a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
40211da177e4SLinus Torvalds 
4022cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
4023cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
4024cd82e61cSMarcel Holtmann 
4025cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
4026cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
4027470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
40281da177e4SLinus Torvalds 	}
40291da177e4SLinus Torvalds 
40301da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
40311da177e4SLinus Torvalds 	skb_orphan(skb);
40321da177e4SLinus Torvalds 
403373d0d3c8SMarcel Holtmann 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
403473d0d3c8SMarcel Holtmann 		kfree_skb(skb);
403573d0d3c8SMarcel Holtmann 		return;
403673d0d3c8SMarcel Holtmann 	}
403773d0d3c8SMarcel Holtmann 
4038cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
4039cdc52faaSMarcel Holtmann 	if (err < 0) {
40402064ee33SMarcel Holtmann 		bt_dev_err(hdev, "sending frame failed (%d)", err);
4041cdc52faaSMarcel Holtmann 		kfree_skb(skb);
4042cdc52faaSMarcel Holtmann 	}
40431da177e4SLinus Torvalds }
40441da177e4SLinus Torvalds 
40451ca3a9d0SJohan Hedberg /* Send HCI command */
404607dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
404707dc93ddSJohan Hedberg 		 const void *param)
40481ca3a9d0SJohan Hedberg {
40491ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
40501ca3a9d0SJohan Hedberg 
40511ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
40521ca3a9d0SJohan Hedberg 
40531ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
40541ca3a9d0SJohan Hedberg 	if (!skb) {
40552064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no memory for command");
40561ca3a9d0SJohan Hedberg 		return -ENOMEM;
40571ca3a9d0SJohan Hedberg 	}
40581ca3a9d0SJohan Hedberg 
405949c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
406011714b3dSJohan Hedberg 	 * single-command requests.
406111714b3dSJohan Hedberg 	 */
406244d27137SJohan Hedberg 	bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
406311714b3dSJohan Hedberg 
40641da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
4065c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
40661da177e4SLinus Torvalds 
40671da177e4SLinus Torvalds 	return 0;
40681da177e4SLinus Torvalds }
40691da177e4SLinus Torvalds 
4070d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
4071d6ee6ad7SLoic Poulain 		   const void *param)
4072d6ee6ad7SLoic Poulain {
4073d6ee6ad7SLoic Poulain 	struct sk_buff *skb;
4074d6ee6ad7SLoic Poulain 
4075d6ee6ad7SLoic Poulain 	if (hci_opcode_ogf(opcode) != 0x3f) {
4076d6ee6ad7SLoic Poulain 		/* A controller receiving a command shall respond with either
4077d6ee6ad7SLoic Poulain 		 * a Command Status Event or a Command Complete Event.
4078d6ee6ad7SLoic Poulain 		 * Therefore, all standard HCI commands must be sent via the
4079d6ee6ad7SLoic Poulain 		 * standard API, using hci_send_cmd or hci_cmd_sync helpers.
4080d6ee6ad7SLoic Poulain 		 * Some vendors do not comply with this rule for vendor-specific
4081d6ee6ad7SLoic Poulain 		 * commands and do not return any event. We want to support
4082d6ee6ad7SLoic Poulain 		 * unresponded commands for such cases only.
4083d6ee6ad7SLoic Poulain 		 */
4084d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "unresponded command not supported");
4085d6ee6ad7SLoic Poulain 		return -EINVAL;
4086d6ee6ad7SLoic Poulain 	}
4087d6ee6ad7SLoic Poulain 
4088d6ee6ad7SLoic Poulain 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
4089d6ee6ad7SLoic Poulain 	if (!skb) {
4090d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
4091d6ee6ad7SLoic Poulain 			   opcode);
4092d6ee6ad7SLoic Poulain 		return -ENOMEM;
4093d6ee6ad7SLoic Poulain 	}
4094d6ee6ad7SLoic Poulain 
4095d6ee6ad7SLoic Poulain 	hci_send_frame(hdev, skb);
4096d6ee6ad7SLoic Poulain 
4097d6ee6ad7SLoic Poulain 	return 0;
4098d6ee6ad7SLoic Poulain }
4099d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
4100d6ee6ad7SLoic Poulain 
41011da177e4SLinus Torvalds /* Get data from the previously sent command */
4102a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
41031da177e4SLinus Torvalds {
41041da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
41051da177e4SLinus Torvalds 
41061da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
41071da177e4SLinus Torvalds 		return NULL;
41081da177e4SLinus Torvalds 
41091da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
41101da177e4SLinus Torvalds 
4111a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
41121da177e4SLinus Torvalds 		return NULL;
41131da177e4SLinus Torvalds 
4114f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
41151da177e4SLinus Torvalds 
41161da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
41171da177e4SLinus Torvalds }
41181da177e4SLinus Torvalds 
4119fbef168fSLoic Poulain /* Send HCI command and wait for command commplete event */
4120fbef168fSLoic Poulain struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
4121fbef168fSLoic Poulain 			     const void *param, u32 timeout)
4122fbef168fSLoic Poulain {
4123fbef168fSLoic Poulain 	struct sk_buff *skb;
4124fbef168fSLoic Poulain 
4125fbef168fSLoic Poulain 	if (!test_bit(HCI_UP, &hdev->flags))
4126fbef168fSLoic Poulain 		return ERR_PTR(-ENETDOWN);
4127fbef168fSLoic Poulain 
4128fbef168fSLoic Poulain 	bt_dev_dbg(hdev, "opcode 0x%4.4x plen %d", opcode, plen);
4129fbef168fSLoic Poulain 
4130b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
4131fbef168fSLoic Poulain 	skb = __hci_cmd_sync(hdev, opcode, plen, param, timeout);
4132b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
4133fbef168fSLoic Poulain 
4134fbef168fSLoic Poulain 	return skb;
4135fbef168fSLoic Poulain }
4136fbef168fSLoic Poulain EXPORT_SYMBOL(hci_cmd_sync);
4137fbef168fSLoic Poulain 
41381da177e4SLinus Torvalds /* Send ACL data */
41391da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
41401da177e4SLinus Torvalds {
41411da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
41421da177e4SLinus Torvalds 	int len = skb->len;
41431da177e4SLinus Torvalds 
4144badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
4145badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
41469c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
4147aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
4148aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
41491da177e4SLinus Torvalds }
41501da177e4SLinus Torvalds 
4151ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
415273d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
41531da177e4SLinus Torvalds {
4154ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
41551da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
41561da177e4SLinus Torvalds 	struct sk_buff *list;
41571da177e4SLinus Torvalds 
4158087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
4159087bfd99SGustavo Padovan 	skb->data_len = 0;
4160087bfd99SGustavo Padovan 
4161d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
4162204a6e54SAndrei Emeltchenko 
4163204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
4164ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
4165087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
4166204a6e54SAndrei Emeltchenko 		break;
4167204a6e54SAndrei Emeltchenko 	case HCI_AMP:
4168204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
4169204a6e54SAndrei Emeltchenko 		break;
4170204a6e54SAndrei Emeltchenko 	default:
41712064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
4172204a6e54SAndrei Emeltchenko 		return;
4173204a6e54SAndrei Emeltchenko 	}
4174087bfd99SGustavo Padovan 
417570f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
417670f23020SAndrei Emeltchenko 	if (!list) {
41771da177e4SLinus Torvalds 		/* Non fragmented */
41781da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
41791da177e4SLinus Torvalds 
418073d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
41811da177e4SLinus Torvalds 	} else {
41821da177e4SLinus Torvalds 		/* Fragmented */
41831da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
41841da177e4SLinus Torvalds 
41851da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
41861da177e4SLinus Torvalds 
41879cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
41889cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
41899cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
41909cfd5a23SJukka Rissanen 		 * deadlocks.
41919cfd5a23SJukka Rissanen 		 */
41929cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
41931da177e4SLinus Torvalds 
419473d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
4195e702112fSAndrei Emeltchenko 
4196e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
4197e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
41981da177e4SLinus Torvalds 		do {
41991da177e4SLinus Torvalds 			skb = list; list = list->next;
42001da177e4SLinus Torvalds 
4201d79f34e3SMarcel Holtmann 			hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
4202e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
42031da177e4SLinus Torvalds 
42041da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
42051da177e4SLinus Torvalds 
420673d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
42071da177e4SLinus Torvalds 		} while (list);
42081da177e4SLinus Torvalds 
42099cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
42101da177e4SLinus Torvalds 	}
421173d80debSLuiz Augusto von Dentz }
421273d80debSLuiz Augusto von Dentz 
421373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
421473d80debSLuiz Augusto von Dentz {
4215ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
421673d80debSLuiz Augusto von Dentz 
4217f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
421873d80debSLuiz Augusto von Dentz 
4219ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
42201da177e4SLinus Torvalds 
42213eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
42221da177e4SLinus Torvalds }
42231da177e4SLinus Torvalds 
42241da177e4SLinus Torvalds /* Send SCO data */
42250d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
42261da177e4SLinus Torvalds {
42271da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
42281da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
42291da177e4SLinus Torvalds 
42301da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
42311da177e4SLinus Torvalds 
4232aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
42331da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
42341da177e4SLinus Torvalds 
4235badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
4236badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
42379c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
42381da177e4SLinus Torvalds 
4239d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
4240c78ae283SMarcel Holtmann 
42411da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
42423eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
42431da177e4SLinus Torvalds }
42441da177e4SLinus Torvalds 
42451da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
42461da177e4SLinus Torvalds 
42471da177e4SLinus Torvalds /* HCI Connection scheduler */
42486039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
4249a8c5fb1aSGustavo Padovan 				     int *quote)
42501da177e4SLinus Torvalds {
42511da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
42528035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
4253abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
42541da177e4SLinus Torvalds 
42551da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
42561da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
4257bf4c6325SGustavo F. Padovan 
4258bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4259bf4c6325SGustavo F. Padovan 
4260bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4261769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
42621da177e4SLinus Torvalds 			continue;
4263769be974SMarcel Holtmann 
4264769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
4265769be974SMarcel Holtmann 			continue;
4266769be974SMarcel Holtmann 
42671da177e4SLinus Torvalds 		num++;
42681da177e4SLinus Torvalds 
42691da177e4SLinus Torvalds 		if (c->sent < min) {
42701da177e4SLinus Torvalds 			min  = c->sent;
42711da177e4SLinus Torvalds 			conn = c;
42721da177e4SLinus Torvalds 		}
427352087a79SLuiz Augusto von Dentz 
427452087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
427552087a79SLuiz Augusto von Dentz 			break;
42761da177e4SLinus Torvalds 	}
42771da177e4SLinus Torvalds 
4278bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4279bf4c6325SGustavo F. Padovan 
42801da177e4SLinus Torvalds 	if (conn) {
42816ed58ec5SVille Tervo 		int cnt, q;
42826ed58ec5SVille Tervo 
42836ed58ec5SVille Tervo 		switch (conn->type) {
42846ed58ec5SVille Tervo 		case ACL_LINK:
42856ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
42866ed58ec5SVille Tervo 			break;
42876ed58ec5SVille Tervo 		case SCO_LINK:
42886ed58ec5SVille Tervo 		case ESCO_LINK:
42896ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
42906ed58ec5SVille Tervo 			break;
42916ed58ec5SVille Tervo 		case LE_LINK:
42926ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
42936ed58ec5SVille Tervo 			break;
42946ed58ec5SVille Tervo 		default:
42956ed58ec5SVille Tervo 			cnt = 0;
42962064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown link type %d", conn->type);
42976ed58ec5SVille Tervo 		}
42986ed58ec5SVille Tervo 
42996ed58ec5SVille Tervo 		q = cnt / num;
43001da177e4SLinus Torvalds 		*quote = q ? q : 1;
43011da177e4SLinus Torvalds 	} else
43021da177e4SLinus Torvalds 		*quote = 0;
43031da177e4SLinus Torvalds 
43041da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
43051da177e4SLinus Torvalds 	return conn;
43061da177e4SLinus Torvalds }
43071da177e4SLinus Torvalds 
43086039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
43091da177e4SLinus Torvalds {
43101da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
43111da177e4SLinus Torvalds 	struct hci_conn *c;
43121da177e4SLinus Torvalds 
43132064ee33SMarcel Holtmann 	bt_dev_err(hdev, "link tx timeout");
43141da177e4SLinus Torvalds 
4315bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4316bf4c6325SGustavo F. Padovan 
43171da177e4SLinus Torvalds 	/* Kill stalled connections */
4318bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4319bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
43202064ee33SMarcel Holtmann 			bt_dev_err(hdev, "killing stalled connection %pMR",
43212064ee33SMarcel Holtmann 				   &c->dst);
4322bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
43231da177e4SLinus Torvalds 		}
43241da177e4SLinus Torvalds 	}
4325bf4c6325SGustavo F. Padovan 
4326bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
43271da177e4SLinus Torvalds }
43281da177e4SLinus Torvalds 
43296039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
433073d80debSLuiz Augusto von Dentz 				      int *quote)
433173d80debSLuiz Augusto von Dentz {
433273d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
433373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4334abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
433573d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
433673d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
433773d80debSLuiz Augusto von Dentz 
433873d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
433973d80debSLuiz Augusto von Dentz 
4340bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4341bf4c6325SGustavo F. Padovan 
4342bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
434373d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
434473d80debSLuiz Augusto von Dentz 
434573d80debSLuiz Augusto von Dentz 		if (conn->type != type)
434673d80debSLuiz Augusto von Dentz 			continue;
434773d80debSLuiz Augusto von Dentz 
434873d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
434973d80debSLuiz Augusto von Dentz 			continue;
435073d80debSLuiz Augusto von Dentz 
435173d80debSLuiz Augusto von Dentz 		conn_num++;
435273d80debSLuiz Augusto von Dentz 
43538192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
435473d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
435573d80debSLuiz Augusto von Dentz 
435673d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
435773d80debSLuiz Augusto von Dentz 				continue;
435873d80debSLuiz Augusto von Dentz 
435973d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
436073d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
436173d80debSLuiz Augusto von Dentz 				continue;
436273d80debSLuiz Augusto von Dentz 
436373d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
436473d80debSLuiz Augusto von Dentz 				num = 0;
436573d80debSLuiz Augusto von Dentz 				min = ~0;
436673d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
436773d80debSLuiz Augusto von Dentz 			}
436873d80debSLuiz Augusto von Dentz 
436973d80debSLuiz Augusto von Dentz 			num++;
437073d80debSLuiz Augusto von Dentz 
437173d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
437273d80debSLuiz Augusto von Dentz 				min  = conn->sent;
437373d80debSLuiz Augusto von Dentz 				chan = tmp;
437473d80debSLuiz Augusto von Dentz 			}
437573d80debSLuiz Augusto von Dentz 		}
437673d80debSLuiz Augusto von Dentz 
437773d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
437873d80debSLuiz Augusto von Dentz 			break;
437973d80debSLuiz Augusto von Dentz 	}
438073d80debSLuiz Augusto von Dentz 
4381bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4382bf4c6325SGustavo F. Padovan 
438373d80debSLuiz Augusto von Dentz 	if (!chan)
438473d80debSLuiz Augusto von Dentz 		return NULL;
438573d80debSLuiz Augusto von Dentz 
438673d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
438773d80debSLuiz Augusto von Dentz 	case ACL_LINK:
438873d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
438973d80debSLuiz Augusto von Dentz 		break;
4390bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4391bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4392bd1eb66bSAndrei Emeltchenko 		break;
439373d80debSLuiz Augusto von Dentz 	case SCO_LINK:
439473d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
439573d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
439673d80debSLuiz Augusto von Dentz 		break;
439773d80debSLuiz Augusto von Dentz 	case LE_LINK:
439873d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
439973d80debSLuiz Augusto von Dentz 		break;
440073d80debSLuiz Augusto von Dentz 	default:
440173d80debSLuiz Augusto von Dentz 		cnt = 0;
44022064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown link type %d", chan->conn->type);
440373d80debSLuiz Augusto von Dentz 	}
440473d80debSLuiz Augusto von Dentz 
440573d80debSLuiz Augusto von Dentz 	q = cnt / num;
440673d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
440773d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
440873d80debSLuiz Augusto von Dentz 	return chan;
440973d80debSLuiz Augusto von Dentz }
441073d80debSLuiz Augusto von Dentz 
441102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
441202b20f0bSLuiz Augusto von Dentz {
441302b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
441402b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
441502b20f0bSLuiz Augusto von Dentz 	int num = 0;
441602b20f0bSLuiz Augusto von Dentz 
441702b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
441802b20f0bSLuiz Augusto von Dentz 
4419bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4420bf4c6325SGustavo F. Padovan 
4421bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
442202b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
442302b20f0bSLuiz Augusto von Dentz 
442402b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
442502b20f0bSLuiz Augusto von Dentz 			continue;
442602b20f0bSLuiz Augusto von Dentz 
442702b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
442802b20f0bSLuiz Augusto von Dentz 			continue;
442902b20f0bSLuiz Augusto von Dentz 
443002b20f0bSLuiz Augusto von Dentz 		num++;
443102b20f0bSLuiz Augusto von Dentz 
44328192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
443302b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
443402b20f0bSLuiz Augusto von Dentz 
443502b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
443602b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
443702b20f0bSLuiz Augusto von Dentz 				continue;
443802b20f0bSLuiz Augusto von Dentz 			}
443902b20f0bSLuiz Augusto von Dentz 
444002b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
444102b20f0bSLuiz Augusto von Dentz 				continue;
444202b20f0bSLuiz Augusto von Dentz 
444302b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
444402b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
444502b20f0bSLuiz Augusto von Dentz 				continue;
444602b20f0bSLuiz Augusto von Dentz 
444702b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
444802b20f0bSLuiz Augusto von Dentz 
444902b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
445002b20f0bSLuiz Augusto von Dentz 			       skb->priority);
445102b20f0bSLuiz Augusto von Dentz 		}
445202b20f0bSLuiz Augusto von Dentz 
445302b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
445402b20f0bSLuiz Augusto von Dentz 			break;
445502b20f0bSLuiz Augusto von Dentz 	}
4456bf4c6325SGustavo F. Padovan 
4457bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4458bf4c6325SGustavo F. Padovan 
445902b20f0bSLuiz Augusto von Dentz }
446002b20f0bSLuiz Augusto von Dentz 
4461b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4462b71d385aSAndrei Emeltchenko {
4463b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4464b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4465b71d385aSAndrei Emeltchenko }
4466b71d385aSAndrei Emeltchenko 
44676039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
44681da177e4SLinus Torvalds {
4469d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
44701da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
44711da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
447263d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
44735f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4474bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
44751da177e4SLinus Torvalds 	}
447663d2bc1bSAndrei Emeltchenko }
44771da177e4SLinus Torvalds 
44787fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
44797fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
44807fedd3bbSAbhishek Pandit-Subedi {
44817fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
44827fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
44837fedd3bbSAbhishek Pandit-Subedi 	int quote;
44847fedd3bbSAbhishek Pandit-Subedi 
44857fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
44867fedd3bbSAbhishek Pandit-Subedi 
44877fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, SCO_LINK))
44887fedd3bbSAbhishek Pandit-Subedi 		return;
44897fedd3bbSAbhishek Pandit-Subedi 
44907fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
44917fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
44927fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
44937fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
44947fedd3bbSAbhishek Pandit-Subedi 
44957fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
44967fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
44977fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
44987fedd3bbSAbhishek Pandit-Subedi 		}
44997fedd3bbSAbhishek Pandit-Subedi 	}
45007fedd3bbSAbhishek Pandit-Subedi }
45017fedd3bbSAbhishek Pandit-Subedi 
45027fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
45037fedd3bbSAbhishek Pandit-Subedi {
45047fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
45057fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
45067fedd3bbSAbhishek Pandit-Subedi 	int quote;
45077fedd3bbSAbhishek Pandit-Subedi 
45087fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
45097fedd3bbSAbhishek Pandit-Subedi 
45107fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, ESCO_LINK))
45117fedd3bbSAbhishek Pandit-Subedi 		return;
45127fedd3bbSAbhishek Pandit-Subedi 
45137fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
45147fedd3bbSAbhishek Pandit-Subedi 						     &quote))) {
45157fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
45167fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
45177fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
45187fedd3bbSAbhishek Pandit-Subedi 
45197fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
45207fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
45217fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
45227fedd3bbSAbhishek Pandit-Subedi 		}
45237fedd3bbSAbhishek Pandit-Subedi 	}
45247fedd3bbSAbhishek Pandit-Subedi }
45257fedd3bbSAbhishek Pandit-Subedi 
45266039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
452763d2bc1bSAndrei Emeltchenko {
452863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
452963d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
453063d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
453163d2bc1bSAndrei Emeltchenko 	int quote;
453263d2bc1bSAndrei Emeltchenko 
453363d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
453404837f64SMarcel Holtmann 
453573d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
453673d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4537ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4538ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
453973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
454073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
454173d80debSLuiz Augusto von Dentz 
4542ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4543ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4544ec1cce24SLuiz Augusto von Dentz 				break;
4545ec1cce24SLuiz Augusto von Dentz 
4546ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4547ec1cce24SLuiz Augusto von Dentz 
454873d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
454973d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
455004837f64SMarcel Holtmann 
455157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
45521da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
45531da177e4SLinus Torvalds 
45541da177e4SLinus Torvalds 			hdev->acl_cnt--;
455573d80debSLuiz Augusto von Dentz 			chan->sent++;
455673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
45577fedd3bbSAbhishek Pandit-Subedi 
45587fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
45597fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
45607fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
45611da177e4SLinus Torvalds 		}
45621da177e4SLinus Torvalds 	}
456302b20f0bSLuiz Augusto von Dentz 
456402b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
456502b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
45661da177e4SLinus Torvalds }
45671da177e4SLinus Torvalds 
45686039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4569b71d385aSAndrei Emeltchenko {
457063d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4571b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4572b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4573b71d385aSAndrei Emeltchenko 	int quote;
4574bd1eb66bSAndrei Emeltchenko 	u8 type;
4575b71d385aSAndrei Emeltchenko 
457663d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
4577b71d385aSAndrei Emeltchenko 
4578bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4579bd1eb66bSAndrei Emeltchenko 
4580bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
4581bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
4582bd1eb66bSAndrei Emeltchenko 	else
4583bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
4584bd1eb66bSAndrei Emeltchenko 
4585b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
4586bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
4587b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
4588b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
4589b71d385aSAndrei Emeltchenko 			int blocks;
4590b71d385aSAndrei Emeltchenko 
4591b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
4592b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
4593b71d385aSAndrei Emeltchenko 
4594b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
4595b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
4596b71d385aSAndrei Emeltchenko 				break;
4597b71d385aSAndrei Emeltchenko 
4598b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
4599b71d385aSAndrei Emeltchenko 
4600b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
4601b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
4602b71d385aSAndrei Emeltchenko 				return;
4603b71d385aSAndrei Emeltchenko 
4604b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
4605b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
4606b71d385aSAndrei Emeltchenko 
460757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4608b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4609b71d385aSAndrei Emeltchenko 
4610b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4611b71d385aSAndrei Emeltchenko 			quote -= blocks;
4612b71d385aSAndrei Emeltchenko 
4613b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4614b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4615b71d385aSAndrei Emeltchenko 		}
4616b71d385aSAndrei Emeltchenko 	}
4617b71d385aSAndrei Emeltchenko 
4618b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4619bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4620b71d385aSAndrei Emeltchenko }
4621b71d385aSAndrei Emeltchenko 
46226039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4623b71d385aSAndrei Emeltchenko {
4624b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4625b71d385aSAndrei Emeltchenko 
4626bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4627ca8bee5dSMarcel Holtmann 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY)
4628bd1eb66bSAndrei Emeltchenko 		return;
4629bd1eb66bSAndrei Emeltchenko 
4630bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4631bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4632b71d385aSAndrei Emeltchenko 		return;
4633b71d385aSAndrei Emeltchenko 
4634b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4635b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4636b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4637b71d385aSAndrei Emeltchenko 		break;
4638b71d385aSAndrei Emeltchenko 
4639b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4640b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4641b71d385aSAndrei Emeltchenko 		break;
4642b71d385aSAndrei Emeltchenko 	}
4643b71d385aSAndrei Emeltchenko }
4644b71d385aSAndrei Emeltchenko 
46456039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
46466ed58ec5SVille Tervo {
464773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
46486ed58ec5SVille Tervo 	struct sk_buff *skb;
464902b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
46506ed58ec5SVille Tervo 
46516ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
46526ed58ec5SVille Tervo 
465352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
465452087a79SLuiz Augusto von Dentz 		return;
465552087a79SLuiz Augusto von Dentz 
46566ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
46571b1d29e5SLuiz Augusto von Dentz 
46581b1d29e5SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt);
46591b1d29e5SLuiz Augusto von Dentz 
466002b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
466173d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4662ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4663ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
466473d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
466573d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
46666ed58ec5SVille Tervo 
4667ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4668ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4669ec1cce24SLuiz Augusto von Dentz 				break;
4670ec1cce24SLuiz Augusto von Dentz 
4671ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4672ec1cce24SLuiz Augusto von Dentz 
467357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
46746ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
46756ed58ec5SVille Tervo 
46766ed58ec5SVille Tervo 			cnt--;
467773d80debSLuiz Augusto von Dentz 			chan->sent++;
467873d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
46797fedd3bbSAbhishek Pandit-Subedi 
46807fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
46817fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
46827fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
46836ed58ec5SVille Tervo 		}
46846ed58ec5SVille Tervo 	}
468573d80debSLuiz Augusto von Dentz 
46866ed58ec5SVille Tervo 	if (hdev->le_pkts)
46876ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
46886ed58ec5SVille Tervo 	else
46896ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
469002b20f0bSLuiz Augusto von Dentz 
469102b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
469202b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
46936ed58ec5SVille Tervo }
46946ed58ec5SVille Tervo 
46953eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
46961da177e4SLinus Torvalds {
46973eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
46981da177e4SLinus Torvalds 	struct sk_buff *skb;
46991da177e4SLinus Torvalds 
47006ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
47016ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
47021da177e4SLinus Torvalds 
4703d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
47041da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
47051da177e4SLinus Torvalds 		hci_sched_sco(hdev);
4706b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
47077fedd3bbSAbhishek Pandit-Subedi 		hci_sched_acl(hdev);
47086ed58ec5SVille Tervo 		hci_sched_le(hdev);
470952de599eSMarcel Holtmann 	}
47106ed58ec5SVille Tervo 
47111da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
47121da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
471357d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
47141da177e4SLinus Torvalds }
47151da177e4SLinus Torvalds 
471625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
47171da177e4SLinus Torvalds 
47181da177e4SLinus Torvalds /* ACL data packet */
47196039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
47201da177e4SLinus Torvalds {
47211da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
47221da177e4SLinus Torvalds 	struct hci_conn *conn;
47231da177e4SLinus Torvalds 	__u16 handle, flags;
47241da177e4SLinus Torvalds 
47251da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
47261da177e4SLinus Torvalds 
47271da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
47281da177e4SLinus Torvalds 	flags  = hci_flags(handle);
47291da177e4SLinus Torvalds 	handle = hci_handle(handle);
47301da177e4SLinus Torvalds 
4731f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4732a8c5fb1aSGustavo Padovan 	       handle, flags);
47331da177e4SLinus Torvalds 
47341da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
47351da177e4SLinus Torvalds 
47361da177e4SLinus Torvalds 	hci_dev_lock(hdev);
47371da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
47381da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
47391da177e4SLinus Torvalds 
47401da177e4SLinus Torvalds 	if (conn) {
474165983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
474204837f64SMarcel Holtmann 
47431da177e4SLinus Torvalds 		/* Send to upper protocol */
4744686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
47451da177e4SLinus Torvalds 		return;
47461da177e4SLinus Torvalds 	} else {
47472064ee33SMarcel Holtmann 		bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
47482064ee33SMarcel Holtmann 			   handle);
47491da177e4SLinus Torvalds 	}
47501da177e4SLinus Torvalds 
47511da177e4SLinus Torvalds 	kfree_skb(skb);
47521da177e4SLinus Torvalds }
47531da177e4SLinus Torvalds 
47541da177e4SLinus Torvalds /* SCO data packet */
47556039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
47561da177e4SLinus Torvalds {
47571da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
47581da177e4SLinus Torvalds 	struct hci_conn *conn;
4759debdedf2SMarcel Holtmann 	__u16 handle, flags;
47601da177e4SLinus Torvalds 
47611da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
47621da177e4SLinus Torvalds 
47631da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
4764debdedf2SMarcel Holtmann 	flags  = hci_flags(handle);
4765debdedf2SMarcel Holtmann 	handle = hci_handle(handle);
47661da177e4SLinus Torvalds 
4767debdedf2SMarcel Holtmann 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4768debdedf2SMarcel Holtmann 	       handle, flags);
47691da177e4SLinus Torvalds 
47701da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
47711da177e4SLinus Torvalds 
47721da177e4SLinus Torvalds 	hci_dev_lock(hdev);
47731da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
47741da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
47751da177e4SLinus Torvalds 
47761da177e4SLinus Torvalds 	if (conn) {
47771da177e4SLinus Torvalds 		/* Send to upper protocol */
477800398e1dSAlain Michaud 		bt_cb(skb)->sco.pkt_status = flags & 0x03;
4779686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
47801da177e4SLinus Torvalds 		return;
47811da177e4SLinus Torvalds 	} else {
47822064ee33SMarcel Holtmann 		bt_dev_err(hdev, "SCO packet for unknown connection handle %d",
47832064ee33SMarcel Holtmann 			   handle);
47841da177e4SLinus Torvalds 	}
47851da177e4SLinus Torvalds 
47861da177e4SLinus Torvalds 	kfree_skb(skb);
47871da177e4SLinus Torvalds }
47881da177e4SLinus Torvalds 
47899238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
47909238f36aSJohan Hedberg {
47919238f36aSJohan Hedberg 	struct sk_buff *skb;
47929238f36aSJohan Hedberg 
47939238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
47949238f36aSJohan Hedberg 	if (!skb)
47959238f36aSJohan Hedberg 		return true;
47969238f36aSJohan Hedberg 
479744d27137SJohan Hedberg 	return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
47989238f36aSJohan Hedberg }
47999238f36aSJohan Hedberg 
480042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
480142c6b129SJohan Hedberg {
480242c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
480342c6b129SJohan Hedberg 	struct sk_buff *skb;
480442c6b129SJohan Hedberg 	u16 opcode;
480542c6b129SJohan Hedberg 
480642c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
480742c6b129SJohan Hedberg 		return;
480842c6b129SJohan Hedberg 
480942c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
481042c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
481142c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
481242c6b129SJohan Hedberg 		return;
481342c6b129SJohan Hedberg 
481442c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
481542c6b129SJohan Hedberg 	if (!skb)
481642c6b129SJohan Hedberg 		return;
481742c6b129SJohan Hedberg 
481842c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
481942c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
482042c6b129SJohan Hedberg }
482142c6b129SJohan Hedberg 
4822e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
4823e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
4824e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
48259238f36aSJohan Hedberg {
48269238f36aSJohan Hedberg 	struct sk_buff *skb;
48279238f36aSJohan Hedberg 	unsigned long flags;
48289238f36aSJohan Hedberg 
48299238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
48309238f36aSJohan Hedberg 
483142c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
483242c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
48339238f36aSJohan Hedberg 	 */
483442c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
483542c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
483642c6b129SJohan Hedberg 		 * reset complete event during init and any pending
483742c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
483842c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
483942c6b129SJohan Hedberg 		 * command.
484042c6b129SJohan Hedberg 		 */
484142c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
484242c6b129SJohan Hedberg 			hci_resend_last(hdev);
484342c6b129SJohan Hedberg 
48449238f36aSJohan Hedberg 		return;
484542c6b129SJohan Hedberg 	}
48469238f36aSJohan Hedberg 
4847f80c5dadSJoão Paulo Rechi Vita 	/* If we reach this point this event matches the last command sent */
4848f80c5dadSJoão Paulo Rechi Vita 	hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
4849f80c5dadSJoão Paulo Rechi Vita 
48509238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
48519238f36aSJohan Hedberg 	 * this request the request is not yet complete.
48529238f36aSJohan Hedberg 	 */
48539238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
48549238f36aSJohan Hedberg 		return;
48559238f36aSJohan Hedberg 
48569238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
48579238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
48589238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
48599238f36aSJohan Hedberg 	 */
486044d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) {
486144d27137SJohan Hedberg 		*req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb;
4862e6214487SJohan Hedberg 		return;
48639238f36aSJohan Hedberg 	}
4864e6214487SJohan Hedberg 
486544d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_complete) {
486644d27137SJohan Hedberg 		*req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete;
4867e6214487SJohan Hedberg 		return;
486853e21fbcSJohan Hedberg 	}
48699238f36aSJohan Hedberg 
48709238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
48719238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
48729238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
487344d27137SJohan Hedberg 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
48749238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
48759238f36aSJohan Hedberg 			break;
48769238f36aSJohan Hedberg 		}
48779238f36aSJohan Hedberg 
48783bd7594eSDouglas Anderson 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
4879242c0ebdSMarcel Holtmann 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
48803bd7594eSDouglas Anderson 		else
48813bd7594eSDouglas Anderson 			*req_complete = bt_cb(skb)->hci.req_complete;
48829238f36aSJohan Hedberg 		kfree_skb(skb);
48839238f36aSJohan Hedberg 	}
48849238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
48859238f36aSJohan Hedberg }
48869238f36aSJohan Hedberg 
4887b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
48881da177e4SLinus Torvalds {
4889b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
48901da177e4SLinus Torvalds 	struct sk_buff *skb;
48911da177e4SLinus Torvalds 
48921da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
48931da177e4SLinus Torvalds 
48941da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
4895cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4896cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4897cd82e61cSMarcel Holtmann 
48981da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
48991da177e4SLinus Torvalds 			/* Send copy to the sockets */
4900470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
49011da177e4SLinus Torvalds 		}
49021da177e4SLinus Torvalds 
4903eb8c101eSMattijs Korpershoek 		/* If the device has been opened in HCI_USER_CHANNEL,
4904eb8c101eSMattijs Korpershoek 		 * the userspace has exclusive access to device.
4905eb8c101eSMattijs Korpershoek 		 * When device is HCI_INIT, we still need to process
4906eb8c101eSMattijs Korpershoek 		 * the data packets to the driver in order
4907eb8c101eSMattijs Korpershoek 		 * to complete its setup().
4908eb8c101eSMattijs Korpershoek 		 */
4909eb8c101eSMattijs Korpershoek 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
4910eb8c101eSMattijs Korpershoek 		    !test_bit(HCI_INIT, &hdev->flags)) {
49111da177e4SLinus Torvalds 			kfree_skb(skb);
49121da177e4SLinus Torvalds 			continue;
49131da177e4SLinus Torvalds 		}
49141da177e4SLinus Torvalds 
49151da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
49161da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
4917d79f34e3SMarcel Holtmann 			switch (hci_skb_pkt_type(skb)) {
49181da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
49191da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
4920cc974003SMarcel Holtmann 			case HCI_ISODATA_PKT:
49211da177e4SLinus Torvalds 				kfree_skb(skb);
49221da177e4SLinus Torvalds 				continue;
49233ff50b79SStephen Hemminger 			}
49241da177e4SLinus Torvalds 		}
49251da177e4SLinus Torvalds 
49261da177e4SLinus Torvalds 		/* Process frame */
4927d79f34e3SMarcel Holtmann 		switch (hci_skb_pkt_type(skb)) {
49281da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4929b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
49301da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
49311da177e4SLinus Torvalds 			break;
49321da177e4SLinus Torvalds 
49331da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
49341da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
49351da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
49361da177e4SLinus Torvalds 			break;
49371da177e4SLinus Torvalds 
49381da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
49391da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
49401da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
49411da177e4SLinus Torvalds 			break;
49421da177e4SLinus Torvalds 
49431da177e4SLinus Torvalds 		default:
49441da177e4SLinus Torvalds 			kfree_skb(skb);
49451da177e4SLinus Torvalds 			break;
49461da177e4SLinus Torvalds 		}
49471da177e4SLinus Torvalds 	}
49481da177e4SLinus Torvalds }
49491da177e4SLinus Torvalds 
4950c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
49511da177e4SLinus Torvalds {
4952c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
49531da177e4SLinus Torvalds 	struct sk_buff *skb;
49541da177e4SLinus Torvalds 
49552104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
49562104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
49571da177e4SLinus Torvalds 
49581da177e4SLinus Torvalds 	/* Send queued commands */
49595a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
49605a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
49615a08ecceSAndrei Emeltchenko 		if (!skb)
49625a08ecceSAndrei Emeltchenko 			return;
49635a08ecceSAndrei Emeltchenko 
49641da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
49651da177e4SLinus Torvalds 
4966a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
496770f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
4968f80c5dadSJoão Paulo Rechi Vita 			if (hci_req_status_pend(hdev))
4969f80c5dadSJoão Paulo Rechi Vita 				hci_dev_set_flag(hdev, HCI_CMD_PENDING);
49701da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
497157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
49727bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
497365cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
49747bdb8a5cSSzymon Janc 			else
497565cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
497665cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
49771da177e4SLinus Torvalds 		} else {
49781da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
4979c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
49801da177e4SLinus Torvalds 		}
49811da177e4SLinus Torvalds 	}
49821da177e4SLinus Torvalds }
4983