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