xref: /openbmc/linux/net/bluetooth/hci_core.c (revision e5e1e7fd)
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 
6088a595619SAlain Michaud 	if (hdev->commands[18] & 0x04)
60900bce3fbSAlain Michaud 		hci_req_add(req, HCI_OP_READ_DEF_ERR_DATA_REPORTING, 0, NULL);
61000bce3fbSAlain Michaud 
611417287deSMarcel Holtmann 	/* Some older Broadcom based Bluetooth 1.2 controllers do not
612417287deSMarcel Holtmann 	 * support the Read Page Scan Type command. Check support for
613417287deSMarcel Holtmann 	 * this command in the bit mask of supported commands.
614417287deSMarcel Holtmann 	 */
615417287deSMarcel Holtmann 	if (hdev->commands[13] & 0x01)
616417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
617417287deSMarcel Holtmann 
6189193c6e8SAndre Guedes 	if (lmp_le_capable(hdev)) {
6199193c6e8SAndre Guedes 		u8 events[8];
6209193c6e8SAndre Guedes 
6219193c6e8SAndre Guedes 		memset(events, 0, sizeof(events));
6224d6c705bSMarcel Holtmann 
6234d6c705bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
6244d6c705bSMarcel Holtmann 			events[0] |= 0x10;	/* LE Long Term Key Request */
625662bc2e6SAndre Guedes 
626662bc2e6SAndre Guedes 		/* If controller supports the Connection Parameters Request
627662bc2e6SAndre Guedes 		 * Link Layer Procedure, enable the corresponding event.
628662bc2e6SAndre Guedes 		 */
629662bc2e6SAndre Guedes 		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
630662bc2e6SAndre Guedes 			events[0] |= 0x20;	/* LE Remote Connection
631662bc2e6SAndre Guedes 						 * Parameter Request
632662bc2e6SAndre Guedes 						 */
633662bc2e6SAndre Guedes 
634a9f6068eSMarcel Holtmann 		/* If the controller supports the Data Length Extension
635a9f6068eSMarcel Holtmann 		 * feature, enable the corresponding event.
636a9f6068eSMarcel Holtmann 		 */
637a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
638a9f6068eSMarcel Holtmann 			events[0] |= 0x40;	/* LE Data Length Change */
639a9f6068eSMarcel Holtmann 
640ff3b8df2SMarcel Holtmann 		/* If the controller supports LL Privacy feature, enable
641ff3b8df2SMarcel Holtmann 		 * the corresponding event.
642ff3b8df2SMarcel Holtmann 		 */
643ff3b8df2SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_LL_PRIVACY)
644ff3b8df2SMarcel Holtmann 			events[1] |= 0x02;	/* LE Enhanced Connection
645ff3b8df2SMarcel Holtmann 						 * Complete
646ff3b8df2SMarcel Holtmann 						 */
647ff3b8df2SMarcel Holtmann 
6484b71bba4SMarcel Holtmann 		/* If the controller supports Extended Scanner Filter
6494b71bba4SMarcel Holtmann 		 * Policies, enable the correspondig event.
6504b71bba4SMarcel Holtmann 		 */
6514b71bba4SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)
6524b71bba4SMarcel Holtmann 			events[1] |= 0x04;	/* LE Direct Advertising
6534b71bba4SMarcel Holtmann 						 * Report
6544b71bba4SMarcel Holtmann 						 */
6554b71bba4SMarcel Holtmann 
6569756d33bSMarcel Holtmann 		/* If the controller supports Channel Selection Algorithm #2
6579756d33bSMarcel Holtmann 		 * feature, enable the corresponding event.
6589756d33bSMarcel Holtmann 		 */
6599756d33bSMarcel Holtmann 		if (hdev->le_features[1] & HCI_LE_CHAN_SEL_ALG2)
6609756d33bSMarcel Holtmann 			events[2] |= 0x08;	/* LE Channel Selection
6619756d33bSMarcel Holtmann 						 * Algorithm
6629756d33bSMarcel Holtmann 						 */
6639756d33bSMarcel Holtmann 
6647d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Set Scan Enable command,
6657d26f5c4SMarcel Holtmann 		 * enable the corresponding advertising report event.
6667d26f5c4SMarcel Holtmann 		 */
6677d26f5c4SMarcel Holtmann 		if (hdev->commands[26] & 0x08)
6687d26f5c4SMarcel Holtmann 			events[0] |= 0x02;	/* LE Advertising Report */
6697d26f5c4SMarcel Holtmann 
6707d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Create Connection
6717d26f5c4SMarcel Holtmann 		 * command, enable the corresponding event.
6727d26f5c4SMarcel Holtmann 		 */
6737d26f5c4SMarcel Holtmann 		if (hdev->commands[26] & 0x10)
6747d26f5c4SMarcel Holtmann 			events[0] |= 0x01;	/* LE Connection Complete */
6757d26f5c4SMarcel Holtmann 
6767d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Connection Update
6777d26f5c4SMarcel Holtmann 		 * command, enable the corresponding event.
6787d26f5c4SMarcel Holtmann 		 */
6797d26f5c4SMarcel Holtmann 		if (hdev->commands[27] & 0x04)
6807d26f5c4SMarcel Holtmann 			events[0] |= 0x04;	/* LE Connection Update
6817d26f5c4SMarcel Holtmann 						 * Complete
6827d26f5c4SMarcel Holtmann 						 */
6837d26f5c4SMarcel Holtmann 
6847d26f5c4SMarcel Holtmann 		/* If the controller supports the LE Read Remote Used Features
6857d26f5c4SMarcel Holtmann 		 * command, enable the corresponding event.
6867d26f5c4SMarcel Holtmann 		 */
6877d26f5c4SMarcel Holtmann 		if (hdev->commands[27] & 0x20)
6887d26f5c4SMarcel Holtmann 			events[0] |= 0x08;	/* LE Read Remote Used
6897d26f5c4SMarcel Holtmann 						 * Features Complete
6907d26f5c4SMarcel Holtmann 						 */
6917d26f5c4SMarcel Holtmann 
6925a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Read Local P-256
6935a34bd5fSMarcel Holtmann 		 * Public Key command, enable the corresponding event.
6945a34bd5fSMarcel Holtmann 		 */
6955a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x02)
6965a34bd5fSMarcel Holtmann 			events[0] |= 0x80;	/* LE Read Local P-256
6975a34bd5fSMarcel Holtmann 						 * Public Key Complete
6985a34bd5fSMarcel Holtmann 						 */
6995a34bd5fSMarcel Holtmann 
7005a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Generate DHKey
7015a34bd5fSMarcel Holtmann 		 * command, enable the corresponding event.
7025a34bd5fSMarcel Holtmann 		 */
7035a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x04)
7045a34bd5fSMarcel Holtmann 			events[1] |= 0x01;	/* LE Generate DHKey Complete */
7055a34bd5fSMarcel Holtmann 
70627bbca44SMarcel Holtmann 		/* If the controller supports the LE Set Default PHY or
70727bbca44SMarcel Holtmann 		 * LE Set PHY commands, enable the corresponding event.
70827bbca44SMarcel Holtmann 		 */
70927bbca44SMarcel Holtmann 		if (hdev->commands[35] & (0x20 | 0x40))
71027bbca44SMarcel Holtmann 			events[1] |= 0x08;        /* LE PHY Update Complete */
71127bbca44SMarcel Holtmann 
712c215e939SJaganath Kanakkassery 		/* If the controller supports LE Set Extended Scan Parameters
713c215e939SJaganath Kanakkassery 		 * and LE Set Extended Scan Enable commands, enable the
714c215e939SJaganath Kanakkassery 		 * corresponding event.
715c215e939SJaganath Kanakkassery 		 */
716c215e939SJaganath Kanakkassery 		if (use_ext_scan(hdev))
717c215e939SJaganath Kanakkassery 			events[1] |= 0x10;	/* LE Extended Advertising
718c215e939SJaganath Kanakkassery 						 * Report
719c215e939SJaganath Kanakkassery 						 */
720c215e939SJaganath Kanakkassery 
721acf0aeaeSJaganath Kanakkassery 		/* If the controller supports the LE Extended Advertising
722acf0aeaeSJaganath Kanakkassery 		 * command, enable the corresponding event.
723acf0aeaeSJaganath Kanakkassery 		 */
724acf0aeaeSJaganath Kanakkassery 		if (ext_adv_capable(hdev))
725acf0aeaeSJaganath Kanakkassery 			events[2] |= 0x02;	/* LE Advertising Set
726acf0aeaeSJaganath Kanakkassery 						 * Terminated
727acf0aeaeSJaganath Kanakkassery 						 */
728acf0aeaeSJaganath Kanakkassery 
7299193c6e8SAndre Guedes 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
7309193c6e8SAndre Guedes 			    events);
7319193c6e8SAndre Guedes 
73215a49ccaSMarcel Holtmann 		/* Read LE Advertising Channel TX Power */
7336b49bcb4SJaganath Kanakkassery 		if ((hdev->commands[25] & 0x40) && !ext_adv_capable(hdev)) {
7346b49bcb4SJaganath Kanakkassery 			/* HCI TS spec forbids mixing of legacy and extended
7356b49bcb4SJaganath Kanakkassery 			 * advertising commands wherein READ_ADV_TX_POWER is
7366b49bcb4SJaganath Kanakkassery 			 * also included. So do not call it if extended adv
7376b49bcb4SJaganath Kanakkassery 			 * is supported otherwise controller will return
7386b49bcb4SJaganath Kanakkassery 			 * COMMAND_DISALLOWED for extended commands.
7396b49bcb4SJaganath Kanakkassery 			 */
74015a49ccaSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
74115a49ccaSMarcel Holtmann 		}
74215a49ccaSMarcel Holtmann 
7432ab216a7SMarcel Holtmann 		if (hdev->commands[26] & 0x40) {
7442ab216a7SMarcel Holtmann 			/* Read LE White List Size */
7452ab216a7SMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE,
7462ab216a7SMarcel Holtmann 				    0, NULL);
7472ab216a7SMarcel Holtmann 		}
7482ab216a7SMarcel Holtmann 
7492ab216a7SMarcel Holtmann 		if (hdev->commands[26] & 0x80) {
7502ab216a7SMarcel Holtmann 			/* Clear LE White List */
7512ab216a7SMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
7522ab216a7SMarcel Holtmann 		}
7532ab216a7SMarcel Holtmann 
754cfdb0c2dSAnkit Navik 		if (hdev->commands[34] & 0x40) {
755cfdb0c2dSAnkit Navik 			/* Read LE Resolving List Size */
756cfdb0c2dSAnkit Navik 			hci_req_add(req, HCI_OP_LE_READ_RESOLV_LIST_SIZE,
757cfdb0c2dSAnkit Navik 				    0, NULL);
758cfdb0c2dSAnkit Navik 		}
759cfdb0c2dSAnkit Navik 
760545f2596SAnkit Navik 		if (hdev->commands[34] & 0x20) {
761545f2596SAnkit Navik 			/* Clear LE Resolving List */
762545f2596SAnkit Navik 			hci_req_add(req, HCI_OP_LE_CLEAR_RESOLV_LIST, 0, NULL);
763545f2596SAnkit Navik 		}
764545f2596SAnkit Navik 
765a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
766a9f6068eSMarcel Holtmann 			/* Read LE Maximum Data Length */
767a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL);
768a9f6068eSMarcel Holtmann 
769a9f6068eSMarcel Holtmann 			/* Read LE Suggested Default Data Length */
770a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL);
771a9f6068eSMarcel Holtmann 		}
772a9f6068eSMarcel Holtmann 
7736b49bcb4SJaganath Kanakkassery 		if (ext_adv_capable(hdev)) {
7746b49bcb4SJaganath Kanakkassery 			/* Read LE Number of Supported Advertising Sets */
7756b49bcb4SJaganath Kanakkassery 			hci_req_add(req, HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS,
7766b49bcb4SJaganath Kanakkassery 				    0, NULL);
7776b49bcb4SJaganath Kanakkassery 		}
7786b49bcb4SJaganath Kanakkassery 
77942c6b129SJohan Hedberg 		hci_set_le_support(req);
7809193c6e8SAndre Guedes 	}
781d2c5d77fSJohan Hedberg 
782d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
783d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
784d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
785d2c5d77fSJohan Hedberg 
786d2c5d77fSJohan Hedberg 		cp.page = p;
787d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
788d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
789d2c5d77fSJohan Hedberg 	}
790a1d01db1SJohan Hedberg 
791a1d01db1SJohan Hedberg 	return 0;
7922177bab5SJohan Hedberg }
7932177bab5SJohan Hedberg 
794a1d01db1SJohan Hedberg static int hci_init4_req(struct hci_request *req, unsigned long opt)
7955d4e7e8dSJohan Hedberg {
7965d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
7975d4e7e8dSJohan Hedberg 
79836f260ceSMarcel Holtmann 	/* Some Broadcom based Bluetooth controllers do not support the
79936f260ceSMarcel Holtmann 	 * Delete Stored Link Key command. They are clearly indicating its
80036f260ceSMarcel Holtmann 	 * absence in the bit mask of supported commands.
80136f260ceSMarcel Holtmann 	 *
80236f260ceSMarcel Holtmann 	 * Check the supported commands and only if the the command is marked
80336f260ceSMarcel Holtmann 	 * as supported send it. If not supported assume that the controller
80436f260ceSMarcel Holtmann 	 * does not have actual support for stored link keys which makes this
80536f260ceSMarcel Holtmann 	 * command redundant anyway.
80636f260ceSMarcel Holtmann 	 *
80736f260ceSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
80836f260ceSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
80936f260ceSMarcel Holtmann 	 * just disable this command.
81036f260ceSMarcel Holtmann 	 */
81136f260ceSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
81236f260ceSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
81336f260ceSMarcel Holtmann 		struct hci_cp_delete_stored_link_key cp;
81436f260ceSMarcel Holtmann 
81536f260ceSMarcel Holtmann 		bacpy(&cp.bdaddr, BDADDR_ANY);
81636f260ceSMarcel Holtmann 		cp.delete_all = 0x01;
81736f260ceSMarcel Holtmann 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
81836f260ceSMarcel Holtmann 			    sizeof(cp), &cp);
81936f260ceSMarcel Holtmann 	}
82036f260ceSMarcel Holtmann 
821d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
822d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
823d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
824d62e6d67SJohan Hedberg 
825109e3191SMarcel Holtmann 	/* Read local codec list if the HCI command is supported */
826109e3191SMarcel Holtmann 	if (hdev->commands[29] & 0x20)
827109e3191SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
828109e3191SMarcel Holtmann 
829a4790360SMarcel Holtmann 	/* Read local pairing options if the HCI command is supported */
830a4790360SMarcel Holtmann 	if (hdev->commands[41] & 0x08)
831a4790360SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_PAIRING_OPTS, 0, NULL);
832a4790360SMarcel Holtmann 
833f4fe73edSMarcel Holtmann 	/* Get MWS transport configuration if the HCI command is supported */
834f4fe73edSMarcel Holtmann 	if (hdev->commands[30] & 0x08)
835f4fe73edSMarcel Holtmann 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
836f4fe73edSMarcel Holtmann 
8375d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
83853b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
8395d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
840a6d0d690SMarcel Holtmann 
841a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
842d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) &&
843574ea3c7SMarcel Holtmann 	    bredr_sc_enabled(hdev)) {
844a6d0d690SMarcel Holtmann 		u8 support = 0x01;
845574ea3c7SMarcel Holtmann 
846a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
847a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
848a6d0d690SMarcel Holtmann 	}
849a1d01db1SJohan Hedberg 
85000bce3fbSAlain Michaud 	/* Set erroneous data reporting if supported to the wideband speech
85100bce3fbSAlain Michaud 	 * setting value
85200bce3fbSAlain Michaud 	 */
8538a595619SAlain Michaud 	if (hdev->commands[18] & 0x08) {
85400bce3fbSAlain Michaud 		bool enabled = hci_dev_test_flag(hdev,
85500bce3fbSAlain Michaud 						 HCI_WIDEBAND_SPEECH_ENABLED);
85600bce3fbSAlain Michaud 
85700bce3fbSAlain Michaud 		if (enabled !=
85800bce3fbSAlain Michaud 		    (hdev->err_data_reporting == ERR_DATA_REPORTING_ENABLED)) {
85900bce3fbSAlain Michaud 			struct hci_cp_write_def_err_data_reporting cp;
86000bce3fbSAlain Michaud 
86100bce3fbSAlain Michaud 			cp.err_data_reporting = enabled ?
86200bce3fbSAlain Michaud 						ERR_DATA_REPORTING_ENABLED :
86300bce3fbSAlain Michaud 						ERR_DATA_REPORTING_DISABLED;
86400bce3fbSAlain Michaud 
86500bce3fbSAlain Michaud 			hci_req_add(req, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING,
86600bce3fbSAlain Michaud 				    sizeof(cp), &cp);
86700bce3fbSAlain Michaud 		}
86800bce3fbSAlain Michaud 	}
86900bce3fbSAlain Michaud 
87012204875SMarcel Holtmann 	/* Set Suggested Default Data Length to maximum if supported */
87112204875SMarcel Holtmann 	if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
87212204875SMarcel Holtmann 		struct hci_cp_le_write_def_data_len cp;
87312204875SMarcel Holtmann 
874727ea61aSBen Dooks (Codethink) 		cp.tx_len = cpu_to_le16(hdev->le_max_tx_len);
875727ea61aSBen Dooks (Codethink) 		cp.tx_time = cpu_to_le16(hdev->le_max_tx_time);
87612204875SMarcel Holtmann 		hci_req_add(req, HCI_OP_LE_WRITE_DEF_DATA_LEN, sizeof(cp), &cp);
87712204875SMarcel Holtmann 	}
87812204875SMarcel Holtmann 
879de2ba303SMarcel Holtmann 	/* Set Default PHY parameters if command is supported */
880de2ba303SMarcel Holtmann 	if (hdev->commands[35] & 0x20) {
881de2ba303SMarcel Holtmann 		struct hci_cp_le_set_default_phy cp;
882de2ba303SMarcel Holtmann 
8836decb5b4SJaganath Kanakkassery 		cp.all_phys = 0x00;
8846decb5b4SJaganath Kanakkassery 		cp.tx_phys = hdev->le_tx_def_phys;
8856decb5b4SJaganath Kanakkassery 		cp.rx_phys = hdev->le_rx_def_phys;
886de2ba303SMarcel Holtmann 
887de2ba303SMarcel Holtmann 		hci_req_add(req, HCI_OP_LE_SET_DEFAULT_PHY, sizeof(cp), &cp);
888de2ba303SMarcel Holtmann 	}
889de2ba303SMarcel Holtmann 
890a1d01db1SJohan Hedberg 	return 0;
8915d4e7e8dSJohan Hedberg }
8925d4e7e8dSJohan Hedberg 
8932177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
8942177bab5SJohan Hedberg {
8952177bab5SJohan Hedberg 	int err;
8962177bab5SJohan Hedberg 
8974ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT, NULL);
8982177bab5SJohan Hedberg 	if (err < 0)
8992177bab5SJohan Hedberg 		return err;
9002177bab5SJohan Hedberg 
901f640ee98SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP))
902f640ee98SMarcel Holtmann 		hci_debugfs_create_basic(hdev);
9034b4148e9SMarcel Holtmann 
9044ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT, NULL);
9052177bab5SJohan Hedberg 	if (err < 0)
9062177bab5SJohan Hedberg 		return err;
9072177bab5SJohan Hedberg 
908ca8bee5dSMarcel Holtmann 	/* HCI_PRIMARY covers both single-mode LE, BR/EDR and dual-mode
9090af801b9SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
9100af801b9SJohan Hedberg 	 * first two stages of init.
9110af801b9SJohan Hedberg 	 */
912ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY)
9130af801b9SJohan Hedberg 		return 0;
9140af801b9SJohan Hedberg 
9154ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT, NULL);
9165d4e7e8dSJohan Hedberg 	if (err < 0)
9175d4e7e8dSJohan Hedberg 		return err;
9185d4e7e8dSJohan Hedberg 
9194ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT, NULL);
920baf27f6eSMarcel Holtmann 	if (err < 0)
921baf27f6eSMarcel Holtmann 		return err;
922baf27f6eSMarcel Holtmann 
923ec6cef9cSMarcel Holtmann 	/* This function is only called when the controller is actually in
924ec6cef9cSMarcel Holtmann 	 * configured state. When the controller is marked as unconfigured,
925ec6cef9cSMarcel Holtmann 	 * this initialization procedure is not run.
926ec6cef9cSMarcel Holtmann 	 *
927ec6cef9cSMarcel Holtmann 	 * It means that it is possible that a controller runs through its
928ec6cef9cSMarcel Holtmann 	 * setup phase and then discovers missing settings. If that is the
929ec6cef9cSMarcel Holtmann 	 * case, then this function will not be called. It then will only
930ec6cef9cSMarcel Holtmann 	 * be called during the config phase.
931ec6cef9cSMarcel Holtmann 	 *
932ec6cef9cSMarcel Holtmann 	 * So only when in setup phase or config phase, create the debugfs
933ec6cef9cSMarcel Holtmann 	 * entries and register the SMP channels.
934baf27f6eSMarcel Holtmann 	 */
935d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
936d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG))
937baf27f6eSMarcel Holtmann 		return 0;
938baf27f6eSMarcel Holtmann 
93960c5f5fbSMarcel Holtmann 	hci_debugfs_create_common(hdev);
94060c5f5fbSMarcel Holtmann 
94171c3b60eSMarcel Holtmann 	if (lmp_bredr_capable(hdev))
94260c5f5fbSMarcel Holtmann 		hci_debugfs_create_bredr(hdev);
9432bfa3531SMarcel Holtmann 
944162a3bacSMarcel Holtmann 	if (lmp_le_capable(hdev))
94560c5f5fbSMarcel Holtmann 		hci_debugfs_create_le(hdev);
946e7b8fc92SMarcel Holtmann 
947baf27f6eSMarcel Holtmann 	return 0;
9482177bab5SJohan Hedberg }
9492177bab5SJohan Hedberg 
950a1d01db1SJohan Hedberg static int hci_init0_req(struct hci_request *req, unsigned long opt)
9510ebca7d6SMarcel Holtmann {
9520ebca7d6SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
9530ebca7d6SMarcel Holtmann 
9540ebca7d6SMarcel Holtmann 	BT_DBG("%s %ld", hdev->name, opt);
9550ebca7d6SMarcel Holtmann 
9560ebca7d6SMarcel Holtmann 	/* Reset */
9570ebca7d6SMarcel Holtmann 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
9580ebca7d6SMarcel Holtmann 		hci_reset_req(req, 0);
9590ebca7d6SMarcel Holtmann 
9600ebca7d6SMarcel Holtmann 	/* Read Local Version */
9610ebca7d6SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
9620ebca7d6SMarcel Holtmann 
9630ebca7d6SMarcel Holtmann 	/* Read BD Address */
9640ebca7d6SMarcel Holtmann 	if (hdev->set_bdaddr)
9650ebca7d6SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
966a1d01db1SJohan Hedberg 
967a1d01db1SJohan Hedberg 	return 0;
9680ebca7d6SMarcel Holtmann }
9690ebca7d6SMarcel Holtmann 
9700ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev)
9710ebca7d6SMarcel Holtmann {
9720ebca7d6SMarcel Holtmann 	int err;
9730ebca7d6SMarcel Holtmann 
974cc78b44bSMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
975cc78b44bSMarcel Holtmann 		return 0;
976cc78b44bSMarcel Holtmann 
9774ebeee2dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT, NULL);
9780ebca7d6SMarcel Holtmann 	if (err < 0)
9790ebca7d6SMarcel Holtmann 		return err;
9800ebca7d6SMarcel Holtmann 
981f640ee98SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP))
982f640ee98SMarcel Holtmann 		hci_debugfs_create_basic(hdev);
983f640ee98SMarcel Holtmann 
9840ebca7d6SMarcel Holtmann 	return 0;
9850ebca7d6SMarcel Holtmann }
9860ebca7d6SMarcel Holtmann 
987a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt)
9881da177e4SLinus Torvalds {
9891da177e4SLinus Torvalds 	__u8 scan = opt;
9901da177e4SLinus Torvalds 
99142c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
9921da177e4SLinus Torvalds 
9931da177e4SLinus Torvalds 	/* Inquiry and Page scans */
99442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
995a1d01db1SJohan Hedberg 	return 0;
9961da177e4SLinus Torvalds }
9971da177e4SLinus Torvalds 
998a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt)
9991da177e4SLinus Torvalds {
10001da177e4SLinus Torvalds 	__u8 auth = opt;
10011da177e4SLinus Torvalds 
100242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
10031da177e4SLinus Torvalds 
10041da177e4SLinus Torvalds 	/* Authentication */
100542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
1006a1d01db1SJohan Hedberg 	return 0;
10071da177e4SLinus Torvalds }
10081da177e4SLinus Torvalds 
1009a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt)
10101da177e4SLinus Torvalds {
10111da177e4SLinus Torvalds 	__u8 encrypt = opt;
10121da177e4SLinus Torvalds 
101342c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
10141da177e4SLinus Torvalds 
1015e4e8e37cSMarcel Holtmann 	/* Encryption */
101642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
1017a1d01db1SJohan Hedberg 	return 0;
10181da177e4SLinus Torvalds }
10191da177e4SLinus Torvalds 
1020a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt)
1021e4e8e37cSMarcel Holtmann {
1022e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
1023e4e8e37cSMarcel Holtmann 
102442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
1025e4e8e37cSMarcel Holtmann 
1026e4e8e37cSMarcel Holtmann 	/* Default link policy */
102742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
1028a1d01db1SJohan Hedberg 	return 0;
1029e4e8e37cSMarcel Holtmann }
1030e4e8e37cSMarcel Holtmann 
10311da177e4SLinus Torvalds /* Get HCI device by index.
10321da177e4SLinus Torvalds  * Device is held on return. */
10331da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
10341da177e4SLinus Torvalds {
10358035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
10361da177e4SLinus Torvalds 
10371da177e4SLinus Torvalds 	BT_DBG("%d", index);
10381da177e4SLinus Torvalds 
10391da177e4SLinus Torvalds 	if (index < 0)
10401da177e4SLinus Torvalds 		return NULL;
10411da177e4SLinus Torvalds 
10421da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
10438035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
10441da177e4SLinus Torvalds 		if (d->id == index) {
10451da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
10461da177e4SLinus Torvalds 			break;
10471da177e4SLinus Torvalds 		}
10481da177e4SLinus Torvalds 	}
10491da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
10501da177e4SLinus Torvalds 	return hdev;
10511da177e4SLinus Torvalds }
10521da177e4SLinus Torvalds 
10531da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1054ff9ef578SJohan Hedberg 
105530dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
105630dc78e1SJohan Hedberg {
105730dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
105830dc78e1SJohan Hedberg 
10596fbe195dSAndre Guedes 	switch (discov->state) {
1060343f935bSAndre Guedes 	case DISCOVERY_FINDING:
10616fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
106230dc78e1SJohan Hedberg 		return true;
106330dc78e1SJohan Hedberg 
10646fbe195dSAndre Guedes 	default:
106530dc78e1SJohan Hedberg 		return false;
106630dc78e1SJohan Hedberg 	}
10676fbe195dSAndre Guedes }
106830dc78e1SJohan Hedberg 
1069ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1070ff9ef578SJohan Hedberg {
1071bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
1072bb3e0a33SJohan Hedberg 
1073ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1074ff9ef578SJohan Hedberg 
1075bb3e0a33SJohan Hedberg 	if (old_state == state)
1076ff9ef578SJohan Hedberg 		return;
1077ff9ef578SJohan Hedberg 
1078bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
1079bb3e0a33SJohan Hedberg 
1080ff9ef578SJohan Hedberg 	switch (state) {
1081ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1082c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
1083c54c3860SAndre Guedes 
1084bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
1085ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1086ff9ef578SJohan Hedberg 		break;
1087ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1088ff9ef578SJohan Hedberg 		break;
1089343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1090ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1091ff9ef578SJohan Hedberg 		break;
109230dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
109330dc78e1SJohan Hedberg 		break;
1094ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1095ff9ef578SJohan Hedberg 		break;
1096ff9ef578SJohan Hedberg 	}
1097ff9ef578SJohan Hedberg }
1098ff9ef578SJohan Hedberg 
10991f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
11001da177e4SLinus Torvalds {
110130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1102b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
11031da177e4SLinus Torvalds 
1104561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
1105561aafbcSJohan Hedberg 		list_del(&p->all);
1106b57c1a56SJohan Hedberg 		kfree(p);
11071da177e4SLinus Torvalds 	}
1108561aafbcSJohan Hedberg 
1109561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
1110561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
11111da177e4SLinus Torvalds }
11121da177e4SLinus Torvalds 
1113a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
1114a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
11151da177e4SLinus Torvalds {
111630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
11171da177e4SLinus Torvalds 	struct inquiry_entry *e;
11181da177e4SLinus Torvalds 
11196ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
11201da177e4SLinus Torvalds 
1121561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
11221da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
11231da177e4SLinus Torvalds 			return e;
11241da177e4SLinus Torvalds 	}
11251da177e4SLinus Torvalds 
1126b57c1a56SJohan Hedberg 	return NULL;
1127b57c1a56SJohan Hedberg }
1128b57c1a56SJohan Hedberg 
1129561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
1130561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
1131561aafbcSJohan Hedberg {
113230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1133561aafbcSJohan Hedberg 	struct inquiry_entry *e;
1134561aafbcSJohan Hedberg 
11356ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1136561aafbcSJohan Hedberg 
1137561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
1138561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
1139561aafbcSJohan Hedberg 			return e;
1140561aafbcSJohan Hedberg 	}
1141561aafbcSJohan Hedberg 
1142561aafbcSJohan Hedberg 	return NULL;
1143561aafbcSJohan Hedberg }
1144561aafbcSJohan Hedberg 
114530dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
114630dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
114730dc78e1SJohan Hedberg 						       int state)
114830dc78e1SJohan Hedberg {
114930dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
115030dc78e1SJohan Hedberg 	struct inquiry_entry *e;
115130dc78e1SJohan Hedberg 
11526ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
115330dc78e1SJohan Hedberg 
115430dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
115530dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
115630dc78e1SJohan Hedberg 			return e;
115730dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
115830dc78e1SJohan Hedberg 			return e;
115930dc78e1SJohan Hedberg 	}
116030dc78e1SJohan Hedberg 
116130dc78e1SJohan Hedberg 	return NULL;
116230dc78e1SJohan Hedberg }
116330dc78e1SJohan Hedberg 
1164a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
1165a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
1166a3d4e20aSJohan Hedberg {
1167a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1168a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
1169a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
1170a3d4e20aSJohan Hedberg 
1171a3d4e20aSJohan Hedberg 	list_del(&ie->list);
1172a3d4e20aSJohan Hedberg 
1173a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
1174a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
1175a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
1176a3d4e20aSJohan Hedberg 			break;
1177a3d4e20aSJohan Hedberg 		pos = &p->list;
1178a3d4e20aSJohan Hedberg 	}
1179a3d4e20aSJohan Hedberg 
1180a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
1181a3d4e20aSJohan Hedberg }
1182a3d4e20aSJohan Hedberg 
1183af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
1184af58925cSMarcel Holtmann 			     bool name_known)
11851da177e4SLinus Torvalds {
118630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
118770f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
1188af58925cSMarcel Holtmann 	u32 flags = 0;
11891da177e4SLinus Torvalds 
11906ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
11911da177e4SLinus Torvalds 
11926928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
11932b2fec4dSSzymon Janc 
1194af58925cSMarcel Holtmann 	if (!data->ssp_mode)
1195af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1196388fc8faSJohan Hedberg 
119770f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
1198a3d4e20aSJohan Hedberg 	if (ie) {
1199af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
1200af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1201388fc8faSJohan Hedberg 
1202a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
1203a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
1204a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
1205a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
1206a3d4e20aSJohan Hedberg 		}
1207a3d4e20aSJohan Hedberg 
1208561aafbcSJohan Hedberg 		goto update;
1209a3d4e20aSJohan Hedberg 	}
1210561aafbcSJohan Hedberg 
12111da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
121227f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
1213af58925cSMarcel Holtmann 	if (!ie) {
1214af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
1215af58925cSMarcel Holtmann 		goto done;
1216af58925cSMarcel Holtmann 	}
121770f23020SAndrei Emeltchenko 
1218561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
1219561aafbcSJohan Hedberg 
1220561aafbcSJohan Hedberg 	if (name_known) {
1221561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1222561aafbcSJohan Hedberg 	} else {
1223561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
1224561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
1225561aafbcSJohan Hedberg 	}
1226561aafbcSJohan Hedberg 
1227561aafbcSJohan Hedberg update:
1228561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
1229561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
1230561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1231561aafbcSJohan Hedberg 		list_del(&ie->list);
12321da177e4SLinus Torvalds 	}
12331da177e4SLinus Torvalds 
123470f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
123570f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
12361da177e4SLinus Torvalds 	cache->timestamp = jiffies;
12373175405bSJohan Hedberg 
12383175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
1239af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
12403175405bSJohan Hedberg 
1241af58925cSMarcel Holtmann done:
1242af58925cSMarcel Holtmann 	return flags;
12431da177e4SLinus Torvalds }
12441da177e4SLinus Torvalds 
12451da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
12461da177e4SLinus Torvalds {
124730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
12481da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
12491da177e4SLinus Torvalds 	struct inquiry_entry *e;
12501da177e4SLinus Torvalds 	int copied = 0;
12511da177e4SLinus Torvalds 
1252561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
12531da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
1254b57c1a56SJohan Hedberg 
1255b57c1a56SJohan Hedberg 		if (copied >= num)
1256b57c1a56SJohan Hedberg 			break;
1257b57c1a56SJohan Hedberg 
12581da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
12591da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
12601da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
12611da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
12621da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
12631da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1264b57c1a56SJohan Hedberg 
12651da177e4SLinus Torvalds 		info++;
1266b57c1a56SJohan Hedberg 		copied++;
12671da177e4SLinus Torvalds 	}
12681da177e4SLinus Torvalds 
12691da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
12701da177e4SLinus Torvalds 	return copied;
12711da177e4SLinus Torvalds }
12721da177e4SLinus Torvalds 
1273a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt)
12741da177e4SLinus Torvalds {
12751da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
127642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
12771da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
12781da177e4SLinus Torvalds 
12791da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
12801da177e4SLinus Torvalds 
12811da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
1282a1d01db1SJohan Hedberg 		return 0;
12831da177e4SLinus Torvalds 
12841da177e4SLinus Torvalds 	/* Start Inquiry */
12851da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
12861da177e4SLinus Torvalds 	cp.length  = ir->length;
12871da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
128842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
1289a1d01db1SJohan Hedberg 
1290a1d01db1SJohan Hedberg 	return 0;
12911da177e4SLinus Torvalds }
12921da177e4SLinus Torvalds 
12931da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
12941da177e4SLinus Torvalds {
12951da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
12961da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
12971da177e4SLinus Torvalds 	struct hci_dev *hdev;
12981da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
12991da177e4SLinus Torvalds 	long timeo;
13001da177e4SLinus Torvalds 	__u8 *buf;
13011da177e4SLinus Torvalds 
13021da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
13031da177e4SLinus Torvalds 		return -EFAULT;
13041da177e4SLinus Torvalds 
13055a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
13065a08ecceSAndrei Emeltchenko 	if (!hdev)
13071da177e4SLinus Torvalds 		return -ENODEV;
13081da177e4SLinus Torvalds 
1309d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
13100736cfa8SMarcel Holtmann 		err = -EBUSY;
13110736cfa8SMarcel Holtmann 		goto done;
13120736cfa8SMarcel Holtmann 	}
13130736cfa8SMarcel Holtmann 
1314d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1315fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1316fee746b0SMarcel Holtmann 		goto done;
1317fee746b0SMarcel Holtmann 	}
1318fee746b0SMarcel Holtmann 
1319ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
13205b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
13215b69bef5SMarcel Holtmann 		goto done;
13225b69bef5SMarcel Holtmann 	}
13235b69bef5SMarcel Holtmann 
1324d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
132556f87901SJohan Hedberg 		err = -EOPNOTSUPP;
132656f87901SJohan Hedberg 		goto done;
132756f87901SJohan Hedberg 	}
132856f87901SJohan Hedberg 
132909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13301da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1331a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
13321f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
13331da177e4SLinus Torvalds 		do_inquiry = 1;
13341da177e4SLinus Torvalds 	}
133509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13361da177e4SLinus Torvalds 
133704837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
133870f23020SAndrei Emeltchenko 
133970f23020SAndrei Emeltchenko 	if (do_inquiry) {
134001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
13414ebeee2dSJohan Hedberg 				   timeo, NULL);
134270f23020SAndrei Emeltchenko 		if (err < 0)
13431da177e4SLinus Torvalds 			goto done;
13443e13fa1eSAndre Guedes 
13453e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
13463e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
13473e13fa1eSAndre Guedes 		 */
134874316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
13493e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
13503e13fa1eSAndre Guedes 			return -EINTR;
135170f23020SAndrei Emeltchenko 	}
13521da177e4SLinus Torvalds 
13538fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
13548fc9ced3SGustavo Padovan 	 * 255 entries
13558fc9ced3SGustavo Padovan 	 */
13561da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
13571da177e4SLinus Torvalds 
13581da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
13591da177e4SLinus Torvalds 	 * copy it to the user space.
13601da177e4SLinus Torvalds 	 */
13616da2ec56SKees Cook 	buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL);
136270f23020SAndrei Emeltchenko 	if (!buf) {
13631da177e4SLinus Torvalds 		err = -ENOMEM;
13641da177e4SLinus Torvalds 		goto done;
13651da177e4SLinus Torvalds 	}
13661da177e4SLinus Torvalds 
136709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13681da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
136909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13701da177e4SLinus Torvalds 
13711da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
13721da177e4SLinus Torvalds 
13731da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
13741da177e4SLinus Torvalds 		ptr += sizeof(ir);
13751da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
13761da177e4SLinus Torvalds 				 ir.num_rsp))
13771da177e4SLinus Torvalds 			err = -EFAULT;
13781da177e4SLinus Torvalds 	} else
13791da177e4SLinus Torvalds 		err = -EFAULT;
13801da177e4SLinus Torvalds 
13811da177e4SLinus Torvalds 	kfree(buf);
13821da177e4SLinus Torvalds 
13831da177e4SLinus Torvalds done:
13841da177e4SLinus Torvalds 	hci_dev_put(hdev);
13851da177e4SLinus Torvalds 	return err;
13861da177e4SLinus Torvalds }
13871da177e4SLinus Torvalds 
13887a0e5b15SMatthias Kaehlcke /**
13897a0e5b15SMatthias Kaehlcke  * hci_dev_get_bd_addr_from_property - Get the Bluetooth Device Address
13907a0e5b15SMatthias Kaehlcke  *				       (BD_ADDR) for a HCI device from
13917a0e5b15SMatthias Kaehlcke  *				       a firmware node property.
13927a0e5b15SMatthias Kaehlcke  * @hdev:	The HCI device
13937a0e5b15SMatthias Kaehlcke  *
13947a0e5b15SMatthias Kaehlcke  * Search the firmware node for 'local-bd-address'.
13957a0e5b15SMatthias Kaehlcke  *
13967a0e5b15SMatthias Kaehlcke  * All-zero BD addresses are rejected, because those could be properties
13977a0e5b15SMatthias Kaehlcke  * that exist in the firmware tables, but were not updated by the firmware. For
13987a0e5b15SMatthias Kaehlcke  * example, the DTS could define 'local-bd-address', with zero BD addresses.
13997a0e5b15SMatthias Kaehlcke  */
14007a0e5b15SMatthias Kaehlcke static void hci_dev_get_bd_addr_from_property(struct hci_dev *hdev)
14017a0e5b15SMatthias Kaehlcke {
14027a0e5b15SMatthias Kaehlcke 	struct fwnode_handle *fwnode = dev_fwnode(hdev->dev.parent);
14037a0e5b15SMatthias Kaehlcke 	bdaddr_t ba;
14047a0e5b15SMatthias Kaehlcke 	int ret;
14057a0e5b15SMatthias Kaehlcke 
14067a0e5b15SMatthias Kaehlcke 	ret = fwnode_property_read_u8_array(fwnode, "local-bd-address",
14077a0e5b15SMatthias Kaehlcke 					    (u8 *)&ba, sizeof(ba));
14087a0e5b15SMatthias Kaehlcke 	if (ret < 0 || !bacmp(&ba, BDADDR_ANY))
14097a0e5b15SMatthias Kaehlcke 		return;
14107a0e5b15SMatthias Kaehlcke 
14117a0e5b15SMatthias Kaehlcke 	bacpy(&hdev->public_addr, &ba);
14127a0e5b15SMatthias Kaehlcke }
14137a0e5b15SMatthias Kaehlcke 
1414cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
14151da177e4SLinus Torvalds {
14161da177e4SLinus Torvalds 	int ret = 0;
14171da177e4SLinus Torvalds 
14181da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
14191da177e4SLinus Torvalds 
1420b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
14211da177e4SLinus Torvalds 
1422d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
142394324962SJohan Hovold 		ret = -ENODEV;
142494324962SJohan Hovold 		goto done;
142594324962SJohan Hovold 	}
142694324962SJohan Hovold 
1427d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1428d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
1429a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1430a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1431bf543036SJohan Hedberg 		 */
1432d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
1433611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1434611b30f7SMarcel Holtmann 			goto done;
1435611b30f7SMarcel Holtmann 		}
1436611b30f7SMarcel Holtmann 
1437a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1438a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1439a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1440a5c8f270SMarcel Holtmann 		 * or not.
1441a5c8f270SMarcel Holtmann 		 *
1442c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
1443c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
1444c6beca0eSMarcel Holtmann 		 * available.
1445c6beca0eSMarcel Holtmann 		 *
1446a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1447a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1448a5c8f270SMarcel Holtmann 		 */
1449d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1450ca8bee5dSMarcel Holtmann 		    hdev->dev_type == HCI_PRIMARY &&
1451a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1452a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1453a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1454a5c8f270SMarcel Holtmann 			goto done;
1455a5c8f270SMarcel Holtmann 		}
1456a5c8f270SMarcel Holtmann 	}
1457a5c8f270SMarcel Holtmann 
14581da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
14591da177e4SLinus Torvalds 		ret = -EALREADY;
14601da177e4SLinus Torvalds 		goto done;
14611da177e4SLinus Torvalds 	}
14621da177e4SLinus Torvalds 
14631da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
14641da177e4SLinus Torvalds 		ret = -EIO;
14651da177e4SLinus Torvalds 		goto done;
14661da177e4SLinus Torvalds 	}
14671da177e4SLinus Torvalds 
1468e9ca8bf1SMarcel Holtmann 	set_bit(HCI_RUNNING, &hdev->flags);
146905fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_OPEN);
14704a3f95b7SMarcel Holtmann 
14711da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
14721da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1473f41c70c4SMarcel Holtmann 
1474740011cfSSean Wang 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
1475740011cfSSean Wang 	    test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
14767fdf6c6aSMarcel Holtmann 		bool invalid_bdaddr;
14777fdf6c6aSMarcel Holtmann 
1478e131d74aSMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_SETUP);
1479e131d74aSMarcel Holtmann 
1480af202f84SMarcel Holtmann 		if (hdev->setup)
1481f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
1482f41c70c4SMarcel Holtmann 
14837fdf6c6aSMarcel Holtmann 		/* The transport driver can set the quirk to mark the
14847fdf6c6aSMarcel Holtmann 		 * BD_ADDR invalid before creating the HCI device or in
14857fdf6c6aSMarcel Holtmann 		 * its setup callback.
14867fdf6c6aSMarcel Holtmann 		 */
14877fdf6c6aSMarcel Holtmann 		invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR,
14887fdf6c6aSMarcel Holtmann 					  &hdev->quirks);
14897fdf6c6aSMarcel Holtmann 
14907a0e5b15SMatthias Kaehlcke 		if (ret)
14917a0e5b15SMatthias Kaehlcke 			goto setup_failed;
14927a0e5b15SMatthias Kaehlcke 
14937a0e5b15SMatthias Kaehlcke 		if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) {
14947a0e5b15SMatthias Kaehlcke 			if (!bacmp(&hdev->public_addr, BDADDR_ANY))
14957a0e5b15SMatthias Kaehlcke 				hci_dev_get_bd_addr_from_property(hdev);
14967a0e5b15SMatthias Kaehlcke 
14977a0e5b15SMatthias Kaehlcke 			if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
14987fdf6c6aSMarcel Holtmann 			    hdev->set_bdaddr) {
14997a0e5b15SMatthias Kaehlcke 				ret = hdev->set_bdaddr(hdev,
15007a0e5b15SMatthias Kaehlcke 						       &hdev->public_addr);
15017fdf6c6aSMarcel Holtmann 
15027fdf6c6aSMarcel Holtmann 				/* If setting of the BD_ADDR from the device
15037fdf6c6aSMarcel Holtmann 				 * property succeeds, then treat the address
15047fdf6c6aSMarcel Holtmann 				 * as valid even if the invalid BD_ADDR
15057fdf6c6aSMarcel Holtmann 				 * quirk indicates otherwise.
15067fdf6c6aSMarcel Holtmann 				 */
15077fdf6c6aSMarcel Holtmann 				if (!ret)
15087fdf6c6aSMarcel Holtmann 					invalid_bdaddr = false;
15097fdf6c6aSMarcel Holtmann 			}
15107a0e5b15SMatthias Kaehlcke 		}
15117a0e5b15SMatthias Kaehlcke 
15127a0e5b15SMatthias Kaehlcke setup_failed:
1513af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
1514af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
1515af202f84SMarcel Holtmann 		 *
15167fdf6c6aSMarcel Holtmann 		 * For the invalid BD_ADDR quirk it is possible that
15177fdf6c6aSMarcel Holtmann 		 * it becomes a valid address if the bootloader does
15187fdf6c6aSMarcel Holtmann 		 * provide it (see above).
15197fdf6c6aSMarcel Holtmann 		 *
1520af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
1521af202f84SMarcel Holtmann 		 * start up as unconfigured.
1522af202f84SMarcel Holtmann 		 */
1523eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
15247fdf6c6aSMarcel Holtmann 		    invalid_bdaddr)
1525a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
1526f41c70c4SMarcel Holtmann 
15270ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
15280ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
15290ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
15300ebca7d6SMarcel Holtmann 		 *
15310ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
15320ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
15330ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
15340ebca7d6SMarcel Holtmann 		 */
1535d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
15360ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
153789bc22d2SMarcel Holtmann 	}
153889bc22d2SMarcel Holtmann 
1539d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_CONFIG)) {
15409713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
15419713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
15429713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
15439713c17bSMarcel Holtmann 		 * on procedure.
154424c457e2SMarcel Holtmann 		 */
15459713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
15469713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
154724c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
154824c457e2SMarcel Holtmann 		else
154924c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
155024c457e2SMarcel Holtmann 	}
155124c457e2SMarcel Holtmann 
1552f41c70c4SMarcel Holtmann 	if (!ret) {
1553d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
155498a63aafSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
15552177bab5SJohan Hedberg 			ret = __hci_init(hdev);
155698a63aafSMarcel Holtmann 			if (!ret && hdev->post_init)
155798a63aafSMarcel Holtmann 				ret = hdev->post_init(hdev);
155898a63aafSMarcel Holtmann 		}
15591da177e4SLinus Torvalds 	}
15601da177e4SLinus Torvalds 
15617e995b9eSMarcel Holtmann 	/* If the HCI Reset command is clearing all diagnostic settings,
15627e995b9eSMarcel Holtmann 	 * then they need to be reprogrammed after the init procedure
15637e995b9eSMarcel Holtmann 	 * completed.
15647e995b9eSMarcel Holtmann 	 */
15657e995b9eSMarcel Holtmann 	if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
1566b56c7b25SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
15677e995b9eSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
15687e995b9eSMarcel Holtmann 		ret = hdev->set_diag(hdev, true);
15697e995b9eSMarcel Holtmann 
1570145373cbSMiao-chen Chou 	msft_do_open(hdev);
1571145373cbSMiao-chen Chou 
1572f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1573f41c70c4SMarcel Holtmann 
15741da177e4SLinus Torvalds 	if (!ret) {
15751da177e4SLinus Torvalds 		hci_dev_hold(hdev);
1576a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
1577a73c046aSJaganath Kanakkassery 		hci_adv_instances_set_rpa_expired(hdev, true);
15781da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
157905fcd4c4SMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_UP);
15806d5d2ee6SHeiner Kallweit 		hci_leds_update_powered(hdev, true);
1581d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1582d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG) &&
1583d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1584d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
15852ff13894SJohan Hedberg 		    hci_dev_test_flag(hdev, HCI_MGMT) &&
1586ca8bee5dSMarcel Holtmann 		    hdev->dev_type == HCI_PRIMARY) {
15872ff13894SJohan Hedberg 			ret = __hci_req_hci_power_on(hdev);
15882ff13894SJohan Hedberg 			mgmt_power_on(hdev, ret);
158956e5cb86SJohan Hedberg 		}
15901da177e4SLinus Torvalds 	} else {
15911da177e4SLinus Torvalds 		/* Init failed, cleanup */
15923eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1593c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1594b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
15951da177e4SLinus Torvalds 
15961da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
15971da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
15981da177e4SLinus Torvalds 
15991da177e4SLinus Torvalds 		if (hdev->flush)
16001da177e4SLinus Torvalds 			hdev->flush(hdev);
16011da177e4SLinus Torvalds 
16021da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
16031da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
16041da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
16051da177e4SLinus Torvalds 		}
16061da177e4SLinus Torvalds 
1607e9ca8bf1SMarcel Holtmann 		clear_bit(HCI_RUNNING, &hdev->flags);
160805fcd4c4SMarcel Holtmann 		hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
16094a3f95b7SMarcel Holtmann 
16101da177e4SLinus Torvalds 		hdev->close(hdev);
1611fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
16121da177e4SLinus Torvalds 	}
16131da177e4SLinus Torvalds 
16141da177e4SLinus Torvalds done:
1615b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
16161da177e4SLinus Torvalds 	return ret;
16171da177e4SLinus Torvalds }
16181da177e4SLinus Torvalds 
1619cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1620cbed0ca1SJohan Hedberg 
1621cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1622cbed0ca1SJohan Hedberg {
1623cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1624cbed0ca1SJohan Hedberg 	int err;
1625cbed0ca1SJohan Hedberg 
1626cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1627cbed0ca1SJohan Hedberg 	if (!hdev)
1628cbed0ca1SJohan Hedberg 		return -ENODEV;
1629cbed0ca1SJohan Hedberg 
16304a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
1631fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
1632fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
1633fee746b0SMarcel Holtmann 	 * possible.
1634fee746b0SMarcel Holtmann 	 *
1635fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
1636fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
1637fee746b0SMarcel Holtmann 	 * open the device.
1638fee746b0SMarcel Holtmann 	 */
1639d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1640d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1641fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1642fee746b0SMarcel Holtmann 		goto done;
1643fee746b0SMarcel Holtmann 	}
1644fee746b0SMarcel Holtmann 
1645e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
1646e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
1647e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
1648e1d08f40SJohan Hedberg 	 * completed.
1649e1d08f40SJohan Hedberg 	 */
1650a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
1651e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
1652e1d08f40SJohan Hedberg 
1653a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
1654a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
1655a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
1656a5c8f270SMarcel Holtmann 	 */
1657e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
1658e1d08f40SJohan Hedberg 
165912aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
1660b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
166112aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
166212aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
166312aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
166412aa4f0aSMarcel Holtmann 	 */
1665d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1666d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
1667a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
166812aa4f0aSMarcel Holtmann 
1669cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
1670cbed0ca1SJohan Hedberg 
1671fee746b0SMarcel Holtmann done:
1672cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
1673cbed0ca1SJohan Hedberg 	return err;
1674cbed0ca1SJohan Hedberg }
1675cbed0ca1SJohan Hedberg 
1676d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
1677d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
1678d7347f3cSJohan Hedberg {
1679d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
1680d7347f3cSJohan Hedberg 
1681f161dd41SJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list) {
1682f161dd41SJohan Hedberg 		if (p->conn) {
1683f161dd41SJohan Hedberg 			hci_conn_drop(p->conn);
1684f8aaf9b6SJohan Hedberg 			hci_conn_put(p->conn);
1685f161dd41SJohan Hedberg 			p->conn = NULL;
1686f161dd41SJohan Hedberg 		}
1687d7347f3cSJohan Hedberg 		list_del_init(&p->action);
1688f161dd41SJohan Hedberg 	}
1689d7347f3cSJohan Hedberg 
1690d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
1691d7347f3cSJohan Hedberg }
1692d7347f3cSJohan Hedberg 
16936b3cc1dbSSimon Fels int hci_dev_do_close(struct hci_dev *hdev)
16941da177e4SLinus Torvalds {
1695acc649c6SMarcel Holtmann 	bool auto_off;
1696acc649c6SMarcel Holtmann 
16971da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
16981da177e4SLinus Torvalds 
1699d24d8144SGabriele Mazzotta 	if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
1700867146a0SLoic Poulain 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1701d24d8144SGabriele Mazzotta 	    test_bit(HCI_UP, &hdev->flags)) {
1702a44fecbdSTedd Ho-Jeong An 		/* Execute vendor specific shutdown routine */
1703a44fecbdSTedd Ho-Jeong An 		if (hdev->shutdown)
1704a44fecbdSTedd Ho-Jeong An 			hdev->shutdown(hdev);
1705a44fecbdSTedd Ho-Jeong An 	}
1706a44fecbdSTedd Ho-Jeong An 
170778c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
170878c04c0bSVinicius Costa Gomes 
17097df0f73eSJohan Hedberg 	hci_request_cancel_all(hdev);
1710b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
17111da177e4SLinus Torvalds 
17121da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
171365cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
1714b504430cSJohan Hedberg 		hci_req_sync_unlock(hdev);
17151da177e4SLinus Torvalds 		return 0;
17161da177e4SLinus Torvalds 	}
17171da177e4SLinus Torvalds 
17186d5d2ee6SHeiner Kallweit 	hci_leds_update_powered(hdev, false);
17196d5d2ee6SHeiner Kallweit 
17203eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
17213eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1722b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
17231da177e4SLinus Torvalds 
172416ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
172516ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
1726a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
1727a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
172816ab91abSJohan Hedberg 	}
172916ab91abSJohan Hedberg 
1730a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
17317d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
17327d78525dSJohan Hedberg 
1733a73c046aSJaganath Kanakkassery 	if (hci_dev_test_flag(hdev, HCI_MGMT)) {
1734a73c046aSJaganath Kanakkassery 		struct adv_info *adv_instance;
1735a73c046aSJaganath Kanakkassery 
1736d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
17377ba8b4beSAndre Guedes 
1738a73c046aSJaganath Kanakkassery 		list_for_each_entry(adv_instance, &hdev->adv_instances, list)
1739a73c046aSJaganath Kanakkassery 			cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1740a73c046aSJaganath Kanakkassery 	}
1741a73c046aSJaganath Kanakkassery 
174276727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
174376727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
174476727c02SJohan Hedberg 	 */
174576727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
174676727c02SJohan Hedberg 
174709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
17481aeb9c65SJohan Hedberg 
17498f502f84SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
17508f502f84SJohan Hedberg 
1751acc649c6SMarcel Holtmann 	auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF);
1752acc649c6SMarcel Holtmann 
1753ca8bee5dSMarcel Holtmann 	if (!auto_off && hdev->dev_type == HCI_PRIMARY &&
1754baab7932SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
17552ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT))
17562ff13894SJohan Hedberg 		__mgmt_power_off(hdev);
17571aeb9c65SJohan Hedberg 
17581f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
1759d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
1760f161dd41SJohan Hedberg 	hci_conn_hash_flush(hdev);
176109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
17621da177e4SLinus Torvalds 
176364dae967SMarcel Holtmann 	smp_unregister(hdev);
176464dae967SMarcel Holtmann 
176505fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_DOWN);
17661da177e4SLinus Torvalds 
1767145373cbSMiao-chen Chou 	msft_do_close(hdev);
1768145373cbSMiao-chen Chou 
17691da177e4SLinus Torvalds 	if (hdev->flush)
17701da177e4SLinus Torvalds 		hdev->flush(hdev);
17711da177e4SLinus Torvalds 
17721da177e4SLinus Torvalds 	/* Reset device */
17731da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
17741da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
1775acc649c6SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) &&
1776acc649c6SMarcel Holtmann 	    !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
17771da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
17784ebeee2dSJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL);
17791da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
17801da177e4SLinus Torvalds 	}
17811da177e4SLinus Torvalds 
1782c347b765SGustavo F. Padovan 	/* flush cmd  work */
1783c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
17841da177e4SLinus Torvalds 
17851da177e4SLinus Torvalds 	/* Drop queues */
17861da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
17871da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
17881da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
17891da177e4SLinus Torvalds 
17901da177e4SLinus Torvalds 	/* Drop last sent command */
17911da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
179265cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
17931da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
17941da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
17951da177e4SLinus Torvalds 	}
17961da177e4SLinus Torvalds 
1797e9ca8bf1SMarcel Holtmann 	clear_bit(HCI_RUNNING, &hdev->flags);
179805fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
17994a3f95b7SMarcel Holtmann 
18009952d90eSAbhishek Pandit-Subedi 	if (test_and_clear_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks))
18019952d90eSAbhishek Pandit-Subedi 		wake_up(&hdev->suspend_wait_q);
18029952d90eSAbhishek Pandit-Subedi 
18031da177e4SLinus Torvalds 	/* After this point our queues are empty
18041da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
18051da177e4SLinus Torvalds 	hdev->close(hdev);
18061da177e4SLinus Torvalds 
180735b973c9SJohan Hedberg 	/* Clear flags */
1808fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
1809eacb44dfSMarcel Holtmann 	hci_dev_clear_volatile_flags(hdev);
181035b973c9SJohan Hedberg 
1811ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1812536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1813ced5c338SAndrei Emeltchenko 
1814e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
181509b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
18167a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
1817e59fda8dSJohan Hedberg 
1818b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
18191da177e4SLinus Torvalds 
18201da177e4SLinus Torvalds 	hci_dev_put(hdev);
18211da177e4SLinus Torvalds 	return 0;
18221da177e4SLinus Torvalds }
18231da177e4SLinus Torvalds 
18241da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
18251da177e4SLinus Torvalds {
18261da177e4SLinus Torvalds 	struct hci_dev *hdev;
18271da177e4SLinus Torvalds 	int err;
18281da177e4SLinus Torvalds 
182970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
183070f23020SAndrei Emeltchenko 	if (!hdev)
18311da177e4SLinus Torvalds 		return -ENODEV;
18328ee56540SMarcel Holtmann 
1833d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
18340736cfa8SMarcel Holtmann 		err = -EBUSY;
18350736cfa8SMarcel Holtmann 		goto done;
18360736cfa8SMarcel Holtmann 	}
18370736cfa8SMarcel Holtmann 
1838a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
18398ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
18408ee56540SMarcel Holtmann 
18411da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
18428ee56540SMarcel Holtmann 
18430736cfa8SMarcel Holtmann done:
18441da177e4SLinus Torvalds 	hci_dev_put(hdev);
18451da177e4SLinus Torvalds 	return err;
18461da177e4SLinus Torvalds }
18471da177e4SLinus Torvalds 
18485c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
18491da177e4SLinus Torvalds {
18505c912495SMarcel Holtmann 	int ret;
18511da177e4SLinus Torvalds 
18525c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
18531da177e4SLinus Torvalds 
1854b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
18551da177e4SLinus Torvalds 
18561da177e4SLinus Torvalds 	/* Drop queues */
18571da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
18581da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
18591da177e4SLinus Torvalds 
186076727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
186176727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
186276727c02SJohan Hedberg 	 */
186376727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
186476727c02SJohan Hedberg 
186509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
18661f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
18671da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
186809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
18691da177e4SLinus Torvalds 
18701da177e4SLinus Torvalds 	if (hdev->flush)
18711da177e4SLinus Torvalds 		hdev->flush(hdev);
18721da177e4SLinus Torvalds 
18731da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
18746ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
18751da177e4SLinus Torvalds 
18764ebeee2dSJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT, NULL);
18771da177e4SLinus Torvalds 
1878b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
18791da177e4SLinus Torvalds 	return ret;
18801da177e4SLinus Torvalds }
18811da177e4SLinus Torvalds 
18825c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
18835c912495SMarcel Holtmann {
18845c912495SMarcel Holtmann 	struct hci_dev *hdev;
18855c912495SMarcel Holtmann 	int err;
18865c912495SMarcel Holtmann 
18875c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
18885c912495SMarcel Holtmann 	if (!hdev)
18895c912495SMarcel Holtmann 		return -ENODEV;
18905c912495SMarcel Holtmann 
18915c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
18925c912495SMarcel Holtmann 		err = -ENETDOWN;
18935c912495SMarcel Holtmann 		goto done;
18945c912495SMarcel Holtmann 	}
18955c912495SMarcel Holtmann 
1896d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
18975c912495SMarcel Holtmann 		err = -EBUSY;
18985c912495SMarcel Holtmann 		goto done;
18995c912495SMarcel Holtmann 	}
19005c912495SMarcel Holtmann 
1901d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
19025c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
19035c912495SMarcel Holtmann 		goto done;
19045c912495SMarcel Holtmann 	}
19055c912495SMarcel Holtmann 
19065c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
19075c912495SMarcel Holtmann 
19085c912495SMarcel Holtmann done:
19095c912495SMarcel Holtmann 	hci_dev_put(hdev);
19105c912495SMarcel Holtmann 	return err;
19115c912495SMarcel Holtmann }
19125c912495SMarcel Holtmann 
19131da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
19141da177e4SLinus Torvalds {
19151da177e4SLinus Torvalds 	struct hci_dev *hdev;
19161da177e4SLinus Torvalds 	int ret = 0;
19171da177e4SLinus Torvalds 
191870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
191970f23020SAndrei Emeltchenko 	if (!hdev)
19201da177e4SLinus Torvalds 		return -ENODEV;
19211da177e4SLinus Torvalds 
1922d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
19230736cfa8SMarcel Holtmann 		ret = -EBUSY;
19240736cfa8SMarcel Holtmann 		goto done;
19250736cfa8SMarcel Holtmann 	}
19260736cfa8SMarcel Holtmann 
1927d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1928fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
1929fee746b0SMarcel Holtmann 		goto done;
1930fee746b0SMarcel Holtmann 	}
1931fee746b0SMarcel Holtmann 
19321da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
19331da177e4SLinus Torvalds 
19340736cfa8SMarcel Holtmann done:
19351da177e4SLinus Torvalds 	hci_dev_put(hdev);
19361da177e4SLinus Torvalds 	return ret;
19371da177e4SLinus Torvalds }
19381da177e4SLinus Torvalds 
1939123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
1940123abc08SJohan Hedberg {
1941bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
1942123abc08SJohan Hedberg 
1943123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
1944123abc08SJohan Hedberg 
1945123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
1946238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
1947238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
1948123abc08SJohan Hedberg 	else
1949a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
1950a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
1951123abc08SJohan Hedberg 
1952bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
1953238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
1954238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
1955bc6d2d04SJohan Hedberg 	} else {
1956a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1957a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
1958a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
1959bc6d2d04SJohan Hedberg 	}
1960bc6d2d04SJohan Hedberg 
1961d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
1962123abc08SJohan Hedberg 		return;
1963123abc08SJohan Hedberg 
1964bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
1965bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
1966a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
1967bc6d2d04SJohan Hedberg 
1968d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
1969cab054abSJohan Hedberg 			hci_req_update_adv_data(hdev, hdev->cur_adv_instance);
1970bc6d2d04SJohan Hedberg 
1971123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
1972123abc08SJohan Hedberg 	}
1973bc6d2d04SJohan Hedberg }
1974123abc08SJohan Hedberg 
19751da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
19761da177e4SLinus Torvalds {
19771da177e4SLinus Torvalds 	struct hci_dev *hdev;
19781da177e4SLinus Torvalds 	struct hci_dev_req dr;
19791da177e4SLinus Torvalds 	int err = 0;
19801da177e4SLinus Torvalds 
19811da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
19821da177e4SLinus Torvalds 		return -EFAULT;
19831da177e4SLinus Torvalds 
198470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
198570f23020SAndrei Emeltchenko 	if (!hdev)
19861da177e4SLinus Torvalds 		return -ENODEV;
19871da177e4SLinus Torvalds 
1988d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
19890736cfa8SMarcel Holtmann 		err = -EBUSY;
19900736cfa8SMarcel Holtmann 		goto done;
19910736cfa8SMarcel Holtmann 	}
19920736cfa8SMarcel Holtmann 
1993d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1994fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1995fee746b0SMarcel Holtmann 		goto done;
1996fee746b0SMarcel Holtmann 	}
1997fee746b0SMarcel Holtmann 
1998ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
19995b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
20005b69bef5SMarcel Holtmann 		goto done;
20015b69bef5SMarcel Holtmann 	}
20025b69bef5SMarcel Holtmann 
2003d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
200456f87901SJohan Hedberg 		err = -EOPNOTSUPP;
200556f87901SJohan Hedberg 		goto done;
200656f87901SJohan Hedberg 	}
200756f87901SJohan Hedberg 
20081da177e4SLinus Torvalds 	switch (cmd) {
20091da177e4SLinus Torvalds 	case HCISETAUTH:
201001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
20114ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20121da177e4SLinus Torvalds 		break;
20131da177e4SLinus Torvalds 
20141da177e4SLinus Torvalds 	case HCISETENCRYPT:
20151da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
20161da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
20171da177e4SLinus Torvalds 			break;
20181da177e4SLinus Torvalds 		}
20191da177e4SLinus Torvalds 
20201da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
20211da177e4SLinus Torvalds 			/* Auth must be enabled first */
202201178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
20234ebeee2dSJohan Hedberg 					   HCI_INIT_TIMEOUT, NULL);
20241da177e4SLinus Torvalds 			if (err)
20251da177e4SLinus Torvalds 				break;
20261da177e4SLinus Torvalds 		}
20271da177e4SLinus Torvalds 
202801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
20294ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20301da177e4SLinus Torvalds 		break;
20311da177e4SLinus Torvalds 
20321da177e4SLinus Torvalds 	case HCISETSCAN:
203301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
20344ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
203591a668b0SJohan Hedberg 
2036bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
2037bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
203891a668b0SJohan Hedberg 		 */
2039123abc08SJohan Hedberg 		if (!err)
2040123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
20411da177e4SLinus Torvalds 		break;
20421da177e4SLinus Torvalds 
20431da177e4SLinus Torvalds 	case HCISETLINKPOL:
204401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
20454ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
20461da177e4SLinus Torvalds 		break;
20471da177e4SLinus Torvalds 
20481da177e4SLinus Torvalds 	case HCISETLINKMODE:
2049e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2050e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2051e4e8e37cSMarcel Holtmann 		break;
2052e4e8e37cSMarcel Holtmann 
2053e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2054b7c23df8SJaganath Kanakkassery 		if (hdev->pkt_type == (__u16) dr.dev_opt)
2055b7c23df8SJaganath Kanakkassery 			break;
2056b7c23df8SJaganath Kanakkassery 
2057e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
2058b7c23df8SJaganath Kanakkassery 		mgmt_phy_configuration_changed(hdev, NULL);
20591da177e4SLinus Torvalds 		break;
20601da177e4SLinus Torvalds 
20611da177e4SLinus Torvalds 	case HCISETACLMTU:
20621da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
20631da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
20641da177e4SLinus Torvalds 		break;
20651da177e4SLinus Torvalds 
20661da177e4SLinus Torvalds 	case HCISETSCOMTU:
20671da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
20681da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
20691da177e4SLinus Torvalds 		break;
20701da177e4SLinus Torvalds 
20711da177e4SLinus Torvalds 	default:
20721da177e4SLinus Torvalds 		err = -EINVAL;
20731da177e4SLinus Torvalds 		break;
20741da177e4SLinus Torvalds 	}
2075e4e8e37cSMarcel Holtmann 
20760736cfa8SMarcel Holtmann done:
20771da177e4SLinus Torvalds 	hci_dev_put(hdev);
20781da177e4SLinus Torvalds 	return err;
20791da177e4SLinus Torvalds }
20801da177e4SLinus Torvalds 
20811da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
20821da177e4SLinus Torvalds {
20838035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
20841da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
20851da177e4SLinus Torvalds 	struct hci_dev_req *dr;
20861da177e4SLinus Torvalds 	int n = 0, size, err;
20871da177e4SLinus Torvalds 	__u16 dev_num;
20881da177e4SLinus Torvalds 
20891da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
20901da177e4SLinus Torvalds 		return -EFAULT;
20911da177e4SLinus Torvalds 
20921da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
20931da177e4SLinus Torvalds 		return -EINVAL;
20941da177e4SLinus Torvalds 
20951da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
20961da177e4SLinus Torvalds 
209770f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
209870f23020SAndrei Emeltchenko 	if (!dl)
20991da177e4SLinus Torvalds 		return -ENOMEM;
21001da177e4SLinus Torvalds 
21011da177e4SLinus Torvalds 	dr = dl->dev_req;
21021da177e4SLinus Torvalds 
2103f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
21048035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
21052e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
2106c542a06cSJohan Hedberg 
21072e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
21082e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
21092e84d8dbSMarcel Holtmann 		 * device is actually down.
21102e84d8dbSMarcel Holtmann 		 */
2111d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
21122e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
2113c542a06cSJohan Hedberg 
21141da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
21152e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
2116c542a06cSJohan Hedberg 
21171da177e4SLinus Torvalds 		if (++n >= dev_num)
21181da177e4SLinus Torvalds 			break;
21191da177e4SLinus Torvalds 	}
2120f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
21211da177e4SLinus Torvalds 
21221da177e4SLinus Torvalds 	dl->dev_num = n;
21231da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
21241da177e4SLinus Torvalds 
21251da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
21261da177e4SLinus Torvalds 	kfree(dl);
21271da177e4SLinus Torvalds 
21281da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
21291da177e4SLinus Torvalds }
21301da177e4SLinus Torvalds 
21311da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
21321da177e4SLinus Torvalds {
21331da177e4SLinus Torvalds 	struct hci_dev *hdev;
21341da177e4SLinus Torvalds 	struct hci_dev_info di;
21352e84d8dbSMarcel Holtmann 	unsigned long flags;
21361da177e4SLinus Torvalds 	int err = 0;
21371da177e4SLinus Torvalds 
21381da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
21391da177e4SLinus Torvalds 		return -EFAULT;
21401da177e4SLinus Torvalds 
214170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
214270f23020SAndrei Emeltchenko 	if (!hdev)
21431da177e4SLinus Torvalds 		return -ENODEV;
21441da177e4SLinus Torvalds 
21452e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
21462e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
21472e84d8dbSMarcel Holtmann 	 * device is actually down.
21482e84d8dbSMarcel Holtmann 	 */
2149d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
21502e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
21512e84d8dbSMarcel Holtmann 	else
21522e84d8dbSMarcel Holtmann 		flags = hdev->flags;
2153c542a06cSJohan Hedberg 
21541da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
21551da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
215660f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
21572e84d8dbSMarcel Holtmann 	di.flags    = flags;
21581da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2159572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
21601da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
21611da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
21621da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
21631da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2164572c7f84SJohan Hedberg 	} else {
2165572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2166572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2167572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2168572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2169572c7f84SJohan Hedberg 	}
21701da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
21711da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
21721da177e4SLinus Torvalds 
21731da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
21741da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
21751da177e4SLinus Torvalds 
21761da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
21771da177e4SLinus Torvalds 		err = -EFAULT;
21781da177e4SLinus Torvalds 
21791da177e4SLinus Torvalds 	hci_dev_put(hdev);
21801da177e4SLinus Torvalds 
21811da177e4SLinus Torvalds 	return err;
21821da177e4SLinus Torvalds }
21831da177e4SLinus Torvalds 
21841da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
21851da177e4SLinus Torvalds 
2186611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2187611b30f7SMarcel Holtmann {
2188611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2189611b30f7SMarcel Holtmann 
2190611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2191611b30f7SMarcel Holtmann 
2192d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
21930736cfa8SMarcel Holtmann 		return -EBUSY;
21940736cfa8SMarcel Holtmann 
21955e130367SJohan Hedberg 	if (blocked) {
2196a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
2197d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
2198d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
2199611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
22005e130367SJohan Hedberg 	} else {
2201a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
22025e130367SJohan Hedberg 	}
2203611b30f7SMarcel Holtmann 
2204611b30f7SMarcel Holtmann 	return 0;
2205611b30f7SMarcel Holtmann }
2206611b30f7SMarcel Holtmann 
2207611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2208611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2209611b30f7SMarcel Holtmann };
2210611b30f7SMarcel Holtmann 
2211ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2212ab81cbf9SJohan Hedberg {
2213ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
221496570ffcSJohan Hedberg 	int err;
2215ab81cbf9SJohan Hedberg 
2216ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2217ab81cbf9SJohan Hedberg 
22182ff13894SJohan Hedberg 	if (test_bit(HCI_UP, &hdev->flags) &&
22192ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT) &&
22202ff13894SJohan Hedberg 	    hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
2221d82142a8SWei-Ning Huang 		cancel_delayed_work(&hdev->power_off);
22222ff13894SJohan Hedberg 		hci_req_sync_lock(hdev);
22232ff13894SJohan Hedberg 		err = __hci_req_hci_power_on(hdev);
22242ff13894SJohan Hedberg 		hci_req_sync_unlock(hdev);
22252ff13894SJohan Hedberg 		mgmt_power_on(hdev, err);
22262ff13894SJohan Hedberg 		return;
22272ff13894SJohan Hedberg 	}
22282ff13894SJohan Hedberg 
2229cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
223096570ffcSJohan Hedberg 	if (err < 0) {
22313ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
223296570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
22333ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
2234ab81cbf9SJohan Hedberg 		return;
223596570ffcSJohan Hedberg 	}
2236ab81cbf9SJohan Hedberg 
2237a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2238a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2239a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2240a5c8f270SMarcel Holtmann 	 */
2241d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
2242d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
2243ca8bee5dSMarcel Holtmann 	    (hdev->dev_type == HCI_PRIMARY &&
2244a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2245a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2246a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
2247bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2248d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
224919202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
225019202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2251bf543036SJohan Hedberg 	}
2252ab81cbf9SJohan Hedberg 
2253a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
22544a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
22554a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
22564a964404SMarcel Holtmann 		 */
2257d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
22584a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
22590602a8adSMarcel Holtmann 
22600602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
22610602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
22620602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
22630602a8adSMarcel Holtmann 		 *
22640602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
22650602a8adSMarcel Holtmann 		 * and no event will be send.
22660602a8adSMarcel Holtmann 		 */
2267744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2268a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
22695ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
22705ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
22715ea234d3SMarcel Holtmann 		 */
2272d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
22735ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
22745ea234d3SMarcel Holtmann 
2275d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
2276d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
2277d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
2278d603b76bSMarcel Holtmann 		 */
2279d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
2280ab81cbf9SJohan Hedberg 	}
2281ab81cbf9SJohan Hedberg }
2282ab81cbf9SJohan Hedberg 
2283ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2284ab81cbf9SJohan Hedberg {
22853243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
22863243553fSJohan Hedberg 					    power_off.work);
2287ab81cbf9SJohan Hedberg 
2288ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2289ab81cbf9SJohan Hedberg 
22908ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2291ab81cbf9SJohan Hedberg }
2292ab81cbf9SJohan Hedberg 
2293c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
2294c7741d16SMarcel Holtmann {
2295c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
2296c7741d16SMarcel Holtmann 
2297c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2298c7741d16SMarcel Holtmann 
2299c7741d16SMarcel Holtmann 	if (hdev->hw_error)
2300c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
2301c7741d16SMarcel Holtmann 	else
23022064ee33SMarcel Holtmann 		bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
2303c7741d16SMarcel Holtmann 
2304c7741d16SMarcel Holtmann 	if (hci_dev_do_close(hdev))
2305c7741d16SMarcel Holtmann 		return;
2306c7741d16SMarcel Holtmann 
2307c7741d16SMarcel Holtmann 	hci_dev_do_open(hdev);
2308c7741d16SMarcel Holtmann }
2309c7741d16SMarcel Holtmann 
231035f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
23112aeb9a1aSJohan Hedberg {
23124821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
23132aeb9a1aSJohan Hedberg 
23144821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
23154821002cSJohan Hedberg 		list_del(&uuid->list);
23162aeb9a1aSJohan Hedberg 		kfree(uuid);
23172aeb9a1aSJohan Hedberg 	}
23182aeb9a1aSJohan Hedberg }
23192aeb9a1aSJohan Hedberg 
232035f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
232155ed8ca1SJohan Hedberg {
232255ed8ca1SJohan Hedberg 	struct link_key *key;
232355ed8ca1SJohan Hedberg 
2324d7d41682SMadhuparna Bhowmik 	list_for_each_entry(key, &hdev->link_keys, list) {
23250378b597SJohan Hedberg 		list_del_rcu(&key->list);
23260378b597SJohan Hedberg 		kfree_rcu(key, rcu);
232755ed8ca1SJohan Hedberg 	}
232855ed8ca1SJohan Hedberg }
232955ed8ca1SJohan Hedberg 
233035f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2331b899efafSVinicius Costa Gomes {
2332970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2333b899efafSVinicius Costa Gomes 
2334d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->long_term_keys, list) {
2335970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2336970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2337b899efafSVinicius Costa Gomes 	}
2338b899efafSVinicius Costa Gomes }
2339b899efafSVinicius Costa Gomes 
2340970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2341970c4e46SJohan Hedberg {
2342adae20cbSJohan Hedberg 	struct smp_irk *k;
2343970c4e46SJohan Hedberg 
2344d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->identity_resolving_keys, list) {
2345adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2346adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2347970c4e46SJohan Hedberg 	}
2348970c4e46SJohan Hedberg }
2349970c4e46SJohan Hedberg 
2350600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev)
2351600a8749SAlain Michaud {
2352600a8749SAlain Michaud 	struct blocked_key *b;
2353600a8749SAlain Michaud 
2354d7d41682SMadhuparna Bhowmik 	list_for_each_entry(b, &hdev->blocked_keys, list) {
2355600a8749SAlain Michaud 		list_del_rcu(&b->list);
2356600a8749SAlain Michaud 		kfree_rcu(b, rcu);
2357600a8749SAlain Michaud 	}
2358600a8749SAlain Michaud }
2359600a8749SAlain Michaud 
2360600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16])
2361600a8749SAlain Michaud {
2362600a8749SAlain Michaud 	bool blocked = false;
2363600a8749SAlain Michaud 	struct blocked_key *b;
2364600a8749SAlain Michaud 
2365600a8749SAlain Michaud 	rcu_read_lock();
23660c2ac7d4SMadhuparna Bhowmik 	list_for_each_entry_rcu(b, &hdev->blocked_keys, list) {
2367600a8749SAlain Michaud 		if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) {
2368600a8749SAlain Michaud 			blocked = true;
2369600a8749SAlain Michaud 			break;
2370600a8749SAlain Michaud 		}
2371600a8749SAlain Michaud 	}
2372600a8749SAlain Michaud 
2373600a8749SAlain Michaud 	rcu_read_unlock();
2374600a8749SAlain Michaud 	return blocked;
2375600a8749SAlain Michaud }
2376600a8749SAlain Michaud 
237755ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
237855ed8ca1SJohan Hedberg {
237955ed8ca1SJohan Hedberg 	struct link_key *k;
238055ed8ca1SJohan Hedberg 
23810378b597SJohan Hedberg 	rcu_read_lock();
23820378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
23830378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
23840378b597SJohan Hedberg 			rcu_read_unlock();
2385600a8749SAlain Michaud 
2386600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev,
2387600a8749SAlain Michaud 					       HCI_BLOCKED_KEY_TYPE_LINKKEY,
2388600a8749SAlain Michaud 					       k->val)) {
2389600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
2390600a8749SAlain Michaud 							"Link key blocked for %pMR",
2391600a8749SAlain Michaud 							&k->bdaddr);
2392600a8749SAlain Michaud 				return NULL;
2393600a8749SAlain Michaud 			}
2394600a8749SAlain Michaud 
239555ed8ca1SJohan Hedberg 			return k;
23960378b597SJohan Hedberg 		}
23970378b597SJohan Hedberg 	}
23980378b597SJohan Hedberg 	rcu_read_unlock();
239955ed8ca1SJohan Hedberg 
240055ed8ca1SJohan Hedberg 	return NULL;
240155ed8ca1SJohan Hedberg }
240255ed8ca1SJohan Hedberg 
2403745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2404d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2405d25e28abSJohan Hedberg {
2406d25e28abSJohan Hedberg 	/* Legacy key */
2407d25e28abSJohan Hedberg 	if (key_type < 0x03)
2408745c0ce3SVishal Agarwal 		return true;
2409d25e28abSJohan Hedberg 
2410d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2411d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2412745c0ce3SVishal Agarwal 		return false;
2413d25e28abSJohan Hedberg 
2414d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2415d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2416745c0ce3SVishal Agarwal 		return false;
2417d25e28abSJohan Hedberg 
2418d25e28abSJohan Hedberg 	/* Security mode 3 case */
2419d25e28abSJohan Hedberg 	if (!conn)
2420745c0ce3SVishal Agarwal 		return true;
2421d25e28abSJohan Hedberg 
2422e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
2423e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
2424e3befab9SJohan Hedberg 		return true;
2425e3befab9SJohan Hedberg 
2426d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2427d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2428745c0ce3SVishal Agarwal 		return true;
2429d25e28abSJohan Hedberg 
2430d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2431d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2432745c0ce3SVishal Agarwal 		return true;
2433d25e28abSJohan Hedberg 
2434d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2435d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2436745c0ce3SVishal Agarwal 		return true;
2437d25e28abSJohan Hedberg 
2438d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2439d25e28abSJohan Hedberg 	 * persistently */
2440745c0ce3SVishal Agarwal 	return false;
2441d25e28abSJohan Hedberg }
2442d25e28abSJohan Hedberg 
2443e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
244498a0b845SJohan Hedberg {
2445e804d25dSJohan Hedberg 	if (type == SMP_LTK)
2446e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
244798a0b845SJohan Hedberg 
2448e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
244998a0b845SJohan Hedberg }
245098a0b845SJohan Hedberg 
2451f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2452e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
245375d262c2SVinicius Costa Gomes {
2454c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
245575d262c2SVinicius Costa Gomes 
2456970d0f1bSJohan Hedberg 	rcu_read_lock();
2457970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
24585378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
24595378bc56SJohan Hedberg 			continue;
24605378bc56SJohan Hedberg 
2461923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
2462970d0f1bSJohan Hedberg 			rcu_read_unlock();
2463600a8749SAlain Michaud 
2464600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK,
2465600a8749SAlain Michaud 					       k->val)) {
2466600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
2467600a8749SAlain Michaud 							"LTK blocked for %pMR",
2468600a8749SAlain Michaud 							&k->bdaddr);
2469600a8749SAlain Michaud 				return NULL;
2470600a8749SAlain Michaud 			}
2471600a8749SAlain Michaud 
247275d262c2SVinicius Costa Gomes 			return k;
2473970d0f1bSJohan Hedberg 		}
2474970d0f1bSJohan Hedberg 	}
2475970d0f1bSJohan Hedberg 	rcu_read_unlock();
247675d262c2SVinicius Costa Gomes 
247775d262c2SVinicius Costa Gomes 	return NULL;
247875d262c2SVinicius Costa Gomes }
247975d262c2SVinicius Costa Gomes 
2480970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2481970c4e46SJohan Hedberg {
2482600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
2483970c4e46SJohan Hedberg 	struct smp_irk *irk;
2484970c4e46SJohan Hedberg 
2485adae20cbSJohan Hedberg 	rcu_read_lock();
2486adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2487adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
2488600a8749SAlain Michaud 			irk_to_return = irk;
2489600a8749SAlain Michaud 			goto done;
2490970c4e46SJohan Hedberg 		}
2491adae20cbSJohan Hedberg 	}
2492970c4e46SJohan Hedberg 
2493adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2494defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
2495970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
2496600a8749SAlain Michaud 			irk_to_return = irk;
2497600a8749SAlain Michaud 			goto done;
2498970c4e46SJohan Hedberg 		}
2499970c4e46SJohan Hedberg 	}
2500600a8749SAlain Michaud 
2501600a8749SAlain Michaud done:
2502600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
2503600a8749SAlain Michaud 						irk_to_return->val)) {
2504600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
2505600a8749SAlain Michaud 					&irk_to_return->bdaddr);
2506600a8749SAlain Michaud 		irk_to_return = NULL;
2507600a8749SAlain Michaud 	}
2508600a8749SAlain Michaud 
2509adae20cbSJohan Hedberg 	rcu_read_unlock();
2510970c4e46SJohan Hedberg 
2511600a8749SAlain Michaud 	return irk_to_return;
2512970c4e46SJohan Hedberg }
2513970c4e46SJohan Hedberg 
2514970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2515970c4e46SJohan Hedberg 				     u8 addr_type)
2516970c4e46SJohan Hedberg {
2517600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
2518970c4e46SJohan Hedberg 	struct smp_irk *irk;
2519970c4e46SJohan Hedberg 
25206cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
25216cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
25226cfc9988SJohan Hedberg 		return NULL;
25236cfc9988SJohan Hedberg 
2524adae20cbSJohan Hedberg 	rcu_read_lock();
2525adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2526970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
2527adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
2528600a8749SAlain Michaud 			irk_to_return = irk;
2529600a8749SAlain Michaud 			goto done;
2530970c4e46SJohan Hedberg 		}
2531adae20cbSJohan Hedberg 	}
2532600a8749SAlain Michaud 
2533600a8749SAlain Michaud done:
2534600a8749SAlain Michaud 
2535600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
2536600a8749SAlain Michaud 						irk_to_return->val)) {
2537600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
2538600a8749SAlain Michaud 					&irk_to_return->bdaddr);
2539600a8749SAlain Michaud 		irk_to_return = NULL;
2540600a8749SAlain Michaud 	}
2541600a8749SAlain Michaud 
2542adae20cbSJohan Hedberg 	rcu_read_unlock();
2543970c4e46SJohan Hedberg 
2544600a8749SAlain Michaud 	return irk_to_return;
2545970c4e46SJohan Hedberg }
2546970c4e46SJohan Hedberg 
2547567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
25487652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
25497652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
255055ed8ca1SJohan Hedberg {
255155ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2552745c0ce3SVishal Agarwal 	u8 old_key_type;
255355ed8ca1SJohan Hedberg 
255455ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
255555ed8ca1SJohan Hedberg 	if (old_key) {
255655ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
255755ed8ca1SJohan Hedberg 		key = old_key;
255855ed8ca1SJohan Hedberg 	} else {
255912adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
25600a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
256155ed8ca1SJohan Hedberg 		if (!key)
2562567fa2aaSJohan Hedberg 			return NULL;
25630378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
256455ed8ca1SJohan Hedberg 	}
256555ed8ca1SJohan Hedberg 
25666ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
256755ed8ca1SJohan Hedberg 
2568d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2569d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2570d25e28abSJohan Hedberg 	 * previous key */
2571d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2572a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2573d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2574655fe6ecSJohan Hedberg 		if (conn)
2575655fe6ecSJohan Hedberg 			conn->key_type = type;
2576655fe6ecSJohan Hedberg 	}
2577d25e28abSJohan Hedberg 
257855ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
25799b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
258055ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
258155ed8ca1SJohan Hedberg 
2582b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
258355ed8ca1SJohan Hedberg 		key->type = old_key_type;
25844748fed2SJohan Hedberg 	else
25854748fed2SJohan Hedberg 		key->type = type;
25864748fed2SJohan Hedberg 
25877652ff6aSJohan Hedberg 	if (persistent)
25887652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
25897652ff6aSJohan Hedberg 						 old_key_type);
25904df378a1SJohan Hedberg 
2591567fa2aaSJohan Hedberg 	return key;
259255ed8ca1SJohan Hedberg }
259355ed8ca1SJohan Hedberg 
2594ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
259535d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
2596fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
259775d262c2SVinicius Costa Gomes {
2598c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
2599e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
260075d262c2SVinicius Costa Gomes 
2601f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
2602c9839a11SVinicius Costa Gomes 	if (old_key)
260375d262c2SVinicius Costa Gomes 		key = old_key;
2604c9839a11SVinicius Costa Gomes 	else {
26050a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
260675d262c2SVinicius Costa Gomes 		if (!key)
2607ca9142b8SJohan Hedberg 			return NULL;
2608970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
260975d262c2SVinicius Costa Gomes 	}
261075d262c2SVinicius Costa Gomes 
261175d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2612c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2613c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2614c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2615c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2616fe39c7b2SMarcel Holtmann 	key->rand = rand;
2617c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2618c9839a11SVinicius Costa Gomes 	key->type = type;
261975d262c2SVinicius Costa Gomes 
2620ca9142b8SJohan Hedberg 	return key;
262175d262c2SVinicius Costa Gomes }
262275d262c2SVinicius Costa Gomes 
2623ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2624ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
2625970c4e46SJohan Hedberg {
2626970c4e46SJohan Hedberg 	struct smp_irk *irk;
2627970c4e46SJohan Hedberg 
2628970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2629970c4e46SJohan Hedberg 	if (!irk) {
2630970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
2631970c4e46SJohan Hedberg 		if (!irk)
2632ca9142b8SJohan Hedberg 			return NULL;
2633970c4e46SJohan Hedberg 
2634970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
2635970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
2636970c4e46SJohan Hedberg 
2637adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
2638970c4e46SJohan Hedberg 	}
2639970c4e46SJohan Hedberg 
2640970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
2641970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
2642970c4e46SJohan Hedberg 
2643ca9142b8SJohan Hedberg 	return irk;
2644970c4e46SJohan Hedberg }
2645970c4e46SJohan Hedberg 
264655ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
264755ed8ca1SJohan Hedberg {
264855ed8ca1SJohan Hedberg 	struct link_key *key;
264955ed8ca1SJohan Hedberg 
265055ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
265155ed8ca1SJohan Hedberg 	if (!key)
265255ed8ca1SJohan Hedberg 		return -ENOENT;
265355ed8ca1SJohan Hedberg 
26546ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
265555ed8ca1SJohan Hedberg 
26560378b597SJohan Hedberg 	list_del_rcu(&key->list);
26570378b597SJohan Hedberg 	kfree_rcu(key, rcu);
265855ed8ca1SJohan Hedberg 
265955ed8ca1SJohan Hedberg 	return 0;
266055ed8ca1SJohan Hedberg }
266155ed8ca1SJohan Hedberg 
2662e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2663b899efafSVinicius Costa Gomes {
2664970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2665c51ffa0bSJohan Hedberg 	int removed = 0;
2666b899efafSVinicius Costa Gomes 
2667970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2668e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2669b899efafSVinicius Costa Gomes 			continue;
2670b899efafSVinicius Costa Gomes 
26716ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2672b899efafSVinicius Costa Gomes 
2673970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2674970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2675c51ffa0bSJohan Hedberg 		removed++;
2676b899efafSVinicius Costa Gomes 	}
2677b899efafSVinicius Costa Gomes 
2678c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
2679b899efafSVinicius Costa Gomes }
2680b899efafSVinicius Costa Gomes 
2681a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
2682a7ec7338SJohan Hedberg {
2683adae20cbSJohan Hedberg 	struct smp_irk *k;
2684a7ec7338SJohan Hedberg 
2685adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2686a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
2687a7ec7338SJohan Hedberg 			continue;
2688a7ec7338SJohan Hedberg 
2689a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2690a7ec7338SJohan Hedberg 
2691adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2692adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2693a7ec7338SJohan Hedberg 	}
2694a7ec7338SJohan Hedberg }
2695a7ec7338SJohan Hedberg 
269655e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
269755e76b38SJohan Hedberg {
269855e76b38SJohan Hedberg 	struct smp_ltk *k;
26994ba9faf3SJohan Hedberg 	struct smp_irk *irk;
270055e76b38SJohan Hedberg 	u8 addr_type;
270155e76b38SJohan Hedberg 
270255e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
270355e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
270455e76b38SJohan Hedberg 			return true;
270555e76b38SJohan Hedberg 		return false;
270655e76b38SJohan Hedberg 	}
270755e76b38SJohan Hedberg 
270855e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
270955e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
271055e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
271155e76b38SJohan Hedberg 	else
271255e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
271355e76b38SJohan Hedberg 
27144ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
27154ba9faf3SJohan Hedberg 	if (irk) {
27164ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
27174ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
27184ba9faf3SJohan Hedberg 	}
27194ba9faf3SJohan Hedberg 
272055e76b38SJohan Hedberg 	rcu_read_lock();
272155e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
272287c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
272387c8b28dSJohan Hedberg 			rcu_read_unlock();
272455e76b38SJohan Hedberg 			return true;
272555e76b38SJohan Hedberg 		}
272687c8b28dSJohan Hedberg 	}
272755e76b38SJohan Hedberg 	rcu_read_unlock();
272855e76b38SJohan Hedberg 
272955e76b38SJohan Hedberg 	return false;
273055e76b38SJohan Hedberg }
273155e76b38SJohan Hedberg 
27326bd32326SVille Tervo /* HCI command timer function */
273365cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
27346bd32326SVille Tervo {
273565cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
273665cc2b49SMarcel Holtmann 					    cmd_timer.work);
27376bd32326SVille Tervo 
2738bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2739bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2740bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2741bda4f23aSAndrei Emeltchenko 
27422064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
2743bda4f23aSAndrei Emeltchenko 	} else {
27442064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command tx timeout");
2745bda4f23aSAndrei Emeltchenko 	}
2746bda4f23aSAndrei Emeltchenko 
2747e2bef384SRajat Jain 	if (hdev->cmd_timeout)
2748e2bef384SRajat Jain 		hdev->cmd_timeout(hdev);
2749e2bef384SRajat Jain 
27506bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2751c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
27526bd32326SVille Tervo }
27536bd32326SVille Tervo 
27542763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
27556928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
27562763eda6SSzymon Janc {
27572763eda6SSzymon Janc 	struct oob_data *data;
27582763eda6SSzymon Janc 
27596928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
27606928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
27616928a924SJohan Hedberg 			continue;
27626928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
27636928a924SJohan Hedberg 			continue;
27642763eda6SSzymon Janc 		return data;
27656928a924SJohan Hedberg 	}
27662763eda6SSzymon Janc 
27672763eda6SSzymon Janc 	return NULL;
27682763eda6SSzymon Janc }
27692763eda6SSzymon Janc 
27706928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
27716928a924SJohan Hedberg 			       u8 bdaddr_type)
27722763eda6SSzymon Janc {
27732763eda6SSzymon Janc 	struct oob_data *data;
27742763eda6SSzymon Janc 
27756928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
27762763eda6SSzymon Janc 	if (!data)
27772763eda6SSzymon Janc 		return -ENOENT;
27782763eda6SSzymon Janc 
27796928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
27802763eda6SSzymon Janc 
27812763eda6SSzymon Janc 	list_del(&data->list);
27822763eda6SSzymon Janc 	kfree(data);
27832763eda6SSzymon Janc 
27842763eda6SSzymon Janc 	return 0;
27852763eda6SSzymon Janc }
27862763eda6SSzymon Janc 
278735f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
27882763eda6SSzymon Janc {
27892763eda6SSzymon Janc 	struct oob_data *data, *n;
27902763eda6SSzymon Janc 
27912763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
27922763eda6SSzymon Janc 		list_del(&data->list);
27932763eda6SSzymon Janc 		kfree(data);
27942763eda6SSzymon Janc 	}
27952763eda6SSzymon Janc }
27962763eda6SSzymon Janc 
27970798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
27986928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
279938da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
28000798872eSMarcel Holtmann {
28010798872eSMarcel Holtmann 	struct oob_data *data;
28020798872eSMarcel Holtmann 
28036928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
28040798872eSMarcel Holtmann 	if (!data) {
28050a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
28060798872eSMarcel Holtmann 		if (!data)
28070798872eSMarcel Holtmann 			return -ENOMEM;
28080798872eSMarcel Holtmann 
28090798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
28106928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
28110798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
28120798872eSMarcel Holtmann 	}
28130798872eSMarcel Holtmann 
281481328d5cSJohan Hedberg 	if (hash192 && rand192) {
28150798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
281638da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
2817f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2818f7697b16SMarcel Holtmann 			data->present = 0x03;
281981328d5cSJohan Hedberg 	} else {
282081328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
282181328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
2822f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2823f7697b16SMarcel Holtmann 			data->present = 0x02;
2824f7697b16SMarcel Holtmann 		else
2825f7697b16SMarcel Holtmann 			data->present = 0x00;
282681328d5cSJohan Hedberg 	}
28270798872eSMarcel Holtmann 
282881328d5cSJohan Hedberg 	if (hash256 && rand256) {
28290798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
283038da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
283181328d5cSJohan Hedberg 	} else {
283281328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
283381328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
2834f7697b16SMarcel Holtmann 		if (hash192 && rand192)
2835f7697b16SMarcel Holtmann 			data->present = 0x01;
283681328d5cSJohan Hedberg 	}
28370798872eSMarcel Holtmann 
28386ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
28392763eda6SSzymon Janc 
28402763eda6SSzymon Janc 	return 0;
28412763eda6SSzymon Janc }
28422763eda6SSzymon Janc 
2843d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2844d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
2845d2609b34SFlorian Grandel {
2846d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2847d2609b34SFlorian Grandel 
2848d2609b34SFlorian Grandel 	list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
2849d2609b34SFlorian Grandel 		if (adv_instance->instance == instance)
2850d2609b34SFlorian Grandel 			return adv_instance;
2851d2609b34SFlorian Grandel 	}
2852d2609b34SFlorian Grandel 
2853d2609b34SFlorian Grandel 	return NULL;
2854d2609b34SFlorian Grandel }
2855d2609b34SFlorian Grandel 
2856d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
285774b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
285874b93e9fSPrasanna Karthik {
2859d2609b34SFlorian Grandel 	struct adv_info *cur_instance;
2860d2609b34SFlorian Grandel 
2861d2609b34SFlorian Grandel 	cur_instance = hci_find_adv_instance(hdev, instance);
2862d2609b34SFlorian Grandel 	if (!cur_instance)
2863d2609b34SFlorian Grandel 		return NULL;
2864d2609b34SFlorian Grandel 
2865d2609b34SFlorian Grandel 	if (cur_instance == list_last_entry(&hdev->adv_instances,
2866d2609b34SFlorian Grandel 					    struct adv_info, list))
2867d2609b34SFlorian Grandel 		return list_first_entry(&hdev->adv_instances,
2868d2609b34SFlorian Grandel 						 struct adv_info, list);
2869d2609b34SFlorian Grandel 	else
2870d2609b34SFlorian Grandel 		return list_next_entry(cur_instance, list);
2871d2609b34SFlorian Grandel }
2872d2609b34SFlorian Grandel 
2873d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2874d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
2875d2609b34SFlorian Grandel {
2876d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2877d2609b34SFlorian Grandel 
2878d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
2879d2609b34SFlorian Grandel 	if (!adv_instance)
2880d2609b34SFlorian Grandel 		return -ENOENT;
2881d2609b34SFlorian Grandel 
2882d2609b34SFlorian Grandel 	BT_DBG("%s removing %dMR", hdev->name, instance);
2883d2609b34SFlorian Grandel 
2884cab054abSJohan Hedberg 	if (hdev->cur_adv_instance == instance) {
2885cab054abSJohan Hedberg 		if (hdev->adv_instance_timeout) {
28865d900e46SFlorian Grandel 			cancel_delayed_work(&hdev->adv_instance_expire);
28875d900e46SFlorian Grandel 			hdev->adv_instance_timeout = 0;
28885d900e46SFlorian Grandel 		}
2889cab054abSJohan Hedberg 		hdev->cur_adv_instance = 0x00;
2890cab054abSJohan Hedberg 	}
28915d900e46SFlorian Grandel 
2892a73c046aSJaganath Kanakkassery 	cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
2893a73c046aSJaganath Kanakkassery 
2894d2609b34SFlorian Grandel 	list_del(&adv_instance->list);
2895d2609b34SFlorian Grandel 	kfree(adv_instance);
2896d2609b34SFlorian Grandel 
2897d2609b34SFlorian Grandel 	hdev->adv_instance_cnt--;
2898d2609b34SFlorian Grandel 
2899d2609b34SFlorian Grandel 	return 0;
2900d2609b34SFlorian Grandel }
2901d2609b34SFlorian Grandel 
2902a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired)
2903a73c046aSJaganath Kanakkassery {
2904a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance, *n;
2905a73c046aSJaganath Kanakkassery 
2906a73c046aSJaganath Kanakkassery 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list)
2907a73c046aSJaganath Kanakkassery 		adv_instance->rpa_expired = rpa_expired;
2908a73c046aSJaganath Kanakkassery }
2909a73c046aSJaganath Kanakkassery 
2910d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2911d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev)
2912d2609b34SFlorian Grandel {
2913d2609b34SFlorian Grandel 	struct adv_info *adv_instance, *n;
2914d2609b34SFlorian Grandel 
29155d900e46SFlorian Grandel 	if (hdev->adv_instance_timeout) {
29165d900e46SFlorian Grandel 		cancel_delayed_work(&hdev->adv_instance_expire);
29175d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
29185d900e46SFlorian Grandel 	}
29195d900e46SFlorian Grandel 
2920d2609b34SFlorian Grandel 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
2921a73c046aSJaganath Kanakkassery 		cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
2922d2609b34SFlorian Grandel 		list_del(&adv_instance->list);
2923d2609b34SFlorian Grandel 		kfree(adv_instance);
2924d2609b34SFlorian Grandel 	}
2925d2609b34SFlorian Grandel 
2926d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
2927cab054abSJohan Hedberg 	hdev->cur_adv_instance = 0x00;
2928d2609b34SFlorian Grandel }
2929d2609b34SFlorian Grandel 
2930a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work)
2931a73c046aSJaganath Kanakkassery {
2932a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance = container_of(work, struct adv_info,
2933a73c046aSJaganath Kanakkassery 						     rpa_expired_cb.work);
2934a73c046aSJaganath Kanakkassery 
2935a73c046aSJaganath Kanakkassery 	BT_DBG("");
2936a73c046aSJaganath Kanakkassery 
2937a73c046aSJaganath Kanakkassery 	adv_instance->rpa_expired = true;
2938a73c046aSJaganath Kanakkassery }
2939a73c046aSJaganath Kanakkassery 
2940d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2941d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
2942d2609b34SFlorian Grandel 			 u16 adv_data_len, u8 *adv_data,
2943d2609b34SFlorian Grandel 			 u16 scan_rsp_len, u8 *scan_rsp_data,
2944d2609b34SFlorian Grandel 			 u16 timeout, u16 duration)
2945d2609b34SFlorian Grandel {
2946d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2947d2609b34SFlorian Grandel 
2948d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
2949d2609b34SFlorian Grandel 	if (adv_instance) {
2950d2609b34SFlorian Grandel 		memset(adv_instance->adv_data, 0,
2951d2609b34SFlorian Grandel 		       sizeof(adv_instance->adv_data));
2952d2609b34SFlorian Grandel 		memset(adv_instance->scan_rsp_data, 0,
2953d2609b34SFlorian Grandel 		       sizeof(adv_instance->scan_rsp_data));
2954d2609b34SFlorian Grandel 	} else {
29551d0fac2cSLuiz Augusto von Dentz 		if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
2956d2609b34SFlorian Grandel 		    instance < 1 || instance > HCI_MAX_ADV_INSTANCES)
2957d2609b34SFlorian Grandel 			return -EOVERFLOW;
2958d2609b34SFlorian Grandel 
295939ecfad6SJohan Hedberg 		adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL);
2960d2609b34SFlorian Grandel 		if (!adv_instance)
2961d2609b34SFlorian Grandel 			return -ENOMEM;
2962d2609b34SFlorian Grandel 
2963fffd38bcSFlorian Grandel 		adv_instance->pending = true;
2964d2609b34SFlorian Grandel 		adv_instance->instance = instance;
2965d2609b34SFlorian Grandel 		list_add(&adv_instance->list, &hdev->adv_instances);
2966d2609b34SFlorian Grandel 		hdev->adv_instance_cnt++;
2967d2609b34SFlorian Grandel 	}
2968d2609b34SFlorian Grandel 
2969d2609b34SFlorian Grandel 	adv_instance->flags = flags;
2970d2609b34SFlorian Grandel 	adv_instance->adv_data_len = adv_data_len;
2971d2609b34SFlorian Grandel 	adv_instance->scan_rsp_len = scan_rsp_len;
2972d2609b34SFlorian Grandel 
2973d2609b34SFlorian Grandel 	if (adv_data_len)
2974d2609b34SFlorian Grandel 		memcpy(adv_instance->adv_data, adv_data, adv_data_len);
2975d2609b34SFlorian Grandel 
2976d2609b34SFlorian Grandel 	if (scan_rsp_len)
2977d2609b34SFlorian Grandel 		memcpy(adv_instance->scan_rsp_data,
2978d2609b34SFlorian Grandel 		       scan_rsp_data, scan_rsp_len);
2979d2609b34SFlorian Grandel 
2980d2609b34SFlorian Grandel 	adv_instance->timeout = timeout;
29815d900e46SFlorian Grandel 	adv_instance->remaining_time = timeout;
2982d2609b34SFlorian Grandel 
2983d2609b34SFlorian Grandel 	if (duration == 0)
298410873f99SAlain Michaud 		adv_instance->duration = hdev->def_multi_adv_rotation_duration;
2985d2609b34SFlorian Grandel 	else
2986d2609b34SFlorian Grandel 		adv_instance->duration = duration;
2987d2609b34SFlorian Grandel 
2988de181e88SJaganath Kanakkassery 	adv_instance->tx_power = HCI_TX_POWER_INVALID;
2989de181e88SJaganath Kanakkassery 
2990a73c046aSJaganath Kanakkassery 	INIT_DELAYED_WORK(&adv_instance->rpa_expired_cb,
2991a73c046aSJaganath Kanakkassery 			  adv_instance_rpa_expired);
2992a73c046aSJaganath Kanakkassery 
2993d2609b34SFlorian Grandel 	BT_DBG("%s for %dMR", hdev->name, instance);
2994d2609b34SFlorian Grandel 
2995d2609b34SFlorian Grandel 	return 0;
2996d2609b34SFlorian Grandel }
2997d2609b34SFlorian Grandel 
2998e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */
2999e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev)
3000e5e1e7fdSMiao-chen Chou {
3001e5e1e7fdSMiao-chen Chou 	idr_destroy(&hdev->adv_monitors_idr);
3002e5e1e7fdSMiao-chen Chou }
3003e5e1e7fdSMiao-chen Chou 
3004dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
3005b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
3006b2a66aadSAntti Julku {
3007b2a66aadSAntti Julku 	struct bdaddr_list *b;
3008b2a66aadSAntti Julku 
3009dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
3010b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3011b2a66aadSAntti Julku 			return b;
3012b9ee0a78SMarcel Holtmann 	}
3013b2a66aadSAntti Julku 
3014b2a66aadSAntti Julku 	return NULL;
3015b2a66aadSAntti Julku }
3016b2a66aadSAntti Julku 
3017b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
3018b950aa88SAnkit Navik 				struct list_head *bdaddr_list, bdaddr_t *bdaddr,
3019b950aa88SAnkit Navik 				u8 type)
3020b950aa88SAnkit Navik {
3021b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *b;
3022b950aa88SAnkit Navik 
3023b950aa88SAnkit Navik 	list_for_each_entry(b, bdaddr_list, list) {
3024b950aa88SAnkit Navik 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3025b950aa88SAnkit Navik 			return b;
3026b950aa88SAnkit Navik 	}
3027b950aa88SAnkit Navik 
3028b950aa88SAnkit Navik 	return NULL;
3029b950aa88SAnkit Navik }
3030b950aa88SAnkit Navik 
30318baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *
30328baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
30338baaa403SAbhishek Pandit-Subedi 				  bdaddr_t *bdaddr, u8 type)
30348baaa403SAbhishek Pandit-Subedi {
30358baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *b;
30368baaa403SAbhishek Pandit-Subedi 
30378baaa403SAbhishek Pandit-Subedi 	list_for_each_entry(b, bdaddr_list, list) {
30388baaa403SAbhishek Pandit-Subedi 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
30398baaa403SAbhishek Pandit-Subedi 			return b;
30408baaa403SAbhishek Pandit-Subedi 	}
30418baaa403SAbhishek Pandit-Subedi 
30428baaa403SAbhishek Pandit-Subedi 	return NULL;
30438baaa403SAbhishek Pandit-Subedi }
30448baaa403SAbhishek Pandit-Subedi 
3045dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
3046b2a66aadSAntti Julku {
30477eb7404fSGeliang Tang 	struct bdaddr_list *b, *n;
3048b2a66aadSAntti Julku 
30497eb7404fSGeliang Tang 	list_for_each_entry_safe(b, n, bdaddr_list, list) {
30507eb7404fSGeliang Tang 		list_del(&b->list);
3051b2a66aadSAntti Julku 		kfree(b);
3052b2a66aadSAntti Julku 	}
3053b2a66aadSAntti Julku }
3054b2a66aadSAntti Julku 
3055dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3056b2a66aadSAntti Julku {
3057b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3058b2a66aadSAntti Julku 
3059b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3060b2a66aadSAntti Julku 		return -EBADF;
3061b2a66aadSAntti Julku 
3062dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
30635e762444SAntti Julku 		return -EEXIST;
3064b2a66aadSAntti Julku 
306527f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
30665e762444SAntti Julku 	if (!entry)
30675e762444SAntti Julku 		return -ENOMEM;
3068b2a66aadSAntti Julku 
3069b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3070b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3071b2a66aadSAntti Julku 
3072dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
3073b2a66aadSAntti Julku 
30742a8357f2SJohan Hedberg 	return 0;
3075b2a66aadSAntti Julku }
3076b2a66aadSAntti Julku 
3077b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
3078b950aa88SAnkit Navik 					u8 type, u8 *peer_irk, u8 *local_irk)
3079b950aa88SAnkit Navik {
3080b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
3081b950aa88SAnkit Navik 
3082b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY))
3083b950aa88SAnkit Navik 		return -EBADF;
3084b950aa88SAnkit Navik 
3085b950aa88SAnkit Navik 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
3086b950aa88SAnkit Navik 		return -EEXIST;
3087b950aa88SAnkit Navik 
3088b950aa88SAnkit Navik 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
3089b950aa88SAnkit Navik 	if (!entry)
3090b950aa88SAnkit Navik 		return -ENOMEM;
3091b950aa88SAnkit Navik 
3092b950aa88SAnkit Navik 	bacpy(&entry->bdaddr, bdaddr);
3093b950aa88SAnkit Navik 	entry->bdaddr_type = type;
3094b950aa88SAnkit Navik 
3095b950aa88SAnkit Navik 	if (peer_irk)
3096b950aa88SAnkit Navik 		memcpy(entry->peer_irk, peer_irk, 16);
3097b950aa88SAnkit Navik 
3098b950aa88SAnkit Navik 	if (local_irk)
3099b950aa88SAnkit Navik 		memcpy(entry->local_irk, local_irk, 16);
3100b950aa88SAnkit Navik 
3101b950aa88SAnkit Navik 	list_add(&entry->list, list);
3102b950aa88SAnkit Navik 
3103b950aa88SAnkit Navik 	return 0;
3104b950aa88SAnkit Navik }
3105b950aa88SAnkit Navik 
31068baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
31078baaa403SAbhishek Pandit-Subedi 				   u8 type, u32 flags)
31088baaa403SAbhishek Pandit-Subedi {
31098baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
31108baaa403SAbhishek Pandit-Subedi 
31118baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY))
31128baaa403SAbhishek Pandit-Subedi 		return -EBADF;
31138baaa403SAbhishek Pandit-Subedi 
31148baaa403SAbhishek Pandit-Subedi 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
31158baaa403SAbhishek Pandit-Subedi 		return -EEXIST;
31168baaa403SAbhishek Pandit-Subedi 
31178baaa403SAbhishek Pandit-Subedi 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
31188baaa403SAbhishek Pandit-Subedi 	if (!entry)
31198baaa403SAbhishek Pandit-Subedi 		return -ENOMEM;
31208baaa403SAbhishek Pandit-Subedi 
31218baaa403SAbhishek Pandit-Subedi 	bacpy(&entry->bdaddr, bdaddr);
31228baaa403SAbhishek Pandit-Subedi 	entry->bdaddr_type = type;
31238baaa403SAbhishek Pandit-Subedi 	entry->current_flags = flags;
31248baaa403SAbhishek Pandit-Subedi 
31258baaa403SAbhishek Pandit-Subedi 	list_add(&entry->list, list);
31268baaa403SAbhishek Pandit-Subedi 
31278baaa403SAbhishek Pandit-Subedi 	return 0;
31288baaa403SAbhishek Pandit-Subedi }
31298baaa403SAbhishek Pandit-Subedi 
3130dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3131b2a66aadSAntti Julku {
3132b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3133b2a66aadSAntti Julku 
313435f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3135dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
313635f7498aSJohan Hedberg 		return 0;
313735f7498aSJohan Hedberg 	}
3138b2a66aadSAntti Julku 
3139dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
3140d2ab0ac1SMarcel Holtmann 	if (!entry)
3141d2ab0ac1SMarcel Holtmann 		return -ENOENT;
3142d2ab0ac1SMarcel Holtmann 
3143d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
3144d2ab0ac1SMarcel Holtmann 	kfree(entry);
3145d2ab0ac1SMarcel Holtmann 
3146d2ab0ac1SMarcel Holtmann 	return 0;
3147d2ab0ac1SMarcel Holtmann }
3148d2ab0ac1SMarcel Holtmann 
3149b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
3150b950aa88SAnkit Navik 							u8 type)
3151b950aa88SAnkit Navik {
3152b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
3153b950aa88SAnkit Navik 
3154b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3155b950aa88SAnkit Navik 		hci_bdaddr_list_clear(list);
3156b950aa88SAnkit Navik 		return 0;
3157b950aa88SAnkit Navik 	}
3158b950aa88SAnkit Navik 
3159b950aa88SAnkit Navik 	entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
3160b950aa88SAnkit Navik 	if (!entry)
3161b950aa88SAnkit Navik 		return -ENOENT;
3162b950aa88SAnkit Navik 
3163b950aa88SAnkit Navik 	list_del(&entry->list);
3164b950aa88SAnkit Navik 	kfree(entry);
3165b950aa88SAnkit Navik 
3166b950aa88SAnkit Navik 	return 0;
3167b950aa88SAnkit Navik }
3168b950aa88SAnkit Navik 
31698baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
31708baaa403SAbhishek Pandit-Subedi 				   u8 type)
31718baaa403SAbhishek Pandit-Subedi {
31728baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
31738baaa403SAbhishek Pandit-Subedi 
31748baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY)) {
31758baaa403SAbhishek Pandit-Subedi 		hci_bdaddr_list_clear(list);
31768baaa403SAbhishek Pandit-Subedi 		return 0;
31778baaa403SAbhishek Pandit-Subedi 	}
31788baaa403SAbhishek Pandit-Subedi 
31798baaa403SAbhishek Pandit-Subedi 	entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
31808baaa403SAbhishek Pandit-Subedi 	if (!entry)
31818baaa403SAbhishek Pandit-Subedi 		return -ENOENT;
31828baaa403SAbhishek Pandit-Subedi 
31838baaa403SAbhishek Pandit-Subedi 	list_del(&entry->list);
31848baaa403SAbhishek Pandit-Subedi 	kfree(entry);
31858baaa403SAbhishek Pandit-Subedi 
31868baaa403SAbhishek Pandit-Subedi 	return 0;
31878baaa403SAbhishek Pandit-Subedi }
31888baaa403SAbhishek Pandit-Subedi 
318915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
319015819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
319115819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
319215819a70SAndre Guedes {
319315819a70SAndre Guedes 	struct hci_conn_params *params;
319415819a70SAndre Guedes 
319515819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
319615819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
319715819a70SAndre Guedes 		    params->addr_type == addr_type) {
319815819a70SAndre Guedes 			return params;
319915819a70SAndre Guedes 		}
320015819a70SAndre Guedes 	}
320115819a70SAndre Guedes 
320215819a70SAndre Guedes 	return NULL;
320315819a70SAndre Guedes }
320415819a70SAndre Guedes 
320515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
3206501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
32074b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
320815819a70SAndre Guedes {
3209912b42efSJohan Hedberg 	struct hci_conn_params *param;
321015819a70SAndre Guedes 
3211501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
3212912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
3213912b42efSJohan Hedberg 		    param->addr_type == addr_type)
3214912b42efSJohan Hedberg 			return param;
32154b10966fSMarcel Holtmann 	}
32164b10966fSMarcel Holtmann 
32174b10966fSMarcel Holtmann 	return NULL;
321815819a70SAndre Guedes }
321915819a70SAndre Guedes 
322015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
322151d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
322251d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
322315819a70SAndre Guedes {
322415819a70SAndre Guedes 	struct hci_conn_params *params;
322515819a70SAndre Guedes 
322615819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
3227cef952ceSAndre Guedes 	if (params)
322851d167c0SMarcel Holtmann 		return params;
322915819a70SAndre Guedes 
323015819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
323115819a70SAndre Guedes 	if (!params) {
32322064ee33SMarcel Holtmann 		bt_dev_err(hdev, "out of memory");
323351d167c0SMarcel Holtmann 		return NULL;
323415819a70SAndre Guedes 	}
323515819a70SAndre Guedes 
323615819a70SAndre Guedes 	bacpy(&params->addr, addr);
323715819a70SAndre Guedes 	params->addr_type = addr_type;
3238cef952ceSAndre Guedes 
3239cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
324093450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
3241cef952ceSAndre Guedes 
3242bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
3243bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
3244bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
3245bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
3246bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
3247bf5b3c8bSMarcel Holtmann 
3248bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
3249bf5b3c8bSMarcel Holtmann 
325051d167c0SMarcel Holtmann 	return params;
3251bf5b3c8bSMarcel Holtmann }
3252bf5b3c8bSMarcel Holtmann 
3253f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
3254f6c63249SJohan Hedberg {
3255f6c63249SJohan Hedberg 	if (params->conn) {
3256f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
3257f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
3258f6c63249SJohan Hedberg 	}
3259f6c63249SJohan Hedberg 
3260f6c63249SJohan Hedberg 	list_del(&params->action);
3261f6c63249SJohan Hedberg 	list_del(&params->list);
3262f6c63249SJohan Hedberg 	kfree(params);
3263f6c63249SJohan Hedberg }
3264f6c63249SJohan Hedberg 
326515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
326615819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
326715819a70SAndre Guedes {
326815819a70SAndre Guedes 	struct hci_conn_params *params;
326915819a70SAndre Guedes 
327015819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
327115819a70SAndre Guedes 	if (!params)
327215819a70SAndre Guedes 		return;
327315819a70SAndre Guedes 
3274f6c63249SJohan Hedberg 	hci_conn_params_free(params);
327515819a70SAndre Guedes 
327695305baaSJohan Hedberg 	hci_update_background_scan(hdev);
327795305baaSJohan Hedberg 
327815819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
327915819a70SAndre Guedes }
328015819a70SAndre Guedes 
328115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
328255af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
328315819a70SAndre Guedes {
328415819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
328515819a70SAndre Guedes 
328615819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
328755af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
328855af49a8SJohan Hedberg 			continue;
3289f75113a2SJakub Pawlowski 
3290f75113a2SJakub Pawlowski 		/* If trying to estabilish one time connection to disabled
3291f75113a2SJakub Pawlowski 		 * device, leave the params, but mark them as just once.
3292f75113a2SJakub Pawlowski 		 */
3293f75113a2SJakub Pawlowski 		if (params->explicit_connect) {
3294f75113a2SJakub Pawlowski 			params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
3295f75113a2SJakub Pawlowski 			continue;
3296f75113a2SJakub Pawlowski 		}
3297f75113a2SJakub Pawlowski 
329815819a70SAndre Guedes 		list_del(&params->list);
329915819a70SAndre Guedes 		kfree(params);
330015819a70SAndre Guedes 	}
330115819a70SAndre Guedes 
330255af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
330355af49a8SJohan Hedberg }
330455af49a8SJohan Hedberg 
330555af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
3306030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev)
330715819a70SAndre Guedes {
330815819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
330915819a70SAndre Guedes 
3310f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
3311f6c63249SJohan Hedberg 		hci_conn_params_free(params);
331215819a70SAndre Guedes 
331315819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
331415819a70SAndre Guedes }
331515819a70SAndre Guedes 
3316a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
3317a1f4c318SJohan Hedberg  *
3318a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
3319a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
3320a1f4c318SJohan Hedberg  * the static random address.
3321a1f4c318SJohan Hedberg  *
3322a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
3323a1f4c318SJohan Hedberg  * public address to use the static random address instead.
332450b5b952SMarcel Holtmann  *
332550b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
332650b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
332750b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
3328a1f4c318SJohan Hedberg  */
3329a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3330a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
3331a1f4c318SJohan Hedberg {
3332b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
333350b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
3334d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
333550b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
3336a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
3337a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
3338a1f4c318SJohan Hedberg 	} else {
3339a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
3340a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
3341a1f4c318SJohan Hedberg 	}
3342a1f4c318SJohan Hedberg }
3343a1f4c318SJohan Hedberg 
33449952d90eSAbhishek Pandit-Subedi static int hci_suspend_wait_event(struct hci_dev *hdev)
33459952d90eSAbhishek Pandit-Subedi {
33469952d90eSAbhishek Pandit-Subedi #define WAKE_COND                                                              \
33479952d90eSAbhishek Pandit-Subedi 	(find_first_bit(hdev->suspend_tasks, __SUSPEND_NUM_TASKS) ==           \
33489952d90eSAbhishek Pandit-Subedi 	 __SUSPEND_NUM_TASKS)
33499952d90eSAbhishek Pandit-Subedi 
33509952d90eSAbhishek Pandit-Subedi 	int i;
33519952d90eSAbhishek Pandit-Subedi 	int ret = wait_event_timeout(hdev->suspend_wait_q,
33529952d90eSAbhishek Pandit-Subedi 				     WAKE_COND, SUSPEND_NOTIFIER_TIMEOUT);
33539952d90eSAbhishek Pandit-Subedi 
33549952d90eSAbhishek Pandit-Subedi 	if (ret == 0) {
3355a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Timed out waiting for suspend events");
33569952d90eSAbhishek Pandit-Subedi 		for (i = 0; i < __SUSPEND_NUM_TASKS; ++i) {
33579952d90eSAbhishek Pandit-Subedi 			if (test_bit(i, hdev->suspend_tasks))
3358a9ec8423SAbhishek Pandit-Subedi 				bt_dev_err(hdev, "Suspend timeout bit: %d", i);
33599952d90eSAbhishek Pandit-Subedi 			clear_bit(i, hdev->suspend_tasks);
33609952d90eSAbhishek Pandit-Subedi 		}
33619952d90eSAbhishek Pandit-Subedi 
33629952d90eSAbhishek Pandit-Subedi 		ret = -ETIMEDOUT;
33639952d90eSAbhishek Pandit-Subedi 	} else {
33649952d90eSAbhishek Pandit-Subedi 		ret = 0;
33659952d90eSAbhishek Pandit-Subedi 	}
33669952d90eSAbhishek Pandit-Subedi 
33679952d90eSAbhishek Pandit-Subedi 	return ret;
33689952d90eSAbhishek Pandit-Subedi }
33699952d90eSAbhishek Pandit-Subedi 
33709952d90eSAbhishek Pandit-Subedi static void hci_prepare_suspend(struct work_struct *work)
33719952d90eSAbhishek Pandit-Subedi {
33729952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
33739952d90eSAbhishek Pandit-Subedi 		container_of(work, struct hci_dev, suspend_prepare);
33749952d90eSAbhishek Pandit-Subedi 
33759952d90eSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
33769952d90eSAbhishek Pandit-Subedi 	hci_req_prepare_suspend(hdev, hdev->suspend_state_next);
33779952d90eSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
33789952d90eSAbhishek Pandit-Subedi }
33799952d90eSAbhishek Pandit-Subedi 
33808731840aSAbhishek Pandit-Subedi static int hci_change_suspend_state(struct hci_dev *hdev,
33818731840aSAbhishek Pandit-Subedi 				    enum suspended_state next)
33828731840aSAbhishek Pandit-Subedi {
33838731840aSAbhishek Pandit-Subedi 	hdev->suspend_state_next = next;
33848731840aSAbhishek Pandit-Subedi 	set_bit(SUSPEND_PREPARE_NOTIFIER, hdev->suspend_tasks);
33858731840aSAbhishek Pandit-Subedi 	queue_work(hdev->req_workqueue, &hdev->suspend_prepare);
33868731840aSAbhishek Pandit-Subedi 	return hci_suspend_wait_event(hdev);
33878731840aSAbhishek Pandit-Subedi }
33888731840aSAbhishek Pandit-Subedi 
33899952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
33909952d90eSAbhishek Pandit-Subedi 				void *data)
33919952d90eSAbhishek Pandit-Subedi {
33929952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
33939952d90eSAbhishek Pandit-Subedi 		container_of(nb, struct hci_dev, suspend_notifier);
33949952d90eSAbhishek Pandit-Subedi 	int ret = 0;
33959952d90eSAbhishek Pandit-Subedi 
33969952d90eSAbhishek Pandit-Subedi 	/* If powering down, wait for completion. */
33979952d90eSAbhishek Pandit-Subedi 	if (mgmt_powering_down(hdev)) {
33989952d90eSAbhishek Pandit-Subedi 		set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks);
33999952d90eSAbhishek Pandit-Subedi 		ret = hci_suspend_wait_event(hdev);
34009952d90eSAbhishek Pandit-Subedi 		if (ret)
34019952d90eSAbhishek Pandit-Subedi 			goto done;
34029952d90eSAbhishek Pandit-Subedi 	}
34039952d90eSAbhishek Pandit-Subedi 
34049952d90eSAbhishek Pandit-Subedi 	/* Suspend notifier should only act on events when powered. */
34059952d90eSAbhishek Pandit-Subedi 	if (!hdev_is_powered(hdev))
34069952d90eSAbhishek Pandit-Subedi 		goto done;
34079952d90eSAbhishek Pandit-Subedi 
34089952d90eSAbhishek Pandit-Subedi 	if (action == PM_SUSPEND_PREPARE) {
34094f40afc6SAbhishek Pandit-Subedi 		/* Suspend consists of two actions:
34104f40afc6SAbhishek Pandit-Subedi 		 *  - First, disconnect everything and make the controller not
34114f40afc6SAbhishek Pandit-Subedi 		 *    connectable (disabling scanning)
34124f40afc6SAbhishek Pandit-Subedi 		 *  - Second, program event filter/whitelist and enable scan
34134f40afc6SAbhishek Pandit-Subedi 		 */
34148731840aSAbhishek Pandit-Subedi 		ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT);
34154f40afc6SAbhishek Pandit-Subedi 
341681dafad5SAbhishek Pandit-Subedi 		/* Only configure whitelist if disconnect succeeded and wake
341781dafad5SAbhishek Pandit-Subedi 		 * isn't being prevented.
341881dafad5SAbhishek Pandit-Subedi 		 */
341981dafad5SAbhishek Pandit-Subedi 		if (!ret && !(hdev->prevent_wake && hdev->prevent_wake(hdev)))
34208731840aSAbhishek Pandit-Subedi 			ret = hci_change_suspend_state(hdev,
34210d2c9825SAbhishek Pandit-Subedi 						BT_SUSPEND_CONFIGURE_WAKE);
34229952d90eSAbhishek Pandit-Subedi 	} else if (action == PM_POST_SUSPEND) {
34238731840aSAbhishek Pandit-Subedi 		ret = hci_change_suspend_state(hdev, BT_RUNNING);
34249952d90eSAbhishek Pandit-Subedi 	}
34259952d90eSAbhishek Pandit-Subedi 
34269952d90eSAbhishek Pandit-Subedi done:
3427a9ec8423SAbhishek Pandit-Subedi 	/* We always allow suspend even if suspend preparation failed and
3428a9ec8423SAbhishek Pandit-Subedi 	 * attempt to recover in resume.
3429a9ec8423SAbhishek Pandit-Subedi 	 */
3430a9ec8423SAbhishek Pandit-Subedi 	if (ret)
3431a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
3432a9ec8423SAbhishek Pandit-Subedi 			   action, ret);
3433a9ec8423SAbhishek Pandit-Subedi 
3434a9ec8423SAbhishek Pandit-Subedi 	return NOTIFY_STOP;
34359952d90eSAbhishek Pandit-Subedi }
34368731840aSAbhishek Pandit-Subedi 
34379be0dab7SDavid Herrmann /* Alloc HCI device */
34389be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
34399be0dab7SDavid Herrmann {
34409be0dab7SDavid Herrmann 	struct hci_dev *hdev;
34419be0dab7SDavid Herrmann 
344227f70f3eSJohan Hedberg 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
34439be0dab7SDavid Herrmann 	if (!hdev)
34449be0dab7SDavid Herrmann 		return NULL;
34459be0dab7SDavid Herrmann 
3446b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3447b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3448b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3449b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3450b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
345196c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
3452bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3453bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3454d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
3455d2609b34SFlorian Grandel 	hdev->cur_adv_instance = 0x00;
34565d900e46SFlorian Grandel 	hdev->adv_instance_timeout = 0;
3457b1b813d4SDavid Herrmann 
3458b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3459b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3460b1b813d4SDavid Herrmann 
34613f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3462628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
3463628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
3464bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3465bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
346610873f99SAlain Michaud 	hdev->le_scan_int_suspend = 0x0400;
346710873f99SAlain Michaud 	hdev->le_scan_window_suspend = 0x0012;
346810873f99SAlain Michaud 	hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
346910873f99SAlain Michaud 	hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
347010873f99SAlain Michaud 	hdev->le_scan_int_connect = 0x0060;
347110873f99SAlain Michaud 	hdev->le_scan_window_connect = 0x0060;
3472b48c3b59SJonas Holmberg 	hdev->le_conn_min_interval = 0x0018;
3473b48c3b59SJonas Holmberg 	hdev->le_conn_max_interval = 0x0028;
347404fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
347504fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
3476a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
3477a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
3478a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
3479a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
3480a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
3481a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
348230d65e08SMatias Karhumaa 	hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
348330d65e08SMatias Karhumaa 	hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
34846decb5b4SJaganath Kanakkassery 	hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
34856decb5b4SJaganath Kanakkassery 	hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
34861d0fac2cSLuiz Augusto von Dentz 	hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
348710873f99SAlain Michaud 	hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
3488bef64738SMarcel Holtmann 
3489d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3490b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
349131ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
349231ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
3493302975cbSSpoorthi Ravishankar Koppad 	hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
349458a96fc3SMarcel Holtmann 	hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
3495d6bfd59cSJohan Hedberg 
349610873f99SAlain Michaud 	/* default 1.28 sec page scan */
349710873f99SAlain Michaud 	hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
349810873f99SAlain Michaud 	hdev->def_page_scan_int = 0x0800;
349910873f99SAlain Michaud 	hdev->def_page_scan_window = 0x0012;
350010873f99SAlain Michaud 
3501b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3502b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3503b1b813d4SDavid Herrmann 
3504b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3505b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
35066659358eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->whitelist);
3507b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3508b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3509b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3510970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3511b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
3512d2ab0ac1SMarcel Holtmann 	INIT_LIST_HEAD(&hdev->le_white_list);
3513cfdb0c2dSAnkit Navik 	INIT_LIST_HEAD(&hdev->le_resolv_list);
351415819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
351577a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
351666f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
35176b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3518d2609b34SFlorian Grandel 	INIT_LIST_HEAD(&hdev->adv_instances);
3519600a8749SAlain Michaud 	INIT_LIST_HEAD(&hdev->blocked_keys);
3520b1b813d4SDavid Herrmann 
3521b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3522b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3523b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3524b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3525c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
35269952d90eSAbhishek Pandit-Subedi 	INIT_WORK(&hdev->suspend_prepare, hci_prepare_suspend);
3527b1b813d4SDavid Herrmann 
3528b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3529b1b813d4SDavid Herrmann 
3530b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3531b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3532b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3533b1b813d4SDavid Herrmann 
3534b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
35359952d90eSAbhishek Pandit-Subedi 	init_waitqueue_head(&hdev->suspend_wait_q);
3536b1b813d4SDavid Herrmann 
353765cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
3538b1b813d4SDavid Herrmann 
35395fc16cc4SJohan Hedberg 	hci_request_setup(hdev);
35405fc16cc4SJohan Hedberg 
3541b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3542b1b813d4SDavid Herrmann 	discovery_init(hdev);
35439be0dab7SDavid Herrmann 
35449be0dab7SDavid Herrmann 	return hdev;
35459be0dab7SDavid Herrmann }
35469be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
35479be0dab7SDavid Herrmann 
35489be0dab7SDavid Herrmann /* Free HCI device */
35499be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
35509be0dab7SDavid Herrmann {
35519be0dab7SDavid Herrmann 	/* will free via device release */
35529be0dab7SDavid Herrmann 	put_device(&hdev->dev);
35539be0dab7SDavid Herrmann }
35549be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
35559be0dab7SDavid Herrmann 
35561da177e4SLinus Torvalds /* Register HCI device */
35571da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
35581da177e4SLinus Torvalds {
3559b1b813d4SDavid Herrmann 	int id, error;
35601da177e4SLinus Torvalds 
356174292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
35621da177e4SLinus Torvalds 		return -EINVAL;
35631da177e4SLinus Torvalds 
356408add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
356508add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
356608add513SMat Martineau 	 */
35673df92b31SSasha Levin 	switch (hdev->dev_type) {
3568ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
35693df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
35701da177e4SLinus Torvalds 		break;
35713df92b31SSasha Levin 	case HCI_AMP:
35723df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
35733df92b31SSasha Levin 		break;
35743df92b31SSasha Levin 	default:
35753df92b31SSasha Levin 		return -EINVAL;
35761da177e4SLinus Torvalds 	}
35771da177e4SLinus Torvalds 
35783df92b31SSasha Levin 	if (id < 0)
35793df92b31SSasha Levin 		return id;
35803df92b31SSasha Levin 
35811da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
35821da177e4SLinus Torvalds 	hdev->id = id;
35832d8b3a11SAndrei Emeltchenko 
35842d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
35852d8b3a11SAndrei Emeltchenko 
358629e2dd0dSTejun Heo 	hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
358733ca954dSDavid Herrmann 	if (!hdev->workqueue) {
358833ca954dSDavid Herrmann 		error = -ENOMEM;
358933ca954dSDavid Herrmann 		goto err;
359033ca954dSDavid Herrmann 	}
3591f48fd9c8SMarcel Holtmann 
359229e2dd0dSTejun Heo 	hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
359329e2dd0dSTejun Heo 						      hdev->name);
35946ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
35956ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
35966ead1bbcSJohan Hedberg 		error = -ENOMEM;
35976ead1bbcSJohan Hedberg 		goto err;
35986ead1bbcSJohan Hedberg 	}
35996ead1bbcSJohan Hedberg 
36000153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
36010153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
36020153e2ecSMarcel Holtmann 
3603bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3604bdc3e0f1SMarcel Holtmann 
3605bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
360633ca954dSDavid Herrmann 	if (error < 0)
360754506918SJohan Hedberg 		goto err_wqueue;
36081da177e4SLinus Torvalds 
36096d5d2ee6SHeiner Kallweit 	hci_leds_init(hdev);
36106d5d2ee6SHeiner Kallweit 
3611611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3612a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3613a8c5fb1aSGustavo Padovan 				    hdev);
3614611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3615611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3616611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3617611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3618611b30f7SMarcel Holtmann 		}
3619611b30f7SMarcel Holtmann 	}
3620611b30f7SMarcel Holtmann 
36215e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
3622a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
36235e130367SJohan Hedberg 
3624a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
3625a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
3626ce2be9acSAndrei Emeltchenko 
3627ca8bee5dSMarcel Holtmann 	if (hdev->dev_type == HCI_PRIMARY) {
362856f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
362956f87901SJohan Hedberg 		 * through reading supported features during init.
363056f87901SJohan Hedberg 		 */
3631a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
363256f87901SJohan Hedberg 	}
3633ce2be9acSAndrei Emeltchenko 
3634fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3635fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3636fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3637fcee3377SGustavo Padovan 
36384a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
36394a964404SMarcel Holtmann 	 * and should not be included in normal operation.
3640fee746b0SMarcel Holtmann 	 */
3641fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
3642a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
3643fee746b0SMarcel Holtmann 
364405fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_REG);
3645dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
36461da177e4SLinus Torvalds 
36479952d90eSAbhishek Pandit-Subedi 	hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
36489952d90eSAbhishek Pandit-Subedi 	error = register_pm_notifier(&hdev->suspend_notifier);
36499952d90eSAbhishek Pandit-Subedi 	if (error)
36509952d90eSAbhishek Pandit-Subedi 		goto err_wqueue;
36519952d90eSAbhishek Pandit-Subedi 
365219202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3653fbe96d6fSMarcel Holtmann 
3654e5e1e7fdSMiao-chen Chou 	idr_init(&hdev->adv_monitors_idr);
3655e5e1e7fdSMiao-chen Chou 
36561da177e4SLinus Torvalds 	return id;
3657f48fd9c8SMarcel Holtmann 
365833ca954dSDavid Herrmann err_wqueue:
365933ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
36606ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
366133ca954dSDavid Herrmann err:
36623df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
3663f48fd9c8SMarcel Holtmann 
366433ca954dSDavid Herrmann 	return error;
36651da177e4SLinus Torvalds }
36661da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
36671da177e4SLinus Torvalds 
36681da177e4SLinus Torvalds /* Unregister HCI device */
366959735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
36701da177e4SLinus Torvalds {
36712d7cc19eSMarcel Holtmann 	int id;
3672ef222013SMarcel Holtmann 
3673c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
36741da177e4SLinus Torvalds 
3675a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
367694324962SJohan Hovold 
36773df92b31SSasha Levin 	id = hdev->id;
36783df92b31SSasha Levin 
3679f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
36801da177e4SLinus Torvalds 	list_del(&hdev->list);
3681f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
36821da177e4SLinus Torvalds 
3683b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
3684b9b5ef18SGustavo Padovan 
3685bf389cabSJiri Slaby 	hci_dev_do_close(hdev);
3686bf389cabSJiri Slaby 
36879952d90eSAbhishek Pandit-Subedi 	unregister_pm_notifier(&hdev->suspend_notifier);
36889952d90eSAbhishek Pandit-Subedi 
3689ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
3690d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
3691d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
369209fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
3693744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
369409fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
369556e5cb86SJohan Hedberg 	}
3696ab81cbf9SJohan Hedberg 
36972e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
36982e58ef3eSJohan Hedberg 	 * pending list */
36992e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
37002e58ef3eSJohan Hedberg 
370105fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_UNREG);
37021da177e4SLinus Torvalds 
3703611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3704611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
3705611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
3706611b30f7SMarcel Holtmann 	}
3707611b30f7SMarcel Holtmann 
3708bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
3709147e2d59SDave Young 
37100153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
37115177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
37125177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
37130153e2ecSMarcel Holtmann 
3714f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
37156ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
3716f48fd9c8SMarcel Holtmann 
371709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
3718dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->blacklist);
37196659358eSJohan Hedberg 	hci_bdaddr_list_clear(&hdev->whitelist);
37202aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
372155ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
3722b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
3723970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
37242763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
3725d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
3726e5e1e7fdSMiao-chen Chou 	hci_adv_monitors_clear(hdev);
3727dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->le_white_list);
3728cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
3729373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
373022078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
3731600a8749SAlain Michaud 	hci_blocked_keys_clear(hdev);
373209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
3733e2e0cacbSJohan Hedberg 
3734dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
37353df92b31SSasha Levin 
37363df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
37371da177e4SLinus Torvalds }
37381da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
37391da177e4SLinus Torvalds 
37401da177e4SLinus Torvalds /* Suspend HCI device */
37411da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
37421da177e4SLinus Torvalds {
374305fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
37441da177e4SLinus Torvalds 	return 0;
37451da177e4SLinus Torvalds }
37461da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
37471da177e4SLinus Torvalds 
37481da177e4SLinus Torvalds /* Resume HCI device */
37491da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
37501da177e4SLinus Torvalds {
375105fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_RESUME);
37521da177e4SLinus Torvalds 	return 0;
37531da177e4SLinus Torvalds }
37541da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
37551da177e4SLinus Torvalds 
375675e0569fSMarcel Holtmann /* Reset HCI device */
375775e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
375875e0569fSMarcel Holtmann {
37591e4b6e91SColin Ian King 	static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
376075e0569fSMarcel Holtmann 	struct sk_buff *skb;
376175e0569fSMarcel Holtmann 
376275e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
376375e0569fSMarcel Holtmann 	if (!skb)
376475e0569fSMarcel Holtmann 		return -ENOMEM;
376575e0569fSMarcel Holtmann 
3766d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
376759ae1d12SJohannes Berg 	skb_put_data(skb, hw_err, 3);
376875e0569fSMarcel Holtmann 
376975e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
377075e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
377175e0569fSMarcel Holtmann }
377275e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
377375e0569fSMarcel Holtmann 
377476bca880SMarcel Holtmann /* Receive frame from HCI drivers */
3775e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
377676bca880SMarcel Holtmann {
377776bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
377876bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
377976bca880SMarcel Holtmann 		kfree_skb(skb);
378076bca880SMarcel Holtmann 		return -ENXIO;
378176bca880SMarcel Holtmann 	}
378276bca880SMarcel Holtmann 
3783d79f34e3SMarcel Holtmann 	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
3784d79f34e3SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
3785cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT &&
3786cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) {
3787fe806dceSMarcel Holtmann 		kfree_skb(skb);
3788fe806dceSMarcel Holtmann 		return -EINVAL;
3789fe806dceSMarcel Holtmann 	}
3790fe806dceSMarcel Holtmann 
3791d82603c6SJorrit Schippers 	/* Incoming skb */
379276bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
379376bca880SMarcel Holtmann 
379476bca880SMarcel Holtmann 	/* Time stamp */
379576bca880SMarcel Holtmann 	__net_timestamp(skb);
379676bca880SMarcel Holtmann 
379776bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3798b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3799c78ae283SMarcel Holtmann 
380076bca880SMarcel Holtmann 	return 0;
380176bca880SMarcel Holtmann }
380276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
380376bca880SMarcel Holtmann 
3804e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
3805e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
3806e875ff84SMarcel Holtmann {
3807581d6fd6SMarcel Holtmann 	/* Mark as diagnostic packet */
3808d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
3809581d6fd6SMarcel Holtmann 
3810e875ff84SMarcel Holtmann 	/* Time stamp */
3811e875ff84SMarcel Holtmann 	__net_timestamp(skb);
3812e875ff84SMarcel Holtmann 
3813581d6fd6SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3814581d6fd6SMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3815e875ff84SMarcel Holtmann 
3816e875ff84SMarcel Holtmann 	return 0;
3817e875ff84SMarcel Holtmann }
3818e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
3819e875ff84SMarcel Holtmann 
38205177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
38215177a838SMarcel Holtmann {
38225177a838SMarcel Holtmann 	va_list vargs;
38235177a838SMarcel Holtmann 
38245177a838SMarcel Holtmann 	va_start(vargs, fmt);
38255177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
38265177a838SMarcel Holtmann 	hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
38275177a838SMarcel Holtmann 	va_end(vargs);
38285177a838SMarcel Holtmann }
38295177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
38305177a838SMarcel Holtmann 
38315177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
38325177a838SMarcel Holtmann {
38335177a838SMarcel Holtmann 	va_list vargs;
38345177a838SMarcel Holtmann 
38355177a838SMarcel Holtmann 	va_start(vargs, fmt);
38365177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
38375177a838SMarcel Holtmann 	hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
38385177a838SMarcel Holtmann 	va_end(vargs);
38395177a838SMarcel Holtmann }
38405177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
38415177a838SMarcel Holtmann 
38421da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
38431da177e4SLinus Torvalds 
38441da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
38451da177e4SLinus Torvalds {
38461da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
38471da177e4SLinus Torvalds 
3848fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
384900629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
3850fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
38511da177e4SLinus Torvalds 
38521da177e4SLinus Torvalds 	return 0;
38531da177e4SLinus Torvalds }
38541da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
38551da177e4SLinus Torvalds 
38561da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
38571da177e4SLinus Torvalds {
38581da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
38591da177e4SLinus Torvalds 
3860fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
38611da177e4SLinus Torvalds 	list_del(&cb->list);
3862fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
38631da177e4SLinus Torvalds 
38641da177e4SLinus Torvalds 	return 0;
38651da177e4SLinus Torvalds }
38661da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
38671da177e4SLinus Torvalds 
386851086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
38691da177e4SLinus Torvalds {
3870cdc52faaSMarcel Holtmann 	int err;
3871cdc52faaSMarcel Holtmann 
3872d79f34e3SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
3873d79f34e3SMarcel Holtmann 	       skb->len);
38741da177e4SLinus Torvalds 
38751da177e4SLinus Torvalds 	/* Time stamp */
3876a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
38771da177e4SLinus Torvalds 
3878cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3879cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3880cd82e61cSMarcel Holtmann 
3881cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3882cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3883470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
38841da177e4SLinus Torvalds 	}
38851da177e4SLinus Torvalds 
38861da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
38871da177e4SLinus Torvalds 	skb_orphan(skb);
38881da177e4SLinus Torvalds 
388973d0d3c8SMarcel Holtmann 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
389073d0d3c8SMarcel Holtmann 		kfree_skb(skb);
389173d0d3c8SMarcel Holtmann 		return;
389273d0d3c8SMarcel Holtmann 	}
389373d0d3c8SMarcel Holtmann 
3894cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
3895cdc52faaSMarcel Holtmann 	if (err < 0) {
38962064ee33SMarcel Holtmann 		bt_dev_err(hdev, "sending frame failed (%d)", err);
3897cdc52faaSMarcel Holtmann 		kfree_skb(skb);
3898cdc52faaSMarcel Holtmann 	}
38991da177e4SLinus Torvalds }
39001da177e4SLinus Torvalds 
39011ca3a9d0SJohan Hedberg /* Send HCI command */
390207dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
390307dc93ddSJohan Hedberg 		 const void *param)
39041ca3a9d0SJohan Hedberg {
39051ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
39061ca3a9d0SJohan Hedberg 
39071ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
39081ca3a9d0SJohan Hedberg 
39091ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
39101ca3a9d0SJohan Hedberg 	if (!skb) {
39112064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no memory for command");
39121ca3a9d0SJohan Hedberg 		return -ENOMEM;
39131ca3a9d0SJohan Hedberg 	}
39141ca3a9d0SJohan Hedberg 
391549c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
391611714b3dSJohan Hedberg 	 * single-command requests.
391711714b3dSJohan Hedberg 	 */
391844d27137SJohan Hedberg 	bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
391911714b3dSJohan Hedberg 
39201da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3921c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
39221da177e4SLinus Torvalds 
39231da177e4SLinus Torvalds 	return 0;
39241da177e4SLinus Torvalds }
39251da177e4SLinus Torvalds 
3926d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
3927d6ee6ad7SLoic Poulain 		   const void *param)
3928d6ee6ad7SLoic Poulain {
3929d6ee6ad7SLoic Poulain 	struct sk_buff *skb;
3930d6ee6ad7SLoic Poulain 
3931d6ee6ad7SLoic Poulain 	if (hci_opcode_ogf(opcode) != 0x3f) {
3932d6ee6ad7SLoic Poulain 		/* A controller receiving a command shall respond with either
3933d6ee6ad7SLoic Poulain 		 * a Command Status Event or a Command Complete Event.
3934d6ee6ad7SLoic Poulain 		 * Therefore, all standard HCI commands must be sent via the
3935d6ee6ad7SLoic Poulain 		 * standard API, using hci_send_cmd or hci_cmd_sync helpers.
3936d6ee6ad7SLoic Poulain 		 * Some vendors do not comply with this rule for vendor-specific
3937d6ee6ad7SLoic Poulain 		 * commands and do not return any event. We want to support
3938d6ee6ad7SLoic Poulain 		 * unresponded commands for such cases only.
3939d6ee6ad7SLoic Poulain 		 */
3940d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "unresponded command not supported");
3941d6ee6ad7SLoic Poulain 		return -EINVAL;
3942d6ee6ad7SLoic Poulain 	}
3943d6ee6ad7SLoic Poulain 
3944d6ee6ad7SLoic Poulain 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
3945d6ee6ad7SLoic Poulain 	if (!skb) {
3946d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
3947d6ee6ad7SLoic Poulain 			   opcode);
3948d6ee6ad7SLoic Poulain 		return -ENOMEM;
3949d6ee6ad7SLoic Poulain 	}
3950d6ee6ad7SLoic Poulain 
3951d6ee6ad7SLoic Poulain 	hci_send_frame(hdev, skb);
3952d6ee6ad7SLoic Poulain 
3953d6ee6ad7SLoic Poulain 	return 0;
3954d6ee6ad7SLoic Poulain }
3955d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
3956d6ee6ad7SLoic Poulain 
39571da177e4SLinus Torvalds /* Get data from the previously sent command */
3958a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
39591da177e4SLinus Torvalds {
39601da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
39611da177e4SLinus Torvalds 
39621da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
39631da177e4SLinus Torvalds 		return NULL;
39641da177e4SLinus Torvalds 
39651da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
39661da177e4SLinus Torvalds 
3967a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
39681da177e4SLinus Torvalds 		return NULL;
39691da177e4SLinus Torvalds 
3970f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
39711da177e4SLinus Torvalds 
39721da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
39731da177e4SLinus Torvalds }
39741da177e4SLinus Torvalds 
3975fbef168fSLoic Poulain /* Send HCI command and wait for command commplete event */
3976fbef168fSLoic Poulain struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
3977fbef168fSLoic Poulain 			     const void *param, u32 timeout)
3978fbef168fSLoic Poulain {
3979fbef168fSLoic Poulain 	struct sk_buff *skb;
3980fbef168fSLoic Poulain 
3981fbef168fSLoic Poulain 	if (!test_bit(HCI_UP, &hdev->flags))
3982fbef168fSLoic Poulain 		return ERR_PTR(-ENETDOWN);
3983fbef168fSLoic Poulain 
3984fbef168fSLoic Poulain 	bt_dev_dbg(hdev, "opcode 0x%4.4x plen %d", opcode, plen);
3985fbef168fSLoic Poulain 
3986b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
3987fbef168fSLoic Poulain 	skb = __hci_cmd_sync(hdev, opcode, plen, param, timeout);
3988b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
3989fbef168fSLoic Poulain 
3990fbef168fSLoic Poulain 	return skb;
3991fbef168fSLoic Poulain }
3992fbef168fSLoic Poulain EXPORT_SYMBOL(hci_cmd_sync);
3993fbef168fSLoic Poulain 
39941da177e4SLinus Torvalds /* Send ACL data */
39951da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
39961da177e4SLinus Torvalds {
39971da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
39981da177e4SLinus Torvalds 	int len = skb->len;
39991da177e4SLinus Torvalds 
4000badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
4001badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
40029c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
4003aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
4004aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
40051da177e4SLinus Torvalds }
40061da177e4SLinus Torvalds 
4007ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
400873d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
40091da177e4SLinus Torvalds {
4010ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
40111da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
40121da177e4SLinus Torvalds 	struct sk_buff *list;
40131da177e4SLinus Torvalds 
4014087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
4015087bfd99SGustavo Padovan 	skb->data_len = 0;
4016087bfd99SGustavo Padovan 
4017d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
4018204a6e54SAndrei Emeltchenko 
4019204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
4020ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
4021087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
4022204a6e54SAndrei Emeltchenko 		break;
4023204a6e54SAndrei Emeltchenko 	case HCI_AMP:
4024204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
4025204a6e54SAndrei Emeltchenko 		break;
4026204a6e54SAndrei Emeltchenko 	default:
40272064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
4028204a6e54SAndrei Emeltchenko 		return;
4029204a6e54SAndrei Emeltchenko 	}
4030087bfd99SGustavo Padovan 
403170f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
403270f23020SAndrei Emeltchenko 	if (!list) {
40331da177e4SLinus Torvalds 		/* Non fragmented */
40341da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
40351da177e4SLinus Torvalds 
403673d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
40371da177e4SLinus Torvalds 	} else {
40381da177e4SLinus Torvalds 		/* Fragmented */
40391da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
40401da177e4SLinus Torvalds 
40411da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
40421da177e4SLinus Torvalds 
40439cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
40449cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
40459cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
40469cfd5a23SJukka Rissanen 		 * deadlocks.
40479cfd5a23SJukka Rissanen 		 */
40489cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
40491da177e4SLinus Torvalds 
405073d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
4051e702112fSAndrei Emeltchenko 
4052e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
4053e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
40541da177e4SLinus Torvalds 		do {
40551da177e4SLinus Torvalds 			skb = list; list = list->next;
40561da177e4SLinus Torvalds 
4057d79f34e3SMarcel Holtmann 			hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
4058e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
40591da177e4SLinus Torvalds 
40601da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
40611da177e4SLinus Torvalds 
406273d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
40631da177e4SLinus Torvalds 		} while (list);
40641da177e4SLinus Torvalds 
40659cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
40661da177e4SLinus Torvalds 	}
406773d80debSLuiz Augusto von Dentz }
406873d80debSLuiz Augusto von Dentz 
406973d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
407073d80debSLuiz Augusto von Dentz {
4071ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
407273d80debSLuiz Augusto von Dentz 
4073f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
407473d80debSLuiz Augusto von Dentz 
4075ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
40761da177e4SLinus Torvalds 
40773eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
40781da177e4SLinus Torvalds }
40791da177e4SLinus Torvalds 
40801da177e4SLinus Torvalds /* Send SCO data */
40810d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
40821da177e4SLinus Torvalds {
40831da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
40841da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
40851da177e4SLinus Torvalds 
40861da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
40871da177e4SLinus Torvalds 
4088aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
40891da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
40901da177e4SLinus Torvalds 
4091badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
4092badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
40939c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
40941da177e4SLinus Torvalds 
4095d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
4096c78ae283SMarcel Holtmann 
40971da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
40983eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
40991da177e4SLinus Torvalds }
41001da177e4SLinus Torvalds 
41011da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
41021da177e4SLinus Torvalds 
41031da177e4SLinus Torvalds /* HCI Connection scheduler */
41046039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
4105a8c5fb1aSGustavo Padovan 				     int *quote)
41061da177e4SLinus Torvalds {
41071da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
41088035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
4109abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
41101da177e4SLinus Torvalds 
41111da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
41121da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
4113bf4c6325SGustavo F. Padovan 
4114bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4115bf4c6325SGustavo F. Padovan 
4116bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4117769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
41181da177e4SLinus Torvalds 			continue;
4119769be974SMarcel Holtmann 
4120769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
4121769be974SMarcel Holtmann 			continue;
4122769be974SMarcel Holtmann 
41231da177e4SLinus Torvalds 		num++;
41241da177e4SLinus Torvalds 
41251da177e4SLinus Torvalds 		if (c->sent < min) {
41261da177e4SLinus Torvalds 			min  = c->sent;
41271da177e4SLinus Torvalds 			conn = c;
41281da177e4SLinus Torvalds 		}
412952087a79SLuiz Augusto von Dentz 
413052087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
413152087a79SLuiz Augusto von Dentz 			break;
41321da177e4SLinus Torvalds 	}
41331da177e4SLinus Torvalds 
4134bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4135bf4c6325SGustavo F. Padovan 
41361da177e4SLinus Torvalds 	if (conn) {
41376ed58ec5SVille Tervo 		int cnt, q;
41386ed58ec5SVille Tervo 
41396ed58ec5SVille Tervo 		switch (conn->type) {
41406ed58ec5SVille Tervo 		case ACL_LINK:
41416ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
41426ed58ec5SVille Tervo 			break;
41436ed58ec5SVille Tervo 		case SCO_LINK:
41446ed58ec5SVille Tervo 		case ESCO_LINK:
41456ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
41466ed58ec5SVille Tervo 			break;
41476ed58ec5SVille Tervo 		case LE_LINK:
41486ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
41496ed58ec5SVille Tervo 			break;
41506ed58ec5SVille Tervo 		default:
41516ed58ec5SVille Tervo 			cnt = 0;
41522064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown link type %d", conn->type);
41536ed58ec5SVille Tervo 		}
41546ed58ec5SVille Tervo 
41556ed58ec5SVille Tervo 		q = cnt / num;
41561da177e4SLinus Torvalds 		*quote = q ? q : 1;
41571da177e4SLinus Torvalds 	} else
41581da177e4SLinus Torvalds 		*quote = 0;
41591da177e4SLinus Torvalds 
41601da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
41611da177e4SLinus Torvalds 	return conn;
41621da177e4SLinus Torvalds }
41631da177e4SLinus Torvalds 
41646039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
41651da177e4SLinus Torvalds {
41661da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
41671da177e4SLinus Torvalds 	struct hci_conn *c;
41681da177e4SLinus Torvalds 
41692064ee33SMarcel Holtmann 	bt_dev_err(hdev, "link tx timeout");
41701da177e4SLinus Torvalds 
4171bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4172bf4c6325SGustavo F. Padovan 
41731da177e4SLinus Torvalds 	/* Kill stalled connections */
4174bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4175bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
41762064ee33SMarcel Holtmann 			bt_dev_err(hdev, "killing stalled connection %pMR",
41772064ee33SMarcel Holtmann 				   &c->dst);
4178bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
41791da177e4SLinus Torvalds 		}
41801da177e4SLinus Torvalds 	}
4181bf4c6325SGustavo F. Padovan 
4182bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
41831da177e4SLinus Torvalds }
41841da177e4SLinus Torvalds 
41856039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
418673d80debSLuiz Augusto von Dentz 				      int *quote)
418773d80debSLuiz Augusto von Dentz {
418873d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
418973d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4190abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
419173d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
419273d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
419373d80debSLuiz Augusto von Dentz 
419473d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
419573d80debSLuiz Augusto von Dentz 
4196bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4197bf4c6325SGustavo F. Padovan 
4198bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
419973d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
420073d80debSLuiz Augusto von Dentz 
420173d80debSLuiz Augusto von Dentz 		if (conn->type != type)
420273d80debSLuiz Augusto von Dentz 			continue;
420373d80debSLuiz Augusto von Dentz 
420473d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
420573d80debSLuiz Augusto von Dentz 			continue;
420673d80debSLuiz Augusto von Dentz 
420773d80debSLuiz Augusto von Dentz 		conn_num++;
420873d80debSLuiz Augusto von Dentz 
42098192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
421073d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
421173d80debSLuiz Augusto von Dentz 
421273d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
421373d80debSLuiz Augusto von Dentz 				continue;
421473d80debSLuiz Augusto von Dentz 
421573d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
421673d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
421773d80debSLuiz Augusto von Dentz 				continue;
421873d80debSLuiz Augusto von Dentz 
421973d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
422073d80debSLuiz Augusto von Dentz 				num = 0;
422173d80debSLuiz Augusto von Dentz 				min = ~0;
422273d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
422373d80debSLuiz Augusto von Dentz 			}
422473d80debSLuiz Augusto von Dentz 
422573d80debSLuiz Augusto von Dentz 			num++;
422673d80debSLuiz Augusto von Dentz 
422773d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
422873d80debSLuiz Augusto von Dentz 				min  = conn->sent;
422973d80debSLuiz Augusto von Dentz 				chan = tmp;
423073d80debSLuiz Augusto von Dentz 			}
423173d80debSLuiz Augusto von Dentz 		}
423273d80debSLuiz Augusto von Dentz 
423373d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
423473d80debSLuiz Augusto von Dentz 			break;
423573d80debSLuiz Augusto von Dentz 	}
423673d80debSLuiz Augusto von Dentz 
4237bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4238bf4c6325SGustavo F. Padovan 
423973d80debSLuiz Augusto von Dentz 	if (!chan)
424073d80debSLuiz Augusto von Dentz 		return NULL;
424173d80debSLuiz Augusto von Dentz 
424273d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
424373d80debSLuiz Augusto von Dentz 	case ACL_LINK:
424473d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
424573d80debSLuiz Augusto von Dentz 		break;
4246bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4247bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4248bd1eb66bSAndrei Emeltchenko 		break;
424973d80debSLuiz Augusto von Dentz 	case SCO_LINK:
425073d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
425173d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
425273d80debSLuiz Augusto von Dentz 		break;
425373d80debSLuiz Augusto von Dentz 	case LE_LINK:
425473d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
425573d80debSLuiz Augusto von Dentz 		break;
425673d80debSLuiz Augusto von Dentz 	default:
425773d80debSLuiz Augusto von Dentz 		cnt = 0;
42582064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown link type %d", chan->conn->type);
425973d80debSLuiz Augusto von Dentz 	}
426073d80debSLuiz Augusto von Dentz 
426173d80debSLuiz Augusto von Dentz 	q = cnt / num;
426273d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
426373d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
426473d80debSLuiz Augusto von Dentz 	return chan;
426573d80debSLuiz Augusto von Dentz }
426673d80debSLuiz Augusto von Dentz 
426702b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
426802b20f0bSLuiz Augusto von Dentz {
426902b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
427002b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
427102b20f0bSLuiz Augusto von Dentz 	int num = 0;
427202b20f0bSLuiz Augusto von Dentz 
427302b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
427402b20f0bSLuiz Augusto von Dentz 
4275bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4276bf4c6325SGustavo F. Padovan 
4277bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
427802b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
427902b20f0bSLuiz Augusto von Dentz 
428002b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
428102b20f0bSLuiz Augusto von Dentz 			continue;
428202b20f0bSLuiz Augusto von Dentz 
428302b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
428402b20f0bSLuiz Augusto von Dentz 			continue;
428502b20f0bSLuiz Augusto von Dentz 
428602b20f0bSLuiz Augusto von Dentz 		num++;
428702b20f0bSLuiz Augusto von Dentz 
42888192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
428902b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
429002b20f0bSLuiz Augusto von Dentz 
429102b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
429202b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
429302b20f0bSLuiz Augusto von Dentz 				continue;
429402b20f0bSLuiz Augusto von Dentz 			}
429502b20f0bSLuiz Augusto von Dentz 
429602b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
429702b20f0bSLuiz Augusto von Dentz 				continue;
429802b20f0bSLuiz Augusto von Dentz 
429902b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
430002b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
430102b20f0bSLuiz Augusto von Dentz 				continue;
430202b20f0bSLuiz Augusto von Dentz 
430302b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
430402b20f0bSLuiz Augusto von Dentz 
430502b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
430602b20f0bSLuiz Augusto von Dentz 			       skb->priority);
430702b20f0bSLuiz Augusto von Dentz 		}
430802b20f0bSLuiz Augusto von Dentz 
430902b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
431002b20f0bSLuiz Augusto von Dentz 			break;
431102b20f0bSLuiz Augusto von Dentz 	}
4312bf4c6325SGustavo F. Padovan 
4313bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4314bf4c6325SGustavo F. Padovan 
431502b20f0bSLuiz Augusto von Dentz }
431602b20f0bSLuiz Augusto von Dentz 
4317b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4318b71d385aSAndrei Emeltchenko {
4319b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4320b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4321b71d385aSAndrei Emeltchenko }
4322b71d385aSAndrei Emeltchenko 
43236039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
43241da177e4SLinus Torvalds {
4325d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
43261da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
43271da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
432863d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
43295f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4330bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
43311da177e4SLinus Torvalds 	}
433263d2bc1bSAndrei Emeltchenko }
43331da177e4SLinus Torvalds 
43347fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
43357fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
43367fedd3bbSAbhishek Pandit-Subedi {
43377fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
43387fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
43397fedd3bbSAbhishek Pandit-Subedi 	int quote;
43407fedd3bbSAbhishek Pandit-Subedi 
43417fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
43427fedd3bbSAbhishek Pandit-Subedi 
43437fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, SCO_LINK))
43447fedd3bbSAbhishek Pandit-Subedi 		return;
43457fedd3bbSAbhishek Pandit-Subedi 
43467fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
43477fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
43487fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
43497fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
43507fedd3bbSAbhishek Pandit-Subedi 
43517fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
43527fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
43537fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
43547fedd3bbSAbhishek Pandit-Subedi 		}
43557fedd3bbSAbhishek Pandit-Subedi 	}
43567fedd3bbSAbhishek Pandit-Subedi }
43577fedd3bbSAbhishek Pandit-Subedi 
43587fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
43597fedd3bbSAbhishek Pandit-Subedi {
43607fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
43617fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
43627fedd3bbSAbhishek Pandit-Subedi 	int quote;
43637fedd3bbSAbhishek Pandit-Subedi 
43647fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
43657fedd3bbSAbhishek Pandit-Subedi 
43667fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, ESCO_LINK))
43677fedd3bbSAbhishek Pandit-Subedi 		return;
43687fedd3bbSAbhishek Pandit-Subedi 
43697fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
43707fedd3bbSAbhishek Pandit-Subedi 						     &quote))) {
43717fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
43727fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
43737fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
43747fedd3bbSAbhishek Pandit-Subedi 
43757fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
43767fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
43777fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
43787fedd3bbSAbhishek Pandit-Subedi 		}
43797fedd3bbSAbhishek Pandit-Subedi 	}
43807fedd3bbSAbhishek Pandit-Subedi }
43817fedd3bbSAbhishek Pandit-Subedi 
43826039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
438363d2bc1bSAndrei Emeltchenko {
438463d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
438563d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
438663d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
438763d2bc1bSAndrei Emeltchenko 	int quote;
438863d2bc1bSAndrei Emeltchenko 
438963d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
439004837f64SMarcel Holtmann 
439173d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
439273d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4393ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4394ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
439573d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
439673d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
439773d80debSLuiz Augusto von Dentz 
4398ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4399ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4400ec1cce24SLuiz Augusto von Dentz 				break;
4401ec1cce24SLuiz Augusto von Dentz 
4402ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4403ec1cce24SLuiz Augusto von Dentz 
440473d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
440573d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
440604837f64SMarcel Holtmann 
440757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
44081da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
44091da177e4SLinus Torvalds 
44101da177e4SLinus Torvalds 			hdev->acl_cnt--;
441173d80debSLuiz Augusto von Dentz 			chan->sent++;
441273d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
44137fedd3bbSAbhishek Pandit-Subedi 
44147fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
44157fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
44167fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
44171da177e4SLinus Torvalds 		}
44181da177e4SLinus Torvalds 	}
441902b20f0bSLuiz Augusto von Dentz 
442002b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
442102b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
44221da177e4SLinus Torvalds }
44231da177e4SLinus Torvalds 
44246039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4425b71d385aSAndrei Emeltchenko {
442663d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4427b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4428b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4429b71d385aSAndrei Emeltchenko 	int quote;
4430bd1eb66bSAndrei Emeltchenko 	u8 type;
4431b71d385aSAndrei Emeltchenko 
443263d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
4433b71d385aSAndrei Emeltchenko 
4434bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4435bd1eb66bSAndrei Emeltchenko 
4436bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
4437bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
4438bd1eb66bSAndrei Emeltchenko 	else
4439bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
4440bd1eb66bSAndrei Emeltchenko 
4441b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
4442bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
4443b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
4444b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
4445b71d385aSAndrei Emeltchenko 			int blocks;
4446b71d385aSAndrei Emeltchenko 
4447b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
4448b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
4449b71d385aSAndrei Emeltchenko 
4450b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
4451b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
4452b71d385aSAndrei Emeltchenko 				break;
4453b71d385aSAndrei Emeltchenko 
4454b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
4455b71d385aSAndrei Emeltchenko 
4456b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
4457b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
4458b71d385aSAndrei Emeltchenko 				return;
4459b71d385aSAndrei Emeltchenko 
4460b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
4461b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
4462b71d385aSAndrei Emeltchenko 
446357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4464b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4465b71d385aSAndrei Emeltchenko 
4466b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4467b71d385aSAndrei Emeltchenko 			quote -= blocks;
4468b71d385aSAndrei Emeltchenko 
4469b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4470b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4471b71d385aSAndrei Emeltchenko 		}
4472b71d385aSAndrei Emeltchenko 	}
4473b71d385aSAndrei Emeltchenko 
4474b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4475bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4476b71d385aSAndrei Emeltchenko }
4477b71d385aSAndrei Emeltchenko 
44786039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4479b71d385aSAndrei Emeltchenko {
4480b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4481b71d385aSAndrei Emeltchenko 
4482bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4483ca8bee5dSMarcel Holtmann 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY)
4484bd1eb66bSAndrei Emeltchenko 		return;
4485bd1eb66bSAndrei Emeltchenko 
4486bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4487bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4488b71d385aSAndrei Emeltchenko 		return;
4489b71d385aSAndrei Emeltchenko 
4490b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4491b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4492b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4493b71d385aSAndrei Emeltchenko 		break;
4494b71d385aSAndrei Emeltchenko 
4495b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4496b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4497b71d385aSAndrei Emeltchenko 		break;
4498b71d385aSAndrei Emeltchenko 	}
4499b71d385aSAndrei Emeltchenko }
4500b71d385aSAndrei Emeltchenko 
45016039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
45026ed58ec5SVille Tervo {
450373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
45046ed58ec5SVille Tervo 	struct sk_buff *skb;
450502b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
45066ed58ec5SVille Tervo 
45076ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
45086ed58ec5SVille Tervo 
450952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
451052087a79SLuiz Augusto von Dentz 		return;
451152087a79SLuiz Augusto von Dentz 
45126ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
45131b1d29e5SLuiz Augusto von Dentz 
45141b1d29e5SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt);
45151b1d29e5SLuiz Augusto von Dentz 
451602b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
451773d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4518ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4519ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
452073d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
452173d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
45226ed58ec5SVille Tervo 
4523ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4524ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4525ec1cce24SLuiz Augusto von Dentz 				break;
4526ec1cce24SLuiz Augusto von Dentz 
4527ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4528ec1cce24SLuiz Augusto von Dentz 
452957d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
45306ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
45316ed58ec5SVille Tervo 
45326ed58ec5SVille Tervo 			cnt--;
453373d80debSLuiz Augusto von Dentz 			chan->sent++;
453473d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
45357fedd3bbSAbhishek Pandit-Subedi 
45367fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
45377fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
45387fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
45396ed58ec5SVille Tervo 		}
45406ed58ec5SVille Tervo 	}
454173d80debSLuiz Augusto von Dentz 
45426ed58ec5SVille Tervo 	if (hdev->le_pkts)
45436ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
45446ed58ec5SVille Tervo 	else
45456ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
454602b20f0bSLuiz Augusto von Dentz 
454702b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
454802b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
45496ed58ec5SVille Tervo }
45506ed58ec5SVille Tervo 
45513eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
45521da177e4SLinus Torvalds {
45533eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
45541da177e4SLinus Torvalds 	struct sk_buff *skb;
45551da177e4SLinus Torvalds 
45566ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
45576ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
45581da177e4SLinus Torvalds 
4559d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
45601da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
45611da177e4SLinus Torvalds 		hci_sched_sco(hdev);
4562b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
45637fedd3bbSAbhishek Pandit-Subedi 		hci_sched_acl(hdev);
45646ed58ec5SVille Tervo 		hci_sched_le(hdev);
456552de599eSMarcel Holtmann 	}
45666ed58ec5SVille Tervo 
45671da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
45681da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
456957d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
45701da177e4SLinus Torvalds }
45711da177e4SLinus Torvalds 
457225985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
45731da177e4SLinus Torvalds 
45741da177e4SLinus Torvalds /* ACL data packet */
45756039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
45761da177e4SLinus Torvalds {
45771da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
45781da177e4SLinus Torvalds 	struct hci_conn *conn;
45791da177e4SLinus Torvalds 	__u16 handle, flags;
45801da177e4SLinus Torvalds 
45811da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
45821da177e4SLinus Torvalds 
45831da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
45841da177e4SLinus Torvalds 	flags  = hci_flags(handle);
45851da177e4SLinus Torvalds 	handle = hci_handle(handle);
45861da177e4SLinus Torvalds 
4587f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4588a8c5fb1aSGustavo Padovan 	       handle, flags);
45891da177e4SLinus Torvalds 
45901da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
45911da177e4SLinus Torvalds 
45921da177e4SLinus Torvalds 	hci_dev_lock(hdev);
45931da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
45941da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
45951da177e4SLinus Torvalds 
45961da177e4SLinus Torvalds 	if (conn) {
459765983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
459804837f64SMarcel Holtmann 
45991da177e4SLinus Torvalds 		/* Send to upper protocol */
4600686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
46011da177e4SLinus Torvalds 		return;
46021da177e4SLinus Torvalds 	} else {
46032064ee33SMarcel Holtmann 		bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
46042064ee33SMarcel Holtmann 			   handle);
46051da177e4SLinus Torvalds 	}
46061da177e4SLinus Torvalds 
46071da177e4SLinus Torvalds 	kfree_skb(skb);
46081da177e4SLinus Torvalds }
46091da177e4SLinus Torvalds 
46101da177e4SLinus Torvalds /* SCO data packet */
46116039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
46121da177e4SLinus Torvalds {
46131da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
46141da177e4SLinus Torvalds 	struct hci_conn *conn;
4615debdedf2SMarcel Holtmann 	__u16 handle, flags;
46161da177e4SLinus Torvalds 
46171da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
46181da177e4SLinus Torvalds 
46191da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
4620debdedf2SMarcel Holtmann 	flags  = hci_flags(handle);
4621debdedf2SMarcel Holtmann 	handle = hci_handle(handle);
46221da177e4SLinus Torvalds 
4623debdedf2SMarcel Holtmann 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4624debdedf2SMarcel Holtmann 	       handle, flags);
46251da177e4SLinus Torvalds 
46261da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
46271da177e4SLinus Torvalds 
46281da177e4SLinus Torvalds 	hci_dev_lock(hdev);
46291da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
46301da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
46311da177e4SLinus Torvalds 
46321da177e4SLinus Torvalds 	if (conn) {
46331da177e4SLinus Torvalds 		/* Send to upper protocol */
463400398e1dSAlain Michaud 		bt_cb(skb)->sco.pkt_status = flags & 0x03;
4635686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
46361da177e4SLinus Torvalds 		return;
46371da177e4SLinus Torvalds 	} else {
46382064ee33SMarcel Holtmann 		bt_dev_err(hdev, "SCO packet for unknown connection handle %d",
46392064ee33SMarcel Holtmann 			   handle);
46401da177e4SLinus Torvalds 	}
46411da177e4SLinus Torvalds 
46421da177e4SLinus Torvalds 	kfree_skb(skb);
46431da177e4SLinus Torvalds }
46441da177e4SLinus Torvalds 
46459238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
46469238f36aSJohan Hedberg {
46479238f36aSJohan Hedberg 	struct sk_buff *skb;
46489238f36aSJohan Hedberg 
46499238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
46509238f36aSJohan Hedberg 	if (!skb)
46519238f36aSJohan Hedberg 		return true;
46529238f36aSJohan Hedberg 
465344d27137SJohan Hedberg 	return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
46549238f36aSJohan Hedberg }
46559238f36aSJohan Hedberg 
465642c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
465742c6b129SJohan Hedberg {
465842c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
465942c6b129SJohan Hedberg 	struct sk_buff *skb;
466042c6b129SJohan Hedberg 	u16 opcode;
466142c6b129SJohan Hedberg 
466242c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
466342c6b129SJohan Hedberg 		return;
466442c6b129SJohan Hedberg 
466542c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
466642c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
466742c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
466842c6b129SJohan Hedberg 		return;
466942c6b129SJohan Hedberg 
467042c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
467142c6b129SJohan Hedberg 	if (!skb)
467242c6b129SJohan Hedberg 		return;
467342c6b129SJohan Hedberg 
467442c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
467542c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
467642c6b129SJohan Hedberg }
467742c6b129SJohan Hedberg 
4678e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
4679e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
4680e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
46819238f36aSJohan Hedberg {
46829238f36aSJohan Hedberg 	struct sk_buff *skb;
46839238f36aSJohan Hedberg 	unsigned long flags;
46849238f36aSJohan Hedberg 
46859238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
46869238f36aSJohan Hedberg 
468742c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
468842c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
46899238f36aSJohan Hedberg 	 */
469042c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
469142c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
469242c6b129SJohan Hedberg 		 * reset complete event during init and any pending
469342c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
469442c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
469542c6b129SJohan Hedberg 		 * command.
469642c6b129SJohan Hedberg 		 */
469742c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
469842c6b129SJohan Hedberg 			hci_resend_last(hdev);
469942c6b129SJohan Hedberg 
47009238f36aSJohan Hedberg 		return;
470142c6b129SJohan Hedberg 	}
47029238f36aSJohan Hedberg 
4703f80c5dadSJoão Paulo Rechi Vita 	/* If we reach this point this event matches the last command sent */
4704f80c5dadSJoão Paulo Rechi Vita 	hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
4705f80c5dadSJoão Paulo Rechi Vita 
47069238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
47079238f36aSJohan Hedberg 	 * this request the request is not yet complete.
47089238f36aSJohan Hedberg 	 */
47099238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
47109238f36aSJohan Hedberg 		return;
47119238f36aSJohan Hedberg 
47129238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
47139238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
47149238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
47159238f36aSJohan Hedberg 	 */
471644d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) {
471744d27137SJohan Hedberg 		*req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb;
4718e6214487SJohan Hedberg 		return;
47199238f36aSJohan Hedberg 	}
4720e6214487SJohan Hedberg 
472144d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_complete) {
472244d27137SJohan Hedberg 		*req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete;
4723e6214487SJohan Hedberg 		return;
472453e21fbcSJohan Hedberg 	}
47259238f36aSJohan Hedberg 
47269238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
47279238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
47289238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
472944d27137SJohan Hedberg 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
47309238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
47319238f36aSJohan Hedberg 			break;
47329238f36aSJohan Hedberg 		}
47339238f36aSJohan Hedberg 
47343bd7594eSDouglas Anderson 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
4735242c0ebdSMarcel Holtmann 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
47363bd7594eSDouglas Anderson 		else
47373bd7594eSDouglas Anderson 			*req_complete = bt_cb(skb)->hci.req_complete;
47389238f36aSJohan Hedberg 		kfree_skb(skb);
47399238f36aSJohan Hedberg 	}
47409238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
47419238f36aSJohan Hedberg }
47429238f36aSJohan Hedberg 
4743b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
47441da177e4SLinus Torvalds {
4745b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
47461da177e4SLinus Torvalds 	struct sk_buff *skb;
47471da177e4SLinus Torvalds 
47481da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
47491da177e4SLinus Torvalds 
47501da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
4751cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4752cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4753cd82e61cSMarcel Holtmann 
47541da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
47551da177e4SLinus Torvalds 			/* Send copy to the sockets */
4756470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
47571da177e4SLinus Torvalds 		}
47581da177e4SLinus Torvalds 
4759eb8c101eSMattijs Korpershoek 		/* If the device has been opened in HCI_USER_CHANNEL,
4760eb8c101eSMattijs Korpershoek 		 * the userspace has exclusive access to device.
4761eb8c101eSMattijs Korpershoek 		 * When device is HCI_INIT, we still need to process
4762eb8c101eSMattijs Korpershoek 		 * the data packets to the driver in order
4763eb8c101eSMattijs Korpershoek 		 * to complete its setup().
4764eb8c101eSMattijs Korpershoek 		 */
4765eb8c101eSMattijs Korpershoek 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
4766eb8c101eSMattijs Korpershoek 		    !test_bit(HCI_INIT, &hdev->flags)) {
47671da177e4SLinus Torvalds 			kfree_skb(skb);
47681da177e4SLinus Torvalds 			continue;
47691da177e4SLinus Torvalds 		}
47701da177e4SLinus Torvalds 
47711da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
47721da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
4773d79f34e3SMarcel Holtmann 			switch (hci_skb_pkt_type(skb)) {
47741da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
47751da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
4776cc974003SMarcel Holtmann 			case HCI_ISODATA_PKT:
47771da177e4SLinus Torvalds 				kfree_skb(skb);
47781da177e4SLinus Torvalds 				continue;
47793ff50b79SStephen Hemminger 			}
47801da177e4SLinus Torvalds 		}
47811da177e4SLinus Torvalds 
47821da177e4SLinus Torvalds 		/* Process frame */
4783d79f34e3SMarcel Holtmann 		switch (hci_skb_pkt_type(skb)) {
47841da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4785b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
47861da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
47871da177e4SLinus Torvalds 			break;
47881da177e4SLinus Torvalds 
47891da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
47901da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
47911da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
47921da177e4SLinus Torvalds 			break;
47931da177e4SLinus Torvalds 
47941da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
47951da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
47961da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
47971da177e4SLinus Torvalds 			break;
47981da177e4SLinus Torvalds 
47991da177e4SLinus Torvalds 		default:
48001da177e4SLinus Torvalds 			kfree_skb(skb);
48011da177e4SLinus Torvalds 			break;
48021da177e4SLinus Torvalds 		}
48031da177e4SLinus Torvalds 	}
48041da177e4SLinus Torvalds }
48051da177e4SLinus Torvalds 
4806c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
48071da177e4SLinus Torvalds {
4808c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
48091da177e4SLinus Torvalds 	struct sk_buff *skb;
48101da177e4SLinus Torvalds 
48112104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
48122104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
48131da177e4SLinus Torvalds 
48141da177e4SLinus Torvalds 	/* Send queued commands */
48155a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
48165a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
48175a08ecceSAndrei Emeltchenko 		if (!skb)
48185a08ecceSAndrei Emeltchenko 			return;
48195a08ecceSAndrei Emeltchenko 
48201da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
48211da177e4SLinus Torvalds 
4822a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
482370f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
4824f80c5dadSJoão Paulo Rechi Vita 			if (hci_req_status_pend(hdev))
4825f80c5dadSJoão Paulo Rechi Vita 				hci_dev_set_flag(hdev, HCI_CMD_PENDING);
48261da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
482757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
48287bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
482965cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
48307bdb8a5cSSzymon Janc 			else
483165cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
483265cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
48331da177e4SLinus Torvalds 		} else {
48341da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
4835c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
48361da177e4SLinus Torvalds 		}
48371da177e4SLinus Torvalds 	}
48381da177e4SLinus Torvalds }
4839