11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 31da177e4SLinus Torvalds Copyright (C) 2000-2001 Qualcomm Incorporated 4590051deSGustavo F. Padovan Copyright (C) 2011 ProFUSION Embedded Systems 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 91da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 101da177e4SLinus Torvalds published by the Free Software Foundation; 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 131da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 141da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 151da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 161da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 171da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 181da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 191da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 221da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 231da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 241da177e4SLinus Torvalds */ 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds /* Bluetooth HCI core. */ 271da177e4SLinus Torvalds 288c520a59SGustavo Padovan #include <linux/export.h> 29611b30f7SMarcel Holtmann #include <linux/rfkill.h> 30baf27f6eSMarcel Holtmann #include <linux/debugfs.h> 3199780a7bSJohan Hedberg #include <linux/crypto.h> 327a0e5b15SMatthias Kaehlcke #include <linux/property.h> 339952d90eSAbhishek Pandit-Subedi #include <linux/suspend.h> 349952d90eSAbhishek Pandit-Subedi #include <linux/wait.h> 3547219839SMarcel Holtmann #include <asm/unaligned.h> 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 381da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 394bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h> 40af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h> 411da177e4SLinus Torvalds 420857dd3bSJohan Hedberg #include "hci_request.h" 4360c5f5fbSMarcel Holtmann #include "hci_debugfs.h" 44970c4e46SJohan Hedberg #include "smp.h" 456d5d2ee6SHeiner Kallweit #include "leds.h" 46145373cbSMiao-chen Chou #include "msft.h" 47f67743f9SMarcel Holtmann #include "aosp.h" 48970c4e46SJohan Hedberg 49b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 50c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 513eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 521da177e4SLinus Torvalds 531da177e4SLinus Torvalds /* HCI device list */ 541da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 551da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds /* HCI callback list */ 581da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 59fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock); 601da177e4SLinus Torvalds 613df92b31SSasha Levin /* HCI ID Numbering */ 623df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 633df92b31SSasha Levin 64baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */ 65baf27f6eSMarcel Holtmann 664b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf, 674b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 684b4148e9SMarcel Holtmann { 694b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 704b4148e9SMarcel Holtmann char buf[3]; 714b4148e9SMarcel Holtmann 72b7cb93e5SMarcel Holtmann buf[0] = hci_dev_test_flag(hdev, HCI_DUT_MODE) ? 'Y' : 'N'; 734b4148e9SMarcel Holtmann buf[1] = '\n'; 744b4148e9SMarcel Holtmann buf[2] = '\0'; 754b4148e9SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 764b4148e9SMarcel Holtmann } 774b4148e9SMarcel Holtmann 784b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf, 794b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 804b4148e9SMarcel Holtmann { 814b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 824b4148e9SMarcel Holtmann struct sk_buff *skb; 834b4148e9SMarcel Holtmann bool enable; 843bf5e97dSAndy Shevchenko int err; 854b4148e9SMarcel Holtmann 864b4148e9SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 874b4148e9SMarcel Holtmann return -ENETDOWN; 884b4148e9SMarcel Holtmann 893bf5e97dSAndy Shevchenko err = kstrtobool_from_user(user_buf, count, &enable); 903bf5e97dSAndy Shevchenko if (err) 913bf5e97dSAndy Shevchenko return err; 924b4148e9SMarcel Holtmann 93b7cb93e5SMarcel Holtmann if (enable == hci_dev_test_flag(hdev, HCI_DUT_MODE)) 944b4148e9SMarcel Holtmann return -EALREADY; 954b4148e9SMarcel Holtmann 96b504430cSJohan Hedberg hci_req_sync_lock(hdev); 974b4148e9SMarcel Holtmann if (enable) 984b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL, 994b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1004b4148e9SMarcel Holtmann else 1014b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, 1024b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 103b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 1044b4148e9SMarcel Holtmann 1054b4148e9SMarcel Holtmann if (IS_ERR(skb)) 1064b4148e9SMarcel Holtmann return PTR_ERR(skb); 1074b4148e9SMarcel Holtmann 1084b4148e9SMarcel Holtmann kfree_skb(skb); 1094b4148e9SMarcel Holtmann 110b7cb93e5SMarcel Holtmann hci_dev_change_flag(hdev, HCI_DUT_MODE); 1114b4148e9SMarcel Holtmann 1124b4148e9SMarcel Holtmann return count; 1134b4148e9SMarcel Holtmann } 1144b4148e9SMarcel Holtmann 1154b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = { 1164b4148e9SMarcel Holtmann .open = simple_open, 1174b4148e9SMarcel Holtmann .read = dut_mode_read, 1184b4148e9SMarcel Holtmann .write = dut_mode_write, 1194b4148e9SMarcel Holtmann .llseek = default_llseek, 1204b4148e9SMarcel Holtmann }; 1214b4148e9SMarcel Holtmann 1224b4113d6SMarcel Holtmann static ssize_t vendor_diag_read(struct file *file, char __user *user_buf, 1234b4113d6SMarcel Holtmann size_t count, loff_t *ppos) 1244b4113d6SMarcel Holtmann { 1254b4113d6SMarcel Holtmann struct hci_dev *hdev = file->private_data; 1264b4113d6SMarcel Holtmann char buf[3]; 1274b4113d6SMarcel Holtmann 1284b4113d6SMarcel Holtmann buf[0] = hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) ? 'Y' : 'N'; 1294b4113d6SMarcel Holtmann buf[1] = '\n'; 1304b4113d6SMarcel Holtmann buf[2] = '\0'; 1314b4113d6SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 1324b4113d6SMarcel Holtmann } 1334b4113d6SMarcel Holtmann 1344b4113d6SMarcel Holtmann static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf, 1354b4113d6SMarcel Holtmann size_t count, loff_t *ppos) 1364b4113d6SMarcel Holtmann { 1374b4113d6SMarcel Holtmann struct hci_dev *hdev = file->private_data; 1384b4113d6SMarcel Holtmann bool enable; 1394b4113d6SMarcel Holtmann int err; 1404b4113d6SMarcel Holtmann 1413bf5e97dSAndy Shevchenko err = kstrtobool_from_user(user_buf, count, &enable); 1423bf5e97dSAndy Shevchenko if (err) 1433bf5e97dSAndy Shevchenko return err; 1444b4113d6SMarcel Holtmann 1457e995b9eSMarcel Holtmann /* When the diagnostic flags are not persistent and the transport 146b56c7b25SMarcel Holtmann * is not active or in user channel operation, then there is no need 147b56c7b25SMarcel Holtmann * for the vendor callback. Instead just store the desired value and 148b56c7b25SMarcel Holtmann * the setting will be programmed when the controller gets powered on. 1497e995b9eSMarcel Holtmann */ 1507e995b9eSMarcel Holtmann if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) && 151b56c7b25SMarcel Holtmann (!test_bit(HCI_RUNNING, &hdev->flags) || 152b56c7b25SMarcel Holtmann hci_dev_test_flag(hdev, HCI_USER_CHANNEL))) 1537e995b9eSMarcel Holtmann goto done; 1547e995b9eSMarcel Holtmann 155b504430cSJohan Hedberg hci_req_sync_lock(hdev); 1564b4113d6SMarcel Holtmann err = hdev->set_diag(hdev, enable); 157b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 1584b4113d6SMarcel Holtmann 1594b4113d6SMarcel Holtmann if (err < 0) 1604b4113d6SMarcel Holtmann return err; 1614b4113d6SMarcel Holtmann 1627e995b9eSMarcel Holtmann done: 1634b4113d6SMarcel Holtmann if (enable) 1644b4113d6SMarcel Holtmann hci_dev_set_flag(hdev, HCI_VENDOR_DIAG); 1654b4113d6SMarcel Holtmann else 1664b4113d6SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_VENDOR_DIAG); 1674b4113d6SMarcel Holtmann 1684b4113d6SMarcel Holtmann return count; 1694b4113d6SMarcel Holtmann } 1704b4113d6SMarcel Holtmann 1714b4113d6SMarcel Holtmann static const struct file_operations vendor_diag_fops = { 1724b4113d6SMarcel Holtmann .open = simple_open, 1734b4113d6SMarcel Holtmann .read = vendor_diag_read, 1744b4113d6SMarcel Holtmann .write = vendor_diag_write, 1754b4113d6SMarcel Holtmann .llseek = default_llseek, 1764b4113d6SMarcel Holtmann }; 1774b4113d6SMarcel Holtmann 178f640ee98SMarcel Holtmann static void hci_debugfs_create_basic(struct hci_dev *hdev) 179f640ee98SMarcel Holtmann { 180f640ee98SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 181f640ee98SMarcel Holtmann &dut_mode_fops); 182f640ee98SMarcel Holtmann 183f640ee98SMarcel Holtmann if (hdev->set_diag) 184f640ee98SMarcel Holtmann debugfs_create_file("vendor_diag", 0644, hdev->debugfs, hdev, 185f640ee98SMarcel Holtmann &vendor_diag_fops); 186f640ee98SMarcel Holtmann } 187f640ee98SMarcel Holtmann 188a1d01db1SJohan Hedberg static int hci_reset_req(struct hci_request *req, unsigned long opt) 1891da177e4SLinus Torvalds { 19042c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 1911da177e4SLinus Torvalds 1921da177e4SLinus Torvalds /* Reset device */ 19342c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 19442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 195a1d01db1SJohan Hedberg return 0; 1961da177e4SLinus Torvalds } 1971da177e4SLinus Torvalds 19842c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 1991da177e4SLinus Torvalds { 20042c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 2012455a3eaSAndrei Emeltchenko 2021da177e4SLinus Torvalds /* Read Local Supported Features */ 20342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 2041da177e4SLinus Torvalds 2051143e5a6SMarcel Holtmann /* Read Local Version */ 20642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2072177bab5SJohan Hedberg 2082177bab5SJohan Hedberg /* Read BD Address */ 20942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 2101da177e4SLinus Torvalds } 2111da177e4SLinus Torvalds 2120af801b9SJohan Hedberg static void amp_init1(struct hci_request *req) 213e61ef499SAndrei Emeltchenko { 21442c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 2152455a3eaSAndrei Emeltchenko 216e61ef499SAndrei Emeltchenko /* Read Local Version */ 21742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2186bcbc489SAndrei Emeltchenko 219f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 220f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 221f6996cfeSMarcel Holtmann 2226bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 22342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 224e71dfabaSAndrei Emeltchenko 225e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 22642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 2277528ca1cSMarcel Holtmann 228f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 229f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 230f38ba941SMarcel Holtmann 2317528ca1cSMarcel Holtmann /* Read Location Data */ 2327528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 233e61ef499SAndrei Emeltchenko } 234e61ef499SAndrei Emeltchenko 235a1d01db1SJohan Hedberg static int amp_init2(struct hci_request *req) 2360af801b9SJohan Hedberg { 2370af801b9SJohan Hedberg /* Read Local Supported Features. Not all AMP controllers 2380af801b9SJohan Hedberg * support this so it's placed conditionally in the second 2390af801b9SJohan Hedberg * stage init. 2400af801b9SJohan Hedberg */ 2410af801b9SJohan Hedberg if (req->hdev->commands[14] & 0x20) 2420af801b9SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 243a1d01db1SJohan Hedberg 244a1d01db1SJohan Hedberg return 0; 2450af801b9SJohan Hedberg } 2460af801b9SJohan Hedberg 247a1d01db1SJohan Hedberg static int hci_init1_req(struct hci_request *req, unsigned long opt) 248e61ef499SAndrei Emeltchenko { 24942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 250e61ef499SAndrei Emeltchenko 251e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 252e61ef499SAndrei Emeltchenko 25311778716SAndrei Emeltchenko /* Reset */ 25411778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 25542c6b129SJohan Hedberg hci_reset_req(req, 0); 25611778716SAndrei Emeltchenko 257e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 258ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 25942c6b129SJohan Hedberg bredr_init(req); 260e61ef499SAndrei Emeltchenko break; 261e61ef499SAndrei Emeltchenko case HCI_AMP: 2620af801b9SJohan Hedberg amp_init1(req); 263e61ef499SAndrei Emeltchenko break; 264e61ef499SAndrei Emeltchenko default: 2652064ee33SMarcel Holtmann bt_dev_err(hdev, "Unknown device type %d", hdev->dev_type); 266e61ef499SAndrei Emeltchenko break; 267e61ef499SAndrei Emeltchenko } 268a1d01db1SJohan Hedberg 269a1d01db1SJohan Hedberg return 0; 270e61ef499SAndrei Emeltchenko } 271e61ef499SAndrei Emeltchenko 27242c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 2732177bab5SJohan Hedberg { 2742177bab5SJohan Hedberg __le16 param; 2752177bab5SJohan Hedberg __u8 flt_type; 2762177bab5SJohan Hedberg 2772177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 27842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 2792177bab5SJohan Hedberg 2802177bab5SJohan Hedberg /* Read Class of Device */ 28142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 2822177bab5SJohan Hedberg 2832177bab5SJohan Hedberg /* Read Local Name */ 28442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 2852177bab5SJohan Hedberg 2862177bab5SJohan Hedberg /* Read Voice Setting */ 28742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 2882177bab5SJohan Hedberg 289b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 290b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 291b4cb9fb2SMarcel Holtmann 2924b836f39SMarcel Holtmann /* Read Current IAC LAP */ 2934b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 2944b836f39SMarcel Holtmann 2952177bab5SJohan Hedberg /* Clear Event Filters */ 2962177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 29742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 2982177bab5SJohan Hedberg 2992177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 300dcf4adbfSJoe Perches param = cpu_to_le16(0x7d00); 30142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 3022177bab5SJohan Hedberg } 3032177bab5SJohan Hedberg 30442c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 3052177bab5SJohan Hedberg { 306c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 307c73eee91SJohan Hedberg 3082177bab5SJohan Hedberg /* Read LE Buffer Size */ 30942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 3102177bab5SJohan Hedberg 3112177bab5SJohan Hedberg /* Read LE Local Supported Features */ 31242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 3132177bab5SJohan Hedberg 314747d3f03SMarcel Holtmann /* Read LE Supported States */ 315747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 316747d3f03SMarcel Holtmann 317c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 318c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 319a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ENABLED); 3202177bab5SJohan Hedberg } 3212177bab5SJohan Hedberg 32242c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 3232177bab5SJohan Hedberg { 32442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 32542c6b129SJohan Hedberg 3262177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 3272177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 3282177bab5SJohan Hedberg * command otherwise. 3292177bab5SJohan Hedberg */ 3302177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 3312177bab5SJohan Hedberg 3322177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 3332177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 3342177bab5SJohan Hedberg */ 3352177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 3362177bab5SJohan Hedberg return; 3372177bab5SJohan Hedberg 3382177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 3392177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 340c7882cbdSMarcel Holtmann } else { 341c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 342c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 343c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 344c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 345c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 3465c3d3b4cSMarcel Holtmann 3475c3d3b4cSMarcel Holtmann /* If the controller supports the Disconnect command, enable 3485c3d3b4cSMarcel Holtmann * the corresponding event. In addition enable packet flow 3495c3d3b4cSMarcel Holtmann * control related events. 3505c3d3b4cSMarcel Holtmann */ 3515c3d3b4cSMarcel Holtmann if (hdev->commands[0] & 0x20) { 3525c3d3b4cSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 353c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 354c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 3555c3d3b4cSMarcel Holtmann } 3565c3d3b4cSMarcel Holtmann 3575c3d3b4cSMarcel Holtmann /* If the controller supports the Read Remote Version 3585c3d3b4cSMarcel Holtmann * Information command, enable the corresponding event. 3595c3d3b4cSMarcel Holtmann */ 3605c3d3b4cSMarcel Holtmann if (hdev->commands[2] & 0x80) 3615c3d3b4cSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information 3625c3d3b4cSMarcel Holtmann * Complete 3635c3d3b4cSMarcel Holtmann */ 3640da71f1bSMarcel Holtmann 3650da71f1bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) { 3660da71f1bSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 367c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 3682177bab5SJohan Hedberg } 3690da71f1bSMarcel Holtmann } 3702177bab5SJohan Hedberg 3719fe759ceSMarcel Holtmann if (lmp_inq_rssi_capable(hdev) || 3729fe759ceSMarcel Holtmann test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) 3732177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 3742177bab5SJohan Hedberg 37570f56aa2SMarcel Holtmann if (lmp_ext_feat_capable(hdev)) 37670f56aa2SMarcel Holtmann events[4] |= 0x04; /* Read Remote Extended Features Complete */ 37770f56aa2SMarcel Holtmann 37870f56aa2SMarcel Holtmann if (lmp_esco_capable(hdev)) { 37970f56aa2SMarcel Holtmann events[5] |= 0x08; /* Synchronous Connection Complete */ 38070f56aa2SMarcel Holtmann events[5] |= 0x10; /* Synchronous Connection Changed */ 38170f56aa2SMarcel Holtmann } 38270f56aa2SMarcel Holtmann 3832177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 3842177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 3852177bab5SJohan Hedberg 3862177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 3872177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 3882177bab5SJohan Hedberg 3892177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 3902177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 3912177bab5SJohan Hedberg 3922177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 3932177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 3942177bab5SJohan Hedberg 3952177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 3962177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 3972177bab5SJohan Hedberg 3982177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 3992177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 4002177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 4012177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 4022177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 4032177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 4042177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 4052177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 4062177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 4072177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 4082177bab5SJohan Hedberg * Features Notification 4092177bab5SJohan Hedberg */ 4102177bab5SJohan Hedberg } 4112177bab5SJohan Hedberg 4122177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 4132177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 4142177bab5SJohan Hedberg 41542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 4162177bab5SJohan Hedberg } 4172177bab5SJohan Hedberg 418a1d01db1SJohan Hedberg static int hci_init2_req(struct hci_request *req, unsigned long opt) 4192177bab5SJohan Hedberg { 42042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 42142c6b129SJohan Hedberg 4220af801b9SJohan Hedberg if (hdev->dev_type == HCI_AMP) 4230af801b9SJohan Hedberg return amp_init2(req); 4240af801b9SJohan Hedberg 4252177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 42642c6b129SJohan Hedberg bredr_setup(req); 42756f87901SJohan Hedberg else 428a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED); 4292177bab5SJohan Hedberg 4302177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 43142c6b129SJohan Hedberg le_setup(req); 4322177bab5SJohan Hedberg 4330f3adeaeSMarcel Holtmann /* All Bluetooth 1.2 and later controllers should support the 4340f3adeaeSMarcel Holtmann * HCI command for reading the local supported commands. 4350f3adeaeSMarcel Holtmann * 4360f3adeaeSMarcel Holtmann * Unfortunately some controllers indicate Bluetooth 1.2 support, 4370f3adeaeSMarcel Holtmann * but do not have support for this command. If that is the case, 4380f3adeaeSMarcel Holtmann * the driver can quirk the behavior and skip reading the local 4390f3adeaeSMarcel Holtmann * supported commands. 4403f8e2d75SJohan Hedberg */ 4410f3adeaeSMarcel Holtmann if (hdev->hci_ver > BLUETOOTH_VER_1_1 && 4420f3adeaeSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks)) 44342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 4442177bab5SJohan Hedberg 4452177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 44657af75a8SMarcel Holtmann /* When SSP is available, then the host features page 44757af75a8SMarcel Holtmann * should also be available as well. However some 44857af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 44957af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 45057af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 45157af75a8SMarcel Holtmann */ 45257af75a8SMarcel Holtmann hdev->max_page = 0x01; 45357af75a8SMarcel Holtmann 454d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) { 4552177bab5SJohan Hedberg u8 mode = 0x01; 456574ea3c7SMarcel Holtmann 45742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 4582177bab5SJohan Hedberg sizeof(mode), &mode); 4592177bab5SJohan Hedberg } else { 4602177bab5SJohan Hedberg struct hci_cp_write_eir cp; 4612177bab5SJohan Hedberg 4622177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 4632177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 4642177bab5SJohan Hedberg 46542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 4662177bab5SJohan Hedberg } 4672177bab5SJohan Hedberg } 4682177bab5SJohan Hedberg 469043ec9bfSMarcel Holtmann if (lmp_inq_rssi_capable(hdev) || 470043ec9bfSMarcel Holtmann test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) { 47104422da9SMarcel Holtmann u8 mode; 47204422da9SMarcel Holtmann 47304422da9SMarcel Holtmann /* If Extended Inquiry Result events are supported, then 47404422da9SMarcel Holtmann * they are clearly preferred over Inquiry Result with RSSI 47504422da9SMarcel Holtmann * events. 47604422da9SMarcel Holtmann */ 47704422da9SMarcel Holtmann mode = lmp_ext_inq_capable(hdev) ? 0x02 : 0x01; 47804422da9SMarcel Holtmann 47904422da9SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 48004422da9SMarcel Holtmann } 4812177bab5SJohan Hedberg 4822177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 48342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 4842177bab5SJohan Hedberg 4852177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 4862177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 4872177bab5SJohan Hedberg 4882177bab5SJohan Hedberg cp.page = 0x01; 48942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 49042c6b129SJohan Hedberg sizeof(cp), &cp); 4912177bab5SJohan Hedberg } 4922177bab5SJohan Hedberg 493d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LINK_SECURITY)) { 4942177bab5SJohan Hedberg u8 enable = 1; 49542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 4962177bab5SJohan Hedberg &enable); 4972177bab5SJohan Hedberg } 498a1d01db1SJohan Hedberg 499a1d01db1SJohan Hedberg return 0; 5002177bab5SJohan Hedberg } 5012177bab5SJohan Hedberg 50242c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 5032177bab5SJohan Hedberg { 50442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 5052177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 5062177bab5SJohan Hedberg u16 link_policy = 0; 5072177bab5SJohan Hedberg 5082177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 5092177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 5102177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 5112177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 5122177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 5132177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 5142177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 5152177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 5162177bab5SJohan Hedberg 5172177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 51842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 5192177bab5SJohan Hedberg } 5202177bab5SJohan Hedberg 52142c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 5222177bab5SJohan Hedberg { 52342c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 5242177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 5252177bab5SJohan Hedberg 526c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 527c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 528c73eee91SJohan Hedberg return; 529c73eee91SJohan Hedberg 5302177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 5312177bab5SJohan Hedberg 532d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) { 5332177bab5SJohan Hedberg cp.le = 0x01; 53432226e4fSMarcel Holtmann cp.simul = 0x00; 5352177bab5SJohan Hedberg } 5362177bab5SJohan Hedberg 5372177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 53842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 5392177bab5SJohan Hedberg &cp); 5402177bab5SJohan Hedberg } 5412177bab5SJohan Hedberg 542d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 543d62e6d67SJohan Hedberg { 544d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 545d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 546313f6888SMarcel Holtmann bool changed = false; 547d62e6d67SJohan Hedberg 548d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 549d62e6d67SJohan Hedberg * enable all necessary events for it. 550d62e6d67SJohan Hedberg */ 55153b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 552d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 553d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 554d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 555d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 556313f6888SMarcel Holtmann changed = true; 557d62e6d67SJohan Hedberg } 558d62e6d67SJohan Hedberg 559d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 560d62e6d67SJohan Hedberg * enable all necessary events for it. 561d62e6d67SJohan Hedberg */ 56253b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 563d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 564d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 565d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 566d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 567313f6888SMarcel Holtmann changed = true; 568d62e6d67SJohan Hedberg } 569d62e6d67SJohan Hedberg 57040c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 571313f6888SMarcel Holtmann if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) { 57240c59fcbSMarcel Holtmann events[2] |= 0x80; 573313f6888SMarcel Holtmann changed = true; 574313f6888SMarcel Holtmann } 57540c59fcbSMarcel Holtmann 576313f6888SMarcel Holtmann /* Some Broadcom based controllers indicate support for Set Event 577313f6888SMarcel Holtmann * Mask Page 2 command, but then actually do not support it. Since 578313f6888SMarcel Holtmann * the default value is all bits set to zero, the command is only 579313f6888SMarcel Holtmann * required if the event mask has to be changed. In case no change 580313f6888SMarcel Holtmann * to the event mask is needed, skip this command. 581313f6888SMarcel Holtmann */ 582313f6888SMarcel Holtmann if (changed) 583313f6888SMarcel Holtmann hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, 584313f6888SMarcel Holtmann sizeof(events), events); 585d62e6d67SJohan Hedberg } 586d62e6d67SJohan Hedberg 587a1d01db1SJohan Hedberg static int hci_init3_req(struct hci_request *req, unsigned long opt) 5882177bab5SJohan Hedberg { 58942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 590d2c5d77fSJohan Hedberg u8 p; 59142c6b129SJohan Hedberg 5920da71f1bSMarcel Holtmann hci_setup_event_mask(req); 5930da71f1bSMarcel Holtmann 594e81be90bSJohan Hedberg if (hdev->commands[6] & 0x20 && 595e81be90bSJohan Hedberg !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 59648ce62c4SMarcel Holtmann struct hci_cp_read_stored_link_key cp; 59748ce62c4SMarcel Holtmann 59848ce62c4SMarcel Holtmann bacpy(&cp.bdaddr, BDADDR_ANY); 59948ce62c4SMarcel Holtmann cp.read_all = 0x01; 60048ce62c4SMarcel Holtmann hci_req_add(req, HCI_OP_READ_STORED_LINK_KEY, sizeof(cp), &cp); 60148ce62c4SMarcel Holtmann } 60248ce62c4SMarcel Holtmann 6032177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 60442c6b129SJohan Hedberg hci_setup_link_policy(req); 6052177bab5SJohan Hedberg 606417287deSMarcel Holtmann if (hdev->commands[8] & 0x01) 607417287deSMarcel Holtmann hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 608417287deSMarcel Holtmann 609cde1a8a9SIsmael Ferreras Morezuelas if (hdev->commands[18] & 0x04 && 610cde1a8a9SIsmael Ferreras Morezuelas !test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks)) 61100bce3fbSAlain Michaud hci_req_add(req, HCI_OP_READ_DEF_ERR_DATA_REPORTING, 0, NULL); 61200bce3fbSAlain Michaud 613417287deSMarcel Holtmann /* Some older Broadcom based Bluetooth 1.2 controllers do not 614417287deSMarcel Holtmann * support the Read Page Scan Type command. Check support for 615417287deSMarcel Holtmann * this command in the bit mask of supported commands. 616417287deSMarcel Holtmann */ 617417287deSMarcel Holtmann if (hdev->commands[13] & 0x01) 618417287deSMarcel Holtmann hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 619417287deSMarcel Holtmann 6209193c6e8SAndre Guedes if (lmp_le_capable(hdev)) { 6219193c6e8SAndre Guedes u8 events[8]; 6229193c6e8SAndre Guedes 6239193c6e8SAndre Guedes memset(events, 0, sizeof(events)); 6244d6c705bSMarcel Holtmann 6254d6c705bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) 6264d6c705bSMarcel Holtmann events[0] |= 0x10; /* LE Long Term Key Request */ 627662bc2e6SAndre Guedes 628662bc2e6SAndre Guedes /* If controller supports the Connection Parameters Request 629662bc2e6SAndre Guedes * Link Layer Procedure, enable the corresponding event. 630662bc2e6SAndre Guedes */ 631662bc2e6SAndre Guedes if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC) 632662bc2e6SAndre Guedes events[0] |= 0x20; /* LE Remote Connection 633662bc2e6SAndre Guedes * Parameter Request 634662bc2e6SAndre Guedes */ 635662bc2e6SAndre Guedes 636a9f6068eSMarcel Holtmann /* If the controller supports the Data Length Extension 637a9f6068eSMarcel Holtmann * feature, enable the corresponding event. 638a9f6068eSMarcel Holtmann */ 639a9f6068eSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) 640a9f6068eSMarcel Holtmann events[0] |= 0x40; /* LE Data Length Change */ 641a9f6068eSMarcel Holtmann 642ff3b8df2SMarcel Holtmann /* If the controller supports LL Privacy feature, enable 643ff3b8df2SMarcel Holtmann * the corresponding event. 644ff3b8df2SMarcel Holtmann */ 645ff3b8df2SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_LL_PRIVACY) 646ff3b8df2SMarcel Holtmann events[1] |= 0x02; /* LE Enhanced Connection 647ff3b8df2SMarcel Holtmann * Complete 648ff3b8df2SMarcel Holtmann */ 649ff3b8df2SMarcel Holtmann 6504b71bba4SMarcel Holtmann /* If the controller supports Extended Scanner Filter 65191641b79SZheng Yongjun * Policies, enable the corresponding event. 6524b71bba4SMarcel Holtmann */ 6534b71bba4SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY) 6544b71bba4SMarcel Holtmann events[1] |= 0x04; /* LE Direct Advertising 6554b71bba4SMarcel Holtmann * Report 6564b71bba4SMarcel Holtmann */ 6574b71bba4SMarcel Holtmann 6589756d33bSMarcel Holtmann /* If the controller supports Channel Selection Algorithm #2 6599756d33bSMarcel Holtmann * feature, enable the corresponding event. 6609756d33bSMarcel Holtmann */ 6619756d33bSMarcel Holtmann if (hdev->le_features[1] & HCI_LE_CHAN_SEL_ALG2) 6629756d33bSMarcel Holtmann events[2] |= 0x08; /* LE Channel Selection 6639756d33bSMarcel Holtmann * Algorithm 6649756d33bSMarcel Holtmann */ 6659756d33bSMarcel Holtmann 6667d26f5c4SMarcel Holtmann /* If the controller supports the LE Set Scan Enable command, 6677d26f5c4SMarcel Holtmann * enable the corresponding advertising report event. 6687d26f5c4SMarcel Holtmann */ 6697d26f5c4SMarcel Holtmann if (hdev->commands[26] & 0x08) 6707d26f5c4SMarcel Holtmann events[0] |= 0x02; /* LE Advertising Report */ 6717d26f5c4SMarcel Holtmann 6727d26f5c4SMarcel Holtmann /* If the controller supports the LE Create Connection 6737d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6747d26f5c4SMarcel Holtmann */ 6757d26f5c4SMarcel Holtmann if (hdev->commands[26] & 0x10) 6767d26f5c4SMarcel Holtmann events[0] |= 0x01; /* LE Connection Complete */ 6777d26f5c4SMarcel Holtmann 6787d26f5c4SMarcel Holtmann /* If the controller supports the LE Connection Update 6797d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6807d26f5c4SMarcel Holtmann */ 6817d26f5c4SMarcel Holtmann if (hdev->commands[27] & 0x04) 6827d26f5c4SMarcel Holtmann events[0] |= 0x04; /* LE Connection Update 6837d26f5c4SMarcel Holtmann * Complete 6847d26f5c4SMarcel Holtmann */ 6857d26f5c4SMarcel Holtmann 6867d26f5c4SMarcel Holtmann /* If the controller supports the LE Read Remote Used Features 6877d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6887d26f5c4SMarcel Holtmann */ 6897d26f5c4SMarcel Holtmann if (hdev->commands[27] & 0x20) 6907d26f5c4SMarcel Holtmann events[0] |= 0x08; /* LE Read Remote Used 6917d26f5c4SMarcel Holtmann * Features Complete 6927d26f5c4SMarcel Holtmann */ 6937d26f5c4SMarcel Holtmann 6945a34bd5fSMarcel Holtmann /* If the controller supports the LE Read Local P-256 6955a34bd5fSMarcel Holtmann * Public Key command, enable the corresponding event. 6965a34bd5fSMarcel Holtmann */ 6975a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x02) 6985a34bd5fSMarcel Holtmann events[0] |= 0x80; /* LE Read Local P-256 6995a34bd5fSMarcel Holtmann * Public Key Complete 7005a34bd5fSMarcel Holtmann */ 7015a34bd5fSMarcel Holtmann 7025a34bd5fSMarcel Holtmann /* If the controller supports the LE Generate DHKey 7035a34bd5fSMarcel Holtmann * command, enable the corresponding event. 7045a34bd5fSMarcel Holtmann */ 7055a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x04) 7065a34bd5fSMarcel Holtmann events[1] |= 0x01; /* LE Generate DHKey Complete */ 7075a34bd5fSMarcel Holtmann 70827bbca44SMarcel Holtmann /* If the controller supports the LE Set Default PHY or 70927bbca44SMarcel Holtmann * LE Set PHY commands, enable the corresponding event. 71027bbca44SMarcel Holtmann */ 71127bbca44SMarcel Holtmann if (hdev->commands[35] & (0x20 | 0x40)) 71227bbca44SMarcel Holtmann events[1] |= 0x08; /* LE PHY Update Complete */ 71327bbca44SMarcel Holtmann 714c215e939SJaganath Kanakkassery /* If the controller supports LE Set Extended Scan Parameters 715c215e939SJaganath Kanakkassery * and LE Set Extended Scan Enable commands, enable the 716c215e939SJaganath Kanakkassery * corresponding event. 717c215e939SJaganath Kanakkassery */ 718c215e939SJaganath Kanakkassery if (use_ext_scan(hdev)) 719c215e939SJaganath Kanakkassery events[1] |= 0x10; /* LE Extended Advertising 720c215e939SJaganath Kanakkassery * Report 721c215e939SJaganath Kanakkassery */ 722c215e939SJaganath Kanakkassery 723acf0aeaeSJaganath Kanakkassery /* If the controller supports the LE Extended Advertising 724acf0aeaeSJaganath Kanakkassery * command, enable the corresponding event. 725acf0aeaeSJaganath Kanakkassery */ 726acf0aeaeSJaganath Kanakkassery if (ext_adv_capable(hdev)) 727acf0aeaeSJaganath Kanakkassery events[2] |= 0x02; /* LE Advertising Set 728acf0aeaeSJaganath Kanakkassery * Terminated 729acf0aeaeSJaganath Kanakkassery */ 730acf0aeaeSJaganath Kanakkassery 7319193c6e8SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), 7329193c6e8SAndre Guedes events); 7339193c6e8SAndre Guedes 73415a49ccaSMarcel Holtmann /* Read LE Advertising Channel TX Power */ 7356b49bcb4SJaganath Kanakkassery if ((hdev->commands[25] & 0x40) && !ext_adv_capable(hdev)) { 7366b49bcb4SJaganath Kanakkassery /* HCI TS spec forbids mixing of legacy and extended 7376b49bcb4SJaganath Kanakkassery * advertising commands wherein READ_ADV_TX_POWER is 7386b49bcb4SJaganath Kanakkassery * also included. So do not call it if extended adv 7396b49bcb4SJaganath Kanakkassery * is supported otherwise controller will return 7406b49bcb4SJaganath Kanakkassery * COMMAND_DISALLOWED for extended commands. 7416b49bcb4SJaganath Kanakkassery */ 74215a49ccaSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 74315a49ccaSMarcel Holtmann } 74415a49ccaSMarcel Holtmann 7457c395ea5SDaniel Winkler if (hdev->commands[38] & 0x80) { 7467c395ea5SDaniel Winkler /* Read LE Min/Max Tx Power*/ 7477c395ea5SDaniel Winkler hci_req_add(req, HCI_OP_LE_READ_TRANSMIT_POWER, 7487c395ea5SDaniel Winkler 0, NULL); 7497c395ea5SDaniel Winkler } 7507c395ea5SDaniel Winkler 7512ab216a7SMarcel Holtmann if (hdev->commands[26] & 0x40) { 7522ab216a7SMarcel Holtmann /* Read LE White List Size */ 7532ab216a7SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 7542ab216a7SMarcel Holtmann 0, NULL); 7552ab216a7SMarcel Holtmann } 7562ab216a7SMarcel Holtmann 7572ab216a7SMarcel Holtmann if (hdev->commands[26] & 0x80) { 7582ab216a7SMarcel Holtmann /* Clear LE White List */ 7592ab216a7SMarcel Holtmann hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL); 7602ab216a7SMarcel Holtmann } 7612ab216a7SMarcel Holtmann 762cfdb0c2dSAnkit Navik if (hdev->commands[34] & 0x40) { 763cfdb0c2dSAnkit Navik /* Read LE Resolving List Size */ 764cfdb0c2dSAnkit Navik hci_req_add(req, HCI_OP_LE_READ_RESOLV_LIST_SIZE, 765cfdb0c2dSAnkit Navik 0, NULL); 766cfdb0c2dSAnkit Navik } 767cfdb0c2dSAnkit Navik 768545f2596SAnkit Navik if (hdev->commands[34] & 0x20) { 769545f2596SAnkit Navik /* Clear LE Resolving List */ 770545f2596SAnkit Navik hci_req_add(req, HCI_OP_LE_CLEAR_RESOLV_LIST, 0, NULL); 771545f2596SAnkit Navik } 772545f2596SAnkit Navik 773a31489d2SEdward Vear if (hdev->commands[35] & 0x04) { 774b2cc2339SSathish Narasimman __le16 rpa_timeout = cpu_to_le16(hdev->rpa_timeout); 775b2cc2339SSathish Narasimman 776b2cc2339SSathish Narasimman /* Set RPA timeout */ 777b2cc2339SSathish Narasimman hci_req_add(req, HCI_OP_LE_SET_RPA_TIMEOUT, 2, 778b2cc2339SSathish Narasimman &rpa_timeout); 779b2cc2339SSathish Narasimman } 780b2cc2339SSathish Narasimman 781a9f6068eSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { 782a9f6068eSMarcel Holtmann /* Read LE Maximum Data Length */ 783a9f6068eSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL); 784a9f6068eSMarcel Holtmann 785a9f6068eSMarcel Holtmann /* Read LE Suggested Default Data Length */ 786a9f6068eSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL); 787a9f6068eSMarcel Holtmann } 788a9f6068eSMarcel Holtmann 7896b49bcb4SJaganath Kanakkassery if (ext_adv_capable(hdev)) { 7906b49bcb4SJaganath Kanakkassery /* Read LE Number of Supported Advertising Sets */ 7916b49bcb4SJaganath Kanakkassery hci_req_add(req, HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS, 7926b49bcb4SJaganath Kanakkassery 0, NULL); 7936b49bcb4SJaganath Kanakkassery } 7946b49bcb4SJaganath Kanakkassery 79542c6b129SJohan Hedberg hci_set_le_support(req); 7969193c6e8SAndre Guedes } 797d2c5d77fSJohan Hedberg 798d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 799d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 800d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 801d2c5d77fSJohan Hedberg 802d2c5d77fSJohan Hedberg cp.page = p; 803d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 804d2c5d77fSJohan Hedberg sizeof(cp), &cp); 805d2c5d77fSJohan Hedberg } 806a1d01db1SJohan Hedberg 807a1d01db1SJohan Hedberg return 0; 8082177bab5SJohan Hedberg } 8092177bab5SJohan Hedberg 810a1d01db1SJohan Hedberg static int hci_init4_req(struct hci_request *req, unsigned long opt) 8115d4e7e8dSJohan Hedberg { 8125d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 8135d4e7e8dSJohan Hedberg 81436f260ceSMarcel Holtmann /* Some Broadcom based Bluetooth controllers do not support the 81536f260ceSMarcel Holtmann * Delete Stored Link Key command. They are clearly indicating its 81636f260ceSMarcel Holtmann * absence in the bit mask of supported commands. 81736f260ceSMarcel Holtmann * 818bb6d6895SRandy Dunlap * Check the supported commands and only if the command is marked 81936f260ceSMarcel Holtmann * as supported send it. If not supported assume that the controller 82036f260ceSMarcel Holtmann * does not have actual support for stored link keys which makes this 82136f260ceSMarcel Holtmann * command redundant anyway. 82236f260ceSMarcel Holtmann * 82336f260ceSMarcel Holtmann * Some controllers indicate that they support handling deleting 82436f260ceSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 82536f260ceSMarcel Holtmann * just disable this command. 82636f260ceSMarcel Holtmann */ 82736f260ceSMarcel Holtmann if (hdev->commands[6] & 0x80 && 82836f260ceSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 82936f260ceSMarcel Holtmann struct hci_cp_delete_stored_link_key cp; 83036f260ceSMarcel Holtmann 83136f260ceSMarcel Holtmann bacpy(&cp.bdaddr, BDADDR_ANY); 83236f260ceSMarcel Holtmann cp.delete_all = 0x01; 83336f260ceSMarcel Holtmann hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 83436f260ceSMarcel Holtmann sizeof(cp), &cp); 83536f260ceSMarcel Holtmann } 83636f260ceSMarcel Holtmann 837d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 838d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 839d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 840d62e6d67SJohan Hedberg 841109e3191SMarcel Holtmann /* Read local codec list if the HCI command is supported */ 842109e3191SMarcel Holtmann if (hdev->commands[29] & 0x20) 843109e3191SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL); 844109e3191SMarcel Holtmann 845a4790360SMarcel Holtmann /* Read local pairing options if the HCI command is supported */ 846a4790360SMarcel Holtmann if (hdev->commands[41] & 0x08) 847a4790360SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_PAIRING_OPTS, 0, NULL); 848a4790360SMarcel Holtmann 849f4fe73edSMarcel Holtmann /* Get MWS transport configuration if the HCI command is supported */ 850f4fe73edSMarcel Holtmann if (hdev->commands[30] & 0x08) 851f4fe73edSMarcel Holtmann hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL); 852f4fe73edSMarcel Holtmann 8535d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 85453b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 8555d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 856a6d0d690SMarcel Holtmann 857a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 858d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) && 859574ea3c7SMarcel Holtmann bredr_sc_enabled(hdev)) { 860a6d0d690SMarcel Holtmann u8 support = 0x01; 861574ea3c7SMarcel Holtmann 862a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 863a6d0d690SMarcel Holtmann sizeof(support), &support); 864a6d0d690SMarcel Holtmann } 865a1d01db1SJohan Hedberg 86600bce3fbSAlain Michaud /* Set erroneous data reporting if supported to the wideband speech 86700bce3fbSAlain Michaud * setting value 86800bce3fbSAlain Michaud */ 869cde1a8a9SIsmael Ferreras Morezuelas if (hdev->commands[18] & 0x08 && 870cde1a8a9SIsmael Ferreras Morezuelas !test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks)) { 87100bce3fbSAlain Michaud bool enabled = hci_dev_test_flag(hdev, 87200bce3fbSAlain Michaud HCI_WIDEBAND_SPEECH_ENABLED); 87300bce3fbSAlain Michaud 87400bce3fbSAlain Michaud if (enabled != 87500bce3fbSAlain Michaud (hdev->err_data_reporting == ERR_DATA_REPORTING_ENABLED)) { 87600bce3fbSAlain Michaud struct hci_cp_write_def_err_data_reporting cp; 87700bce3fbSAlain Michaud 87800bce3fbSAlain Michaud cp.err_data_reporting = enabled ? 87900bce3fbSAlain Michaud ERR_DATA_REPORTING_ENABLED : 88000bce3fbSAlain Michaud ERR_DATA_REPORTING_DISABLED; 88100bce3fbSAlain Michaud 88200bce3fbSAlain Michaud hci_req_add(req, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING, 88300bce3fbSAlain Michaud sizeof(cp), &cp); 88400bce3fbSAlain Michaud } 88500bce3fbSAlain Michaud } 88600bce3fbSAlain Michaud 88712204875SMarcel Holtmann /* Set Suggested Default Data Length to maximum if supported */ 88812204875SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { 88912204875SMarcel Holtmann struct hci_cp_le_write_def_data_len cp; 89012204875SMarcel Holtmann 891727ea61aSBen Dooks (Codethink) cp.tx_len = cpu_to_le16(hdev->le_max_tx_len); 892727ea61aSBen Dooks (Codethink) cp.tx_time = cpu_to_le16(hdev->le_max_tx_time); 89312204875SMarcel Holtmann hci_req_add(req, HCI_OP_LE_WRITE_DEF_DATA_LEN, sizeof(cp), &cp); 89412204875SMarcel Holtmann } 89512204875SMarcel Holtmann 896de2ba303SMarcel Holtmann /* Set Default PHY parameters if command is supported */ 897de2ba303SMarcel Holtmann if (hdev->commands[35] & 0x20) { 898de2ba303SMarcel Holtmann struct hci_cp_le_set_default_phy cp; 899de2ba303SMarcel Holtmann 9006decb5b4SJaganath Kanakkassery cp.all_phys = 0x00; 9016decb5b4SJaganath Kanakkassery cp.tx_phys = hdev->le_tx_def_phys; 9026decb5b4SJaganath Kanakkassery cp.rx_phys = hdev->le_rx_def_phys; 903de2ba303SMarcel Holtmann 904de2ba303SMarcel Holtmann hci_req_add(req, HCI_OP_LE_SET_DEFAULT_PHY, sizeof(cp), &cp); 905de2ba303SMarcel Holtmann } 906de2ba303SMarcel Holtmann 907a1d01db1SJohan Hedberg return 0; 9085d4e7e8dSJohan Hedberg } 9095d4e7e8dSJohan Hedberg 9102177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 9112177bab5SJohan Hedberg { 9122177bab5SJohan Hedberg int err; 9132177bab5SJohan Hedberg 9144ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT, NULL); 9152177bab5SJohan Hedberg if (err < 0) 9162177bab5SJohan Hedberg return err; 9172177bab5SJohan Hedberg 918f640ee98SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 919f640ee98SMarcel Holtmann hci_debugfs_create_basic(hdev); 9204b4148e9SMarcel Holtmann 9214ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT, NULL); 9222177bab5SJohan Hedberg if (err < 0) 9232177bab5SJohan Hedberg return err; 9242177bab5SJohan Hedberg 925ca8bee5dSMarcel Holtmann /* HCI_PRIMARY covers both single-mode LE, BR/EDR and dual-mode 9260af801b9SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 9270af801b9SJohan Hedberg * first two stages of init. 9280af801b9SJohan Hedberg */ 929ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) 9300af801b9SJohan Hedberg return 0; 9310af801b9SJohan Hedberg 9324ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT, NULL); 9335d4e7e8dSJohan Hedberg if (err < 0) 9345d4e7e8dSJohan Hedberg return err; 9355d4e7e8dSJohan Hedberg 9364ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT, NULL); 937baf27f6eSMarcel Holtmann if (err < 0) 938baf27f6eSMarcel Holtmann return err; 939baf27f6eSMarcel Holtmann 940ec6cef9cSMarcel Holtmann /* This function is only called when the controller is actually in 941ec6cef9cSMarcel Holtmann * configured state. When the controller is marked as unconfigured, 942ec6cef9cSMarcel Holtmann * this initialization procedure is not run. 943ec6cef9cSMarcel Holtmann * 944ec6cef9cSMarcel Holtmann * It means that it is possible that a controller runs through its 945ec6cef9cSMarcel Holtmann * setup phase and then discovers missing settings. If that is the 946ec6cef9cSMarcel Holtmann * case, then this function will not be called. It then will only 947ec6cef9cSMarcel Holtmann * be called during the config phase. 948ec6cef9cSMarcel Holtmann * 949ec6cef9cSMarcel Holtmann * So only when in setup phase or config phase, create the debugfs 950ec6cef9cSMarcel Holtmann * entries and register the SMP channels. 951baf27f6eSMarcel Holtmann */ 952d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 953d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 954baf27f6eSMarcel Holtmann return 0; 955baf27f6eSMarcel Holtmann 95660c5f5fbSMarcel Holtmann hci_debugfs_create_common(hdev); 95760c5f5fbSMarcel Holtmann 95871c3b60eSMarcel Holtmann if (lmp_bredr_capable(hdev)) 95960c5f5fbSMarcel Holtmann hci_debugfs_create_bredr(hdev); 9602bfa3531SMarcel Holtmann 961162a3bacSMarcel Holtmann if (lmp_le_capable(hdev)) 96260c5f5fbSMarcel Holtmann hci_debugfs_create_le(hdev); 963e7b8fc92SMarcel Holtmann 964baf27f6eSMarcel Holtmann return 0; 9652177bab5SJohan Hedberg } 9662177bab5SJohan Hedberg 967a1d01db1SJohan Hedberg static int hci_init0_req(struct hci_request *req, unsigned long opt) 9680ebca7d6SMarcel Holtmann { 9690ebca7d6SMarcel Holtmann struct hci_dev *hdev = req->hdev; 9700ebca7d6SMarcel Holtmann 9710ebca7d6SMarcel Holtmann BT_DBG("%s %ld", hdev->name, opt); 9720ebca7d6SMarcel Holtmann 9730ebca7d6SMarcel Holtmann /* Reset */ 9740ebca7d6SMarcel Holtmann if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 9750ebca7d6SMarcel Holtmann hci_reset_req(req, 0); 9760ebca7d6SMarcel Holtmann 9770ebca7d6SMarcel Holtmann /* Read Local Version */ 9780ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 9790ebca7d6SMarcel Holtmann 9800ebca7d6SMarcel Holtmann /* Read BD Address */ 9810ebca7d6SMarcel Holtmann if (hdev->set_bdaddr) 9820ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 983a1d01db1SJohan Hedberg 984a1d01db1SJohan Hedberg return 0; 9850ebca7d6SMarcel Holtmann } 9860ebca7d6SMarcel Holtmann 9870ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev) 9880ebca7d6SMarcel Holtmann { 9890ebca7d6SMarcel Holtmann int err; 9900ebca7d6SMarcel Holtmann 991cc78b44bSMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 992cc78b44bSMarcel Holtmann return 0; 993cc78b44bSMarcel Holtmann 9944ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT, NULL); 9950ebca7d6SMarcel Holtmann if (err < 0) 9960ebca7d6SMarcel Holtmann return err; 9970ebca7d6SMarcel Holtmann 998f640ee98SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 999f640ee98SMarcel Holtmann hci_debugfs_create_basic(hdev); 1000f640ee98SMarcel Holtmann 10010ebca7d6SMarcel Holtmann return 0; 10020ebca7d6SMarcel Holtmann } 10030ebca7d6SMarcel Holtmann 1004a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt) 10051da177e4SLinus Torvalds { 10061da177e4SLinus Torvalds __u8 scan = opt; 10071da177e4SLinus Torvalds 100842c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 10091da177e4SLinus Torvalds 10101da177e4SLinus Torvalds /* Inquiry and Page scans */ 101142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 1012a1d01db1SJohan Hedberg return 0; 10131da177e4SLinus Torvalds } 10141da177e4SLinus Torvalds 1015a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt) 10161da177e4SLinus Torvalds { 10171da177e4SLinus Torvalds __u8 auth = opt; 10181da177e4SLinus Torvalds 101942c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 10201da177e4SLinus Torvalds 10211da177e4SLinus Torvalds /* Authentication */ 102242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 1023a1d01db1SJohan Hedberg return 0; 10241da177e4SLinus Torvalds } 10251da177e4SLinus Torvalds 1026a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt) 10271da177e4SLinus Torvalds { 10281da177e4SLinus Torvalds __u8 encrypt = opt; 10291da177e4SLinus Torvalds 103042c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 10311da177e4SLinus Torvalds 1032e4e8e37cSMarcel Holtmann /* Encryption */ 103342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 1034a1d01db1SJohan Hedberg return 0; 10351da177e4SLinus Torvalds } 10361da177e4SLinus Torvalds 1037a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt) 1038e4e8e37cSMarcel Holtmann { 1039e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1040e4e8e37cSMarcel Holtmann 104142c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1042e4e8e37cSMarcel Holtmann 1043e4e8e37cSMarcel Holtmann /* Default link policy */ 104442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1045a1d01db1SJohan Hedberg return 0; 1046e4e8e37cSMarcel Holtmann } 1047e4e8e37cSMarcel Holtmann 10481da177e4SLinus Torvalds /* Get HCI device by index. 10491da177e4SLinus Torvalds * Device is held on return. */ 10501da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 10511da177e4SLinus Torvalds { 10528035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 10531da177e4SLinus Torvalds 10541da177e4SLinus Torvalds BT_DBG("%d", index); 10551da177e4SLinus Torvalds 10561da177e4SLinus Torvalds if (index < 0) 10571da177e4SLinus Torvalds return NULL; 10581da177e4SLinus Torvalds 10591da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 10608035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 10611da177e4SLinus Torvalds if (d->id == index) { 10621da177e4SLinus Torvalds hdev = hci_dev_hold(d); 10631da177e4SLinus Torvalds break; 10641da177e4SLinus Torvalds } 10651da177e4SLinus Torvalds } 10661da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 10671da177e4SLinus Torvalds return hdev; 10681da177e4SLinus Torvalds } 10691da177e4SLinus Torvalds 10701da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1071ff9ef578SJohan Hedberg 107230dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 107330dc78e1SJohan Hedberg { 107430dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 107530dc78e1SJohan Hedberg 10766fbe195dSAndre Guedes switch (discov->state) { 1077343f935bSAndre Guedes case DISCOVERY_FINDING: 10786fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 107930dc78e1SJohan Hedberg return true; 108030dc78e1SJohan Hedberg 10816fbe195dSAndre Guedes default: 108230dc78e1SJohan Hedberg return false; 108330dc78e1SJohan Hedberg } 10846fbe195dSAndre Guedes } 108530dc78e1SJohan Hedberg 1086ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1087ff9ef578SJohan Hedberg { 1088bb3e0a33SJohan Hedberg int old_state = hdev->discovery.state; 1089bb3e0a33SJohan Hedberg 1090ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1091ff9ef578SJohan Hedberg 1092bb3e0a33SJohan Hedberg if (old_state == state) 1093ff9ef578SJohan Hedberg return; 1094ff9ef578SJohan Hedberg 1095bb3e0a33SJohan Hedberg hdev->discovery.state = state; 1096bb3e0a33SJohan Hedberg 1097ff9ef578SJohan Hedberg switch (state) { 1098ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 1099c54c3860SAndre Guedes hci_update_background_scan(hdev); 1100c54c3860SAndre Guedes 1101bb3e0a33SJohan Hedberg if (old_state != DISCOVERY_STARTING) 1102ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1103ff9ef578SJohan Hedberg break; 1104ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1105ff9ef578SJohan Hedberg break; 1106343f935bSAndre Guedes case DISCOVERY_FINDING: 1107ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1108ff9ef578SJohan Hedberg break; 110930dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 111030dc78e1SJohan Hedberg break; 1111ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1112ff9ef578SJohan Hedberg break; 1113ff9ef578SJohan Hedberg } 1114ff9ef578SJohan Hedberg } 1115ff9ef578SJohan Hedberg 11161f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 11171da177e4SLinus Torvalds { 111830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1119b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 11201da177e4SLinus Torvalds 1121561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1122561aafbcSJohan Hedberg list_del(&p->all); 1123b57c1a56SJohan Hedberg kfree(p); 11241da177e4SLinus Torvalds } 1125561aafbcSJohan Hedberg 1126561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1127561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 11281da177e4SLinus Torvalds } 11291da177e4SLinus Torvalds 1130a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1131a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 11321da177e4SLinus Torvalds { 113330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 11341da177e4SLinus Torvalds struct inquiry_entry *e; 11351da177e4SLinus Torvalds 11366ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 11371da177e4SLinus Torvalds 1138561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 11391da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 11401da177e4SLinus Torvalds return e; 11411da177e4SLinus Torvalds } 11421da177e4SLinus Torvalds 1143b57c1a56SJohan Hedberg return NULL; 1144b57c1a56SJohan Hedberg } 1145b57c1a56SJohan Hedberg 1146561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1147561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1148561aafbcSJohan Hedberg { 114930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1150561aafbcSJohan Hedberg struct inquiry_entry *e; 1151561aafbcSJohan Hedberg 11526ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1153561aafbcSJohan Hedberg 1154561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1155561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1156561aafbcSJohan Hedberg return e; 1157561aafbcSJohan Hedberg } 1158561aafbcSJohan Hedberg 1159561aafbcSJohan Hedberg return NULL; 1160561aafbcSJohan Hedberg } 1161561aafbcSJohan Hedberg 116230dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 116330dc78e1SJohan Hedberg bdaddr_t *bdaddr, 116430dc78e1SJohan Hedberg int state) 116530dc78e1SJohan Hedberg { 116630dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 116730dc78e1SJohan Hedberg struct inquiry_entry *e; 116830dc78e1SJohan Hedberg 11696ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 117030dc78e1SJohan Hedberg 117130dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 117230dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 117330dc78e1SJohan Hedberg return e; 117430dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 117530dc78e1SJohan Hedberg return e; 117630dc78e1SJohan Hedberg } 117730dc78e1SJohan Hedberg 117830dc78e1SJohan Hedberg return NULL; 117930dc78e1SJohan Hedberg } 118030dc78e1SJohan Hedberg 1181a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1182a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1183a3d4e20aSJohan Hedberg { 1184a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1185a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1186a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1187a3d4e20aSJohan Hedberg 1188a3d4e20aSJohan Hedberg list_del(&ie->list); 1189a3d4e20aSJohan Hedberg 1190a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1191a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1192a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1193a3d4e20aSJohan Hedberg break; 1194a3d4e20aSJohan Hedberg pos = &p->list; 1195a3d4e20aSJohan Hedberg } 1196a3d4e20aSJohan Hedberg 1197a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1198a3d4e20aSJohan Hedberg } 1199a3d4e20aSJohan Hedberg 1200af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1201af58925cSMarcel Holtmann bool name_known) 12021da177e4SLinus Torvalds { 120330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 120470f23020SAndrei Emeltchenko struct inquiry_entry *ie; 1205af58925cSMarcel Holtmann u32 flags = 0; 12061da177e4SLinus Torvalds 12076ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 12081da177e4SLinus Torvalds 12096928a924SJohan Hedberg hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR); 12102b2fec4dSSzymon Janc 1211af58925cSMarcel Holtmann if (!data->ssp_mode) 1212af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1213388fc8faSJohan Hedberg 121470f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1215a3d4e20aSJohan Hedberg if (ie) { 1216af58925cSMarcel Holtmann if (!ie->data.ssp_mode) 1217af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1218388fc8faSJohan Hedberg 1219a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1220a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1221a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1222a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1223a3d4e20aSJohan Hedberg } 1224a3d4e20aSJohan Hedberg 1225561aafbcSJohan Hedberg goto update; 1226a3d4e20aSJohan Hedberg } 1227561aafbcSJohan Hedberg 12281da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 122927f70f3eSJohan Hedberg ie = kzalloc(sizeof(*ie), GFP_KERNEL); 1230af58925cSMarcel Holtmann if (!ie) { 1231af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 1232af58925cSMarcel Holtmann goto done; 1233af58925cSMarcel Holtmann } 123470f23020SAndrei Emeltchenko 1235561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1236561aafbcSJohan Hedberg 1237561aafbcSJohan Hedberg if (name_known) { 1238561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1239561aafbcSJohan Hedberg } else { 1240561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1241561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1242561aafbcSJohan Hedberg } 1243561aafbcSJohan Hedberg 1244561aafbcSJohan Hedberg update: 1245561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1246561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1247561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1248561aafbcSJohan Hedberg list_del(&ie->list); 12491da177e4SLinus Torvalds } 12501da177e4SLinus Torvalds 125170f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 125270f23020SAndrei Emeltchenko ie->timestamp = jiffies; 12531da177e4SLinus Torvalds cache->timestamp = jiffies; 12543175405bSJohan Hedberg 12553175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 1256af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 12573175405bSJohan Hedberg 1258af58925cSMarcel Holtmann done: 1259af58925cSMarcel Holtmann return flags; 12601da177e4SLinus Torvalds } 12611da177e4SLinus Torvalds 12621da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 12631da177e4SLinus Torvalds { 126430883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 12651da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 12661da177e4SLinus Torvalds struct inquiry_entry *e; 12671da177e4SLinus Torvalds int copied = 0; 12681da177e4SLinus Torvalds 1269561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 12701da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1271b57c1a56SJohan Hedberg 1272b57c1a56SJohan Hedberg if (copied >= num) 1273b57c1a56SJohan Hedberg break; 1274b57c1a56SJohan Hedberg 12751da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 12761da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 12771da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 12781da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 12791da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 12801da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1281b57c1a56SJohan Hedberg 12821da177e4SLinus Torvalds info++; 1283b57c1a56SJohan Hedberg copied++; 12841da177e4SLinus Torvalds } 12851da177e4SLinus Torvalds 12861da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 12871da177e4SLinus Torvalds return copied; 12881da177e4SLinus Torvalds } 12891da177e4SLinus Torvalds 1290a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt) 12911da177e4SLinus Torvalds { 12921da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 129342c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 12941da177e4SLinus Torvalds struct hci_cp_inquiry cp; 12951da177e4SLinus Torvalds 12961da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 12971da177e4SLinus Torvalds 12981da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 1299a1d01db1SJohan Hedberg return 0; 13001da177e4SLinus Torvalds 13011da177e4SLinus Torvalds /* Start Inquiry */ 13021da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 13031da177e4SLinus Torvalds cp.length = ir->length; 13041da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 130542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 1306a1d01db1SJohan Hedberg 1307a1d01db1SJohan Hedberg return 0; 13081da177e4SLinus Torvalds } 13091da177e4SLinus Torvalds 13101da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 13111da177e4SLinus Torvalds { 13121da177e4SLinus Torvalds __u8 __user *ptr = arg; 13131da177e4SLinus Torvalds struct hci_inquiry_req ir; 13141da177e4SLinus Torvalds struct hci_dev *hdev; 13151da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 13161da177e4SLinus Torvalds long timeo; 13171da177e4SLinus Torvalds __u8 *buf; 13181da177e4SLinus Torvalds 13191da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 13201da177e4SLinus Torvalds return -EFAULT; 13211da177e4SLinus Torvalds 13225a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 13235a08ecceSAndrei Emeltchenko if (!hdev) 13241da177e4SLinus Torvalds return -ENODEV; 13251da177e4SLinus Torvalds 1326d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 13270736cfa8SMarcel Holtmann err = -EBUSY; 13280736cfa8SMarcel Holtmann goto done; 13290736cfa8SMarcel Holtmann } 13300736cfa8SMarcel Holtmann 1331d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1332fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1333fee746b0SMarcel Holtmann goto done; 1334fee746b0SMarcel Holtmann } 1335fee746b0SMarcel Holtmann 1336ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 13375b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 13385b69bef5SMarcel Holtmann goto done; 13395b69bef5SMarcel Holtmann } 13405b69bef5SMarcel Holtmann 1341d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 134256f87901SJohan Hedberg err = -EOPNOTSUPP; 134356f87901SJohan Hedberg goto done; 134456f87901SJohan Hedberg } 134556f87901SJohan Hedberg 134609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 13471da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1348a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 13491f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 13501da177e4SLinus Torvalds do_inquiry = 1; 13511da177e4SLinus Torvalds } 135209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13531da177e4SLinus Torvalds 135404837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 135570f23020SAndrei Emeltchenko 135670f23020SAndrei Emeltchenko if (do_inquiry) { 135701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 13584ebeee2dSJohan Hedberg timeo, NULL); 135970f23020SAndrei Emeltchenko if (err < 0) 13601da177e4SLinus Torvalds goto done; 13613e13fa1eSAndre Guedes 13623e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 13633e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 13643e13fa1eSAndre Guedes */ 136574316201SNeilBrown if (wait_on_bit(&hdev->flags, HCI_INQUIRY, 136628a758c8SPan Bian TASK_INTERRUPTIBLE)) { 136728a758c8SPan Bian err = -EINTR; 136828a758c8SPan Bian goto done; 136928a758c8SPan Bian } 137070f23020SAndrei Emeltchenko } 13711da177e4SLinus Torvalds 13728fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 13738fc9ced3SGustavo Padovan * 255 entries 13748fc9ced3SGustavo Padovan */ 13751da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 13761da177e4SLinus Torvalds 13771da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 13781da177e4SLinus Torvalds * copy it to the user space. 13791da177e4SLinus Torvalds */ 13806da2ec56SKees Cook buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL); 138170f23020SAndrei Emeltchenko if (!buf) { 13821da177e4SLinus Torvalds err = -ENOMEM; 13831da177e4SLinus Torvalds goto done; 13841da177e4SLinus Torvalds } 13851da177e4SLinus Torvalds 138609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 13871da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 138809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13891da177e4SLinus Torvalds 13901da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 13911da177e4SLinus Torvalds 13921da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 13931da177e4SLinus Torvalds ptr += sizeof(ir); 13941da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 13951da177e4SLinus Torvalds ir.num_rsp)) 13961da177e4SLinus Torvalds err = -EFAULT; 13971da177e4SLinus Torvalds } else 13981da177e4SLinus Torvalds err = -EFAULT; 13991da177e4SLinus Torvalds 14001da177e4SLinus Torvalds kfree(buf); 14011da177e4SLinus Torvalds 14021da177e4SLinus Torvalds done: 14031da177e4SLinus Torvalds hci_dev_put(hdev); 14041da177e4SLinus Torvalds return err; 14051da177e4SLinus Torvalds } 14061da177e4SLinus Torvalds 14077a0e5b15SMatthias Kaehlcke /** 14087a0e5b15SMatthias Kaehlcke * hci_dev_get_bd_addr_from_property - Get the Bluetooth Device Address 14097a0e5b15SMatthias Kaehlcke * (BD_ADDR) for a HCI device from 14107a0e5b15SMatthias Kaehlcke * a firmware node property. 14117a0e5b15SMatthias Kaehlcke * @hdev: The HCI device 14127a0e5b15SMatthias Kaehlcke * 14137a0e5b15SMatthias Kaehlcke * Search the firmware node for 'local-bd-address'. 14147a0e5b15SMatthias Kaehlcke * 14157a0e5b15SMatthias Kaehlcke * All-zero BD addresses are rejected, because those could be properties 14167a0e5b15SMatthias Kaehlcke * that exist in the firmware tables, but were not updated by the firmware. For 14177a0e5b15SMatthias Kaehlcke * example, the DTS could define 'local-bd-address', with zero BD addresses. 14187a0e5b15SMatthias Kaehlcke */ 14197a0e5b15SMatthias Kaehlcke static void hci_dev_get_bd_addr_from_property(struct hci_dev *hdev) 14207a0e5b15SMatthias Kaehlcke { 14217a0e5b15SMatthias Kaehlcke struct fwnode_handle *fwnode = dev_fwnode(hdev->dev.parent); 14227a0e5b15SMatthias Kaehlcke bdaddr_t ba; 14237a0e5b15SMatthias Kaehlcke int ret; 14247a0e5b15SMatthias Kaehlcke 14257a0e5b15SMatthias Kaehlcke ret = fwnode_property_read_u8_array(fwnode, "local-bd-address", 14267a0e5b15SMatthias Kaehlcke (u8 *)&ba, sizeof(ba)); 14277a0e5b15SMatthias Kaehlcke if (ret < 0 || !bacmp(&ba, BDADDR_ANY)) 14287a0e5b15SMatthias Kaehlcke return; 14297a0e5b15SMatthias Kaehlcke 14307a0e5b15SMatthias Kaehlcke bacpy(&hdev->public_addr, &ba); 14317a0e5b15SMatthias Kaehlcke } 14327a0e5b15SMatthias Kaehlcke 1433cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 14341da177e4SLinus Torvalds { 14351da177e4SLinus Torvalds int ret = 0; 14361da177e4SLinus Torvalds 14371da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 14381da177e4SLinus Torvalds 1439b504430cSJohan Hedberg hci_req_sync_lock(hdev); 14401da177e4SLinus Torvalds 1441d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) { 144294324962SJohan Hovold ret = -ENODEV; 144394324962SJohan Hovold goto done; 144494324962SJohan Hovold } 144594324962SJohan Hovold 1446d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 1447d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 1448a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1449a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1450bf543036SJohan Hedberg */ 1451d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED)) { 1452611b30f7SMarcel Holtmann ret = -ERFKILL; 1453611b30f7SMarcel Holtmann goto done; 1454611b30f7SMarcel Holtmann } 1455611b30f7SMarcel Holtmann 1456a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 145791641b79SZheng Yongjun * random address, but let the HCI setup proceed to 1458a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1459a5c8f270SMarcel Holtmann * or not. 1460a5c8f270SMarcel Holtmann * 1461c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 1462c6beca0eSMarcel Holtmann * if a public address or static random address is 1463c6beca0eSMarcel Holtmann * available. 1464c6beca0eSMarcel Holtmann * 1465a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1466a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1467a5c8f270SMarcel Holtmann */ 1468d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1469ca8bee5dSMarcel Holtmann hdev->dev_type == HCI_PRIMARY && 1470a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1471a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1472a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1473a5c8f270SMarcel Holtmann goto done; 1474a5c8f270SMarcel Holtmann } 1475a5c8f270SMarcel Holtmann } 1476a5c8f270SMarcel Holtmann 14771da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 14781da177e4SLinus Torvalds ret = -EALREADY; 14791da177e4SLinus Torvalds goto done; 14801da177e4SLinus Torvalds } 14811da177e4SLinus Torvalds 14821da177e4SLinus Torvalds if (hdev->open(hdev)) { 14831da177e4SLinus Torvalds ret = -EIO; 14841da177e4SLinus Torvalds goto done; 14851da177e4SLinus Torvalds } 14861da177e4SLinus Torvalds 1487e9ca8bf1SMarcel Holtmann set_bit(HCI_RUNNING, &hdev->flags); 148805fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_OPEN); 14894a3f95b7SMarcel Holtmann 14901da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 14911da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1492f41c70c4SMarcel Holtmann 1493740011cfSSean Wang if (hci_dev_test_flag(hdev, HCI_SETUP) || 1494740011cfSSean Wang test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) { 14957fdf6c6aSMarcel Holtmann bool invalid_bdaddr; 14967fdf6c6aSMarcel Holtmann 1497e131d74aSMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_SETUP); 1498e131d74aSMarcel Holtmann 1499af202f84SMarcel Holtmann if (hdev->setup) 1500f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1501f41c70c4SMarcel Holtmann 15027fdf6c6aSMarcel Holtmann /* The transport driver can set the quirk to mark the 15037fdf6c6aSMarcel Holtmann * BD_ADDR invalid before creating the HCI device or in 15047fdf6c6aSMarcel Holtmann * its setup callback. 15057fdf6c6aSMarcel Holtmann */ 15067fdf6c6aSMarcel Holtmann invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR, 15077fdf6c6aSMarcel Holtmann &hdev->quirks); 15087fdf6c6aSMarcel Holtmann 15097a0e5b15SMatthias Kaehlcke if (ret) 15107a0e5b15SMatthias Kaehlcke goto setup_failed; 15117a0e5b15SMatthias Kaehlcke 15127a0e5b15SMatthias Kaehlcke if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) { 15137a0e5b15SMatthias Kaehlcke if (!bacmp(&hdev->public_addr, BDADDR_ANY)) 15147a0e5b15SMatthias Kaehlcke hci_dev_get_bd_addr_from_property(hdev); 15157a0e5b15SMatthias Kaehlcke 15167a0e5b15SMatthias Kaehlcke if (bacmp(&hdev->public_addr, BDADDR_ANY) && 15177fdf6c6aSMarcel Holtmann hdev->set_bdaddr) { 15187a0e5b15SMatthias Kaehlcke ret = hdev->set_bdaddr(hdev, 15197a0e5b15SMatthias Kaehlcke &hdev->public_addr); 15207fdf6c6aSMarcel Holtmann 15217fdf6c6aSMarcel Holtmann /* If setting of the BD_ADDR from the device 15227fdf6c6aSMarcel Holtmann * property succeeds, then treat the address 15237fdf6c6aSMarcel Holtmann * as valid even if the invalid BD_ADDR 15247fdf6c6aSMarcel Holtmann * quirk indicates otherwise. 15257fdf6c6aSMarcel Holtmann */ 15267fdf6c6aSMarcel Holtmann if (!ret) 15277fdf6c6aSMarcel Holtmann invalid_bdaddr = false; 15287fdf6c6aSMarcel Holtmann } 15297a0e5b15SMatthias Kaehlcke } 15307a0e5b15SMatthias Kaehlcke 15317a0e5b15SMatthias Kaehlcke setup_failed: 1532af202f84SMarcel Holtmann /* The transport driver can set these quirks before 1533af202f84SMarcel Holtmann * creating the HCI device or in its setup callback. 1534af202f84SMarcel Holtmann * 15357fdf6c6aSMarcel Holtmann * For the invalid BD_ADDR quirk it is possible that 15367fdf6c6aSMarcel Holtmann * it becomes a valid address if the bootloader does 15377fdf6c6aSMarcel Holtmann * provide it (see above). 15387fdf6c6aSMarcel Holtmann * 1539af202f84SMarcel Holtmann * In case any of them is set, the controller has to 1540af202f84SMarcel Holtmann * start up as unconfigured. 1541af202f84SMarcel Holtmann */ 1542eb1904f4SMarcel Holtmann if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) || 15437fdf6c6aSMarcel Holtmann invalid_bdaddr) 1544a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 1545f41c70c4SMarcel Holtmann 15460ebca7d6SMarcel Holtmann /* For an unconfigured controller it is required to 15470ebca7d6SMarcel Holtmann * read at least the version information provided by 15480ebca7d6SMarcel Holtmann * the Read Local Version Information command. 15490ebca7d6SMarcel Holtmann * 15500ebca7d6SMarcel Holtmann * If the set_bdaddr driver callback is provided, then 15510ebca7d6SMarcel Holtmann * also the original Bluetooth public device address 15520ebca7d6SMarcel Holtmann * will be read using the Read BD Address command. 15530ebca7d6SMarcel Holtmann */ 1554d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 15550ebca7d6SMarcel Holtmann ret = __hci_unconf_init(hdev); 155689bc22d2SMarcel Holtmann } 155789bc22d2SMarcel Holtmann 1558d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_CONFIG)) { 15599713c17bSMarcel Holtmann /* If public address change is configured, ensure that 15609713c17bSMarcel Holtmann * the address gets programmed. If the driver does not 15619713c17bSMarcel Holtmann * support changing the public address, fail the power 15629713c17bSMarcel Holtmann * on procedure. 156324c457e2SMarcel Holtmann */ 15649713c17bSMarcel Holtmann if (bacmp(&hdev->public_addr, BDADDR_ANY) && 15659713c17bSMarcel Holtmann hdev->set_bdaddr) 156624c457e2SMarcel Holtmann ret = hdev->set_bdaddr(hdev, &hdev->public_addr); 156724c457e2SMarcel Holtmann else 156824c457e2SMarcel Holtmann ret = -EADDRNOTAVAIL; 156924c457e2SMarcel Holtmann } 157024c457e2SMarcel Holtmann 1571f41c70c4SMarcel Holtmann if (!ret) { 1572d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 157398a63aafSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 15742177bab5SJohan Hedberg ret = __hci_init(hdev); 157598a63aafSMarcel Holtmann if (!ret && hdev->post_init) 157698a63aafSMarcel Holtmann ret = hdev->post_init(hdev); 157798a63aafSMarcel Holtmann } 15781da177e4SLinus Torvalds } 15791da177e4SLinus Torvalds 15807e995b9eSMarcel Holtmann /* If the HCI Reset command is clearing all diagnostic settings, 15817e995b9eSMarcel Holtmann * then they need to be reprogrammed after the init procedure 15827e995b9eSMarcel Holtmann * completed. 15837e995b9eSMarcel Holtmann */ 15847e995b9eSMarcel Holtmann if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) && 1585b56c7b25SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 15867e995b9eSMarcel Holtmann hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag) 15877e995b9eSMarcel Holtmann ret = hdev->set_diag(hdev, true); 15887e995b9eSMarcel Holtmann 1589145373cbSMiao-chen Chou msft_do_open(hdev); 1590f67743f9SMarcel Holtmann aosp_do_open(hdev); 1591145373cbSMiao-chen Chou 1592f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1593f41c70c4SMarcel Holtmann 15941da177e4SLinus Torvalds if (!ret) { 15951da177e4SLinus Torvalds hci_dev_hold(hdev); 1596a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); 1597a73c046aSJaganath Kanakkassery hci_adv_instances_set_rpa_expired(hdev, true); 15981da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 159905fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UP); 16006d5d2ee6SHeiner Kallweit hci_leds_update_powered(hdev, true); 1601d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 1602d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG) && 1603d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 1604d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 16052ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 1606ca8bee5dSMarcel Holtmann hdev->dev_type == HCI_PRIMARY) { 16072ff13894SJohan Hedberg ret = __hci_req_hci_power_on(hdev); 16082ff13894SJohan Hedberg mgmt_power_on(hdev, ret); 160956e5cb86SJohan Hedberg } 16101da177e4SLinus Torvalds } else { 16111da177e4SLinus Torvalds /* Init failed, cleanup */ 16123eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 16136a137caeSLin Ma 16146a137caeSLin Ma /* Since hci_rx_work() is possible to awake new cmd_work 16156a137caeSLin Ma * it should be flushed first to avoid unexpected call of 16166a137caeSLin Ma * hci_cmd_work() 16176a137caeSLin Ma */ 1618b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 16196a137caeSLin Ma flush_work(&hdev->cmd_work); 16201da177e4SLinus Torvalds 16211da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 16221da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 16231da177e4SLinus Torvalds 16241da177e4SLinus Torvalds if (hdev->flush) 16251da177e4SLinus Torvalds hdev->flush(hdev); 16261da177e4SLinus Torvalds 16271da177e4SLinus Torvalds if (hdev->sent_cmd) { 16281da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 16291da177e4SLinus Torvalds hdev->sent_cmd = NULL; 16301da177e4SLinus Torvalds } 16311da177e4SLinus Torvalds 1632e9ca8bf1SMarcel Holtmann clear_bit(HCI_RUNNING, &hdev->flags); 163305fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_CLOSE); 16344a3f95b7SMarcel Holtmann 16351da177e4SLinus Torvalds hdev->close(hdev); 1636fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 16371da177e4SLinus Torvalds } 16381da177e4SLinus Torvalds 16391da177e4SLinus Torvalds done: 1640b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 16411da177e4SLinus Torvalds return ret; 16421da177e4SLinus Torvalds } 16431da177e4SLinus Torvalds 1644cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 1645cbed0ca1SJohan Hedberg 1646cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 1647cbed0ca1SJohan Hedberg { 1648cbed0ca1SJohan Hedberg struct hci_dev *hdev; 1649cbed0ca1SJohan Hedberg int err; 1650cbed0ca1SJohan Hedberg 1651cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 1652cbed0ca1SJohan Hedberg if (!hdev) 1653cbed0ca1SJohan Hedberg return -ENODEV; 1654cbed0ca1SJohan Hedberg 16554a964404SMarcel Holtmann /* Devices that are marked as unconfigured can only be powered 1656fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices 1657fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is 1658fee746b0SMarcel Holtmann * possible. 1659fee746b0SMarcel Holtmann * 1660fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag 1661fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to 1662fee746b0SMarcel Holtmann * open the device. 1663fee746b0SMarcel Holtmann */ 1664d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 1665d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 1666fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1667fee746b0SMarcel Holtmann goto done; 1668fee746b0SMarcel Holtmann } 1669fee746b0SMarcel Holtmann 1670e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 1671e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 1672e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 1673e1d08f40SJohan Hedberg * completed. 1674e1d08f40SJohan Hedberg */ 1675a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 1676e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 1677e1d08f40SJohan Hedberg 1678a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 1679a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 1680a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 1681a5c8f270SMarcel Holtmann */ 1682e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 1683e1d08f40SJohan Hedberg 168412aa4f0aSMarcel Holtmann /* For controllers not using the management interface and that 1685b6ae8457SJohan Hedberg * are brought up using legacy ioctl, set the HCI_BONDABLE bit 168612aa4f0aSMarcel Holtmann * so that pairing works for them. Once the management interface 168712aa4f0aSMarcel Holtmann * is in use this bit will be cleared again and userspace has 168812aa4f0aSMarcel Holtmann * to explicitly enable it. 168912aa4f0aSMarcel Holtmann */ 1690d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1691d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_MGMT)) 1692a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BONDABLE); 169312aa4f0aSMarcel Holtmann 1694cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 1695cbed0ca1SJohan Hedberg 1696fee746b0SMarcel Holtmann done: 1697cbed0ca1SJohan Hedberg hci_dev_put(hdev); 1698cbed0ca1SJohan Hedberg return err; 1699cbed0ca1SJohan Hedberg } 1700cbed0ca1SJohan Hedberg 1701d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */ 1702d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev) 1703d7347f3cSJohan Hedberg { 1704d7347f3cSJohan Hedberg struct hci_conn_params *p; 1705d7347f3cSJohan Hedberg 1706f161dd41SJohan Hedberg list_for_each_entry(p, &hdev->le_conn_params, list) { 1707f161dd41SJohan Hedberg if (p->conn) { 1708f161dd41SJohan Hedberg hci_conn_drop(p->conn); 1709f8aaf9b6SJohan Hedberg hci_conn_put(p->conn); 1710f161dd41SJohan Hedberg p->conn = NULL; 1711f161dd41SJohan Hedberg } 1712d7347f3cSJohan Hedberg list_del_init(&p->action); 1713f161dd41SJohan Hedberg } 1714d7347f3cSJohan Hedberg 1715d7347f3cSJohan Hedberg BT_DBG("All LE pending actions cleared"); 1716d7347f3cSJohan Hedberg } 1717d7347f3cSJohan Hedberg 17186b3cc1dbSSimon Fels int hci_dev_do_close(struct hci_dev *hdev) 17191da177e4SLinus Torvalds { 1720acc649c6SMarcel Holtmann bool auto_off; 1721acc649c6SMarcel Holtmann 17221da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 17231da177e4SLinus Torvalds 172478c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 1725de75cd0dSManish Mandlik cancel_delayed_work(&hdev->ncmd_timer); 172678c04c0bSVinicius Costa Gomes 17277df0f73eSJohan Hedberg hci_request_cancel_all(hdev); 1728b504430cSJohan Hedberg hci_req_sync_lock(hdev); 17291da177e4SLinus Torvalds 17301da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 173165cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 1732b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 17331da177e4SLinus Torvalds return 0; 17341da177e4SLinus Torvalds } 17351da177e4SLinus Torvalds 17366d5d2ee6SHeiner Kallweit hci_leds_update_powered(hdev, false); 17376d5d2ee6SHeiner Kallweit 17383eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 17393eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1740b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 17411da177e4SLinus Torvalds 174216ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 174316ab91abSJohan Hedberg hdev->discov_timeout = 0; 1744a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_DISCOVERABLE); 1745a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 174616ab91abSJohan Hedberg } 174716ab91abSJohan Hedberg 1748a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE)) 17497d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 17507d78525dSJohan Hedberg 1751a73c046aSJaganath Kanakkassery if (hci_dev_test_flag(hdev, HCI_MGMT)) { 1752a73c046aSJaganath Kanakkassery struct adv_info *adv_instance; 1753a73c046aSJaganath Kanakkassery 1754d6bfd59cSJohan Hedberg cancel_delayed_work_sync(&hdev->rpa_expired); 17557ba8b4beSAndre Guedes 1756a73c046aSJaganath Kanakkassery list_for_each_entry(adv_instance, &hdev->adv_instances, list) 1757a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 1758a73c046aSJaganath Kanakkassery } 1759a73c046aSJaganath Kanakkassery 176076727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 176176727c02SJohan Hedberg * ensuring the workqueue is empty up front. 176276727c02SJohan Hedberg */ 176376727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 176476727c02SJohan Hedberg 176509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 17661aeb9c65SJohan Hedberg 17678f502f84SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 17688f502f84SJohan Hedberg 1769acc649c6SMarcel Holtmann auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF); 1770acc649c6SMarcel Holtmann 1771ca8bee5dSMarcel Holtmann if (!auto_off && hdev->dev_type == HCI_PRIMARY && 1772baab7932SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 17732ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT)) 17742ff13894SJohan Hedberg __mgmt_power_off(hdev); 17751aeb9c65SJohan Hedberg 17761f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 1777d7347f3cSJohan Hedberg hci_pend_le_actions_clear(hdev); 1778f161dd41SJohan Hedberg hci_conn_hash_flush(hdev); 177909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 17801da177e4SLinus Torvalds 178164dae967SMarcel Holtmann smp_unregister(hdev); 178264dae967SMarcel Holtmann 178305fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_DOWN); 17841da177e4SLinus Torvalds 1785f67743f9SMarcel Holtmann aosp_do_close(hdev); 1786145373cbSMiao-chen Chou msft_do_close(hdev); 1787145373cbSMiao-chen Chou 17881da177e4SLinus Torvalds if (hdev->flush) 17891da177e4SLinus Torvalds hdev->flush(hdev); 17901da177e4SLinus Torvalds 17911da177e4SLinus Torvalds /* Reset device */ 17921da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 17931da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 1794acc649c6SMarcel Holtmann if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) && 1795acc649c6SMarcel Holtmann !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 17961da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 17974ebeee2dSJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL); 17981da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 17991da177e4SLinus Torvalds } 18001da177e4SLinus Torvalds 1801*0ea9fd00SKai-Heng Feng if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && 1802*0ea9fd00SKai-Heng Feng !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1803*0ea9fd00SKai-Heng Feng test_bit(HCI_UP, &hdev->flags)) { 1804*0ea9fd00SKai-Heng Feng /* Execute vendor specific shutdown routine */ 1805*0ea9fd00SKai-Heng Feng if (hdev->shutdown) 1806*0ea9fd00SKai-Heng Feng hdev->shutdown(hdev); 1807*0ea9fd00SKai-Heng Feng } 1808*0ea9fd00SKai-Heng Feng 1809c347b765SGustavo F. Padovan /* flush cmd work */ 1810c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 18111da177e4SLinus Torvalds 18121da177e4SLinus Torvalds /* Drop queues */ 18131da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 18141da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 18151da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 18161da177e4SLinus Torvalds 18171da177e4SLinus Torvalds /* Drop last sent command */ 18181da177e4SLinus Torvalds if (hdev->sent_cmd) { 181965cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 18201da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 18211da177e4SLinus Torvalds hdev->sent_cmd = NULL; 18221da177e4SLinus Torvalds } 18231da177e4SLinus Torvalds 1824e9ca8bf1SMarcel Holtmann clear_bit(HCI_RUNNING, &hdev->flags); 182505fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_CLOSE); 18264a3f95b7SMarcel Holtmann 18279952d90eSAbhishek Pandit-Subedi if (test_and_clear_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks)) 18289952d90eSAbhishek Pandit-Subedi wake_up(&hdev->suspend_wait_q); 18299952d90eSAbhishek Pandit-Subedi 18301da177e4SLinus Torvalds /* After this point our queues are empty 18311da177e4SLinus Torvalds * and no tasks are scheduled. */ 18321da177e4SLinus Torvalds hdev->close(hdev); 18331da177e4SLinus Torvalds 183435b973c9SJohan Hedberg /* Clear flags */ 1835fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 1836eacb44dfSMarcel Holtmann hci_dev_clear_volatile_flags(hdev); 183735b973c9SJohan Hedberg 1838ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 1839536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 1840ced5c338SAndrei Emeltchenko 1841e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 184209b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 18437a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, BDADDR_ANY); 1844e59fda8dSJohan Hedberg 1845b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 18461da177e4SLinus Torvalds 18471da177e4SLinus Torvalds hci_dev_put(hdev); 18481da177e4SLinus Torvalds return 0; 18491da177e4SLinus Torvalds } 18501da177e4SLinus Torvalds 18511da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 18521da177e4SLinus Torvalds { 18531da177e4SLinus Torvalds struct hci_dev *hdev; 18541da177e4SLinus Torvalds int err; 18551da177e4SLinus Torvalds 185670f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 185770f23020SAndrei Emeltchenko if (!hdev) 18581da177e4SLinus Torvalds return -ENODEV; 18598ee56540SMarcel Holtmann 1860d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 18610736cfa8SMarcel Holtmann err = -EBUSY; 18620736cfa8SMarcel Holtmann goto done; 18630736cfa8SMarcel Holtmann } 18640736cfa8SMarcel Holtmann 1865a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 18668ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 18678ee56540SMarcel Holtmann 18681da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 18698ee56540SMarcel Holtmann 18700736cfa8SMarcel Holtmann done: 18711da177e4SLinus Torvalds hci_dev_put(hdev); 18721da177e4SLinus Torvalds return err; 18731da177e4SLinus Torvalds } 18741da177e4SLinus Torvalds 18755c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev) 18761da177e4SLinus Torvalds { 18775c912495SMarcel Holtmann int ret; 18781da177e4SLinus Torvalds 18795c912495SMarcel Holtmann BT_DBG("%s %p", hdev->name, hdev); 18801da177e4SLinus Torvalds 1881b504430cSJohan Hedberg hci_req_sync_lock(hdev); 18821da177e4SLinus Torvalds 18831da177e4SLinus Torvalds /* Drop queues */ 18841da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 18851da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 18861da177e4SLinus Torvalds 188776727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 188876727c02SJohan Hedberg * ensuring the workqueue is empty up front. 188976727c02SJohan Hedberg */ 189076727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 189176727c02SJohan Hedberg 189209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 18931f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 18941da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 189509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18961da177e4SLinus Torvalds 18971da177e4SLinus Torvalds if (hdev->flush) 18981da177e4SLinus Torvalds hdev->flush(hdev); 18991da177e4SLinus Torvalds 19001da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 19016ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 19021da177e4SLinus Torvalds 19034ebeee2dSJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT, NULL); 19041da177e4SLinus Torvalds 1905b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 19061da177e4SLinus Torvalds return ret; 19071da177e4SLinus Torvalds } 19081da177e4SLinus Torvalds 19095c912495SMarcel Holtmann int hci_dev_reset(__u16 dev) 19105c912495SMarcel Holtmann { 19115c912495SMarcel Holtmann struct hci_dev *hdev; 19125c912495SMarcel Holtmann int err; 19135c912495SMarcel Holtmann 19145c912495SMarcel Holtmann hdev = hci_dev_get(dev); 19155c912495SMarcel Holtmann if (!hdev) 19165c912495SMarcel Holtmann return -ENODEV; 19175c912495SMarcel Holtmann 19185c912495SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 19195c912495SMarcel Holtmann err = -ENETDOWN; 19205c912495SMarcel Holtmann goto done; 19215c912495SMarcel Holtmann } 19225c912495SMarcel Holtmann 1923d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 19245c912495SMarcel Holtmann err = -EBUSY; 19255c912495SMarcel Holtmann goto done; 19265c912495SMarcel Holtmann } 19275c912495SMarcel Holtmann 1928d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 19295c912495SMarcel Holtmann err = -EOPNOTSUPP; 19305c912495SMarcel Holtmann goto done; 19315c912495SMarcel Holtmann } 19325c912495SMarcel Holtmann 19335c912495SMarcel Holtmann err = hci_dev_do_reset(hdev); 19345c912495SMarcel Holtmann 19355c912495SMarcel Holtmann done: 19365c912495SMarcel Holtmann hci_dev_put(hdev); 19375c912495SMarcel Holtmann return err; 19385c912495SMarcel Holtmann } 19395c912495SMarcel Holtmann 19401da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 19411da177e4SLinus Torvalds { 19421da177e4SLinus Torvalds struct hci_dev *hdev; 19431da177e4SLinus Torvalds int ret = 0; 19441da177e4SLinus Torvalds 194570f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 194670f23020SAndrei Emeltchenko if (!hdev) 19471da177e4SLinus Torvalds return -ENODEV; 19481da177e4SLinus Torvalds 1949d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 19500736cfa8SMarcel Holtmann ret = -EBUSY; 19510736cfa8SMarcel Holtmann goto done; 19520736cfa8SMarcel Holtmann } 19530736cfa8SMarcel Holtmann 1954d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1955fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 1956fee746b0SMarcel Holtmann goto done; 1957fee746b0SMarcel Holtmann } 1958fee746b0SMarcel Holtmann 19591da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 19601da177e4SLinus Torvalds 19610736cfa8SMarcel Holtmann done: 19621da177e4SLinus Torvalds hci_dev_put(hdev); 19631da177e4SLinus Torvalds return ret; 19641da177e4SLinus Torvalds } 19651da177e4SLinus Torvalds 1966123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan) 1967123abc08SJohan Hedberg { 1968bc6d2d04SJohan Hedberg bool conn_changed, discov_changed; 1969123abc08SJohan Hedberg 1970123abc08SJohan Hedberg BT_DBG("%s scan 0x%02x", hdev->name, scan); 1971123abc08SJohan Hedberg 1972123abc08SJohan Hedberg if ((scan & SCAN_PAGE)) 1973238be788SMarcel Holtmann conn_changed = !hci_dev_test_and_set_flag(hdev, 1974238be788SMarcel Holtmann HCI_CONNECTABLE); 1975123abc08SJohan Hedberg else 1976a69d8927SMarcel Holtmann conn_changed = hci_dev_test_and_clear_flag(hdev, 1977a69d8927SMarcel Holtmann HCI_CONNECTABLE); 1978123abc08SJohan Hedberg 1979bc6d2d04SJohan Hedberg if ((scan & SCAN_INQUIRY)) { 1980238be788SMarcel Holtmann discov_changed = !hci_dev_test_and_set_flag(hdev, 1981238be788SMarcel Holtmann HCI_DISCOVERABLE); 1982bc6d2d04SJohan Hedberg } else { 1983a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 1984a69d8927SMarcel Holtmann discov_changed = hci_dev_test_and_clear_flag(hdev, 1985a69d8927SMarcel Holtmann HCI_DISCOVERABLE); 1986bc6d2d04SJohan Hedberg } 1987bc6d2d04SJohan Hedberg 1988d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 1989123abc08SJohan Hedberg return; 1990123abc08SJohan Hedberg 1991bc6d2d04SJohan Hedberg if (conn_changed || discov_changed) { 1992bc6d2d04SJohan Hedberg /* In case this was disabled through mgmt */ 1993a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 1994bc6d2d04SJohan Hedberg 1995d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 1996cab054abSJohan Hedberg hci_req_update_adv_data(hdev, hdev->cur_adv_instance); 1997bc6d2d04SJohan Hedberg 1998123abc08SJohan Hedberg mgmt_new_settings(hdev); 1999123abc08SJohan Hedberg } 2000bc6d2d04SJohan Hedberg } 2001123abc08SJohan Hedberg 20021da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 20031da177e4SLinus Torvalds { 20041da177e4SLinus Torvalds struct hci_dev *hdev; 20051da177e4SLinus Torvalds struct hci_dev_req dr; 20061da177e4SLinus Torvalds int err = 0; 20071da177e4SLinus Torvalds 20081da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 20091da177e4SLinus Torvalds return -EFAULT; 20101da177e4SLinus Torvalds 201170f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 201270f23020SAndrei Emeltchenko if (!hdev) 20131da177e4SLinus Torvalds return -ENODEV; 20141da177e4SLinus Torvalds 2015d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 20160736cfa8SMarcel Holtmann err = -EBUSY; 20170736cfa8SMarcel Holtmann goto done; 20180736cfa8SMarcel Holtmann } 20190736cfa8SMarcel Holtmann 2020d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 2021fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2022fee746b0SMarcel Holtmann goto done; 2023fee746b0SMarcel Holtmann } 2024fee746b0SMarcel Holtmann 2025ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 20265b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 20275b69bef5SMarcel Holtmann goto done; 20285b69bef5SMarcel Holtmann } 20295b69bef5SMarcel Holtmann 2030d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 203156f87901SJohan Hedberg err = -EOPNOTSUPP; 203256f87901SJohan Hedberg goto done; 203356f87901SJohan Hedberg } 203456f87901SJohan Hedberg 20351da177e4SLinus Torvalds switch (cmd) { 20361da177e4SLinus Torvalds case HCISETAUTH: 203701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 20384ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20391da177e4SLinus Torvalds break; 20401da177e4SLinus Torvalds 20411da177e4SLinus Torvalds case HCISETENCRYPT: 20421da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 20431da177e4SLinus Torvalds err = -EOPNOTSUPP; 20441da177e4SLinus Torvalds break; 20451da177e4SLinus Torvalds } 20461da177e4SLinus Torvalds 20471da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 20481da177e4SLinus Torvalds /* Auth must be enabled first */ 204901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 20504ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20511da177e4SLinus Torvalds if (err) 20521da177e4SLinus Torvalds break; 20531da177e4SLinus Torvalds } 20541da177e4SLinus Torvalds 205501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 20564ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20571da177e4SLinus Torvalds break; 20581da177e4SLinus Torvalds 20591da177e4SLinus Torvalds case HCISETSCAN: 206001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 20614ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 206291a668b0SJohan Hedberg 2063bc6d2d04SJohan Hedberg /* Ensure that the connectable and discoverable states 2064bc6d2d04SJohan Hedberg * get correctly modified as this was a non-mgmt change. 206591a668b0SJohan Hedberg */ 2066123abc08SJohan Hedberg if (!err) 2067123abc08SJohan Hedberg hci_update_scan_state(hdev, dr.dev_opt); 20681da177e4SLinus Torvalds break; 20691da177e4SLinus Torvalds 20701da177e4SLinus Torvalds case HCISETLINKPOL: 207101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 20724ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20731da177e4SLinus Torvalds break; 20741da177e4SLinus Torvalds 20751da177e4SLinus Torvalds case HCISETLINKMODE: 2076e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2077e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2078e4e8e37cSMarcel Holtmann break; 2079e4e8e37cSMarcel Holtmann 2080e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2081b7c23df8SJaganath Kanakkassery if (hdev->pkt_type == (__u16) dr.dev_opt) 2082b7c23df8SJaganath Kanakkassery break; 2083b7c23df8SJaganath Kanakkassery 2084e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 2085b7c23df8SJaganath Kanakkassery mgmt_phy_configuration_changed(hdev, NULL); 20861da177e4SLinus Torvalds break; 20871da177e4SLinus Torvalds 20881da177e4SLinus Torvalds case HCISETACLMTU: 20891da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 20901da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 20911da177e4SLinus Torvalds break; 20921da177e4SLinus Torvalds 20931da177e4SLinus Torvalds case HCISETSCOMTU: 20941da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 20951da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 20961da177e4SLinus Torvalds break; 20971da177e4SLinus Torvalds 20981da177e4SLinus Torvalds default: 20991da177e4SLinus Torvalds err = -EINVAL; 21001da177e4SLinus Torvalds break; 21011da177e4SLinus Torvalds } 2102e4e8e37cSMarcel Holtmann 21030736cfa8SMarcel Holtmann done: 21041da177e4SLinus Torvalds hci_dev_put(hdev); 21051da177e4SLinus Torvalds return err; 21061da177e4SLinus Torvalds } 21071da177e4SLinus Torvalds 21081da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 21091da177e4SLinus Torvalds { 21108035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 21111da177e4SLinus Torvalds struct hci_dev_list_req *dl; 21121da177e4SLinus Torvalds struct hci_dev_req *dr; 21131da177e4SLinus Torvalds int n = 0, size, err; 21141da177e4SLinus Torvalds __u16 dev_num; 21151da177e4SLinus Torvalds 21161da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 21171da177e4SLinus Torvalds return -EFAULT; 21181da177e4SLinus Torvalds 21191da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 21201da177e4SLinus Torvalds return -EINVAL; 21211da177e4SLinus Torvalds 21221da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 21231da177e4SLinus Torvalds 212470f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 212570f23020SAndrei Emeltchenko if (!dl) 21261da177e4SLinus Torvalds return -ENOMEM; 21271da177e4SLinus Torvalds 21281da177e4SLinus Torvalds dr = dl->dev_req; 21291da177e4SLinus Torvalds 2130f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 21318035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 21322e84d8dbSMarcel Holtmann unsigned long flags = hdev->flags; 2133c542a06cSJohan Hedberg 21342e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 21352e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 21362e84d8dbSMarcel Holtmann * device is actually down. 21372e84d8dbSMarcel Holtmann */ 2138d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 21392e84d8dbSMarcel Holtmann flags &= ~BIT(HCI_UP); 2140c542a06cSJohan Hedberg 21411da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 21422e84d8dbSMarcel Holtmann (dr + n)->dev_opt = flags; 2143c542a06cSJohan Hedberg 21441da177e4SLinus Torvalds if (++n >= dev_num) 21451da177e4SLinus Torvalds break; 21461da177e4SLinus Torvalds } 2147f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 21481da177e4SLinus Torvalds 21491da177e4SLinus Torvalds dl->dev_num = n; 21501da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 21511da177e4SLinus Torvalds 21521da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 21531da177e4SLinus Torvalds kfree(dl); 21541da177e4SLinus Torvalds 21551da177e4SLinus Torvalds return err ? -EFAULT : 0; 21561da177e4SLinus Torvalds } 21571da177e4SLinus Torvalds 21581da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 21591da177e4SLinus Torvalds { 21601da177e4SLinus Torvalds struct hci_dev *hdev; 21611da177e4SLinus Torvalds struct hci_dev_info di; 21622e84d8dbSMarcel Holtmann unsigned long flags; 21631da177e4SLinus Torvalds int err = 0; 21641da177e4SLinus Torvalds 21651da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 21661da177e4SLinus Torvalds return -EFAULT; 21671da177e4SLinus Torvalds 216870f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 216970f23020SAndrei Emeltchenko if (!hdev) 21701da177e4SLinus Torvalds return -ENODEV; 21711da177e4SLinus Torvalds 21722e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 21732e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 21742e84d8dbSMarcel Holtmann * device is actually down. 21752e84d8dbSMarcel Holtmann */ 2176d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 21772e84d8dbSMarcel Holtmann flags = hdev->flags & ~BIT(HCI_UP); 21782e84d8dbSMarcel Holtmann else 21792e84d8dbSMarcel Holtmann flags = hdev->flags; 2180c542a06cSJohan Hedberg 21811da177e4SLinus Torvalds strcpy(di.name, hdev->name); 21821da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 218360f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 21842e84d8dbSMarcel Holtmann di.flags = flags; 21851da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2186572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 21871da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 21881da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 21891da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 21901da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2191572c7f84SJohan Hedberg } else { 2192572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2193572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2194572c7f84SJohan Hedberg di.sco_mtu = 0; 2195572c7f84SJohan Hedberg di.sco_pkts = 0; 2196572c7f84SJohan Hedberg } 21971da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 21981da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 21991da177e4SLinus Torvalds 22001da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 22011da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 22021da177e4SLinus Torvalds 22031da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 22041da177e4SLinus Torvalds err = -EFAULT; 22051da177e4SLinus Torvalds 22061da177e4SLinus Torvalds hci_dev_put(hdev); 22071da177e4SLinus Torvalds 22081da177e4SLinus Torvalds return err; 22091da177e4SLinus Torvalds } 22101da177e4SLinus Torvalds 22111da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 22121da177e4SLinus Torvalds 2213611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2214611b30f7SMarcel Holtmann { 2215611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2216611b30f7SMarcel Holtmann 2217611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2218611b30f7SMarcel Holtmann 2219d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) 22200736cfa8SMarcel Holtmann return -EBUSY; 22210736cfa8SMarcel Holtmann 22225e130367SJohan Hedberg if (blocked) { 2223a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 2224d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 2225d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 2226611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 22275e130367SJohan Hedberg } else { 2228a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_RFKILLED); 22295e130367SJohan Hedberg } 2230611b30f7SMarcel Holtmann 2231611b30f7SMarcel Holtmann return 0; 2232611b30f7SMarcel Holtmann } 2233611b30f7SMarcel Holtmann 2234611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2235611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2236611b30f7SMarcel Holtmann }; 2237611b30f7SMarcel Holtmann 2238ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2239ab81cbf9SJohan Hedberg { 2240ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 224196570ffcSJohan Hedberg int err; 2242ab81cbf9SJohan Hedberg 2243ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2244ab81cbf9SJohan Hedberg 22452ff13894SJohan Hedberg if (test_bit(HCI_UP, &hdev->flags) && 22462ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 22472ff13894SJohan Hedberg hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) { 2248d82142a8SWei-Ning Huang cancel_delayed_work(&hdev->power_off); 22492ff13894SJohan Hedberg hci_req_sync_lock(hdev); 22502ff13894SJohan Hedberg err = __hci_req_hci_power_on(hdev); 22512ff13894SJohan Hedberg hci_req_sync_unlock(hdev); 22522ff13894SJohan Hedberg mgmt_power_on(hdev, err); 22532ff13894SJohan Hedberg return; 22542ff13894SJohan Hedberg } 22552ff13894SJohan Hedberg 2256cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 225796570ffcSJohan Hedberg if (err < 0) { 22583ad67582SJaganath Kanakkassery hci_dev_lock(hdev); 225996570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 22603ad67582SJaganath Kanakkassery hci_dev_unlock(hdev); 2261ab81cbf9SJohan Hedberg return; 226296570ffcSJohan Hedberg } 2263ab81cbf9SJohan Hedberg 2264a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2265a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2266a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2267a5c8f270SMarcel Holtmann */ 2268d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED) || 2269d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_UNCONFIGURED) || 2270ca8bee5dSMarcel Holtmann (hdev->dev_type == HCI_PRIMARY && 2271a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2272a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2273a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_AUTO_OFF); 2274bf543036SJohan Hedberg hci_dev_do_close(hdev); 2275d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) { 227619202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 227719202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2278bf543036SJohan Hedberg } 2279ab81cbf9SJohan Hedberg 2280a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) { 22814a964404SMarcel Holtmann /* For unconfigured devices, set the HCI_RAW flag 22824a964404SMarcel Holtmann * so that userspace can easily identify them. 22834a964404SMarcel Holtmann */ 2284d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 22854a964404SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 22860602a8adSMarcel Holtmann 22870602a8adSMarcel Holtmann /* For fully configured devices, this will send 22880602a8adSMarcel Holtmann * the Index Added event. For unconfigured devices, 22890602a8adSMarcel Holtmann * it will send Unconfigued Index Added event. 22900602a8adSMarcel Holtmann * 22910602a8adSMarcel Holtmann * Devices with HCI_QUIRK_RAW_DEVICE are ignored 22920602a8adSMarcel Holtmann * and no event will be send. 22930602a8adSMarcel Holtmann */ 2294744cf19eSJohan Hedberg mgmt_index_added(hdev); 2295a69d8927SMarcel Holtmann } else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) { 22965ea234d3SMarcel Holtmann /* When the controller is now configured, then it 22975ea234d3SMarcel Holtmann * is important to clear the HCI_RAW flag. 22985ea234d3SMarcel Holtmann */ 2299d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 23005ea234d3SMarcel Holtmann clear_bit(HCI_RAW, &hdev->flags); 23015ea234d3SMarcel Holtmann 2302d603b76bSMarcel Holtmann /* Powering on the controller with HCI_CONFIG set only 2303d603b76bSMarcel Holtmann * happens with the transition from unconfigured to 2304d603b76bSMarcel Holtmann * configured. This will send the Index Added event. 2305d603b76bSMarcel Holtmann */ 2306d603b76bSMarcel Holtmann mgmt_index_added(hdev); 2307ab81cbf9SJohan Hedberg } 2308ab81cbf9SJohan Hedberg } 2309ab81cbf9SJohan Hedberg 2310ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2311ab81cbf9SJohan Hedberg { 23123243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 23133243553fSJohan Hedberg power_off.work); 2314ab81cbf9SJohan Hedberg 2315ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2316ab81cbf9SJohan Hedberg 23178ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2318ab81cbf9SJohan Hedberg } 2319ab81cbf9SJohan Hedberg 2320c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work) 2321c7741d16SMarcel Holtmann { 2322c7741d16SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset); 2323c7741d16SMarcel Holtmann 2324c7741d16SMarcel Holtmann BT_DBG("%s", hdev->name); 2325c7741d16SMarcel Holtmann 2326c7741d16SMarcel Holtmann if (hdev->hw_error) 2327c7741d16SMarcel Holtmann hdev->hw_error(hdev, hdev->hw_error_code); 2328c7741d16SMarcel Holtmann else 23292064ee33SMarcel Holtmann bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code); 2330c7741d16SMarcel Holtmann 2331c7741d16SMarcel Holtmann if (hci_dev_do_close(hdev)) 2332c7741d16SMarcel Holtmann return; 2333c7741d16SMarcel Holtmann 2334c7741d16SMarcel Holtmann hci_dev_do_open(hdev); 2335c7741d16SMarcel Holtmann } 2336c7741d16SMarcel Holtmann 233735f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 23382aeb9a1aSJohan Hedberg { 23394821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 23402aeb9a1aSJohan Hedberg 23414821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 23424821002cSJohan Hedberg list_del(&uuid->list); 23432aeb9a1aSJohan Hedberg kfree(uuid); 23442aeb9a1aSJohan Hedberg } 23452aeb9a1aSJohan Hedberg } 23462aeb9a1aSJohan Hedberg 234735f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 234855ed8ca1SJohan Hedberg { 234955ed8ca1SJohan Hedberg struct link_key *key; 235055ed8ca1SJohan Hedberg 2351d7d41682SMadhuparna Bhowmik list_for_each_entry(key, &hdev->link_keys, list) { 23520378b597SJohan Hedberg list_del_rcu(&key->list); 23530378b597SJohan Hedberg kfree_rcu(key, rcu); 235455ed8ca1SJohan Hedberg } 235555ed8ca1SJohan Hedberg } 235655ed8ca1SJohan Hedberg 235735f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2358b899efafSVinicius Costa Gomes { 2359970d0f1bSJohan Hedberg struct smp_ltk *k; 2360b899efafSVinicius Costa Gomes 2361d7d41682SMadhuparna Bhowmik list_for_each_entry(k, &hdev->long_term_keys, list) { 2362970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2363970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2364b899efafSVinicius Costa Gomes } 2365b899efafSVinicius Costa Gomes } 2366b899efafSVinicius Costa Gomes 2367970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2368970c4e46SJohan Hedberg { 2369adae20cbSJohan Hedberg struct smp_irk *k; 2370970c4e46SJohan Hedberg 2371d7d41682SMadhuparna Bhowmik list_for_each_entry(k, &hdev->identity_resolving_keys, list) { 2372adae20cbSJohan Hedberg list_del_rcu(&k->list); 2373adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2374970c4e46SJohan Hedberg } 2375970c4e46SJohan Hedberg } 2376970c4e46SJohan Hedberg 2377600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev) 2378600a8749SAlain Michaud { 2379600a8749SAlain Michaud struct blocked_key *b; 2380600a8749SAlain Michaud 2381d7d41682SMadhuparna Bhowmik list_for_each_entry(b, &hdev->blocked_keys, list) { 2382600a8749SAlain Michaud list_del_rcu(&b->list); 2383600a8749SAlain Michaud kfree_rcu(b, rcu); 2384600a8749SAlain Michaud } 2385600a8749SAlain Michaud } 2386600a8749SAlain Michaud 2387600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16]) 2388600a8749SAlain Michaud { 2389600a8749SAlain Michaud bool blocked = false; 2390600a8749SAlain Michaud struct blocked_key *b; 2391600a8749SAlain Michaud 2392600a8749SAlain Michaud rcu_read_lock(); 23930c2ac7d4SMadhuparna Bhowmik list_for_each_entry_rcu(b, &hdev->blocked_keys, list) { 2394600a8749SAlain Michaud if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) { 2395600a8749SAlain Michaud blocked = true; 2396600a8749SAlain Michaud break; 2397600a8749SAlain Michaud } 2398600a8749SAlain Michaud } 2399600a8749SAlain Michaud 2400600a8749SAlain Michaud rcu_read_unlock(); 2401600a8749SAlain Michaud return blocked; 2402600a8749SAlain Michaud } 2403600a8749SAlain Michaud 240455ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 240555ed8ca1SJohan Hedberg { 240655ed8ca1SJohan Hedberg struct link_key *k; 240755ed8ca1SJohan Hedberg 24080378b597SJohan Hedberg rcu_read_lock(); 24090378b597SJohan Hedberg list_for_each_entry_rcu(k, &hdev->link_keys, list) { 24100378b597SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) { 24110378b597SJohan Hedberg rcu_read_unlock(); 2412600a8749SAlain Michaud 2413600a8749SAlain Michaud if (hci_is_blocked_key(hdev, 2414600a8749SAlain Michaud HCI_BLOCKED_KEY_TYPE_LINKKEY, 2415600a8749SAlain Michaud k->val)) { 2416600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, 2417600a8749SAlain Michaud "Link key blocked for %pMR", 2418600a8749SAlain Michaud &k->bdaddr); 2419600a8749SAlain Michaud return NULL; 2420600a8749SAlain Michaud } 2421600a8749SAlain Michaud 242255ed8ca1SJohan Hedberg return k; 24230378b597SJohan Hedberg } 24240378b597SJohan Hedberg } 24250378b597SJohan Hedberg rcu_read_unlock(); 242655ed8ca1SJohan Hedberg 242755ed8ca1SJohan Hedberg return NULL; 242855ed8ca1SJohan Hedberg } 242955ed8ca1SJohan Hedberg 2430745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2431d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2432d25e28abSJohan Hedberg { 2433d25e28abSJohan Hedberg /* Legacy key */ 2434d25e28abSJohan Hedberg if (key_type < 0x03) 2435745c0ce3SVishal Agarwal return true; 2436d25e28abSJohan Hedberg 2437d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2438d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2439745c0ce3SVishal Agarwal return false; 2440d25e28abSJohan Hedberg 2441d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2442d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2443745c0ce3SVishal Agarwal return false; 2444d25e28abSJohan Hedberg 2445d25e28abSJohan Hedberg /* Security mode 3 case */ 2446d25e28abSJohan Hedberg if (!conn) 2447745c0ce3SVishal Agarwal return true; 2448d25e28abSJohan Hedberg 2449e3befab9SJohan Hedberg /* BR/EDR key derived using SC from an LE link */ 2450e3befab9SJohan Hedberg if (conn->type == LE_LINK) 2451e3befab9SJohan Hedberg return true; 2452e3befab9SJohan Hedberg 2453d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2454d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2455745c0ce3SVishal Agarwal return true; 2456d25e28abSJohan Hedberg 2457d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2458d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2459745c0ce3SVishal Agarwal return true; 2460d25e28abSJohan Hedberg 2461d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2462d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2463745c0ce3SVishal Agarwal return true; 2464d25e28abSJohan Hedberg 2465d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2466d25e28abSJohan Hedberg * persistently */ 2467745c0ce3SVishal Agarwal return false; 2468d25e28abSJohan Hedberg } 2469d25e28abSJohan Hedberg 2470e804d25dSJohan Hedberg static u8 ltk_role(u8 type) 247198a0b845SJohan Hedberg { 2472e804d25dSJohan Hedberg if (type == SMP_LTK) 2473e804d25dSJohan Hedberg return HCI_ROLE_MASTER; 247498a0b845SJohan Hedberg 2475e804d25dSJohan Hedberg return HCI_ROLE_SLAVE; 247698a0b845SJohan Hedberg } 247798a0b845SJohan Hedberg 2478f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2479e804d25dSJohan Hedberg u8 addr_type, u8 role) 248075d262c2SVinicius Costa Gomes { 2481c9839a11SVinicius Costa Gomes struct smp_ltk *k; 248275d262c2SVinicius Costa Gomes 2483970d0f1bSJohan Hedberg rcu_read_lock(); 2484970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 24855378bc56SJohan Hedberg if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr)) 24865378bc56SJohan Hedberg continue; 24875378bc56SJohan Hedberg 2488923e2414SJohan Hedberg if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) { 2489970d0f1bSJohan Hedberg rcu_read_unlock(); 2490600a8749SAlain Michaud 2491600a8749SAlain Michaud if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK, 2492600a8749SAlain Michaud k->val)) { 2493600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, 2494600a8749SAlain Michaud "LTK blocked for %pMR", 2495600a8749SAlain Michaud &k->bdaddr); 2496600a8749SAlain Michaud return NULL; 2497600a8749SAlain Michaud } 2498600a8749SAlain Michaud 249975d262c2SVinicius Costa Gomes return k; 2500970d0f1bSJohan Hedberg } 2501970d0f1bSJohan Hedberg } 2502970d0f1bSJohan Hedberg rcu_read_unlock(); 250375d262c2SVinicius Costa Gomes 250475d262c2SVinicius Costa Gomes return NULL; 250575d262c2SVinicius Costa Gomes } 250675d262c2SVinicius Costa Gomes 2507970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 2508970c4e46SJohan Hedberg { 2509600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL; 2510970c4e46SJohan Hedberg struct smp_irk *irk; 2511970c4e46SJohan Hedberg 2512adae20cbSJohan Hedberg rcu_read_lock(); 2513adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2514adae20cbSJohan Hedberg if (!bacmp(&irk->rpa, rpa)) { 2515600a8749SAlain Michaud irk_to_return = irk; 2516600a8749SAlain Michaud goto done; 2517970c4e46SJohan Hedberg } 2518adae20cbSJohan Hedberg } 2519970c4e46SJohan Hedberg 2520adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2521defce9e8SJohan Hedberg if (smp_irk_matches(hdev, irk->val, rpa)) { 2522970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2523600a8749SAlain Michaud irk_to_return = irk; 2524600a8749SAlain Michaud goto done; 2525970c4e46SJohan Hedberg } 2526970c4e46SJohan Hedberg } 2527600a8749SAlain Michaud 2528600a8749SAlain Michaud done: 2529600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK, 2530600a8749SAlain Michaud irk_to_return->val)) { 2531600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR", 2532600a8749SAlain Michaud &irk_to_return->bdaddr); 2533600a8749SAlain Michaud irk_to_return = NULL; 2534600a8749SAlain Michaud } 2535600a8749SAlain Michaud 2536adae20cbSJohan Hedberg rcu_read_unlock(); 2537970c4e46SJohan Hedberg 2538600a8749SAlain Michaud return irk_to_return; 2539970c4e46SJohan Hedberg } 2540970c4e46SJohan Hedberg 2541970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2542970c4e46SJohan Hedberg u8 addr_type) 2543970c4e46SJohan Hedberg { 2544600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL; 2545970c4e46SJohan Hedberg struct smp_irk *irk; 2546970c4e46SJohan Hedberg 25476cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 25486cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 25496cfc9988SJohan Hedberg return NULL; 25506cfc9988SJohan Hedberg 2551adae20cbSJohan Hedberg rcu_read_lock(); 2552adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2553970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 2554adae20cbSJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) { 2555600a8749SAlain Michaud irk_to_return = irk; 2556600a8749SAlain Michaud goto done; 2557970c4e46SJohan Hedberg } 2558adae20cbSJohan Hedberg } 2559600a8749SAlain Michaud 2560600a8749SAlain Michaud done: 2561600a8749SAlain Michaud 2562600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK, 2563600a8749SAlain Michaud irk_to_return->val)) { 2564600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR", 2565600a8749SAlain Michaud &irk_to_return->bdaddr); 2566600a8749SAlain Michaud irk_to_return = NULL; 2567600a8749SAlain Michaud } 2568600a8749SAlain Michaud 2569adae20cbSJohan Hedberg rcu_read_unlock(); 2570970c4e46SJohan Hedberg 2571600a8749SAlain Michaud return irk_to_return; 2572970c4e46SJohan Hedberg } 2573970c4e46SJohan Hedberg 2574567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 25757652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 25767652ff6aSJohan Hedberg u8 pin_len, bool *persistent) 257755ed8ca1SJohan Hedberg { 257855ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2579745c0ce3SVishal Agarwal u8 old_key_type; 258055ed8ca1SJohan Hedberg 258155ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 258255ed8ca1SJohan Hedberg if (old_key) { 258355ed8ca1SJohan Hedberg old_key_type = old_key->type; 258455ed8ca1SJohan Hedberg key = old_key; 258555ed8ca1SJohan Hedberg } else { 258612adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 25870a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 258855ed8ca1SJohan Hedberg if (!key) 2589567fa2aaSJohan Hedberg return NULL; 25900378b597SJohan Hedberg list_add_rcu(&key->list, &hdev->link_keys); 259155ed8ca1SJohan Hedberg } 259255ed8ca1SJohan Hedberg 25936ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 259455ed8ca1SJohan Hedberg 2595d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2596d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2597d25e28abSJohan Hedberg * previous key */ 2598d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2599a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2600d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2601655fe6ecSJohan Hedberg if (conn) 2602655fe6ecSJohan Hedberg conn->key_type = type; 2603655fe6ecSJohan Hedberg } 2604d25e28abSJohan Hedberg 260555ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 26069b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 260755ed8ca1SJohan Hedberg key->pin_len = pin_len; 260855ed8ca1SJohan Hedberg 2609b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 261055ed8ca1SJohan Hedberg key->type = old_key_type; 26114748fed2SJohan Hedberg else 26124748fed2SJohan Hedberg key->type = type; 26134748fed2SJohan Hedberg 26147652ff6aSJohan Hedberg if (persistent) 26157652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type, 26167652ff6aSJohan Hedberg old_key_type); 26174df378a1SJohan Hedberg 2618567fa2aaSJohan Hedberg return key; 261955ed8ca1SJohan Hedberg } 262055ed8ca1SJohan Hedberg 2621ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 262235d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 2623fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand) 262475d262c2SVinicius Costa Gomes { 2625c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 2626e804d25dSJohan Hedberg u8 role = ltk_role(type); 262775d262c2SVinicius Costa Gomes 2628f3a73d97SJohan Hedberg old_key = hci_find_ltk(hdev, bdaddr, addr_type, role); 2629c9839a11SVinicius Costa Gomes if (old_key) 263075d262c2SVinicius Costa Gomes key = old_key; 2631c9839a11SVinicius Costa Gomes else { 26320a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 263375d262c2SVinicius Costa Gomes if (!key) 2634ca9142b8SJohan Hedberg return NULL; 2635970d0f1bSJohan Hedberg list_add_rcu(&key->list, &hdev->long_term_keys); 263675d262c2SVinicius Costa Gomes } 263775d262c2SVinicius Costa Gomes 263875d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2639c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2640c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2641c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2642c9839a11SVinicius Costa Gomes key->ediv = ediv; 2643fe39c7b2SMarcel Holtmann key->rand = rand; 2644c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2645c9839a11SVinicius Costa Gomes key->type = type; 264675d262c2SVinicius Costa Gomes 2647ca9142b8SJohan Hedberg return key; 264875d262c2SVinicius Costa Gomes } 264975d262c2SVinicius Costa Gomes 2650ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2651ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 2652970c4e46SJohan Hedberg { 2653970c4e46SJohan Hedberg struct smp_irk *irk; 2654970c4e46SJohan Hedberg 2655970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 2656970c4e46SJohan Hedberg if (!irk) { 2657970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 2658970c4e46SJohan Hedberg if (!irk) 2659ca9142b8SJohan Hedberg return NULL; 2660970c4e46SJohan Hedberg 2661970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 2662970c4e46SJohan Hedberg irk->addr_type = addr_type; 2663970c4e46SJohan Hedberg 2664adae20cbSJohan Hedberg list_add_rcu(&irk->list, &hdev->identity_resolving_keys); 2665970c4e46SJohan Hedberg } 2666970c4e46SJohan Hedberg 2667970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 2668970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2669970c4e46SJohan Hedberg 2670ca9142b8SJohan Hedberg return irk; 2671970c4e46SJohan Hedberg } 2672970c4e46SJohan Hedberg 267355ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 267455ed8ca1SJohan Hedberg { 267555ed8ca1SJohan Hedberg struct link_key *key; 267655ed8ca1SJohan Hedberg 267755ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 267855ed8ca1SJohan Hedberg if (!key) 267955ed8ca1SJohan Hedberg return -ENOENT; 268055ed8ca1SJohan Hedberg 26816ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 268255ed8ca1SJohan Hedberg 26830378b597SJohan Hedberg list_del_rcu(&key->list); 26840378b597SJohan Hedberg kfree_rcu(key, rcu); 268555ed8ca1SJohan Hedberg 268655ed8ca1SJohan Hedberg return 0; 268755ed8ca1SJohan Hedberg } 268855ed8ca1SJohan Hedberg 2689e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 2690b899efafSVinicius Costa Gomes { 2691970d0f1bSJohan Hedberg struct smp_ltk *k; 2692c51ffa0bSJohan Hedberg int removed = 0; 2693b899efafSVinicius Costa Gomes 2694970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 2695e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 2696b899efafSVinicius Costa Gomes continue; 2697b899efafSVinicius Costa Gomes 26986ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2699b899efafSVinicius Costa Gomes 2700970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2701970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2702c51ffa0bSJohan Hedberg removed++; 2703b899efafSVinicius Costa Gomes } 2704b899efafSVinicius Costa Gomes 2705c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 2706b899efafSVinicius Costa Gomes } 2707b899efafSVinicius Costa Gomes 2708a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 2709a7ec7338SJohan Hedberg { 2710adae20cbSJohan Hedberg struct smp_irk *k; 2711a7ec7338SJohan Hedberg 2712adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 2713a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 2714a7ec7338SJohan Hedberg continue; 2715a7ec7338SJohan Hedberg 2716a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2717a7ec7338SJohan Hedberg 2718adae20cbSJohan Hedberg list_del_rcu(&k->list); 2719adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2720a7ec7338SJohan Hedberg } 2721a7ec7338SJohan Hedberg } 2722a7ec7338SJohan Hedberg 272355e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 272455e76b38SJohan Hedberg { 272555e76b38SJohan Hedberg struct smp_ltk *k; 27264ba9faf3SJohan Hedberg struct smp_irk *irk; 272755e76b38SJohan Hedberg u8 addr_type; 272855e76b38SJohan Hedberg 272955e76b38SJohan Hedberg if (type == BDADDR_BREDR) { 273055e76b38SJohan Hedberg if (hci_find_link_key(hdev, bdaddr)) 273155e76b38SJohan Hedberg return true; 273255e76b38SJohan Hedberg return false; 273355e76b38SJohan Hedberg } 273455e76b38SJohan Hedberg 273555e76b38SJohan Hedberg /* Convert to HCI addr type which struct smp_ltk uses */ 273655e76b38SJohan Hedberg if (type == BDADDR_LE_PUBLIC) 273755e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_PUBLIC; 273855e76b38SJohan Hedberg else 273955e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_RANDOM; 274055e76b38SJohan Hedberg 27414ba9faf3SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, addr_type); 27424ba9faf3SJohan Hedberg if (irk) { 27434ba9faf3SJohan Hedberg bdaddr = &irk->bdaddr; 27444ba9faf3SJohan Hedberg addr_type = irk->addr_type; 27454ba9faf3SJohan Hedberg } 27464ba9faf3SJohan Hedberg 274755e76b38SJohan Hedberg rcu_read_lock(); 274855e76b38SJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 274987c8b28dSJohan Hedberg if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) { 275087c8b28dSJohan Hedberg rcu_read_unlock(); 275155e76b38SJohan Hedberg return true; 275255e76b38SJohan Hedberg } 275387c8b28dSJohan Hedberg } 275455e76b38SJohan Hedberg rcu_read_unlock(); 275555e76b38SJohan Hedberg 275655e76b38SJohan Hedberg return false; 275755e76b38SJohan Hedberg } 275855e76b38SJohan Hedberg 27596bd32326SVille Tervo /* HCI command timer function */ 276065cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work) 27616bd32326SVille Tervo { 276265cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, 276365cc2b49SMarcel Holtmann cmd_timer.work); 27646bd32326SVille Tervo 2765bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2766bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2767bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2768bda4f23aSAndrei Emeltchenko 27692064ee33SMarcel Holtmann bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); 2770bda4f23aSAndrei Emeltchenko } else { 27712064ee33SMarcel Holtmann bt_dev_err(hdev, "command tx timeout"); 2772bda4f23aSAndrei Emeltchenko } 2773bda4f23aSAndrei Emeltchenko 2774e2bef384SRajat Jain if (hdev->cmd_timeout) 2775e2bef384SRajat Jain hdev->cmd_timeout(hdev); 2776e2bef384SRajat Jain 27776bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2778c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 27796bd32326SVille Tervo } 27806bd32326SVille Tervo 2781de75cd0dSManish Mandlik /* HCI ncmd timer function */ 2782de75cd0dSManish Mandlik static void hci_ncmd_timeout(struct work_struct *work) 2783de75cd0dSManish Mandlik { 2784de75cd0dSManish Mandlik struct hci_dev *hdev = container_of(work, struct hci_dev, 2785de75cd0dSManish Mandlik ncmd_timer.work); 2786de75cd0dSManish Mandlik 2787de75cd0dSManish Mandlik bt_dev_err(hdev, "Controller not accepting commands anymore: ncmd = 0"); 2788de75cd0dSManish Mandlik 2789de75cd0dSManish Mandlik /* During HCI_INIT phase no events can be injected if the ncmd timer 2790de75cd0dSManish Mandlik * triggers since the procedure has its own timeout handling. 2791de75cd0dSManish Mandlik */ 2792de75cd0dSManish Mandlik if (test_bit(HCI_INIT, &hdev->flags)) 2793de75cd0dSManish Mandlik return; 2794de75cd0dSManish Mandlik 2795de75cd0dSManish Mandlik /* This is an irrecoverable state, inject hardware error event */ 2796de75cd0dSManish Mandlik hci_reset_dev(hdev); 2797de75cd0dSManish Mandlik } 2798de75cd0dSManish Mandlik 27992763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 28006928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type) 28012763eda6SSzymon Janc { 28022763eda6SSzymon Janc struct oob_data *data; 28032763eda6SSzymon Janc 28046928a924SJohan Hedberg list_for_each_entry(data, &hdev->remote_oob_data, list) { 28056928a924SJohan Hedberg if (bacmp(bdaddr, &data->bdaddr) != 0) 28066928a924SJohan Hedberg continue; 28076928a924SJohan Hedberg if (data->bdaddr_type != bdaddr_type) 28086928a924SJohan Hedberg continue; 28092763eda6SSzymon Janc return data; 28106928a924SJohan Hedberg } 28112763eda6SSzymon Janc 28122763eda6SSzymon Janc return NULL; 28132763eda6SSzymon Janc } 28142763eda6SSzymon Janc 28156928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 28166928a924SJohan Hedberg u8 bdaddr_type) 28172763eda6SSzymon Janc { 28182763eda6SSzymon Janc struct oob_data *data; 28192763eda6SSzymon Janc 28206928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 28212763eda6SSzymon Janc if (!data) 28222763eda6SSzymon Janc return -ENOENT; 28232763eda6SSzymon Janc 28246928a924SJohan Hedberg BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type); 28252763eda6SSzymon Janc 28262763eda6SSzymon Janc list_del(&data->list); 28272763eda6SSzymon Janc kfree(data); 28282763eda6SSzymon Janc 28292763eda6SSzymon Janc return 0; 28302763eda6SSzymon Janc } 28312763eda6SSzymon Janc 283235f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 28332763eda6SSzymon Janc { 28342763eda6SSzymon Janc struct oob_data *data, *n; 28352763eda6SSzymon Janc 28362763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 28372763eda6SSzymon Janc list_del(&data->list); 28382763eda6SSzymon Janc kfree(data); 28392763eda6SSzymon Janc } 28402763eda6SSzymon Janc } 28412763eda6SSzymon Janc 28420798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 28436928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192, 284438da1703SJohan Hedberg u8 *hash256, u8 *rand256) 28450798872eSMarcel Holtmann { 28460798872eSMarcel Holtmann struct oob_data *data; 28470798872eSMarcel Holtmann 28486928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 28490798872eSMarcel Holtmann if (!data) { 28500a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 28510798872eSMarcel Holtmann if (!data) 28520798872eSMarcel Holtmann return -ENOMEM; 28530798872eSMarcel Holtmann 28540798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 28556928a924SJohan Hedberg data->bdaddr_type = bdaddr_type; 28560798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 28570798872eSMarcel Holtmann } 28580798872eSMarcel Holtmann 285981328d5cSJohan Hedberg if (hash192 && rand192) { 28600798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 286138da1703SJohan Hedberg memcpy(data->rand192, rand192, sizeof(data->rand192)); 2862f7697b16SMarcel Holtmann if (hash256 && rand256) 2863f7697b16SMarcel Holtmann data->present = 0x03; 286481328d5cSJohan Hedberg } else { 286581328d5cSJohan Hedberg memset(data->hash192, 0, sizeof(data->hash192)); 286681328d5cSJohan Hedberg memset(data->rand192, 0, sizeof(data->rand192)); 2867f7697b16SMarcel Holtmann if (hash256 && rand256) 2868f7697b16SMarcel Holtmann data->present = 0x02; 2869f7697b16SMarcel Holtmann else 2870f7697b16SMarcel Holtmann data->present = 0x00; 287181328d5cSJohan Hedberg } 28720798872eSMarcel Holtmann 287381328d5cSJohan Hedberg if (hash256 && rand256) { 28740798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 287538da1703SJohan Hedberg memcpy(data->rand256, rand256, sizeof(data->rand256)); 287681328d5cSJohan Hedberg } else { 287781328d5cSJohan Hedberg memset(data->hash256, 0, sizeof(data->hash256)); 287881328d5cSJohan Hedberg memset(data->rand256, 0, sizeof(data->rand256)); 2879f7697b16SMarcel Holtmann if (hash192 && rand192) 2880f7697b16SMarcel Holtmann data->present = 0x01; 288181328d5cSJohan Hedberg } 28820798872eSMarcel Holtmann 28836ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 28842763eda6SSzymon Janc 28852763eda6SSzymon Janc return 0; 28862763eda6SSzymon Janc } 28872763eda6SSzymon Janc 2888d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2889d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance) 2890d2609b34SFlorian Grandel { 2891d2609b34SFlorian Grandel struct adv_info *adv_instance; 2892d2609b34SFlorian Grandel 2893d2609b34SFlorian Grandel list_for_each_entry(adv_instance, &hdev->adv_instances, list) { 2894d2609b34SFlorian Grandel if (adv_instance->instance == instance) 2895d2609b34SFlorian Grandel return adv_instance; 2896d2609b34SFlorian Grandel } 2897d2609b34SFlorian Grandel 2898d2609b34SFlorian Grandel return NULL; 2899d2609b34SFlorian Grandel } 2900d2609b34SFlorian Grandel 2901d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 290274b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance) 290374b93e9fSPrasanna Karthik { 2904d2609b34SFlorian Grandel struct adv_info *cur_instance; 2905d2609b34SFlorian Grandel 2906d2609b34SFlorian Grandel cur_instance = hci_find_adv_instance(hdev, instance); 2907d2609b34SFlorian Grandel if (!cur_instance) 2908d2609b34SFlorian Grandel return NULL; 2909d2609b34SFlorian Grandel 2910d2609b34SFlorian Grandel if (cur_instance == list_last_entry(&hdev->adv_instances, 2911d2609b34SFlorian Grandel struct adv_info, list)) 2912d2609b34SFlorian Grandel return list_first_entry(&hdev->adv_instances, 2913d2609b34SFlorian Grandel struct adv_info, list); 2914d2609b34SFlorian Grandel else 2915d2609b34SFlorian Grandel return list_next_entry(cur_instance, list); 2916d2609b34SFlorian Grandel } 2917d2609b34SFlorian Grandel 2918d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2919d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance) 2920d2609b34SFlorian Grandel { 2921d2609b34SFlorian Grandel struct adv_info *adv_instance; 2922d2609b34SFlorian Grandel 2923d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 2924d2609b34SFlorian Grandel if (!adv_instance) 2925d2609b34SFlorian Grandel return -ENOENT; 2926d2609b34SFlorian Grandel 2927d2609b34SFlorian Grandel BT_DBG("%s removing %dMR", hdev->name, instance); 2928d2609b34SFlorian Grandel 2929cab054abSJohan Hedberg if (hdev->cur_adv_instance == instance) { 2930cab054abSJohan Hedberg if (hdev->adv_instance_timeout) { 29315d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 29325d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 29335d900e46SFlorian Grandel } 2934cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 2935cab054abSJohan Hedberg } 29365d900e46SFlorian Grandel 2937a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 2938a73c046aSJaganath Kanakkassery 2939d2609b34SFlorian Grandel list_del(&adv_instance->list); 2940d2609b34SFlorian Grandel kfree(adv_instance); 2941d2609b34SFlorian Grandel 2942d2609b34SFlorian Grandel hdev->adv_instance_cnt--; 2943d2609b34SFlorian Grandel 2944d2609b34SFlorian Grandel return 0; 2945d2609b34SFlorian Grandel } 2946d2609b34SFlorian Grandel 2947a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired) 2948a73c046aSJaganath Kanakkassery { 2949a73c046aSJaganath Kanakkassery struct adv_info *adv_instance, *n; 2950a73c046aSJaganath Kanakkassery 2951a73c046aSJaganath Kanakkassery list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) 2952a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = rpa_expired; 2953a73c046aSJaganath Kanakkassery } 2954a73c046aSJaganath Kanakkassery 2955d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2956d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev) 2957d2609b34SFlorian Grandel { 2958d2609b34SFlorian Grandel struct adv_info *adv_instance, *n; 2959d2609b34SFlorian Grandel 29605d900e46SFlorian Grandel if (hdev->adv_instance_timeout) { 29615d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 29625d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 29635d900e46SFlorian Grandel } 29645d900e46SFlorian Grandel 2965d2609b34SFlorian Grandel list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) { 2966a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 2967d2609b34SFlorian Grandel list_del(&adv_instance->list); 2968d2609b34SFlorian Grandel kfree(adv_instance); 2969d2609b34SFlorian Grandel } 2970d2609b34SFlorian Grandel 2971d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 2972cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 2973d2609b34SFlorian Grandel } 2974d2609b34SFlorian Grandel 2975a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work) 2976a73c046aSJaganath Kanakkassery { 2977a73c046aSJaganath Kanakkassery struct adv_info *adv_instance = container_of(work, struct adv_info, 2978a73c046aSJaganath Kanakkassery rpa_expired_cb.work); 2979a73c046aSJaganath Kanakkassery 2980a73c046aSJaganath Kanakkassery BT_DBG(""); 2981a73c046aSJaganath Kanakkassery 2982a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = true; 2983a73c046aSJaganath Kanakkassery } 2984a73c046aSJaganath Kanakkassery 2985d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2986d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags, 2987d2609b34SFlorian Grandel u16 adv_data_len, u8 *adv_data, 2988d2609b34SFlorian Grandel u16 scan_rsp_len, u8 *scan_rsp_data, 29899bf9f4b6SDaniel Winkler u16 timeout, u16 duration, s8 tx_power, 29909bf9f4b6SDaniel Winkler u32 min_interval, u32 max_interval) 2991d2609b34SFlorian Grandel { 2992d2609b34SFlorian Grandel struct adv_info *adv_instance; 2993d2609b34SFlorian Grandel 2994d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 2995d2609b34SFlorian Grandel if (adv_instance) { 2996d2609b34SFlorian Grandel memset(adv_instance->adv_data, 0, 2997d2609b34SFlorian Grandel sizeof(adv_instance->adv_data)); 2998d2609b34SFlorian Grandel memset(adv_instance->scan_rsp_data, 0, 2999d2609b34SFlorian Grandel sizeof(adv_instance->scan_rsp_data)); 3000d2609b34SFlorian Grandel } else { 30011d0fac2cSLuiz Augusto von Dentz if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets || 300287597482SDaniel Winkler instance < 1 || instance > hdev->le_num_of_adv_sets) 3003d2609b34SFlorian Grandel return -EOVERFLOW; 3004d2609b34SFlorian Grandel 300539ecfad6SJohan Hedberg adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL); 3006d2609b34SFlorian Grandel if (!adv_instance) 3007d2609b34SFlorian Grandel return -ENOMEM; 3008d2609b34SFlorian Grandel 3009fffd38bcSFlorian Grandel adv_instance->pending = true; 3010d2609b34SFlorian Grandel adv_instance->instance = instance; 3011d2609b34SFlorian Grandel list_add(&adv_instance->list, &hdev->adv_instances); 3012d2609b34SFlorian Grandel hdev->adv_instance_cnt++; 3013d2609b34SFlorian Grandel } 3014d2609b34SFlorian Grandel 3015d2609b34SFlorian Grandel adv_instance->flags = flags; 3016d2609b34SFlorian Grandel adv_instance->adv_data_len = adv_data_len; 3017d2609b34SFlorian Grandel adv_instance->scan_rsp_len = scan_rsp_len; 30189bf9f4b6SDaniel Winkler adv_instance->min_interval = min_interval; 30199bf9f4b6SDaniel Winkler adv_instance->max_interval = max_interval; 30209bf9f4b6SDaniel Winkler adv_instance->tx_power = tx_power; 3021d2609b34SFlorian Grandel 3022d2609b34SFlorian Grandel if (adv_data_len) 3023d2609b34SFlorian Grandel memcpy(adv_instance->adv_data, adv_data, adv_data_len); 3024d2609b34SFlorian Grandel 3025d2609b34SFlorian Grandel if (scan_rsp_len) 3026d2609b34SFlorian Grandel memcpy(adv_instance->scan_rsp_data, 3027d2609b34SFlorian Grandel scan_rsp_data, scan_rsp_len); 3028d2609b34SFlorian Grandel 3029d2609b34SFlorian Grandel adv_instance->timeout = timeout; 30305d900e46SFlorian Grandel adv_instance->remaining_time = timeout; 3031d2609b34SFlorian Grandel 3032d2609b34SFlorian Grandel if (duration == 0) 303310873f99SAlain Michaud adv_instance->duration = hdev->def_multi_adv_rotation_duration; 3034d2609b34SFlorian Grandel else 3035d2609b34SFlorian Grandel adv_instance->duration = duration; 3036d2609b34SFlorian Grandel 3037a73c046aSJaganath Kanakkassery INIT_DELAYED_WORK(&adv_instance->rpa_expired_cb, 3038a73c046aSJaganath Kanakkassery adv_instance_rpa_expired); 3039a73c046aSJaganath Kanakkassery 3040d2609b34SFlorian Grandel BT_DBG("%s for %dMR", hdev->name, instance); 3041d2609b34SFlorian Grandel 3042d2609b34SFlorian Grandel return 0; 3043d2609b34SFlorian Grandel } 3044d2609b34SFlorian Grandel 3045e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */ 304631aab5c2SDaniel Winkler int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance, 304731aab5c2SDaniel Winkler u16 adv_data_len, u8 *adv_data, 304831aab5c2SDaniel Winkler u16 scan_rsp_len, u8 *scan_rsp_data) 304931aab5c2SDaniel Winkler { 305031aab5c2SDaniel Winkler struct adv_info *adv_instance; 305131aab5c2SDaniel Winkler 305231aab5c2SDaniel Winkler adv_instance = hci_find_adv_instance(hdev, instance); 305331aab5c2SDaniel Winkler 305431aab5c2SDaniel Winkler /* If advertisement doesn't exist, we can't modify its data */ 305531aab5c2SDaniel Winkler if (!adv_instance) 305631aab5c2SDaniel Winkler return -ENOENT; 305731aab5c2SDaniel Winkler 305831aab5c2SDaniel Winkler if (adv_data_len) { 305931aab5c2SDaniel Winkler memset(adv_instance->adv_data, 0, 306031aab5c2SDaniel Winkler sizeof(adv_instance->adv_data)); 306131aab5c2SDaniel Winkler memcpy(adv_instance->adv_data, adv_data, adv_data_len); 306231aab5c2SDaniel Winkler adv_instance->adv_data_len = adv_data_len; 306331aab5c2SDaniel Winkler } 306431aab5c2SDaniel Winkler 306531aab5c2SDaniel Winkler if (scan_rsp_len) { 306631aab5c2SDaniel Winkler memset(adv_instance->scan_rsp_data, 0, 306731aab5c2SDaniel Winkler sizeof(adv_instance->scan_rsp_data)); 306831aab5c2SDaniel Winkler memcpy(adv_instance->scan_rsp_data, 306931aab5c2SDaniel Winkler scan_rsp_data, scan_rsp_len); 307031aab5c2SDaniel Winkler adv_instance->scan_rsp_len = scan_rsp_len; 307131aab5c2SDaniel Winkler } 307231aab5c2SDaniel Winkler 307331aab5c2SDaniel Winkler return 0; 307431aab5c2SDaniel Winkler } 307531aab5c2SDaniel Winkler 307631aab5c2SDaniel Winkler /* This function requires the caller holds hdev->lock */ 3077e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev) 3078e5e1e7fdSMiao-chen Chou { 3079b139553dSMiao-chen Chou struct adv_monitor *monitor; 3080b139553dSMiao-chen Chou int handle; 3081b139553dSMiao-chen Chou 3082b139553dSMiao-chen Chou idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle) 308366bd095aSArchie Pusaka hci_free_adv_monitor(hdev, monitor); 3084b139553dSMiao-chen Chou 3085e5e1e7fdSMiao-chen Chou idr_destroy(&hdev->adv_monitors_idr); 3086e5e1e7fdSMiao-chen Chou } 3087e5e1e7fdSMiao-chen Chou 308866bd095aSArchie Pusaka /* Frees the monitor structure and do some bookkeepings. 308966bd095aSArchie Pusaka * This function requires the caller holds hdev->lock. 309066bd095aSArchie Pusaka */ 309166bd095aSArchie Pusaka void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor) 3092b139553dSMiao-chen Chou { 3093b139553dSMiao-chen Chou struct adv_pattern *pattern; 3094b139553dSMiao-chen Chou struct adv_pattern *tmp; 3095b139553dSMiao-chen Chou 3096b139553dSMiao-chen Chou if (!monitor) 3097b139553dSMiao-chen Chou return; 3098b139553dSMiao-chen Chou 309966bd095aSArchie Pusaka list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) { 310066bd095aSArchie Pusaka list_del(&pattern->list); 3101b139553dSMiao-chen Chou kfree(pattern); 310266bd095aSArchie Pusaka } 310366bd095aSArchie Pusaka 310466bd095aSArchie Pusaka if (monitor->handle) 310566bd095aSArchie Pusaka idr_remove(&hdev->adv_monitors_idr, monitor->handle); 310666bd095aSArchie Pusaka 310766bd095aSArchie Pusaka if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) { 310866bd095aSArchie Pusaka hdev->adv_monitors_cnt--; 310966bd095aSArchie Pusaka mgmt_adv_monitor_removed(hdev, monitor->handle); 311066bd095aSArchie Pusaka } 3111b139553dSMiao-chen Chou 3112b139553dSMiao-chen Chou kfree(monitor); 3113b139553dSMiao-chen Chou } 3114b139553dSMiao-chen Chou 3115a2a4dedfSArchie Pusaka int hci_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status) 3116a2a4dedfSArchie Pusaka { 3117a2a4dedfSArchie Pusaka return mgmt_add_adv_patterns_monitor_complete(hdev, status); 3118a2a4dedfSArchie Pusaka } 3119a2a4dedfSArchie Pusaka 312066bd095aSArchie Pusaka int hci_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status) 312166bd095aSArchie Pusaka { 312266bd095aSArchie Pusaka return mgmt_remove_adv_monitor_complete(hdev, status); 312366bd095aSArchie Pusaka } 312466bd095aSArchie Pusaka 3125a2a4dedfSArchie Pusaka /* Assigns handle to a monitor, and if offloading is supported and power is on, 3126a2a4dedfSArchie Pusaka * also attempts to forward the request to the controller. 3127a2a4dedfSArchie Pusaka * Returns true if request is forwarded (result is pending), false otherwise. 3128a2a4dedfSArchie Pusaka * This function requires the caller holds hdev->lock. 3129a2a4dedfSArchie Pusaka */ 3130a2a4dedfSArchie Pusaka bool hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor, 3131a2a4dedfSArchie Pusaka int *err) 3132b139553dSMiao-chen Chou { 3133b139553dSMiao-chen Chou int min, max, handle; 3134b139553dSMiao-chen Chou 3135a2a4dedfSArchie Pusaka *err = 0; 3136a2a4dedfSArchie Pusaka 3137a2a4dedfSArchie Pusaka if (!monitor) { 3138a2a4dedfSArchie Pusaka *err = -EINVAL; 3139a2a4dedfSArchie Pusaka return false; 3140a2a4dedfSArchie Pusaka } 3141b139553dSMiao-chen Chou 3142b139553dSMiao-chen Chou min = HCI_MIN_ADV_MONITOR_HANDLE; 3143b139553dSMiao-chen Chou max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES; 3144b139553dSMiao-chen Chou handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max, 3145b139553dSMiao-chen Chou GFP_KERNEL); 3146a2a4dedfSArchie Pusaka if (handle < 0) { 3147a2a4dedfSArchie Pusaka *err = handle; 3148a2a4dedfSArchie Pusaka return false; 3149a2a4dedfSArchie Pusaka } 3150b139553dSMiao-chen Chou 3151b139553dSMiao-chen Chou monitor->handle = handle; 31528208f5a9SMiao-chen Chou 3153a2a4dedfSArchie Pusaka if (!hdev_is_powered(hdev)) 3154a2a4dedfSArchie Pusaka return false; 31558208f5a9SMiao-chen Chou 3156a2a4dedfSArchie Pusaka switch (hci_get_adv_monitor_offload_ext(hdev)) { 3157a2a4dedfSArchie Pusaka case HCI_ADV_MONITOR_EXT_NONE: 3158a2a4dedfSArchie Pusaka hci_update_background_scan(hdev); 3159a2a4dedfSArchie Pusaka bt_dev_dbg(hdev, "%s add monitor status %d", hdev->name, *err); 3160a2a4dedfSArchie Pusaka /* Message was not forwarded to controller - not an error */ 3161a2a4dedfSArchie Pusaka return false; 3162a2a4dedfSArchie Pusaka case HCI_ADV_MONITOR_EXT_MSFT: 3163a2a4dedfSArchie Pusaka *err = msft_add_monitor_pattern(hdev, monitor); 3164a2a4dedfSArchie Pusaka bt_dev_dbg(hdev, "%s add monitor msft status %d", hdev->name, 3165a2a4dedfSArchie Pusaka *err); 3166a2a4dedfSArchie Pusaka break; 3167a2a4dedfSArchie Pusaka } 3168a2a4dedfSArchie Pusaka 3169a2a4dedfSArchie Pusaka return (*err == 0); 3170b139553dSMiao-chen Chou } 3171b139553dSMiao-chen Chou 317266bd095aSArchie Pusaka /* Attempts to tell the controller and free the monitor. If somehow the 317366bd095aSArchie Pusaka * controller doesn't have a corresponding handle, remove anyway. 317466bd095aSArchie Pusaka * Returns true if request is forwarded (result is pending), false otherwise. 317566bd095aSArchie Pusaka * This function requires the caller holds hdev->lock. 317666bd095aSArchie Pusaka */ 317766bd095aSArchie Pusaka static bool hci_remove_adv_monitor(struct hci_dev *hdev, 317866bd095aSArchie Pusaka struct adv_monitor *monitor, 317966bd095aSArchie Pusaka u16 handle, int *err) 3180bd2fbc6cSMiao-chen Chou { 318166bd095aSArchie Pusaka *err = 0; 3182bd2fbc6cSMiao-chen Chou 318366bd095aSArchie Pusaka switch (hci_get_adv_monitor_offload_ext(hdev)) { 318466bd095aSArchie Pusaka case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */ 318566bd095aSArchie Pusaka goto free_monitor; 318666bd095aSArchie Pusaka case HCI_ADV_MONITOR_EXT_MSFT: 318766bd095aSArchie Pusaka *err = msft_remove_monitor(hdev, monitor, handle); 318866bd095aSArchie Pusaka break; 3189bd2fbc6cSMiao-chen Chou } 3190bd2fbc6cSMiao-chen Chou 319166bd095aSArchie Pusaka /* In case no matching handle registered, just free the monitor */ 319266bd095aSArchie Pusaka if (*err == -ENOENT) 319366bd095aSArchie Pusaka goto free_monitor; 3194bd2fbc6cSMiao-chen Chou 319566bd095aSArchie Pusaka return (*err == 0); 3196bd2fbc6cSMiao-chen Chou 319766bd095aSArchie Pusaka free_monitor: 319866bd095aSArchie Pusaka if (*err == -ENOENT) 319966bd095aSArchie Pusaka bt_dev_warn(hdev, "Removing monitor with no matching handle %d", 320066bd095aSArchie Pusaka monitor->handle); 320166bd095aSArchie Pusaka hci_free_adv_monitor(hdev, monitor); 320266bd095aSArchie Pusaka 320366bd095aSArchie Pusaka *err = 0; 320466bd095aSArchie Pusaka return false; 3205bd2fbc6cSMiao-chen Chou } 3206bd2fbc6cSMiao-chen Chou 320766bd095aSArchie Pusaka /* Returns true if request is forwarded (result is pending), false otherwise. 320866bd095aSArchie Pusaka * This function requires the caller holds hdev->lock. 320966bd095aSArchie Pusaka */ 321066bd095aSArchie Pusaka bool hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle, int *err) 321166bd095aSArchie Pusaka { 321266bd095aSArchie Pusaka struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle); 321366bd095aSArchie Pusaka bool pending; 321466bd095aSArchie Pusaka 321566bd095aSArchie Pusaka if (!monitor) { 321666bd095aSArchie Pusaka *err = -EINVAL; 321766bd095aSArchie Pusaka return false; 321866bd095aSArchie Pusaka } 321966bd095aSArchie Pusaka 322066bd095aSArchie Pusaka pending = hci_remove_adv_monitor(hdev, monitor, handle, err); 322166bd095aSArchie Pusaka if (!*err && !pending) 32228208f5a9SMiao-chen Chou hci_update_background_scan(hdev); 32238208f5a9SMiao-chen Chou 322466bd095aSArchie Pusaka bt_dev_dbg(hdev, "%s remove monitor handle %d, status %d, %spending", 322566bd095aSArchie Pusaka hdev->name, handle, *err, pending ? "" : "not "); 322666bd095aSArchie Pusaka 322766bd095aSArchie Pusaka return pending; 322866bd095aSArchie Pusaka } 322966bd095aSArchie Pusaka 323066bd095aSArchie Pusaka /* Returns true if request is forwarded (result is pending), false otherwise. 323166bd095aSArchie Pusaka * This function requires the caller holds hdev->lock. 323266bd095aSArchie Pusaka */ 323366bd095aSArchie Pusaka bool hci_remove_all_adv_monitor(struct hci_dev *hdev, int *err) 323466bd095aSArchie Pusaka { 323566bd095aSArchie Pusaka struct adv_monitor *monitor; 323666bd095aSArchie Pusaka int idr_next_id = 0; 323766bd095aSArchie Pusaka bool pending = false; 323866bd095aSArchie Pusaka bool update = false; 323966bd095aSArchie Pusaka 324066bd095aSArchie Pusaka *err = 0; 324166bd095aSArchie Pusaka 324266bd095aSArchie Pusaka while (!*err && !pending) { 324366bd095aSArchie Pusaka monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id); 324466bd095aSArchie Pusaka if (!monitor) 324566bd095aSArchie Pusaka break; 324666bd095aSArchie Pusaka 324766bd095aSArchie Pusaka pending = hci_remove_adv_monitor(hdev, monitor, 0, err); 324866bd095aSArchie Pusaka 324966bd095aSArchie Pusaka if (!*err && !pending) 325066bd095aSArchie Pusaka update = true; 325166bd095aSArchie Pusaka } 325266bd095aSArchie Pusaka 325366bd095aSArchie Pusaka if (update) 325466bd095aSArchie Pusaka hci_update_background_scan(hdev); 325566bd095aSArchie Pusaka 325666bd095aSArchie Pusaka bt_dev_dbg(hdev, "%s remove all monitors status %d, %spending", 325766bd095aSArchie Pusaka hdev->name, *err, pending ? "" : "not "); 325866bd095aSArchie Pusaka 325966bd095aSArchie Pusaka return pending; 3260bd2fbc6cSMiao-chen Chou } 3261bd2fbc6cSMiao-chen Chou 32628208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */ 32638208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev) 32648208f5a9SMiao-chen Chou { 32658208f5a9SMiao-chen Chou return !idr_is_empty(&hdev->adv_monitors_idr); 32668208f5a9SMiao-chen Chou } 32678208f5a9SMiao-chen Chou 3268a2a4dedfSArchie Pusaka int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev) 3269a2a4dedfSArchie Pusaka { 3270a2a4dedfSArchie Pusaka if (msft_monitor_supported(hdev)) 3271a2a4dedfSArchie Pusaka return HCI_ADV_MONITOR_EXT_MSFT; 3272a2a4dedfSArchie Pusaka 3273a2a4dedfSArchie Pusaka return HCI_ADV_MONITOR_EXT_NONE; 3274a2a4dedfSArchie Pusaka } 3275a2a4dedfSArchie Pusaka 3276dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list, 3277b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 3278b2a66aadSAntti Julku { 3279b2a66aadSAntti Julku struct bdaddr_list *b; 3280b2a66aadSAntti Julku 3281dcc36c16SJohan Hedberg list_for_each_entry(b, bdaddr_list, list) { 3282b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3283b2a66aadSAntti Julku return b; 3284b9ee0a78SMarcel Holtmann } 3285b2a66aadSAntti Julku 3286b2a66aadSAntti Julku return NULL; 3287b2a66aadSAntti Julku } 3288b2a66aadSAntti Julku 3289b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk( 3290b950aa88SAnkit Navik struct list_head *bdaddr_list, bdaddr_t *bdaddr, 3291b950aa88SAnkit Navik u8 type) 3292b950aa88SAnkit Navik { 3293b950aa88SAnkit Navik struct bdaddr_list_with_irk *b; 3294b950aa88SAnkit Navik 3295b950aa88SAnkit Navik list_for_each_entry(b, bdaddr_list, list) { 3296b950aa88SAnkit Navik if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3297b950aa88SAnkit Navik return b; 3298b950aa88SAnkit Navik } 3299b950aa88SAnkit Navik 3300b950aa88SAnkit Navik return NULL; 3301b950aa88SAnkit Navik } 3302b950aa88SAnkit Navik 33038baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags * 33048baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list, 33058baaa403SAbhishek Pandit-Subedi bdaddr_t *bdaddr, u8 type) 33068baaa403SAbhishek Pandit-Subedi { 33078baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *b; 33088baaa403SAbhishek Pandit-Subedi 33098baaa403SAbhishek Pandit-Subedi list_for_each_entry(b, bdaddr_list, list) { 33108baaa403SAbhishek Pandit-Subedi if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 33118baaa403SAbhishek Pandit-Subedi return b; 33128baaa403SAbhishek Pandit-Subedi } 33138baaa403SAbhishek Pandit-Subedi 33148baaa403SAbhishek Pandit-Subedi return NULL; 33158baaa403SAbhishek Pandit-Subedi } 33168baaa403SAbhishek Pandit-Subedi 3317dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list) 3318b2a66aadSAntti Julku { 33197eb7404fSGeliang Tang struct bdaddr_list *b, *n; 3320b2a66aadSAntti Julku 33217eb7404fSGeliang Tang list_for_each_entry_safe(b, n, bdaddr_list, list) { 33227eb7404fSGeliang Tang list_del(&b->list); 3323b2a66aadSAntti Julku kfree(b); 3324b2a66aadSAntti Julku } 3325b2a66aadSAntti Julku } 3326b2a66aadSAntti Julku 3327dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type) 3328b2a66aadSAntti Julku { 3329b2a66aadSAntti Julku struct bdaddr_list *entry; 3330b2a66aadSAntti Julku 3331b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3332b2a66aadSAntti Julku return -EBADF; 3333b2a66aadSAntti Julku 3334dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(list, bdaddr, type)) 33355e762444SAntti Julku return -EEXIST; 3336b2a66aadSAntti Julku 333727f70f3eSJohan Hedberg entry = kzalloc(sizeof(*entry), GFP_KERNEL); 33385e762444SAntti Julku if (!entry) 33395e762444SAntti Julku return -ENOMEM; 3340b2a66aadSAntti Julku 3341b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 3342b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 3343b2a66aadSAntti Julku 3344dcc36c16SJohan Hedberg list_add(&entry->list, list); 3345b2a66aadSAntti Julku 33462a8357f2SJohan Hedberg return 0; 3347b2a66aadSAntti Julku } 3348b2a66aadSAntti Julku 3349b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr, 3350b950aa88SAnkit Navik u8 type, u8 *peer_irk, u8 *local_irk) 3351b950aa88SAnkit Navik { 3352b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 3353b950aa88SAnkit Navik 3354b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) 3355b950aa88SAnkit Navik return -EBADF; 3356b950aa88SAnkit Navik 3357b950aa88SAnkit Navik if (hci_bdaddr_list_lookup(list, bdaddr, type)) 3358b950aa88SAnkit Navik return -EEXIST; 3359b950aa88SAnkit Navik 3360b950aa88SAnkit Navik entry = kzalloc(sizeof(*entry), GFP_KERNEL); 3361b950aa88SAnkit Navik if (!entry) 3362b950aa88SAnkit Navik return -ENOMEM; 3363b950aa88SAnkit Navik 3364b950aa88SAnkit Navik bacpy(&entry->bdaddr, bdaddr); 3365b950aa88SAnkit Navik entry->bdaddr_type = type; 3366b950aa88SAnkit Navik 3367b950aa88SAnkit Navik if (peer_irk) 3368b950aa88SAnkit Navik memcpy(entry->peer_irk, peer_irk, 16); 3369b950aa88SAnkit Navik 3370b950aa88SAnkit Navik if (local_irk) 3371b950aa88SAnkit Navik memcpy(entry->local_irk, local_irk, 16); 3372b950aa88SAnkit Navik 3373b950aa88SAnkit Navik list_add(&entry->list, list); 3374b950aa88SAnkit Navik 3375b950aa88SAnkit Navik return 0; 3376b950aa88SAnkit Navik } 3377b950aa88SAnkit Navik 33788baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr, 33798baaa403SAbhishek Pandit-Subedi u8 type, u32 flags) 33808baaa403SAbhishek Pandit-Subedi { 33818baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *entry; 33828baaa403SAbhishek Pandit-Subedi 33838baaa403SAbhishek Pandit-Subedi if (!bacmp(bdaddr, BDADDR_ANY)) 33848baaa403SAbhishek Pandit-Subedi return -EBADF; 33858baaa403SAbhishek Pandit-Subedi 33868baaa403SAbhishek Pandit-Subedi if (hci_bdaddr_list_lookup(list, bdaddr, type)) 33878baaa403SAbhishek Pandit-Subedi return -EEXIST; 33888baaa403SAbhishek Pandit-Subedi 33898baaa403SAbhishek Pandit-Subedi entry = kzalloc(sizeof(*entry), GFP_KERNEL); 33908baaa403SAbhishek Pandit-Subedi if (!entry) 33918baaa403SAbhishek Pandit-Subedi return -ENOMEM; 33928baaa403SAbhishek Pandit-Subedi 33938baaa403SAbhishek Pandit-Subedi bacpy(&entry->bdaddr, bdaddr); 33948baaa403SAbhishek Pandit-Subedi entry->bdaddr_type = type; 33958baaa403SAbhishek Pandit-Subedi entry->current_flags = flags; 33968baaa403SAbhishek Pandit-Subedi 33978baaa403SAbhishek Pandit-Subedi list_add(&entry->list, list); 33988baaa403SAbhishek Pandit-Subedi 33998baaa403SAbhishek Pandit-Subedi return 0; 34008baaa403SAbhishek Pandit-Subedi } 34018baaa403SAbhishek Pandit-Subedi 3402dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type) 3403b2a66aadSAntti Julku { 3404b2a66aadSAntti Julku struct bdaddr_list *entry; 3405b2a66aadSAntti Julku 340635f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 3407dcc36c16SJohan Hedberg hci_bdaddr_list_clear(list); 340835f7498aSJohan Hedberg return 0; 340935f7498aSJohan Hedberg } 3410b2a66aadSAntti Julku 3411dcc36c16SJohan Hedberg entry = hci_bdaddr_list_lookup(list, bdaddr, type); 3412d2ab0ac1SMarcel Holtmann if (!entry) 3413d2ab0ac1SMarcel Holtmann return -ENOENT; 3414d2ab0ac1SMarcel Holtmann 3415d2ab0ac1SMarcel Holtmann list_del(&entry->list); 3416d2ab0ac1SMarcel Holtmann kfree(entry); 3417d2ab0ac1SMarcel Holtmann 3418d2ab0ac1SMarcel Holtmann return 0; 3419d2ab0ac1SMarcel Holtmann } 3420d2ab0ac1SMarcel Holtmann 3421b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr, 3422b950aa88SAnkit Navik u8 type) 3423b950aa88SAnkit Navik { 3424b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 3425b950aa88SAnkit Navik 3426b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) { 3427b950aa88SAnkit Navik hci_bdaddr_list_clear(list); 3428b950aa88SAnkit Navik return 0; 3429b950aa88SAnkit Navik } 3430b950aa88SAnkit Navik 3431b950aa88SAnkit Navik entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type); 3432b950aa88SAnkit Navik if (!entry) 3433b950aa88SAnkit Navik return -ENOENT; 3434b950aa88SAnkit Navik 3435b950aa88SAnkit Navik list_del(&entry->list); 3436b950aa88SAnkit Navik kfree(entry); 3437b950aa88SAnkit Navik 3438b950aa88SAnkit Navik return 0; 3439b950aa88SAnkit Navik } 3440b950aa88SAnkit Navik 34418baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr, 34428baaa403SAbhishek Pandit-Subedi u8 type) 34438baaa403SAbhishek Pandit-Subedi { 34448baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *entry; 34458baaa403SAbhishek Pandit-Subedi 34468baaa403SAbhishek Pandit-Subedi if (!bacmp(bdaddr, BDADDR_ANY)) { 34478baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_clear(list); 34488baaa403SAbhishek Pandit-Subedi return 0; 34498baaa403SAbhishek Pandit-Subedi } 34508baaa403SAbhishek Pandit-Subedi 34518baaa403SAbhishek Pandit-Subedi entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type); 34528baaa403SAbhishek Pandit-Subedi if (!entry) 34538baaa403SAbhishek Pandit-Subedi return -ENOENT; 34548baaa403SAbhishek Pandit-Subedi 34558baaa403SAbhishek Pandit-Subedi list_del(&entry->list); 34568baaa403SAbhishek Pandit-Subedi kfree(entry); 34578baaa403SAbhishek Pandit-Subedi 34588baaa403SAbhishek Pandit-Subedi return 0; 34598baaa403SAbhishek Pandit-Subedi } 34608baaa403SAbhishek Pandit-Subedi 346115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 346215819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 346315819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 346415819a70SAndre Guedes { 346515819a70SAndre Guedes struct hci_conn_params *params; 346615819a70SAndre Guedes 346715819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 346815819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 346915819a70SAndre Guedes params->addr_type == addr_type) { 347015819a70SAndre Guedes return params; 347115819a70SAndre Guedes } 347215819a70SAndre Guedes } 347315819a70SAndre Guedes 347415819a70SAndre Guedes return NULL; 347515819a70SAndre Guedes } 347615819a70SAndre Guedes 347715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 3478501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 34794b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type) 348015819a70SAndre Guedes { 3481912b42efSJohan Hedberg struct hci_conn_params *param; 348215819a70SAndre Guedes 34836540351eSMarcel Holtmann switch (addr_type) { 34846540351eSMarcel Holtmann case ADDR_LE_DEV_PUBLIC_RESOLVED: 34856540351eSMarcel Holtmann addr_type = ADDR_LE_DEV_PUBLIC; 34866540351eSMarcel Holtmann break; 34876540351eSMarcel Holtmann case ADDR_LE_DEV_RANDOM_RESOLVED: 34886540351eSMarcel Holtmann addr_type = ADDR_LE_DEV_RANDOM; 34896540351eSMarcel Holtmann break; 34906540351eSMarcel Holtmann } 34916540351eSMarcel Holtmann 3492501f8827SJohan Hedberg list_for_each_entry(param, list, action) { 3493912b42efSJohan Hedberg if (bacmp(¶m->addr, addr) == 0 && 3494912b42efSJohan Hedberg param->addr_type == addr_type) 3495912b42efSJohan Hedberg return param; 34964b10966fSMarcel Holtmann } 34974b10966fSMarcel Holtmann 34984b10966fSMarcel Holtmann return NULL; 349915819a70SAndre Guedes } 350015819a70SAndre Guedes 350115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 350251d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 350351d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type) 350415819a70SAndre Guedes { 350515819a70SAndre Guedes struct hci_conn_params *params; 350615819a70SAndre Guedes 350715819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 3508cef952ceSAndre Guedes if (params) 350951d167c0SMarcel Holtmann return params; 351015819a70SAndre Guedes 351115819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 351215819a70SAndre Guedes if (!params) { 35132064ee33SMarcel Holtmann bt_dev_err(hdev, "out of memory"); 351451d167c0SMarcel Holtmann return NULL; 351515819a70SAndre Guedes } 351615819a70SAndre Guedes 351715819a70SAndre Guedes bacpy(¶ms->addr, addr); 351815819a70SAndre Guedes params->addr_type = addr_type; 3519cef952ceSAndre Guedes 3520cef952ceSAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 352193450c75SJohan Hedberg INIT_LIST_HEAD(¶ms->action); 3522cef952ceSAndre Guedes 3523bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval; 3524bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval; 3525bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency; 3526bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout; 3527bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED; 3528bf5b3c8bSMarcel Holtmann 3529bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 3530bf5b3c8bSMarcel Holtmann 353151d167c0SMarcel Holtmann return params; 3532bf5b3c8bSMarcel Holtmann } 3533bf5b3c8bSMarcel Holtmann 3534f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params) 3535f6c63249SJohan Hedberg { 3536f6c63249SJohan Hedberg if (params->conn) { 3537f6c63249SJohan Hedberg hci_conn_drop(params->conn); 3538f6c63249SJohan Hedberg hci_conn_put(params->conn); 3539f6c63249SJohan Hedberg } 3540f6c63249SJohan Hedberg 3541f6c63249SJohan Hedberg list_del(¶ms->action); 3542f6c63249SJohan Hedberg list_del(¶ms->list); 3543f6c63249SJohan Hedberg kfree(params); 3544f6c63249SJohan Hedberg } 3545f6c63249SJohan Hedberg 354615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 354715819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 354815819a70SAndre Guedes { 354915819a70SAndre Guedes struct hci_conn_params *params; 355015819a70SAndre Guedes 355115819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 355215819a70SAndre Guedes if (!params) 355315819a70SAndre Guedes return; 355415819a70SAndre Guedes 3555f6c63249SJohan Hedberg hci_conn_params_free(params); 355615819a70SAndre Guedes 355795305baaSJohan Hedberg hci_update_background_scan(hdev); 355895305baaSJohan Hedberg 355915819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 356015819a70SAndre Guedes } 356115819a70SAndre Guedes 356215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 356355af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev) 356415819a70SAndre Guedes { 356515819a70SAndre Guedes struct hci_conn_params *params, *tmp; 356615819a70SAndre Guedes 356715819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 356855af49a8SJohan Hedberg if (params->auto_connect != HCI_AUTO_CONN_DISABLED) 356955af49a8SJohan Hedberg continue; 3570f75113a2SJakub Pawlowski 357191641b79SZheng Yongjun /* If trying to establish one time connection to disabled 3572f75113a2SJakub Pawlowski * device, leave the params, but mark them as just once. 3573f75113a2SJakub Pawlowski */ 3574f75113a2SJakub Pawlowski if (params->explicit_connect) { 3575f75113a2SJakub Pawlowski params->auto_connect = HCI_AUTO_CONN_EXPLICIT; 3576f75113a2SJakub Pawlowski continue; 3577f75113a2SJakub Pawlowski } 3578f75113a2SJakub Pawlowski 357915819a70SAndre Guedes list_del(¶ms->list); 358015819a70SAndre Guedes kfree(params); 358115819a70SAndre Guedes } 358215819a70SAndre Guedes 358355af49a8SJohan Hedberg BT_DBG("All LE disabled connection parameters were removed"); 358455af49a8SJohan Hedberg } 358555af49a8SJohan Hedberg 358655af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */ 3587030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev) 358815819a70SAndre Guedes { 358915819a70SAndre Guedes struct hci_conn_params *params, *tmp; 359015819a70SAndre Guedes 3591f6c63249SJohan Hedberg list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) 3592f6c63249SJohan Hedberg hci_conn_params_free(params); 359315819a70SAndre Guedes 359415819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 359515819a70SAndre Guedes } 359615819a70SAndre Guedes 3597a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 3598a1f4c318SJohan Hedberg * 3599a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 3600a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 3601a1f4c318SJohan Hedberg * the static random address. 3602a1f4c318SJohan Hedberg * 3603a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 3604a1f4c318SJohan Hedberg * public address to use the static random address instead. 360550b5b952SMarcel Holtmann * 360650b5b952SMarcel Holtmann * In case BR/EDR has been disabled on a dual-mode controller and 360750b5b952SMarcel Holtmann * userspace has configured a static address, then that address 360850b5b952SMarcel Holtmann * becomes the identity address instead of the public BR/EDR address. 3609a1f4c318SJohan Hedberg */ 3610a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 3611a1f4c318SJohan Hedberg u8 *bdaddr_type) 3612a1f4c318SJohan Hedberg { 3613b7cb93e5SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) || 361450b5b952SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) || 3615d7a5a11dSMarcel Holtmann (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) && 361650b5b952SMarcel Holtmann bacmp(&hdev->static_addr, BDADDR_ANY))) { 3617a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 3618a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 3619a1f4c318SJohan Hedberg } else { 3620a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 3621a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 3622a1f4c318SJohan Hedberg } 3623a1f4c318SJohan Hedberg } 3624a1f4c318SJohan Hedberg 36250e995280SAbhishek Pandit-Subedi static void hci_suspend_clear_tasks(struct hci_dev *hdev) 36260e995280SAbhishek Pandit-Subedi { 36270e995280SAbhishek Pandit-Subedi int i; 36280e995280SAbhishek Pandit-Subedi 36290e995280SAbhishek Pandit-Subedi for (i = 0; i < __SUSPEND_NUM_TASKS; i++) 36300e995280SAbhishek Pandit-Subedi clear_bit(i, hdev->suspend_tasks); 36310e995280SAbhishek Pandit-Subedi 36320e995280SAbhishek Pandit-Subedi wake_up(&hdev->suspend_wait_q); 36330e995280SAbhishek Pandit-Subedi } 36340e995280SAbhishek Pandit-Subedi 36359952d90eSAbhishek Pandit-Subedi static int hci_suspend_wait_event(struct hci_dev *hdev) 36369952d90eSAbhishek Pandit-Subedi { 36379952d90eSAbhishek Pandit-Subedi #define WAKE_COND \ 36389952d90eSAbhishek Pandit-Subedi (find_first_bit(hdev->suspend_tasks, __SUSPEND_NUM_TASKS) == \ 36399952d90eSAbhishek Pandit-Subedi __SUSPEND_NUM_TASKS) 36409952d90eSAbhishek Pandit-Subedi 36419952d90eSAbhishek Pandit-Subedi int i; 36429952d90eSAbhishek Pandit-Subedi int ret = wait_event_timeout(hdev->suspend_wait_q, 36439952d90eSAbhishek Pandit-Subedi WAKE_COND, SUSPEND_NOTIFIER_TIMEOUT); 36449952d90eSAbhishek Pandit-Subedi 36459952d90eSAbhishek Pandit-Subedi if (ret == 0) { 3646a9ec8423SAbhishek Pandit-Subedi bt_dev_err(hdev, "Timed out waiting for suspend events"); 36479952d90eSAbhishek Pandit-Subedi for (i = 0; i < __SUSPEND_NUM_TASKS; ++i) { 36489952d90eSAbhishek Pandit-Subedi if (test_bit(i, hdev->suspend_tasks)) 3649a9ec8423SAbhishek Pandit-Subedi bt_dev_err(hdev, "Suspend timeout bit: %d", i); 36509952d90eSAbhishek Pandit-Subedi clear_bit(i, hdev->suspend_tasks); 36519952d90eSAbhishek Pandit-Subedi } 36529952d90eSAbhishek Pandit-Subedi 36539952d90eSAbhishek Pandit-Subedi ret = -ETIMEDOUT; 36549952d90eSAbhishek Pandit-Subedi } else { 36559952d90eSAbhishek Pandit-Subedi ret = 0; 36569952d90eSAbhishek Pandit-Subedi } 36579952d90eSAbhishek Pandit-Subedi 36589952d90eSAbhishek Pandit-Subedi return ret; 36599952d90eSAbhishek Pandit-Subedi } 36609952d90eSAbhishek Pandit-Subedi 36619952d90eSAbhishek Pandit-Subedi static void hci_prepare_suspend(struct work_struct *work) 36629952d90eSAbhishek Pandit-Subedi { 36639952d90eSAbhishek Pandit-Subedi struct hci_dev *hdev = 36649952d90eSAbhishek Pandit-Subedi container_of(work, struct hci_dev, suspend_prepare); 36659952d90eSAbhishek Pandit-Subedi 36669952d90eSAbhishek Pandit-Subedi hci_dev_lock(hdev); 36679952d90eSAbhishek Pandit-Subedi hci_req_prepare_suspend(hdev, hdev->suspend_state_next); 36689952d90eSAbhishek Pandit-Subedi hci_dev_unlock(hdev); 36699952d90eSAbhishek Pandit-Subedi } 36709952d90eSAbhishek Pandit-Subedi 36718731840aSAbhishek Pandit-Subedi static int hci_change_suspend_state(struct hci_dev *hdev, 36728731840aSAbhishek Pandit-Subedi enum suspended_state next) 36738731840aSAbhishek Pandit-Subedi { 36748731840aSAbhishek Pandit-Subedi hdev->suspend_state_next = next; 36758731840aSAbhishek Pandit-Subedi set_bit(SUSPEND_PREPARE_NOTIFIER, hdev->suspend_tasks); 36768731840aSAbhishek Pandit-Subedi queue_work(hdev->req_workqueue, &hdev->suspend_prepare); 36778731840aSAbhishek Pandit-Subedi return hci_suspend_wait_event(hdev); 36788731840aSAbhishek Pandit-Subedi } 36798731840aSAbhishek Pandit-Subedi 36802f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev) 36812f20216cSAbhishek Pandit-Subedi { 36822f20216cSAbhishek Pandit-Subedi hci_dev_lock(hdev); 36832f20216cSAbhishek Pandit-Subedi 36842f20216cSAbhishek Pandit-Subedi hdev->wake_reason = 0; 36852f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, BDADDR_ANY); 36862f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = 0; 36872f20216cSAbhishek Pandit-Subedi 36882f20216cSAbhishek Pandit-Subedi hci_dev_unlock(hdev); 36892f20216cSAbhishek Pandit-Subedi } 36902f20216cSAbhishek Pandit-Subedi 36919952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, 36929952d90eSAbhishek Pandit-Subedi void *data) 36939952d90eSAbhishek Pandit-Subedi { 36949952d90eSAbhishek Pandit-Subedi struct hci_dev *hdev = 36959952d90eSAbhishek Pandit-Subedi container_of(nb, struct hci_dev, suspend_notifier); 36969952d90eSAbhishek Pandit-Subedi int ret = 0; 36972f20216cSAbhishek Pandit-Subedi u8 state = BT_RUNNING; 36989952d90eSAbhishek Pandit-Subedi 36999952d90eSAbhishek Pandit-Subedi /* If powering down, wait for completion. */ 37009952d90eSAbhishek Pandit-Subedi if (mgmt_powering_down(hdev)) { 37019952d90eSAbhishek Pandit-Subedi set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks); 37029952d90eSAbhishek Pandit-Subedi ret = hci_suspend_wait_event(hdev); 37039952d90eSAbhishek Pandit-Subedi if (ret) 37049952d90eSAbhishek Pandit-Subedi goto done; 37059952d90eSAbhishek Pandit-Subedi } 37069952d90eSAbhishek Pandit-Subedi 37079952d90eSAbhishek Pandit-Subedi /* Suspend notifier should only act on events when powered. */ 37085ff20cbeSVamshi K Sthambamkadi if (!hdev_is_powered(hdev) || 37095ff20cbeSVamshi K Sthambamkadi hci_dev_test_flag(hdev, HCI_UNREGISTER)) 37109952d90eSAbhishek Pandit-Subedi goto done; 37119952d90eSAbhishek Pandit-Subedi 37129952d90eSAbhishek Pandit-Subedi if (action == PM_SUSPEND_PREPARE) { 37134f40afc6SAbhishek Pandit-Subedi /* Suspend consists of two actions: 37144f40afc6SAbhishek Pandit-Subedi * - First, disconnect everything and make the controller not 37154f40afc6SAbhishek Pandit-Subedi * connectable (disabling scanning) 37164f40afc6SAbhishek Pandit-Subedi * - Second, program event filter/whitelist and enable scan 37174f40afc6SAbhishek Pandit-Subedi */ 37188731840aSAbhishek Pandit-Subedi ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT); 37192f20216cSAbhishek Pandit-Subedi if (!ret) 37202f20216cSAbhishek Pandit-Subedi state = BT_SUSPEND_DISCONNECT; 37214f40afc6SAbhishek Pandit-Subedi 372281dafad5SAbhishek Pandit-Subedi /* Only configure whitelist if disconnect succeeded and wake 372381dafad5SAbhishek Pandit-Subedi * isn't being prevented. 372481dafad5SAbhishek Pandit-Subedi */ 37252f20216cSAbhishek Pandit-Subedi if (!ret && !(hdev->prevent_wake && hdev->prevent_wake(hdev))) { 37268731840aSAbhishek Pandit-Subedi ret = hci_change_suspend_state(hdev, 37270d2c9825SAbhishek Pandit-Subedi BT_SUSPEND_CONFIGURE_WAKE); 37282f20216cSAbhishek Pandit-Subedi if (!ret) 37292f20216cSAbhishek Pandit-Subedi state = BT_SUSPEND_CONFIGURE_WAKE; 37302f20216cSAbhishek Pandit-Subedi } 37312f20216cSAbhishek Pandit-Subedi 37322f20216cSAbhishek Pandit-Subedi hci_clear_wake_reason(hdev); 37332f20216cSAbhishek Pandit-Subedi mgmt_suspending(hdev, state); 37342f20216cSAbhishek Pandit-Subedi 37359952d90eSAbhishek Pandit-Subedi } else if (action == PM_POST_SUSPEND) { 37368731840aSAbhishek Pandit-Subedi ret = hci_change_suspend_state(hdev, BT_RUNNING); 37372f20216cSAbhishek Pandit-Subedi 37382f20216cSAbhishek Pandit-Subedi mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr, 37392f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type); 37409952d90eSAbhishek Pandit-Subedi } 37419952d90eSAbhishek Pandit-Subedi 37429952d90eSAbhishek Pandit-Subedi done: 3743a9ec8423SAbhishek Pandit-Subedi /* We always allow suspend even if suspend preparation failed and 3744a9ec8423SAbhishek Pandit-Subedi * attempt to recover in resume. 3745a9ec8423SAbhishek Pandit-Subedi */ 3746a9ec8423SAbhishek Pandit-Subedi if (ret) 3747a9ec8423SAbhishek Pandit-Subedi bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d", 3748a9ec8423SAbhishek Pandit-Subedi action, ret); 3749a9ec8423SAbhishek Pandit-Subedi 375024b06572SMax Chou return NOTIFY_DONE; 37519952d90eSAbhishek Pandit-Subedi } 37528731840aSAbhishek Pandit-Subedi 37539be0dab7SDavid Herrmann /* Alloc HCI device */ 37549be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 37559be0dab7SDavid Herrmann { 37569be0dab7SDavid Herrmann struct hci_dev *hdev; 37579be0dab7SDavid Herrmann 375827f70f3eSJohan Hedberg hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); 37599be0dab7SDavid Herrmann if (!hdev) 37609be0dab7SDavid Herrmann return NULL; 37619be0dab7SDavid Herrmann 3762b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3763b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3764b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3765b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3766b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 376796c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */ 3768bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3769bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3770d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 3771d2609b34SFlorian Grandel hdev->cur_adv_instance = 0x00; 37725d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 3773b1b813d4SDavid Herrmann 3774c4f1f408SHoward Chung hdev->advmon_allowlist_duration = 300; 3775c4f1f408SHoward Chung hdev->advmon_no_filter_duration = 500; 377680af16a3SHoward Chung hdev->enable_advmon_interleave_scan = 0x00; /* Default to disable */ 3777c4f1f408SHoward Chung 3778b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3779b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3780b1b813d4SDavid Herrmann 37813f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 3782628531c9SGeorg Lukas hdev->le_adv_min_interval = 0x0800; 3783628531c9SGeorg Lukas hdev->le_adv_max_interval = 0x0800; 3784bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3785bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 378610873f99SAlain Michaud hdev->le_scan_int_suspend = 0x0400; 378710873f99SAlain Michaud hdev->le_scan_window_suspend = 0x0012; 378810873f99SAlain Michaud hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT; 378910873f99SAlain Michaud hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN; 3790ba29d036SMarcel Holtmann hdev->le_scan_int_adv_monitor = 0x0060; 3791ba29d036SMarcel Holtmann hdev->le_scan_window_adv_monitor = 0x0030; 379210873f99SAlain Michaud hdev->le_scan_int_connect = 0x0060; 379310873f99SAlain Michaud hdev->le_scan_window_connect = 0x0060; 3794b48c3b59SJonas Holmberg hdev->le_conn_min_interval = 0x0018; 3795b48c3b59SJonas Holmberg hdev->le_conn_max_interval = 0x0028; 379604fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000; 379704fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a; 3798a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = 0x001b; 3799a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = 0x0148; 3800a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = 0x001b; 3801a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = 0x0148; 3802a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = 0x001b; 3803a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = 0x0148; 380430d65e08SMatias Karhumaa hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE; 380530d65e08SMatias Karhumaa hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE; 38066decb5b4SJaganath Kanakkassery hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M; 38076decb5b4SJaganath Kanakkassery hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M; 38081d0fac2cSLuiz Augusto von Dentz hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES; 380910873f99SAlain Michaud hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION; 381049b020c1SAlain Michaud hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT; 38117c395ea5SDaniel Winkler hdev->min_le_tx_power = HCI_TX_POWER_INVALID; 38127c395ea5SDaniel Winkler hdev->max_le_tx_power = HCI_TX_POWER_INVALID; 3813bef64738SMarcel Holtmann 3814d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 3815b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 381631ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 381731ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 3818302975cbSSpoorthi Ravishankar Koppad hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT; 381958a96fc3SMarcel Holtmann hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE; 3820d6bfd59cSJohan Hedberg 382110873f99SAlain Michaud /* default 1.28 sec page scan */ 382210873f99SAlain Michaud hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD; 382310873f99SAlain Michaud hdev->def_page_scan_int = 0x0800; 382410873f99SAlain Michaud hdev->def_page_scan_window = 0x0012; 382510873f99SAlain Michaud 3826b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3827b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3828b1b813d4SDavid Herrmann 3829b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3830b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 38316659358eSJohan Hedberg INIT_LIST_HEAD(&hdev->whitelist); 3832b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3833b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3834b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3835970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3836b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 3837d2ab0ac1SMarcel Holtmann INIT_LIST_HEAD(&hdev->le_white_list); 3838cfdb0c2dSAnkit Navik INIT_LIST_HEAD(&hdev->le_resolv_list); 383915819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 384077a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 384166f8455aSJohan Hedberg INIT_LIST_HEAD(&hdev->pend_le_reports); 38426b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3843d2609b34SFlorian Grandel INIT_LIST_HEAD(&hdev->adv_instances); 3844600a8749SAlain Michaud INIT_LIST_HEAD(&hdev->blocked_keys); 3845b1b813d4SDavid Herrmann 3846b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3847b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3848b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3849b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3850c7741d16SMarcel Holtmann INIT_WORK(&hdev->error_reset, hci_error_reset); 38519952d90eSAbhishek Pandit-Subedi INIT_WORK(&hdev->suspend_prepare, hci_prepare_suspend); 3852b1b813d4SDavid Herrmann 3853b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3854b1b813d4SDavid Herrmann 3855b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3856b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3857b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3858b1b813d4SDavid Herrmann 3859b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 38609952d90eSAbhishek Pandit-Subedi init_waitqueue_head(&hdev->suspend_wait_q); 3861b1b813d4SDavid Herrmann 386265cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout); 3863de75cd0dSManish Mandlik INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout); 3864b1b813d4SDavid Herrmann 38655fc16cc4SJohan Hedberg hci_request_setup(hdev); 38665fc16cc4SJohan Hedberg 3867b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3868b1b813d4SDavid Herrmann discovery_init(hdev); 38699be0dab7SDavid Herrmann 38709be0dab7SDavid Herrmann return hdev; 38719be0dab7SDavid Herrmann } 38729be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 38739be0dab7SDavid Herrmann 38749be0dab7SDavid Herrmann /* Free HCI device */ 38759be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 38769be0dab7SDavid Herrmann { 38779be0dab7SDavid Herrmann /* will free via device release */ 38789be0dab7SDavid Herrmann put_device(&hdev->dev); 38799be0dab7SDavid Herrmann } 38809be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 38819be0dab7SDavid Herrmann 38821da177e4SLinus Torvalds /* Register HCI device */ 38831da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 38841da177e4SLinus Torvalds { 3885b1b813d4SDavid Herrmann int id, error; 38861da177e4SLinus Torvalds 388774292d5aSMarcel Holtmann if (!hdev->open || !hdev->close || !hdev->send) 38881da177e4SLinus Torvalds return -EINVAL; 38891da177e4SLinus Torvalds 389008add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 389108add513SMat Martineau * so the index can be used as the AMP controller ID. 389208add513SMat Martineau */ 38933df92b31SSasha Levin switch (hdev->dev_type) { 3894ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 38953df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 38961da177e4SLinus Torvalds break; 38973df92b31SSasha Levin case HCI_AMP: 38983df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 38993df92b31SSasha Levin break; 39003df92b31SSasha Levin default: 39013df92b31SSasha Levin return -EINVAL; 39021da177e4SLinus Torvalds } 39031da177e4SLinus Torvalds 39043df92b31SSasha Levin if (id < 0) 39053df92b31SSasha Levin return id; 39063df92b31SSasha Levin 39071da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 39081da177e4SLinus Torvalds hdev->id = id; 39092d8b3a11SAndrei Emeltchenko 39102d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 39112d8b3a11SAndrei Emeltchenko 391229e2dd0dSTejun Heo hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name); 391333ca954dSDavid Herrmann if (!hdev->workqueue) { 391433ca954dSDavid Herrmann error = -ENOMEM; 391533ca954dSDavid Herrmann goto err; 391633ca954dSDavid Herrmann } 3917f48fd9c8SMarcel Holtmann 391829e2dd0dSTejun Heo hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, 391929e2dd0dSTejun Heo hdev->name); 39206ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 39216ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 39226ead1bbcSJohan Hedberg error = -ENOMEM; 39236ead1bbcSJohan Hedberg goto err; 39246ead1bbcSJohan Hedberg } 39256ead1bbcSJohan Hedberg 39260153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 39270153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 39280153e2ecSMarcel Holtmann 3929bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3930bdc3e0f1SMarcel Holtmann 3931bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 393233ca954dSDavid Herrmann if (error < 0) 393354506918SJohan Hedberg goto err_wqueue; 39341da177e4SLinus Torvalds 39356d5d2ee6SHeiner Kallweit hci_leds_init(hdev); 39366d5d2ee6SHeiner Kallweit 3937611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3938a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3939a8c5fb1aSGustavo Padovan hdev); 3940611b30f7SMarcel Holtmann if (hdev->rfkill) { 3941611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3942611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3943611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3944611b30f7SMarcel Holtmann } 3945611b30f7SMarcel Holtmann } 3946611b30f7SMarcel Holtmann 39475e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 3948a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 39495e130367SJohan Hedberg 3950a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SETUP); 3951a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_AUTO_OFF); 3952ce2be9acSAndrei Emeltchenko 3953ca8bee5dSMarcel Holtmann if (hdev->dev_type == HCI_PRIMARY) { 395456f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 395556f87901SJohan Hedberg * through reading supported features during init. 395656f87901SJohan Hedberg */ 3957a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 395856f87901SJohan Hedberg } 3959ce2be9acSAndrei Emeltchenko 3960fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3961fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3962fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3963fcee3377SGustavo Padovan 39644a964404SMarcel Holtmann /* Devices that are marked for raw-only usage are unconfigured 39654a964404SMarcel Holtmann * and should not be included in normal operation. 3966fee746b0SMarcel Holtmann */ 3967fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 3968a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 3969fee746b0SMarcel Holtmann 397005fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_REG); 3971dc946bd8SDavid Herrmann hci_dev_hold(hdev); 39721da177e4SLinus Torvalds 3973219991e6SHans de Goede if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) { 39749952d90eSAbhishek Pandit-Subedi hdev->suspend_notifier.notifier_call = hci_suspend_notifier; 39759952d90eSAbhishek Pandit-Subedi error = register_pm_notifier(&hdev->suspend_notifier); 39769952d90eSAbhishek Pandit-Subedi if (error) 39779952d90eSAbhishek Pandit-Subedi goto err_wqueue; 3978219991e6SHans de Goede } 39799952d90eSAbhishek Pandit-Subedi 398019202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3981fbe96d6fSMarcel Holtmann 3982e5e1e7fdSMiao-chen Chou idr_init(&hdev->adv_monitors_idr); 3983e5e1e7fdSMiao-chen Chou 39841da177e4SLinus Torvalds return id; 3985f48fd9c8SMarcel Holtmann 398633ca954dSDavid Herrmann err_wqueue: 398733ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 39886ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 398933ca954dSDavid Herrmann err: 39903df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3991f48fd9c8SMarcel Holtmann 399233ca954dSDavid Herrmann return error; 39931da177e4SLinus Torvalds } 39941da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 39951da177e4SLinus Torvalds 39961da177e4SLinus Torvalds /* Unregister HCI device */ 399759735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 39981da177e4SLinus Torvalds { 39992d7cc19eSMarcel Holtmann int id; 4000ef222013SMarcel Holtmann 4001c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 40021da177e4SLinus Torvalds 4003a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNREGISTER); 400494324962SJohan Hovold 40053df92b31SSasha Levin id = hdev->id; 40063df92b31SSasha Levin 4007f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 40081da177e4SLinus Torvalds list_del(&hdev->list); 4009f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 40101da177e4SLinus Torvalds 4011b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 4012b9b5ef18SGustavo Padovan 4013219991e6SHans de Goede if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) { 40140e995280SAbhishek Pandit-Subedi hci_suspend_clear_tasks(hdev); 40159952d90eSAbhishek Pandit-Subedi unregister_pm_notifier(&hdev->suspend_notifier); 40164e8c36c3SAbhishek Pandit-Subedi cancel_work_sync(&hdev->suspend_prepare); 4017219991e6SHans de Goede } 40184e8c36c3SAbhishek Pandit-Subedi 40194e8c36c3SAbhishek Pandit-Subedi hci_dev_do_close(hdev); 40209952d90eSAbhishek Pandit-Subedi 4021ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 4022d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_SETUP) && 4023d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 402409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4025744cf19eSJohan Hedberg mgmt_index_removed(hdev); 402609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 402756e5cb86SJohan Hedberg } 4028ab81cbf9SJohan Hedberg 40292e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 40302e58ef3eSJohan Hedberg * pending list */ 40312e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 40322e58ef3eSJohan Hedberg 403305fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UNREG); 40341da177e4SLinus Torvalds 4035611b30f7SMarcel Holtmann if (hdev->rfkill) { 4036611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 4037611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 4038611b30f7SMarcel Holtmann } 4039611b30f7SMarcel Holtmann 4040bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 4041147e2d59SDave Young 40420153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 40435177a838SMarcel Holtmann kfree_const(hdev->hw_info); 40445177a838SMarcel Holtmann kfree_const(hdev->fw_info); 40450153e2ecSMarcel Holtmann 4046f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 40476ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 4048f48fd9c8SMarcel Holtmann 404909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4050dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->blacklist); 40516659358eSJohan Hedberg hci_bdaddr_list_clear(&hdev->whitelist); 40522aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 405355ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 4054b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 4055970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 40562763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 4057d2609b34SFlorian Grandel hci_adv_instances_clear(hdev); 4058e5e1e7fdSMiao-chen Chou hci_adv_monitors_clear(hdev); 4059dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->le_white_list); 4060cfdb0c2dSAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 4061373110c5SJohan Hedberg hci_conn_params_clear_all(hdev); 406222078800SMarcel Holtmann hci_discovery_filter_clear(hdev); 4063600a8749SAlain Michaud hci_blocked_keys_clear(hdev); 406409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 4065e2e0cacbSJohan Hedberg 4066dc946bd8SDavid Herrmann hci_dev_put(hdev); 40673df92b31SSasha Levin 40683df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 40691da177e4SLinus Torvalds } 40701da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 40711da177e4SLinus Torvalds 40721da177e4SLinus Torvalds /* Suspend HCI device */ 40731da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 40741da177e4SLinus Torvalds { 407505fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_SUSPEND); 40761da177e4SLinus Torvalds return 0; 40771da177e4SLinus Torvalds } 40781da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 40791da177e4SLinus Torvalds 40801da177e4SLinus Torvalds /* Resume HCI device */ 40811da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 40821da177e4SLinus Torvalds { 408305fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_RESUME); 40841da177e4SLinus Torvalds return 0; 40851da177e4SLinus Torvalds } 40861da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 40871da177e4SLinus Torvalds 408875e0569fSMarcel Holtmann /* Reset HCI device */ 408975e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev) 409075e0569fSMarcel Holtmann { 40911e4b6e91SColin Ian King static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; 409275e0569fSMarcel Holtmann struct sk_buff *skb; 409375e0569fSMarcel Holtmann 409475e0569fSMarcel Holtmann skb = bt_skb_alloc(3, GFP_ATOMIC); 409575e0569fSMarcel Holtmann if (!skb) 409675e0569fSMarcel Holtmann return -ENOMEM; 409775e0569fSMarcel Holtmann 4098d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_EVENT_PKT; 409959ae1d12SJohannes Berg skb_put_data(skb, hw_err, 3); 410075e0569fSMarcel Holtmann 4101de75cd0dSManish Mandlik bt_dev_err(hdev, "Injecting HCI hardware error event"); 4102de75cd0dSManish Mandlik 410375e0569fSMarcel Holtmann /* Send Hardware Error to upper stack */ 410475e0569fSMarcel Holtmann return hci_recv_frame(hdev, skb); 410575e0569fSMarcel Holtmann } 410675e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev); 410775e0569fSMarcel Holtmann 410876bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 4109e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 411076bca880SMarcel Holtmann { 411176bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 411276bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 411376bca880SMarcel Holtmann kfree_skb(skb); 411476bca880SMarcel Holtmann return -ENXIO; 411576bca880SMarcel Holtmann } 411676bca880SMarcel Holtmann 4117d79f34e3SMarcel Holtmann if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT && 4118d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && 4119cc974003SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_SCODATA_PKT && 4120cc974003SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) { 4121fe806dceSMarcel Holtmann kfree_skb(skb); 4122fe806dceSMarcel Holtmann return -EINVAL; 4123fe806dceSMarcel Holtmann } 4124fe806dceSMarcel Holtmann 4125d82603c6SJorrit Schippers /* Incoming skb */ 412676bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 412776bca880SMarcel Holtmann 412876bca880SMarcel Holtmann /* Time stamp */ 412976bca880SMarcel Holtmann __net_timestamp(skb); 413076bca880SMarcel Holtmann 413176bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 4132b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 4133c78ae283SMarcel Holtmann 413476bca880SMarcel Holtmann return 0; 413576bca880SMarcel Holtmann } 413676bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 413776bca880SMarcel Holtmann 4138e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */ 4139e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb) 4140e875ff84SMarcel Holtmann { 4141581d6fd6SMarcel Holtmann /* Mark as diagnostic packet */ 4142d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_DIAG_PKT; 4143581d6fd6SMarcel Holtmann 4144e875ff84SMarcel Holtmann /* Time stamp */ 4145e875ff84SMarcel Holtmann __net_timestamp(skb); 4146e875ff84SMarcel Holtmann 4147581d6fd6SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 4148581d6fd6SMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 4149e875ff84SMarcel Holtmann 4150e875ff84SMarcel Holtmann return 0; 4151e875ff84SMarcel Holtmann } 4152e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag); 4153e875ff84SMarcel Holtmann 41545177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...) 41555177a838SMarcel Holtmann { 41565177a838SMarcel Holtmann va_list vargs; 41575177a838SMarcel Holtmann 41585177a838SMarcel Holtmann va_start(vargs, fmt); 41595177a838SMarcel Holtmann kfree_const(hdev->hw_info); 41605177a838SMarcel Holtmann hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 41615177a838SMarcel Holtmann va_end(vargs); 41625177a838SMarcel Holtmann } 41635177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info); 41645177a838SMarcel Holtmann 41655177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...) 41665177a838SMarcel Holtmann { 41675177a838SMarcel Holtmann va_list vargs; 41685177a838SMarcel Holtmann 41695177a838SMarcel Holtmann va_start(vargs, fmt); 41705177a838SMarcel Holtmann kfree_const(hdev->fw_info); 41715177a838SMarcel Holtmann hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 41725177a838SMarcel Holtmann va_end(vargs); 41735177a838SMarcel Holtmann } 41745177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info); 41755177a838SMarcel Holtmann 41761da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 41771da177e4SLinus Torvalds 41781da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 41791da177e4SLinus Torvalds { 41801da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 41811da177e4SLinus Torvalds 4182fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 418300629e0fSJohan Hedberg list_add_tail(&cb->list, &hci_cb_list); 4184fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 41851da177e4SLinus Torvalds 41861da177e4SLinus Torvalds return 0; 41871da177e4SLinus Torvalds } 41881da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 41891da177e4SLinus Torvalds 41901da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 41911da177e4SLinus Torvalds { 41921da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 41931da177e4SLinus Torvalds 4194fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 41951da177e4SLinus Torvalds list_del(&cb->list); 4196fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 41971da177e4SLinus Torvalds 41981da177e4SLinus Torvalds return 0; 41991da177e4SLinus Torvalds } 42001da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 42011da177e4SLinus Torvalds 420251086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 42031da177e4SLinus Torvalds { 4204cdc52faaSMarcel Holtmann int err; 4205cdc52faaSMarcel Holtmann 4206d79f34e3SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb), 4207d79f34e3SMarcel Holtmann skb->len); 42081da177e4SLinus Torvalds 42091da177e4SLinus Torvalds /* Time stamp */ 4210a61bbcf2SPatrick McHardy __net_timestamp(skb); 42111da177e4SLinus Torvalds 4212cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4213cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4214cd82e61cSMarcel Holtmann 4215cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 4216cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 4217470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 42181da177e4SLinus Torvalds } 42191da177e4SLinus Torvalds 42201da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 42211da177e4SLinus Torvalds skb_orphan(skb); 42221da177e4SLinus Torvalds 422373d0d3c8SMarcel Holtmann if (!test_bit(HCI_RUNNING, &hdev->flags)) { 422473d0d3c8SMarcel Holtmann kfree_skb(skb); 422573d0d3c8SMarcel Holtmann return; 422673d0d3c8SMarcel Holtmann } 422773d0d3c8SMarcel Holtmann 4228cdc52faaSMarcel Holtmann err = hdev->send(hdev, skb); 4229cdc52faaSMarcel Holtmann if (err < 0) { 42302064ee33SMarcel Holtmann bt_dev_err(hdev, "sending frame failed (%d)", err); 4231cdc52faaSMarcel Holtmann kfree_skb(skb); 4232cdc52faaSMarcel Holtmann } 42331da177e4SLinus Torvalds } 42341da177e4SLinus Torvalds 42351ca3a9d0SJohan Hedberg /* Send HCI command */ 423607dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 423707dc93ddSJohan Hedberg const void *param) 42381ca3a9d0SJohan Hedberg { 42391ca3a9d0SJohan Hedberg struct sk_buff *skb; 42401ca3a9d0SJohan Hedberg 42411ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 42421ca3a9d0SJohan Hedberg 42431ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 42441ca3a9d0SJohan Hedberg if (!skb) { 42452064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for command"); 42461ca3a9d0SJohan Hedberg return -ENOMEM; 42471ca3a9d0SJohan Hedberg } 42481ca3a9d0SJohan Hedberg 424949c922bbSStephen Hemminger /* Stand-alone HCI commands must be flagged as 425011714b3dSJohan Hedberg * single-command requests. 425111714b3dSJohan Hedberg */ 425244d27137SJohan Hedberg bt_cb(skb)->hci.req_flags |= HCI_REQ_START; 425311714b3dSJohan Hedberg 42541da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 4255c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 42561da177e4SLinus Torvalds 42571da177e4SLinus Torvalds return 0; 42581da177e4SLinus Torvalds } 42591da177e4SLinus Torvalds 4260d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen, 4261d6ee6ad7SLoic Poulain const void *param) 4262d6ee6ad7SLoic Poulain { 4263d6ee6ad7SLoic Poulain struct sk_buff *skb; 4264d6ee6ad7SLoic Poulain 4265d6ee6ad7SLoic Poulain if (hci_opcode_ogf(opcode) != 0x3f) { 4266d6ee6ad7SLoic Poulain /* A controller receiving a command shall respond with either 4267d6ee6ad7SLoic Poulain * a Command Status Event or a Command Complete Event. 4268d6ee6ad7SLoic Poulain * Therefore, all standard HCI commands must be sent via the 4269d6ee6ad7SLoic Poulain * standard API, using hci_send_cmd or hci_cmd_sync helpers. 4270d6ee6ad7SLoic Poulain * Some vendors do not comply with this rule for vendor-specific 4271d6ee6ad7SLoic Poulain * commands and do not return any event. We want to support 4272d6ee6ad7SLoic Poulain * unresponded commands for such cases only. 4273d6ee6ad7SLoic Poulain */ 4274d6ee6ad7SLoic Poulain bt_dev_err(hdev, "unresponded command not supported"); 4275d6ee6ad7SLoic Poulain return -EINVAL; 4276d6ee6ad7SLoic Poulain } 4277d6ee6ad7SLoic Poulain 4278d6ee6ad7SLoic Poulain skb = hci_prepare_cmd(hdev, opcode, plen, param); 4279d6ee6ad7SLoic Poulain if (!skb) { 4280d6ee6ad7SLoic Poulain bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)", 4281d6ee6ad7SLoic Poulain opcode); 4282d6ee6ad7SLoic Poulain return -ENOMEM; 4283d6ee6ad7SLoic Poulain } 4284d6ee6ad7SLoic Poulain 4285d6ee6ad7SLoic Poulain hci_send_frame(hdev, skb); 4286d6ee6ad7SLoic Poulain 4287d6ee6ad7SLoic Poulain return 0; 4288d6ee6ad7SLoic Poulain } 4289d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send); 4290d6ee6ad7SLoic Poulain 42911da177e4SLinus Torvalds /* Get data from the previously sent command */ 4292a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 42931da177e4SLinus Torvalds { 42941da177e4SLinus Torvalds struct hci_command_hdr *hdr; 42951da177e4SLinus Torvalds 42961da177e4SLinus Torvalds if (!hdev->sent_cmd) 42971da177e4SLinus Torvalds return NULL; 42981da177e4SLinus Torvalds 42991da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 43001da177e4SLinus Torvalds 4301a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 43021da177e4SLinus Torvalds return NULL; 43031da177e4SLinus Torvalds 4304f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 43051da177e4SLinus Torvalds 43061da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 43071da177e4SLinus Torvalds } 43081da177e4SLinus Torvalds 430991641b79SZheng Yongjun /* Send HCI command and wait for command complete event */ 4310fbef168fSLoic Poulain struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 4311fbef168fSLoic Poulain const void *param, u32 timeout) 4312fbef168fSLoic Poulain { 4313fbef168fSLoic Poulain struct sk_buff *skb; 4314fbef168fSLoic Poulain 4315fbef168fSLoic Poulain if (!test_bit(HCI_UP, &hdev->flags)) 4316fbef168fSLoic Poulain return ERR_PTR(-ENETDOWN); 4317fbef168fSLoic Poulain 4318fbef168fSLoic Poulain bt_dev_dbg(hdev, "opcode 0x%4.4x plen %d", opcode, plen); 4319fbef168fSLoic Poulain 4320b504430cSJohan Hedberg hci_req_sync_lock(hdev); 4321fbef168fSLoic Poulain skb = __hci_cmd_sync(hdev, opcode, plen, param, timeout); 4322b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 4323fbef168fSLoic Poulain 4324fbef168fSLoic Poulain return skb; 4325fbef168fSLoic Poulain } 4326fbef168fSLoic Poulain EXPORT_SYMBOL(hci_cmd_sync); 4327fbef168fSLoic Poulain 43281da177e4SLinus Torvalds /* Send ACL data */ 43291da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 43301da177e4SLinus Torvalds { 43311da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 43321da177e4SLinus Torvalds int len = skb->len; 43331da177e4SLinus Torvalds 4334badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 4335badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 43369c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 4337aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 4338aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 43391da177e4SLinus Torvalds } 43401da177e4SLinus Torvalds 4341ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 434273d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 43431da177e4SLinus Torvalds { 4344ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 43451da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 43461da177e4SLinus Torvalds struct sk_buff *list; 43471da177e4SLinus Torvalds 4348087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 4349087bfd99SGustavo Padovan skb->data_len = 0; 4350087bfd99SGustavo Padovan 4351d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 4352204a6e54SAndrei Emeltchenko 4353204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 4354ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 4355087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 4356204a6e54SAndrei Emeltchenko break; 4357204a6e54SAndrei Emeltchenko case HCI_AMP: 4358204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 4359204a6e54SAndrei Emeltchenko break; 4360204a6e54SAndrei Emeltchenko default: 43612064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type); 4362204a6e54SAndrei Emeltchenko return; 4363204a6e54SAndrei Emeltchenko } 4364087bfd99SGustavo Padovan 436570f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 436670f23020SAndrei Emeltchenko if (!list) { 43671da177e4SLinus Torvalds /* Non fragmented */ 43681da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 43691da177e4SLinus Torvalds 437073d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 43711da177e4SLinus Torvalds } else { 43721da177e4SLinus Torvalds /* Fragmented */ 43731da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 43741da177e4SLinus Torvalds 43751da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 43761da177e4SLinus Torvalds 43779cfd5a23SJukka Rissanen /* Queue all fragments atomically. We need to use spin_lock_bh 43789cfd5a23SJukka Rissanen * here because of 6LoWPAN links, as there this function is 43799cfd5a23SJukka Rissanen * called from softirq and using normal spin lock could cause 43809cfd5a23SJukka Rissanen * deadlocks. 43819cfd5a23SJukka Rissanen */ 43829cfd5a23SJukka Rissanen spin_lock_bh(&queue->lock); 43831da177e4SLinus Torvalds 438473d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 4385e702112fSAndrei Emeltchenko 4386e702112fSAndrei Emeltchenko flags &= ~ACL_START; 4387e702112fSAndrei Emeltchenko flags |= ACL_CONT; 43881da177e4SLinus Torvalds do { 43891da177e4SLinus Torvalds skb = list; list = list->next; 43901da177e4SLinus Torvalds 4391d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 4392e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 43931da177e4SLinus Torvalds 43941da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 43951da177e4SLinus Torvalds 439673d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 43971da177e4SLinus Torvalds } while (list); 43981da177e4SLinus Torvalds 43999cfd5a23SJukka Rissanen spin_unlock_bh(&queue->lock); 44001da177e4SLinus Torvalds } 440173d80debSLuiz Augusto von Dentz } 440273d80debSLuiz Augusto von Dentz 440373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 440473d80debSLuiz Augusto von Dentz { 4405ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 440673d80debSLuiz Augusto von Dentz 4407f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 440873d80debSLuiz Augusto von Dentz 4409ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 44101da177e4SLinus Torvalds 44113eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 44121da177e4SLinus Torvalds } 44131da177e4SLinus Torvalds 44141da177e4SLinus Torvalds /* Send SCO data */ 44150d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 44161da177e4SLinus Torvalds { 44171da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 44181da177e4SLinus Torvalds struct hci_sco_hdr hdr; 44191da177e4SLinus Torvalds 44201da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 44211da177e4SLinus Torvalds 4422aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 44231da177e4SLinus Torvalds hdr.dlen = skb->len; 44241da177e4SLinus Torvalds 4425badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 4426badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 44279c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 44281da177e4SLinus Torvalds 4429d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_SCODATA_PKT; 4430c78ae283SMarcel Holtmann 44311da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 44323eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 44331da177e4SLinus Torvalds } 44341da177e4SLinus Torvalds 44351da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 44361da177e4SLinus Torvalds 44371da177e4SLinus Torvalds /* HCI Connection scheduler */ 44386039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 4439a8c5fb1aSGustavo Padovan int *quote) 44401da177e4SLinus Torvalds { 44411da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 44428035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 4443abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 44441da177e4SLinus Torvalds 44451da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 44461da177e4SLinus Torvalds * added and removed with TX task disabled. */ 4447bf4c6325SGustavo F. Padovan 4448bf4c6325SGustavo F. Padovan rcu_read_lock(); 4449bf4c6325SGustavo F. Padovan 4450bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4451769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 44521da177e4SLinus Torvalds continue; 4453769be974SMarcel Holtmann 4454769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 4455769be974SMarcel Holtmann continue; 4456769be974SMarcel Holtmann 44571da177e4SLinus Torvalds num++; 44581da177e4SLinus Torvalds 44591da177e4SLinus Torvalds if (c->sent < min) { 44601da177e4SLinus Torvalds min = c->sent; 44611da177e4SLinus Torvalds conn = c; 44621da177e4SLinus Torvalds } 446352087a79SLuiz Augusto von Dentz 446452087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 446552087a79SLuiz Augusto von Dentz break; 44661da177e4SLinus Torvalds } 44671da177e4SLinus Torvalds 4468bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4469bf4c6325SGustavo F. Padovan 44701da177e4SLinus Torvalds if (conn) { 44716ed58ec5SVille Tervo int cnt, q; 44726ed58ec5SVille Tervo 44736ed58ec5SVille Tervo switch (conn->type) { 44746ed58ec5SVille Tervo case ACL_LINK: 44756ed58ec5SVille Tervo cnt = hdev->acl_cnt; 44766ed58ec5SVille Tervo break; 44776ed58ec5SVille Tervo case SCO_LINK: 44786ed58ec5SVille Tervo case ESCO_LINK: 44796ed58ec5SVille Tervo cnt = hdev->sco_cnt; 44806ed58ec5SVille Tervo break; 44816ed58ec5SVille Tervo case LE_LINK: 44826ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 44836ed58ec5SVille Tervo break; 44846ed58ec5SVille Tervo default: 44856ed58ec5SVille Tervo cnt = 0; 44862064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown link type %d", conn->type); 44876ed58ec5SVille Tervo } 44886ed58ec5SVille Tervo 44896ed58ec5SVille Tervo q = cnt / num; 44901da177e4SLinus Torvalds *quote = q ? q : 1; 44911da177e4SLinus Torvalds } else 44921da177e4SLinus Torvalds *quote = 0; 44931da177e4SLinus Torvalds 44941da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 44951da177e4SLinus Torvalds return conn; 44961da177e4SLinus Torvalds } 44971da177e4SLinus Torvalds 44986039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 44991da177e4SLinus Torvalds { 45001da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 45011da177e4SLinus Torvalds struct hci_conn *c; 45021da177e4SLinus Torvalds 45032064ee33SMarcel Holtmann bt_dev_err(hdev, "link tx timeout"); 45041da177e4SLinus Torvalds 4505bf4c6325SGustavo F. Padovan rcu_read_lock(); 4506bf4c6325SGustavo F. Padovan 45071da177e4SLinus Torvalds /* Kill stalled connections */ 4508bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4509bae1f5d9SVille Tervo if (c->type == type && c->sent) { 45102064ee33SMarcel Holtmann bt_dev_err(hdev, "killing stalled connection %pMR", 45112064ee33SMarcel Holtmann &c->dst); 4512bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 45131da177e4SLinus Torvalds } 45141da177e4SLinus Torvalds } 4515bf4c6325SGustavo F. Padovan 4516bf4c6325SGustavo F. Padovan rcu_read_unlock(); 45171da177e4SLinus Torvalds } 45181da177e4SLinus Torvalds 45196039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 452073d80debSLuiz Augusto von Dentz int *quote) 452173d80debSLuiz Augusto von Dentz { 452273d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 452373d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 4524abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 452573d80debSLuiz Augusto von Dentz struct hci_conn *conn; 452673d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 452773d80debSLuiz Augusto von Dentz 452873d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 452973d80debSLuiz Augusto von Dentz 4530bf4c6325SGustavo F. Padovan rcu_read_lock(); 4531bf4c6325SGustavo F. Padovan 4532bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 453373d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 453473d80debSLuiz Augusto von Dentz 453573d80debSLuiz Augusto von Dentz if (conn->type != type) 453673d80debSLuiz Augusto von Dentz continue; 453773d80debSLuiz Augusto von Dentz 453873d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 453973d80debSLuiz Augusto von Dentz continue; 454073d80debSLuiz Augusto von Dentz 454173d80debSLuiz Augusto von Dentz conn_num++; 454273d80debSLuiz Augusto von Dentz 45438192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 454473d80debSLuiz Augusto von Dentz struct sk_buff *skb; 454573d80debSLuiz Augusto von Dentz 454673d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 454773d80debSLuiz Augusto von Dentz continue; 454873d80debSLuiz Augusto von Dentz 454973d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 455073d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 455173d80debSLuiz Augusto von Dentz continue; 455273d80debSLuiz Augusto von Dentz 455373d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 455473d80debSLuiz Augusto von Dentz num = 0; 455573d80debSLuiz Augusto von Dentz min = ~0; 455673d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 455773d80debSLuiz Augusto von Dentz } 455873d80debSLuiz Augusto von Dentz 455973d80debSLuiz Augusto von Dentz num++; 456073d80debSLuiz Augusto von Dentz 456173d80debSLuiz Augusto von Dentz if (conn->sent < min) { 456273d80debSLuiz Augusto von Dentz min = conn->sent; 456373d80debSLuiz Augusto von Dentz chan = tmp; 456473d80debSLuiz Augusto von Dentz } 456573d80debSLuiz Augusto von Dentz } 456673d80debSLuiz Augusto von Dentz 456773d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 456873d80debSLuiz Augusto von Dentz break; 456973d80debSLuiz Augusto von Dentz } 457073d80debSLuiz Augusto von Dentz 4571bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4572bf4c6325SGustavo F. Padovan 457373d80debSLuiz Augusto von Dentz if (!chan) 457473d80debSLuiz Augusto von Dentz return NULL; 457573d80debSLuiz Augusto von Dentz 457673d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 457773d80debSLuiz Augusto von Dentz case ACL_LINK: 457873d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 457973d80debSLuiz Augusto von Dentz break; 4580bd1eb66bSAndrei Emeltchenko case AMP_LINK: 4581bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 4582bd1eb66bSAndrei Emeltchenko break; 458373d80debSLuiz Augusto von Dentz case SCO_LINK: 458473d80debSLuiz Augusto von Dentz case ESCO_LINK: 458573d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 458673d80debSLuiz Augusto von Dentz break; 458773d80debSLuiz Augusto von Dentz case LE_LINK: 458873d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 458973d80debSLuiz Augusto von Dentz break; 459073d80debSLuiz Augusto von Dentz default: 459173d80debSLuiz Augusto von Dentz cnt = 0; 45922064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown link type %d", chan->conn->type); 459373d80debSLuiz Augusto von Dentz } 459473d80debSLuiz Augusto von Dentz 459573d80debSLuiz Augusto von Dentz q = cnt / num; 459673d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 459773d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 459873d80debSLuiz Augusto von Dentz return chan; 459973d80debSLuiz Augusto von Dentz } 460073d80debSLuiz Augusto von Dentz 460102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 460202b20f0bSLuiz Augusto von Dentz { 460302b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 460402b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 460502b20f0bSLuiz Augusto von Dentz int num = 0; 460602b20f0bSLuiz Augusto von Dentz 460702b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 460802b20f0bSLuiz Augusto von Dentz 4609bf4c6325SGustavo F. Padovan rcu_read_lock(); 4610bf4c6325SGustavo F. Padovan 4611bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 461202b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 461302b20f0bSLuiz Augusto von Dentz 461402b20f0bSLuiz Augusto von Dentz if (conn->type != type) 461502b20f0bSLuiz Augusto von Dentz continue; 461602b20f0bSLuiz Augusto von Dentz 461702b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 461802b20f0bSLuiz Augusto von Dentz continue; 461902b20f0bSLuiz Augusto von Dentz 462002b20f0bSLuiz Augusto von Dentz num++; 462102b20f0bSLuiz Augusto von Dentz 46228192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 462302b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 462402b20f0bSLuiz Augusto von Dentz 462502b20f0bSLuiz Augusto von Dentz if (chan->sent) { 462602b20f0bSLuiz Augusto von Dentz chan->sent = 0; 462702b20f0bSLuiz Augusto von Dentz continue; 462802b20f0bSLuiz Augusto von Dentz } 462902b20f0bSLuiz Augusto von Dentz 463002b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 463102b20f0bSLuiz Augusto von Dentz continue; 463202b20f0bSLuiz Augusto von Dentz 463302b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 463402b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 463502b20f0bSLuiz Augusto von Dentz continue; 463602b20f0bSLuiz Augusto von Dentz 463702b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 463802b20f0bSLuiz Augusto von Dentz 463902b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 464002b20f0bSLuiz Augusto von Dentz skb->priority); 464102b20f0bSLuiz Augusto von Dentz } 464202b20f0bSLuiz Augusto von Dentz 464302b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 464402b20f0bSLuiz Augusto von Dentz break; 464502b20f0bSLuiz Augusto von Dentz } 4646bf4c6325SGustavo F. Padovan 4647bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4648bf4c6325SGustavo F. Padovan 464902b20f0bSLuiz Augusto von Dentz } 465002b20f0bSLuiz Augusto von Dentz 4651b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4652b71d385aSAndrei Emeltchenko { 4653b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4654b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4655b71d385aSAndrei Emeltchenko } 4656b71d385aSAndrei Emeltchenko 46576039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 46581da177e4SLinus Torvalds { 4659d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 46601da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 46611da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 466263d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 46635f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 4664bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 46651da177e4SLinus Torvalds } 466663d2bc1bSAndrei Emeltchenko } 46671da177e4SLinus Torvalds 46687fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */ 46697fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev) 46707fedd3bbSAbhishek Pandit-Subedi { 46717fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn; 46727fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb; 46737fedd3bbSAbhishek Pandit-Subedi int quote; 46747fedd3bbSAbhishek Pandit-Subedi 46757fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name); 46767fedd3bbSAbhishek Pandit-Subedi 46777fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, SCO_LINK)) 46787fedd3bbSAbhishek Pandit-Subedi return; 46797fedd3bbSAbhishek Pandit-Subedi 46807fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 46817fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 46827fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len); 46837fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb); 46847fedd3bbSAbhishek Pandit-Subedi 46857fedd3bbSAbhishek Pandit-Subedi conn->sent++; 46867fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0) 46877fedd3bbSAbhishek Pandit-Subedi conn->sent = 0; 46887fedd3bbSAbhishek Pandit-Subedi } 46897fedd3bbSAbhishek Pandit-Subedi } 46907fedd3bbSAbhishek Pandit-Subedi } 46917fedd3bbSAbhishek Pandit-Subedi 46927fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev) 46937fedd3bbSAbhishek Pandit-Subedi { 46947fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn; 46957fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb; 46967fedd3bbSAbhishek Pandit-Subedi int quote; 46977fedd3bbSAbhishek Pandit-Subedi 46987fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name); 46997fedd3bbSAbhishek Pandit-Subedi 47007fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, ESCO_LINK)) 47017fedd3bbSAbhishek Pandit-Subedi return; 47027fedd3bbSAbhishek Pandit-Subedi 47037fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 47047fedd3bbSAbhishek Pandit-Subedi "e))) { 47057fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 47067fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len); 47077fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb); 47087fedd3bbSAbhishek Pandit-Subedi 47097fedd3bbSAbhishek Pandit-Subedi conn->sent++; 47107fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0) 47117fedd3bbSAbhishek Pandit-Subedi conn->sent = 0; 47127fedd3bbSAbhishek Pandit-Subedi } 47137fedd3bbSAbhishek Pandit-Subedi } 47147fedd3bbSAbhishek Pandit-Subedi } 47157fedd3bbSAbhishek Pandit-Subedi 47166039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 471763d2bc1bSAndrei Emeltchenko { 471863d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 471963d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 472063d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 472163d2bc1bSAndrei Emeltchenko int quote; 472263d2bc1bSAndrei Emeltchenko 472363d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 472404837f64SMarcel Holtmann 472573d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 472673d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 4727ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4728ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 472973d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 473073d80debSLuiz Augusto von Dentz skb->len, skb->priority); 473173d80debSLuiz Augusto von Dentz 4732ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4733ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4734ec1cce24SLuiz Augusto von Dentz break; 4735ec1cce24SLuiz Augusto von Dentz 4736ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4737ec1cce24SLuiz Augusto von Dentz 473873d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 473973d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 474004837f64SMarcel Holtmann 474157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 47421da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 47431da177e4SLinus Torvalds 47441da177e4SLinus Torvalds hdev->acl_cnt--; 474573d80debSLuiz Augusto von Dentz chan->sent++; 474673d80debSLuiz Augusto von Dentz chan->conn->sent++; 47477fedd3bbSAbhishek Pandit-Subedi 47487fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */ 47497fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev); 47507fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev); 47511da177e4SLinus Torvalds } 47521da177e4SLinus Torvalds } 475302b20f0bSLuiz Augusto von Dentz 475402b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 475502b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 47561da177e4SLinus Torvalds } 47571da177e4SLinus Torvalds 47586039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4759b71d385aSAndrei Emeltchenko { 476063d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4761b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4762b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4763b71d385aSAndrei Emeltchenko int quote; 4764bd1eb66bSAndrei Emeltchenko u8 type; 4765b71d385aSAndrei Emeltchenko 476663d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4767b71d385aSAndrei Emeltchenko 4768bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4769bd1eb66bSAndrei Emeltchenko 4770bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4771bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4772bd1eb66bSAndrei Emeltchenko else 4773bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4774bd1eb66bSAndrei Emeltchenko 4775b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4776bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4777b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4778b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4779b71d385aSAndrei Emeltchenko int blocks; 4780b71d385aSAndrei Emeltchenko 4781b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4782b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4783b71d385aSAndrei Emeltchenko 4784b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4785b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4786b71d385aSAndrei Emeltchenko break; 4787b71d385aSAndrei Emeltchenko 4788b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4789b71d385aSAndrei Emeltchenko 4790b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4791b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4792b71d385aSAndrei Emeltchenko return; 4793b71d385aSAndrei Emeltchenko 4794b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4795b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4796b71d385aSAndrei Emeltchenko 479757d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4798b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4799b71d385aSAndrei Emeltchenko 4800b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4801b71d385aSAndrei Emeltchenko quote -= blocks; 4802b71d385aSAndrei Emeltchenko 4803b71d385aSAndrei Emeltchenko chan->sent += blocks; 4804b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4805b71d385aSAndrei Emeltchenko } 4806b71d385aSAndrei Emeltchenko } 4807b71d385aSAndrei Emeltchenko 4808b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4809bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4810b71d385aSAndrei Emeltchenko } 4811b71d385aSAndrei Emeltchenko 48126039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4813b71d385aSAndrei Emeltchenko { 4814b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4815b71d385aSAndrei Emeltchenko 4816bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4817ca8bee5dSMarcel Holtmann if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY) 4818bd1eb66bSAndrei Emeltchenko return; 4819bd1eb66bSAndrei Emeltchenko 4820bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4821bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4822b71d385aSAndrei Emeltchenko return; 4823b71d385aSAndrei Emeltchenko 4824b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4825b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4826b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4827b71d385aSAndrei Emeltchenko break; 4828b71d385aSAndrei Emeltchenko 4829b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4830b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4831b71d385aSAndrei Emeltchenko break; 4832b71d385aSAndrei Emeltchenko } 4833b71d385aSAndrei Emeltchenko } 4834b71d385aSAndrei Emeltchenko 48356039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 48366ed58ec5SVille Tervo { 483773d80debSLuiz Augusto von Dentz struct hci_chan *chan; 48386ed58ec5SVille Tervo struct sk_buff *skb; 483902b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 48406ed58ec5SVille Tervo 48416ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 48426ed58ec5SVille Tervo 484352087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 484452087a79SLuiz Augusto von Dentz return; 484552087a79SLuiz Augusto von Dentz 48466ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 48471b1d29e5SLuiz Augusto von Dentz 48481b1d29e5SLuiz Augusto von Dentz __check_timeout(hdev, cnt); 48491b1d29e5SLuiz Augusto von Dentz 485002b20f0bSLuiz Augusto von Dentz tmp = cnt; 485173d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 4852ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4853ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 485473d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 485573d80debSLuiz Augusto von Dentz skb->len, skb->priority); 48566ed58ec5SVille Tervo 4857ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4858ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4859ec1cce24SLuiz Augusto von Dentz break; 4860ec1cce24SLuiz Augusto von Dentz 4861ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4862ec1cce24SLuiz Augusto von Dentz 486357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 48646ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 48656ed58ec5SVille Tervo 48666ed58ec5SVille Tervo cnt--; 486773d80debSLuiz Augusto von Dentz chan->sent++; 486873d80debSLuiz Augusto von Dentz chan->conn->sent++; 48697fedd3bbSAbhishek Pandit-Subedi 48707fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */ 48717fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev); 48727fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev); 48736ed58ec5SVille Tervo } 48746ed58ec5SVille Tervo } 487573d80debSLuiz Augusto von Dentz 48766ed58ec5SVille Tervo if (hdev->le_pkts) 48776ed58ec5SVille Tervo hdev->le_cnt = cnt; 48786ed58ec5SVille Tervo else 48796ed58ec5SVille Tervo hdev->acl_cnt = cnt; 488002b20f0bSLuiz Augusto von Dentz 488102b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 488202b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 48836ed58ec5SVille Tervo } 48846ed58ec5SVille Tervo 48853eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 48861da177e4SLinus Torvalds { 48873eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 48881da177e4SLinus Torvalds struct sk_buff *skb; 48891da177e4SLinus Torvalds 48906ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 48916ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 48921da177e4SLinus Torvalds 4893d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 48941da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 48951da177e4SLinus Torvalds hci_sched_sco(hdev); 4896b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 48977fedd3bbSAbhishek Pandit-Subedi hci_sched_acl(hdev); 48986ed58ec5SVille Tervo hci_sched_le(hdev); 489952de599eSMarcel Holtmann } 49006ed58ec5SVille Tervo 49011da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 49021da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 490357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 49041da177e4SLinus Torvalds } 49051da177e4SLinus Torvalds 490625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 49071da177e4SLinus Torvalds 49081da177e4SLinus Torvalds /* ACL data packet */ 49096039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 49101da177e4SLinus Torvalds { 49111da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 49121da177e4SLinus Torvalds struct hci_conn *conn; 49131da177e4SLinus Torvalds __u16 handle, flags; 49141da177e4SLinus Torvalds 49151da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 49161da177e4SLinus Torvalds 49171da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 49181da177e4SLinus Torvalds flags = hci_flags(handle); 49191da177e4SLinus Torvalds handle = hci_handle(handle); 49201da177e4SLinus Torvalds 4921f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4922a8c5fb1aSGustavo Padovan handle, flags); 49231da177e4SLinus Torvalds 49241da177e4SLinus Torvalds hdev->stat.acl_rx++; 49251da177e4SLinus Torvalds 49261da177e4SLinus Torvalds hci_dev_lock(hdev); 49271da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 49281da177e4SLinus Torvalds hci_dev_unlock(hdev); 49291da177e4SLinus Torvalds 49301da177e4SLinus Torvalds if (conn) { 493165983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 493204837f64SMarcel Holtmann 49331da177e4SLinus Torvalds /* Send to upper protocol */ 4934686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 49351da177e4SLinus Torvalds return; 49361da177e4SLinus Torvalds } else { 49372064ee33SMarcel Holtmann bt_dev_err(hdev, "ACL packet for unknown connection handle %d", 49382064ee33SMarcel Holtmann handle); 49391da177e4SLinus Torvalds } 49401da177e4SLinus Torvalds 49411da177e4SLinus Torvalds kfree_skb(skb); 49421da177e4SLinus Torvalds } 49431da177e4SLinus Torvalds 49441da177e4SLinus Torvalds /* SCO data packet */ 49456039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 49461da177e4SLinus Torvalds { 49471da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 49481da177e4SLinus Torvalds struct hci_conn *conn; 4949debdedf2SMarcel Holtmann __u16 handle, flags; 49501da177e4SLinus Torvalds 49511da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 49521da177e4SLinus Torvalds 49531da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 4954debdedf2SMarcel Holtmann flags = hci_flags(handle); 4955debdedf2SMarcel Holtmann handle = hci_handle(handle); 49561da177e4SLinus Torvalds 4957debdedf2SMarcel Holtmann BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4958debdedf2SMarcel Holtmann handle, flags); 49591da177e4SLinus Torvalds 49601da177e4SLinus Torvalds hdev->stat.sco_rx++; 49611da177e4SLinus Torvalds 49621da177e4SLinus Torvalds hci_dev_lock(hdev); 49631da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 49641da177e4SLinus Torvalds hci_dev_unlock(hdev); 49651da177e4SLinus Torvalds 49661da177e4SLinus Torvalds if (conn) { 49671da177e4SLinus Torvalds /* Send to upper protocol */ 496800398e1dSAlain Michaud bt_cb(skb)->sco.pkt_status = flags & 0x03; 4969686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 49701da177e4SLinus Torvalds return; 49711da177e4SLinus Torvalds } else { 49722064ee33SMarcel Holtmann bt_dev_err(hdev, "SCO packet for unknown connection handle %d", 49732064ee33SMarcel Holtmann handle); 49741da177e4SLinus Torvalds } 49751da177e4SLinus Torvalds 49761da177e4SLinus Torvalds kfree_skb(skb); 49771da177e4SLinus Torvalds } 49781da177e4SLinus Torvalds 49799238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 49809238f36aSJohan Hedberg { 49819238f36aSJohan Hedberg struct sk_buff *skb; 49829238f36aSJohan Hedberg 49839238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 49849238f36aSJohan Hedberg if (!skb) 49859238f36aSJohan Hedberg return true; 49869238f36aSJohan Hedberg 498744d27137SJohan Hedberg return (bt_cb(skb)->hci.req_flags & HCI_REQ_START); 49889238f36aSJohan Hedberg } 49899238f36aSJohan Hedberg 499042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 499142c6b129SJohan Hedberg { 499242c6b129SJohan Hedberg struct hci_command_hdr *sent; 499342c6b129SJohan Hedberg struct sk_buff *skb; 499442c6b129SJohan Hedberg u16 opcode; 499542c6b129SJohan Hedberg 499642c6b129SJohan Hedberg if (!hdev->sent_cmd) 499742c6b129SJohan Hedberg return; 499842c6b129SJohan Hedberg 499942c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 500042c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 500142c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 500242c6b129SJohan Hedberg return; 500342c6b129SJohan Hedberg 500442c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 500542c6b129SJohan Hedberg if (!skb) 500642c6b129SJohan Hedberg return; 500742c6b129SJohan Hedberg 500842c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 500942c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 501042c6b129SJohan Hedberg } 501142c6b129SJohan Hedberg 5012e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, 5013e6214487SJohan Hedberg hci_req_complete_t *req_complete, 5014e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 50159238f36aSJohan Hedberg { 50169238f36aSJohan Hedberg struct sk_buff *skb; 50179238f36aSJohan Hedberg unsigned long flags; 50189238f36aSJohan Hedberg 50199238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 50209238f36aSJohan Hedberg 502142c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 502242c6b129SJohan Hedberg * sent we need to do special handling of it. 50239238f36aSJohan Hedberg */ 502442c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 502542c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 502642c6b129SJohan Hedberg * reset complete event during init and any pending 502742c6b129SJohan Hedberg * command will never be completed. In such a case we 502842c6b129SJohan Hedberg * need to resend whatever was the last sent 502942c6b129SJohan Hedberg * command. 503042c6b129SJohan Hedberg */ 503142c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 503242c6b129SJohan Hedberg hci_resend_last(hdev); 503342c6b129SJohan Hedberg 50349238f36aSJohan Hedberg return; 503542c6b129SJohan Hedberg } 50369238f36aSJohan Hedberg 5037f80c5dadSJoão Paulo Rechi Vita /* If we reach this point this event matches the last command sent */ 5038f80c5dadSJoão Paulo Rechi Vita hci_dev_clear_flag(hdev, HCI_CMD_PENDING); 5039f80c5dadSJoão Paulo Rechi Vita 50409238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 50419238f36aSJohan Hedberg * this request the request is not yet complete. 50429238f36aSJohan Hedberg */ 50439238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 50449238f36aSJohan Hedberg return; 50459238f36aSJohan Hedberg 50469238f36aSJohan Hedberg /* If this was the last command in a request the complete 50479238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 50489238f36aSJohan Hedberg * command queue (hdev->cmd_q). 50499238f36aSJohan Hedberg */ 505044d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) { 505144d27137SJohan Hedberg *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb; 5052e6214487SJohan Hedberg return; 50539238f36aSJohan Hedberg } 5054e6214487SJohan Hedberg 505544d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_complete) { 505644d27137SJohan Hedberg *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete; 5057e6214487SJohan Hedberg return; 505853e21fbcSJohan Hedberg } 50599238f36aSJohan Hedberg 50609238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 50619238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 50629238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 506344d27137SJohan Hedberg if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) { 50649238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 50659238f36aSJohan Hedberg break; 50669238f36aSJohan Hedberg } 50679238f36aSJohan Hedberg 50683bd7594eSDouglas Anderson if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) 5069242c0ebdSMarcel Holtmann *req_complete_skb = bt_cb(skb)->hci.req_complete_skb; 50703bd7594eSDouglas Anderson else 50713bd7594eSDouglas Anderson *req_complete = bt_cb(skb)->hci.req_complete; 50729238f36aSJohan Hedberg kfree_skb(skb); 50739238f36aSJohan Hedberg } 50749238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 50759238f36aSJohan Hedberg } 50769238f36aSJohan Hedberg 5077b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 50781da177e4SLinus Torvalds { 5079b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 50801da177e4SLinus Torvalds struct sk_buff *skb; 50811da177e4SLinus Torvalds 50821da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 50831da177e4SLinus Torvalds 50841da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 5085cd82e61cSMarcel Holtmann /* Send copy to monitor */ 5086cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 5087cd82e61cSMarcel Holtmann 50881da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 50891da177e4SLinus Torvalds /* Send copy to the sockets */ 5090470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 50911da177e4SLinus Torvalds } 50921da177e4SLinus Torvalds 5093eb8c101eSMattijs Korpershoek /* If the device has been opened in HCI_USER_CHANNEL, 5094eb8c101eSMattijs Korpershoek * the userspace has exclusive access to device. 5095eb8c101eSMattijs Korpershoek * When device is HCI_INIT, we still need to process 5096eb8c101eSMattijs Korpershoek * the data packets to the driver in order 5097eb8c101eSMattijs Korpershoek * to complete its setup(). 5098eb8c101eSMattijs Korpershoek */ 5099eb8c101eSMattijs Korpershoek if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 5100eb8c101eSMattijs Korpershoek !test_bit(HCI_INIT, &hdev->flags)) { 51011da177e4SLinus Torvalds kfree_skb(skb); 51021da177e4SLinus Torvalds continue; 51031da177e4SLinus Torvalds } 51041da177e4SLinus Torvalds 51051da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 51061da177e4SLinus Torvalds /* Don't process data packets in this states. */ 5107d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 51081da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 51091da177e4SLinus Torvalds case HCI_SCODATA_PKT: 5110cc974003SMarcel Holtmann case HCI_ISODATA_PKT: 51111da177e4SLinus Torvalds kfree_skb(skb); 51121da177e4SLinus Torvalds continue; 51133ff50b79SStephen Hemminger } 51141da177e4SLinus Torvalds } 51151da177e4SLinus Torvalds 51161da177e4SLinus Torvalds /* Process frame */ 5117d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 51181da177e4SLinus Torvalds case HCI_EVENT_PKT: 5119b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 51201da177e4SLinus Torvalds hci_event_packet(hdev, skb); 51211da177e4SLinus Torvalds break; 51221da177e4SLinus Torvalds 51231da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 51241da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 51251da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 51261da177e4SLinus Torvalds break; 51271da177e4SLinus Torvalds 51281da177e4SLinus Torvalds case HCI_SCODATA_PKT: 51291da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 51301da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 51311da177e4SLinus Torvalds break; 51321da177e4SLinus Torvalds 51331da177e4SLinus Torvalds default: 51341da177e4SLinus Torvalds kfree_skb(skb); 51351da177e4SLinus Torvalds break; 51361da177e4SLinus Torvalds } 51371da177e4SLinus Torvalds } 51381da177e4SLinus Torvalds } 51391da177e4SLinus Torvalds 5140c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 51411da177e4SLinus Torvalds { 5142c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 51431da177e4SLinus Torvalds struct sk_buff *skb; 51441da177e4SLinus Torvalds 51452104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 51462104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 51471da177e4SLinus Torvalds 51481da177e4SLinus Torvalds /* Send queued commands */ 51495a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 51505a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 51515a08ecceSAndrei Emeltchenko if (!skb) 51525a08ecceSAndrei Emeltchenko return; 51535a08ecceSAndrei Emeltchenko 51541da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 51551da177e4SLinus Torvalds 5156a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 515770f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 5158f80c5dadSJoão Paulo Rechi Vita if (hci_req_status_pend(hdev)) 5159f80c5dadSJoão Paulo Rechi Vita hci_dev_set_flag(hdev, HCI_CMD_PENDING); 51601da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 516157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 51627bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 516365cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 51647bdb8a5cSSzymon Janc else 516565cc2b49SMarcel Holtmann schedule_delayed_work(&hdev->cmd_timer, 516665cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT); 51671da177e4SLinus Torvalds } else { 51681da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 5169c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 51701da177e4SLinus Torvalds } 51711da177e4SLinus Torvalds } 51721da177e4SLinus Torvalds } 5173