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