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 608cde1a8a9SIsmael Ferreras Morezuelas if (hdev->commands[18] & 0x04 && 609cde1a8a9SIsmael Ferreras Morezuelas !test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks)) 61000bce3fbSAlain Michaud hci_req_add(req, HCI_OP_READ_DEF_ERR_DATA_REPORTING, 0, NULL); 61100bce3fbSAlain Michaud 612417287deSMarcel Holtmann /* Some older Broadcom based Bluetooth 1.2 controllers do not 613417287deSMarcel Holtmann * support the Read Page Scan Type command. Check support for 614417287deSMarcel Holtmann * this command in the bit mask of supported commands. 615417287deSMarcel Holtmann */ 616417287deSMarcel Holtmann if (hdev->commands[13] & 0x01) 617417287deSMarcel Holtmann hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 618417287deSMarcel Holtmann 6199193c6e8SAndre Guedes if (lmp_le_capable(hdev)) { 6209193c6e8SAndre Guedes u8 events[8]; 6219193c6e8SAndre Guedes 6229193c6e8SAndre Guedes memset(events, 0, sizeof(events)); 6234d6c705bSMarcel Holtmann 6244d6c705bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) 6254d6c705bSMarcel Holtmann events[0] |= 0x10; /* LE Long Term Key Request */ 626662bc2e6SAndre Guedes 627662bc2e6SAndre Guedes /* If controller supports the Connection Parameters Request 628662bc2e6SAndre Guedes * Link Layer Procedure, enable the corresponding event. 629662bc2e6SAndre Guedes */ 630662bc2e6SAndre Guedes if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC) 631662bc2e6SAndre Guedes events[0] |= 0x20; /* LE Remote Connection 632662bc2e6SAndre Guedes * Parameter Request 633662bc2e6SAndre Guedes */ 634662bc2e6SAndre Guedes 635a9f6068eSMarcel Holtmann /* If the controller supports the Data Length Extension 636a9f6068eSMarcel Holtmann * feature, enable the corresponding event. 637a9f6068eSMarcel Holtmann */ 638a9f6068eSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) 639a9f6068eSMarcel Holtmann events[0] |= 0x40; /* LE Data Length Change */ 640a9f6068eSMarcel Holtmann 641ff3b8df2SMarcel Holtmann /* If the controller supports LL Privacy feature, enable 642ff3b8df2SMarcel Holtmann * the corresponding event. 643ff3b8df2SMarcel Holtmann */ 644ff3b8df2SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_LL_PRIVACY) 645ff3b8df2SMarcel Holtmann events[1] |= 0x02; /* LE Enhanced Connection 646ff3b8df2SMarcel Holtmann * Complete 647ff3b8df2SMarcel Holtmann */ 648ff3b8df2SMarcel Holtmann 6494b71bba4SMarcel Holtmann /* If the controller supports Extended Scanner Filter 6504b71bba4SMarcel Holtmann * Policies, enable the correspondig event. 6514b71bba4SMarcel Holtmann */ 6524b71bba4SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY) 6534b71bba4SMarcel Holtmann events[1] |= 0x04; /* LE Direct Advertising 6544b71bba4SMarcel Holtmann * Report 6554b71bba4SMarcel Holtmann */ 6564b71bba4SMarcel Holtmann 6579756d33bSMarcel Holtmann /* If the controller supports Channel Selection Algorithm #2 6589756d33bSMarcel Holtmann * feature, enable the corresponding event. 6599756d33bSMarcel Holtmann */ 6609756d33bSMarcel Holtmann if (hdev->le_features[1] & HCI_LE_CHAN_SEL_ALG2) 6619756d33bSMarcel Holtmann events[2] |= 0x08; /* LE Channel Selection 6629756d33bSMarcel Holtmann * Algorithm 6639756d33bSMarcel Holtmann */ 6649756d33bSMarcel Holtmann 6657d26f5c4SMarcel Holtmann /* If the controller supports the LE Set Scan Enable command, 6667d26f5c4SMarcel Holtmann * enable the corresponding advertising report event. 6677d26f5c4SMarcel Holtmann */ 6687d26f5c4SMarcel Holtmann if (hdev->commands[26] & 0x08) 6697d26f5c4SMarcel Holtmann events[0] |= 0x02; /* LE Advertising Report */ 6707d26f5c4SMarcel Holtmann 6717d26f5c4SMarcel Holtmann /* If the controller supports the LE Create Connection 6727d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6737d26f5c4SMarcel Holtmann */ 6747d26f5c4SMarcel Holtmann if (hdev->commands[26] & 0x10) 6757d26f5c4SMarcel Holtmann events[0] |= 0x01; /* LE Connection Complete */ 6767d26f5c4SMarcel Holtmann 6777d26f5c4SMarcel Holtmann /* If the controller supports the LE Connection Update 6787d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6797d26f5c4SMarcel Holtmann */ 6807d26f5c4SMarcel Holtmann if (hdev->commands[27] & 0x04) 6817d26f5c4SMarcel Holtmann events[0] |= 0x04; /* LE Connection Update 6827d26f5c4SMarcel Holtmann * Complete 6837d26f5c4SMarcel Holtmann */ 6847d26f5c4SMarcel Holtmann 6857d26f5c4SMarcel Holtmann /* If the controller supports the LE Read Remote Used Features 6867d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6877d26f5c4SMarcel Holtmann */ 6887d26f5c4SMarcel Holtmann if (hdev->commands[27] & 0x20) 6897d26f5c4SMarcel Holtmann events[0] |= 0x08; /* LE Read Remote Used 6907d26f5c4SMarcel Holtmann * Features Complete 6917d26f5c4SMarcel Holtmann */ 6927d26f5c4SMarcel Holtmann 6935a34bd5fSMarcel Holtmann /* If the controller supports the LE Read Local P-256 6945a34bd5fSMarcel Holtmann * Public Key command, enable the corresponding event. 6955a34bd5fSMarcel Holtmann */ 6965a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x02) 6975a34bd5fSMarcel Holtmann events[0] |= 0x80; /* LE Read Local P-256 6985a34bd5fSMarcel Holtmann * Public Key Complete 6995a34bd5fSMarcel Holtmann */ 7005a34bd5fSMarcel Holtmann 7015a34bd5fSMarcel Holtmann /* If the controller supports the LE Generate DHKey 7025a34bd5fSMarcel Holtmann * command, enable the corresponding event. 7035a34bd5fSMarcel Holtmann */ 7045a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x04) 7055a34bd5fSMarcel Holtmann events[1] |= 0x01; /* LE Generate DHKey Complete */ 7065a34bd5fSMarcel Holtmann 70727bbca44SMarcel Holtmann /* If the controller supports the LE Set Default PHY or 70827bbca44SMarcel Holtmann * LE Set PHY commands, enable the corresponding event. 70927bbca44SMarcel Holtmann */ 71027bbca44SMarcel Holtmann if (hdev->commands[35] & (0x20 | 0x40)) 71127bbca44SMarcel Holtmann events[1] |= 0x08; /* LE PHY Update Complete */ 71227bbca44SMarcel Holtmann 713c215e939SJaganath Kanakkassery /* If the controller supports LE Set Extended Scan Parameters 714c215e939SJaganath Kanakkassery * and LE Set Extended Scan Enable commands, enable the 715c215e939SJaganath Kanakkassery * corresponding event. 716c215e939SJaganath Kanakkassery */ 717c215e939SJaganath Kanakkassery if (use_ext_scan(hdev)) 718c215e939SJaganath Kanakkassery events[1] |= 0x10; /* LE Extended Advertising 719c215e939SJaganath Kanakkassery * Report 720c215e939SJaganath Kanakkassery */ 721c215e939SJaganath Kanakkassery 722acf0aeaeSJaganath Kanakkassery /* If the controller supports the LE Extended Advertising 723acf0aeaeSJaganath Kanakkassery * command, enable the corresponding event. 724acf0aeaeSJaganath Kanakkassery */ 725acf0aeaeSJaganath Kanakkassery if (ext_adv_capable(hdev)) 726acf0aeaeSJaganath Kanakkassery events[2] |= 0x02; /* LE Advertising Set 727acf0aeaeSJaganath Kanakkassery * Terminated 728acf0aeaeSJaganath Kanakkassery */ 729acf0aeaeSJaganath Kanakkassery 7309193c6e8SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), 7319193c6e8SAndre Guedes events); 7329193c6e8SAndre Guedes 73315a49ccaSMarcel Holtmann /* Read LE Advertising Channel TX Power */ 7346b49bcb4SJaganath Kanakkassery if ((hdev->commands[25] & 0x40) && !ext_adv_capable(hdev)) { 7356b49bcb4SJaganath Kanakkassery /* HCI TS spec forbids mixing of legacy and extended 7366b49bcb4SJaganath Kanakkassery * advertising commands wherein READ_ADV_TX_POWER is 7376b49bcb4SJaganath Kanakkassery * also included. So do not call it if extended adv 7386b49bcb4SJaganath Kanakkassery * is supported otherwise controller will return 7396b49bcb4SJaganath Kanakkassery * COMMAND_DISALLOWED for extended commands. 7406b49bcb4SJaganath Kanakkassery */ 74115a49ccaSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 74215a49ccaSMarcel Holtmann } 74315a49ccaSMarcel Holtmann 7442ab216a7SMarcel Holtmann if (hdev->commands[26] & 0x40) { 7452ab216a7SMarcel Holtmann /* Read LE White List Size */ 7462ab216a7SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 7472ab216a7SMarcel Holtmann 0, NULL); 7482ab216a7SMarcel Holtmann } 7492ab216a7SMarcel Holtmann 7502ab216a7SMarcel Holtmann if (hdev->commands[26] & 0x80) { 7512ab216a7SMarcel Holtmann /* Clear LE White List */ 7522ab216a7SMarcel Holtmann hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL); 7532ab216a7SMarcel Holtmann } 7542ab216a7SMarcel Holtmann 755cfdb0c2dSAnkit Navik if (hdev->commands[34] & 0x40) { 756cfdb0c2dSAnkit Navik /* Read LE Resolving List Size */ 757cfdb0c2dSAnkit Navik hci_req_add(req, HCI_OP_LE_READ_RESOLV_LIST_SIZE, 758cfdb0c2dSAnkit Navik 0, NULL); 759cfdb0c2dSAnkit Navik } 760cfdb0c2dSAnkit Navik 761545f2596SAnkit Navik if (hdev->commands[34] & 0x20) { 762545f2596SAnkit Navik /* Clear LE Resolving List */ 763545f2596SAnkit Navik hci_req_add(req, HCI_OP_LE_CLEAR_RESOLV_LIST, 0, NULL); 764545f2596SAnkit Navik } 765545f2596SAnkit Navik 766b2cc2339SSathish Narasimman if (hdev->commands[35] & 0x40) { 767b2cc2339SSathish Narasimman __le16 rpa_timeout = cpu_to_le16(hdev->rpa_timeout); 768b2cc2339SSathish Narasimman 769b2cc2339SSathish Narasimman /* Set RPA timeout */ 770b2cc2339SSathish Narasimman hci_req_add(req, HCI_OP_LE_SET_RPA_TIMEOUT, 2, 771b2cc2339SSathish Narasimman &rpa_timeout); 772b2cc2339SSathish Narasimman } 773b2cc2339SSathish Narasimman 774a9f6068eSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { 775a9f6068eSMarcel Holtmann /* Read LE Maximum Data Length */ 776a9f6068eSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL); 777a9f6068eSMarcel Holtmann 778a9f6068eSMarcel Holtmann /* Read LE Suggested Default Data Length */ 779a9f6068eSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL); 780a9f6068eSMarcel Holtmann } 781a9f6068eSMarcel Holtmann 7826b49bcb4SJaganath Kanakkassery if (ext_adv_capable(hdev)) { 7836b49bcb4SJaganath Kanakkassery /* Read LE Number of Supported Advertising Sets */ 7846b49bcb4SJaganath Kanakkassery hci_req_add(req, HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS, 7856b49bcb4SJaganath Kanakkassery 0, NULL); 7866b49bcb4SJaganath Kanakkassery } 7876b49bcb4SJaganath Kanakkassery 78842c6b129SJohan Hedberg hci_set_le_support(req); 7899193c6e8SAndre Guedes } 790d2c5d77fSJohan Hedberg 791d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 792d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 793d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 794d2c5d77fSJohan Hedberg 795d2c5d77fSJohan Hedberg cp.page = p; 796d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 797d2c5d77fSJohan Hedberg sizeof(cp), &cp); 798d2c5d77fSJohan Hedberg } 799a1d01db1SJohan Hedberg 800a1d01db1SJohan Hedberg return 0; 8012177bab5SJohan Hedberg } 8022177bab5SJohan Hedberg 803a1d01db1SJohan Hedberg static int hci_init4_req(struct hci_request *req, unsigned long opt) 8045d4e7e8dSJohan Hedberg { 8055d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 8065d4e7e8dSJohan Hedberg 80736f260ceSMarcel Holtmann /* Some Broadcom based Bluetooth controllers do not support the 80836f260ceSMarcel Holtmann * Delete Stored Link Key command. They are clearly indicating its 80936f260ceSMarcel Holtmann * absence in the bit mask of supported commands. 81036f260ceSMarcel Holtmann * 81136f260ceSMarcel Holtmann * Check the supported commands and only if the the command is marked 81236f260ceSMarcel Holtmann * as supported send it. If not supported assume that the controller 81336f260ceSMarcel Holtmann * does not have actual support for stored link keys which makes this 81436f260ceSMarcel Holtmann * command redundant anyway. 81536f260ceSMarcel Holtmann * 81636f260ceSMarcel Holtmann * Some controllers indicate that they support handling deleting 81736f260ceSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 81836f260ceSMarcel Holtmann * just disable this command. 81936f260ceSMarcel Holtmann */ 82036f260ceSMarcel Holtmann if (hdev->commands[6] & 0x80 && 82136f260ceSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 82236f260ceSMarcel Holtmann struct hci_cp_delete_stored_link_key cp; 82336f260ceSMarcel Holtmann 82436f260ceSMarcel Holtmann bacpy(&cp.bdaddr, BDADDR_ANY); 82536f260ceSMarcel Holtmann cp.delete_all = 0x01; 82636f260ceSMarcel Holtmann hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 82736f260ceSMarcel Holtmann sizeof(cp), &cp); 82836f260ceSMarcel Holtmann } 82936f260ceSMarcel Holtmann 830d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 831d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 832d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 833d62e6d67SJohan Hedberg 834109e3191SMarcel Holtmann /* Read local codec list if the HCI command is supported */ 835109e3191SMarcel Holtmann if (hdev->commands[29] & 0x20) 836109e3191SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL); 837109e3191SMarcel Holtmann 838a4790360SMarcel Holtmann /* Read local pairing options if the HCI command is supported */ 839a4790360SMarcel Holtmann if (hdev->commands[41] & 0x08) 840a4790360SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_PAIRING_OPTS, 0, NULL); 841a4790360SMarcel Holtmann 842f4fe73edSMarcel Holtmann /* Get MWS transport configuration if the HCI command is supported */ 843f4fe73edSMarcel Holtmann if (hdev->commands[30] & 0x08) 844f4fe73edSMarcel Holtmann hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL); 845f4fe73edSMarcel Holtmann 8465d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 84753b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 8485d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 849a6d0d690SMarcel Holtmann 850a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 851d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) && 852574ea3c7SMarcel Holtmann bredr_sc_enabled(hdev)) { 853a6d0d690SMarcel Holtmann u8 support = 0x01; 854574ea3c7SMarcel Holtmann 855a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 856a6d0d690SMarcel Holtmann sizeof(support), &support); 857a6d0d690SMarcel Holtmann } 858a1d01db1SJohan Hedberg 85900bce3fbSAlain Michaud /* Set erroneous data reporting if supported to the wideband speech 86000bce3fbSAlain Michaud * setting value 86100bce3fbSAlain Michaud */ 862cde1a8a9SIsmael Ferreras Morezuelas if (hdev->commands[18] & 0x08 && 863cde1a8a9SIsmael Ferreras Morezuelas !test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks)) { 86400bce3fbSAlain Michaud bool enabled = hci_dev_test_flag(hdev, 86500bce3fbSAlain Michaud HCI_WIDEBAND_SPEECH_ENABLED); 86600bce3fbSAlain Michaud 86700bce3fbSAlain Michaud if (enabled != 86800bce3fbSAlain Michaud (hdev->err_data_reporting == ERR_DATA_REPORTING_ENABLED)) { 86900bce3fbSAlain Michaud struct hci_cp_write_def_err_data_reporting cp; 87000bce3fbSAlain Michaud 87100bce3fbSAlain Michaud cp.err_data_reporting = enabled ? 87200bce3fbSAlain Michaud ERR_DATA_REPORTING_ENABLED : 87300bce3fbSAlain Michaud ERR_DATA_REPORTING_DISABLED; 87400bce3fbSAlain Michaud 87500bce3fbSAlain Michaud hci_req_add(req, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING, 87600bce3fbSAlain Michaud sizeof(cp), &cp); 87700bce3fbSAlain Michaud } 87800bce3fbSAlain Michaud } 87900bce3fbSAlain Michaud 88012204875SMarcel Holtmann /* Set Suggested Default Data Length to maximum if supported */ 88112204875SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { 88212204875SMarcel Holtmann struct hci_cp_le_write_def_data_len cp; 88312204875SMarcel Holtmann 884727ea61aSBen Dooks (Codethink) cp.tx_len = cpu_to_le16(hdev->le_max_tx_len); 885727ea61aSBen Dooks (Codethink) cp.tx_time = cpu_to_le16(hdev->le_max_tx_time); 88612204875SMarcel Holtmann hci_req_add(req, HCI_OP_LE_WRITE_DEF_DATA_LEN, sizeof(cp), &cp); 88712204875SMarcel Holtmann } 88812204875SMarcel Holtmann 889de2ba303SMarcel Holtmann /* Set Default PHY parameters if command is supported */ 890de2ba303SMarcel Holtmann if (hdev->commands[35] & 0x20) { 891de2ba303SMarcel Holtmann struct hci_cp_le_set_default_phy cp; 892de2ba303SMarcel Holtmann 8936decb5b4SJaganath Kanakkassery cp.all_phys = 0x00; 8946decb5b4SJaganath Kanakkassery cp.tx_phys = hdev->le_tx_def_phys; 8956decb5b4SJaganath Kanakkassery cp.rx_phys = hdev->le_rx_def_phys; 896de2ba303SMarcel Holtmann 897de2ba303SMarcel Holtmann hci_req_add(req, HCI_OP_LE_SET_DEFAULT_PHY, sizeof(cp), &cp); 898de2ba303SMarcel Holtmann } 899de2ba303SMarcel Holtmann 900a1d01db1SJohan Hedberg return 0; 9015d4e7e8dSJohan Hedberg } 9025d4e7e8dSJohan Hedberg 9032177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 9042177bab5SJohan Hedberg { 9052177bab5SJohan Hedberg int err; 9062177bab5SJohan Hedberg 9074ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT, NULL); 9082177bab5SJohan Hedberg if (err < 0) 9092177bab5SJohan Hedberg return err; 9102177bab5SJohan Hedberg 911f640ee98SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 912f640ee98SMarcel Holtmann hci_debugfs_create_basic(hdev); 9134b4148e9SMarcel Holtmann 9144ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT, NULL); 9152177bab5SJohan Hedberg if (err < 0) 9162177bab5SJohan Hedberg return err; 9172177bab5SJohan Hedberg 918ca8bee5dSMarcel Holtmann /* HCI_PRIMARY covers both single-mode LE, BR/EDR and dual-mode 9190af801b9SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 9200af801b9SJohan Hedberg * first two stages of init. 9210af801b9SJohan Hedberg */ 922ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) 9230af801b9SJohan Hedberg return 0; 9240af801b9SJohan Hedberg 9254ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT, NULL); 9265d4e7e8dSJohan Hedberg if (err < 0) 9275d4e7e8dSJohan Hedberg return err; 9285d4e7e8dSJohan Hedberg 9294ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT, NULL); 930baf27f6eSMarcel Holtmann if (err < 0) 931baf27f6eSMarcel Holtmann return err; 932baf27f6eSMarcel Holtmann 933ec6cef9cSMarcel Holtmann /* This function is only called when the controller is actually in 934ec6cef9cSMarcel Holtmann * configured state. When the controller is marked as unconfigured, 935ec6cef9cSMarcel Holtmann * this initialization procedure is not run. 936ec6cef9cSMarcel Holtmann * 937ec6cef9cSMarcel Holtmann * It means that it is possible that a controller runs through its 938ec6cef9cSMarcel Holtmann * setup phase and then discovers missing settings. If that is the 939ec6cef9cSMarcel Holtmann * case, then this function will not be called. It then will only 940ec6cef9cSMarcel Holtmann * be called during the config phase. 941ec6cef9cSMarcel Holtmann * 942ec6cef9cSMarcel Holtmann * So only when in setup phase or config phase, create the debugfs 943ec6cef9cSMarcel Holtmann * entries and register the SMP channels. 944baf27f6eSMarcel Holtmann */ 945d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 946d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 947baf27f6eSMarcel Holtmann return 0; 948baf27f6eSMarcel Holtmann 94960c5f5fbSMarcel Holtmann hci_debugfs_create_common(hdev); 95060c5f5fbSMarcel Holtmann 95171c3b60eSMarcel Holtmann if (lmp_bredr_capable(hdev)) 95260c5f5fbSMarcel Holtmann hci_debugfs_create_bredr(hdev); 9532bfa3531SMarcel Holtmann 954162a3bacSMarcel Holtmann if (lmp_le_capable(hdev)) 95560c5f5fbSMarcel Holtmann hci_debugfs_create_le(hdev); 956e7b8fc92SMarcel Holtmann 957baf27f6eSMarcel Holtmann return 0; 9582177bab5SJohan Hedberg } 9592177bab5SJohan Hedberg 960a1d01db1SJohan Hedberg static int hci_init0_req(struct hci_request *req, unsigned long opt) 9610ebca7d6SMarcel Holtmann { 9620ebca7d6SMarcel Holtmann struct hci_dev *hdev = req->hdev; 9630ebca7d6SMarcel Holtmann 9640ebca7d6SMarcel Holtmann BT_DBG("%s %ld", hdev->name, opt); 9650ebca7d6SMarcel Holtmann 9660ebca7d6SMarcel Holtmann /* Reset */ 9670ebca7d6SMarcel Holtmann if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 9680ebca7d6SMarcel Holtmann hci_reset_req(req, 0); 9690ebca7d6SMarcel Holtmann 9700ebca7d6SMarcel Holtmann /* Read Local Version */ 9710ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 9720ebca7d6SMarcel Holtmann 9730ebca7d6SMarcel Holtmann /* Read BD Address */ 9740ebca7d6SMarcel Holtmann if (hdev->set_bdaddr) 9750ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 976a1d01db1SJohan Hedberg 977a1d01db1SJohan Hedberg return 0; 9780ebca7d6SMarcel Holtmann } 9790ebca7d6SMarcel Holtmann 9800ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev) 9810ebca7d6SMarcel Holtmann { 9820ebca7d6SMarcel Holtmann int err; 9830ebca7d6SMarcel Holtmann 984cc78b44bSMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 985cc78b44bSMarcel Holtmann return 0; 986cc78b44bSMarcel Holtmann 9874ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT, NULL); 9880ebca7d6SMarcel Holtmann if (err < 0) 9890ebca7d6SMarcel Holtmann return err; 9900ebca7d6SMarcel Holtmann 991f640ee98SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 992f640ee98SMarcel Holtmann hci_debugfs_create_basic(hdev); 993f640ee98SMarcel Holtmann 9940ebca7d6SMarcel Holtmann return 0; 9950ebca7d6SMarcel Holtmann } 9960ebca7d6SMarcel Holtmann 997a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt) 9981da177e4SLinus Torvalds { 9991da177e4SLinus Torvalds __u8 scan = opt; 10001da177e4SLinus Torvalds 100142c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 10021da177e4SLinus Torvalds 10031da177e4SLinus Torvalds /* Inquiry and Page scans */ 100442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 1005a1d01db1SJohan Hedberg return 0; 10061da177e4SLinus Torvalds } 10071da177e4SLinus Torvalds 1008a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt) 10091da177e4SLinus Torvalds { 10101da177e4SLinus Torvalds __u8 auth = opt; 10111da177e4SLinus Torvalds 101242c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 10131da177e4SLinus Torvalds 10141da177e4SLinus Torvalds /* Authentication */ 101542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 1016a1d01db1SJohan Hedberg return 0; 10171da177e4SLinus Torvalds } 10181da177e4SLinus Torvalds 1019a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt) 10201da177e4SLinus Torvalds { 10211da177e4SLinus Torvalds __u8 encrypt = opt; 10221da177e4SLinus Torvalds 102342c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 10241da177e4SLinus Torvalds 1025e4e8e37cSMarcel Holtmann /* Encryption */ 102642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 1027a1d01db1SJohan Hedberg return 0; 10281da177e4SLinus Torvalds } 10291da177e4SLinus Torvalds 1030a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt) 1031e4e8e37cSMarcel Holtmann { 1032e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1033e4e8e37cSMarcel Holtmann 103442c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1035e4e8e37cSMarcel Holtmann 1036e4e8e37cSMarcel Holtmann /* Default link policy */ 103742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1038a1d01db1SJohan Hedberg return 0; 1039e4e8e37cSMarcel Holtmann } 1040e4e8e37cSMarcel Holtmann 10411da177e4SLinus Torvalds /* Get HCI device by index. 10421da177e4SLinus Torvalds * Device is held on return. */ 10431da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 10441da177e4SLinus Torvalds { 10458035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 10461da177e4SLinus Torvalds 10471da177e4SLinus Torvalds BT_DBG("%d", index); 10481da177e4SLinus Torvalds 10491da177e4SLinus Torvalds if (index < 0) 10501da177e4SLinus Torvalds return NULL; 10511da177e4SLinus Torvalds 10521da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 10538035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 10541da177e4SLinus Torvalds if (d->id == index) { 10551da177e4SLinus Torvalds hdev = hci_dev_hold(d); 10561da177e4SLinus Torvalds break; 10571da177e4SLinus Torvalds } 10581da177e4SLinus Torvalds } 10591da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 10601da177e4SLinus Torvalds return hdev; 10611da177e4SLinus Torvalds } 10621da177e4SLinus Torvalds 10631da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1064ff9ef578SJohan Hedberg 106530dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 106630dc78e1SJohan Hedberg { 106730dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 106830dc78e1SJohan Hedberg 10696fbe195dSAndre Guedes switch (discov->state) { 1070343f935bSAndre Guedes case DISCOVERY_FINDING: 10716fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 107230dc78e1SJohan Hedberg return true; 107330dc78e1SJohan Hedberg 10746fbe195dSAndre Guedes default: 107530dc78e1SJohan Hedberg return false; 107630dc78e1SJohan Hedberg } 10776fbe195dSAndre Guedes } 107830dc78e1SJohan Hedberg 1079ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1080ff9ef578SJohan Hedberg { 1081bb3e0a33SJohan Hedberg int old_state = hdev->discovery.state; 1082bb3e0a33SJohan Hedberg 1083ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1084ff9ef578SJohan Hedberg 1085bb3e0a33SJohan Hedberg if (old_state == state) 1086ff9ef578SJohan Hedberg return; 1087ff9ef578SJohan Hedberg 1088bb3e0a33SJohan Hedberg hdev->discovery.state = state; 1089bb3e0a33SJohan Hedberg 1090ff9ef578SJohan Hedberg switch (state) { 1091ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 1092c54c3860SAndre Guedes hci_update_background_scan(hdev); 1093c54c3860SAndre Guedes 1094bb3e0a33SJohan Hedberg if (old_state != DISCOVERY_STARTING) 1095ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1096ff9ef578SJohan Hedberg break; 1097ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1098ff9ef578SJohan Hedberg break; 1099343f935bSAndre Guedes case DISCOVERY_FINDING: 1100ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1101ff9ef578SJohan Hedberg break; 110230dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 110330dc78e1SJohan Hedberg break; 1104ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1105ff9ef578SJohan Hedberg break; 1106ff9ef578SJohan Hedberg } 1107ff9ef578SJohan Hedberg } 1108ff9ef578SJohan Hedberg 11091f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 11101da177e4SLinus Torvalds { 111130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1112b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 11131da177e4SLinus Torvalds 1114561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1115561aafbcSJohan Hedberg list_del(&p->all); 1116b57c1a56SJohan Hedberg kfree(p); 11171da177e4SLinus Torvalds } 1118561aafbcSJohan Hedberg 1119561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1120561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 11211da177e4SLinus Torvalds } 11221da177e4SLinus Torvalds 1123a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1124a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 11251da177e4SLinus Torvalds { 112630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 11271da177e4SLinus Torvalds struct inquiry_entry *e; 11281da177e4SLinus Torvalds 11296ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 11301da177e4SLinus Torvalds 1131561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 11321da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 11331da177e4SLinus Torvalds return e; 11341da177e4SLinus Torvalds } 11351da177e4SLinus Torvalds 1136b57c1a56SJohan Hedberg return NULL; 1137b57c1a56SJohan Hedberg } 1138b57c1a56SJohan Hedberg 1139561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1140561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1141561aafbcSJohan Hedberg { 114230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1143561aafbcSJohan Hedberg struct inquiry_entry *e; 1144561aafbcSJohan Hedberg 11456ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1146561aafbcSJohan Hedberg 1147561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1148561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1149561aafbcSJohan Hedberg return e; 1150561aafbcSJohan Hedberg } 1151561aafbcSJohan Hedberg 1152561aafbcSJohan Hedberg return NULL; 1153561aafbcSJohan Hedberg } 1154561aafbcSJohan Hedberg 115530dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 115630dc78e1SJohan Hedberg bdaddr_t *bdaddr, 115730dc78e1SJohan Hedberg int state) 115830dc78e1SJohan Hedberg { 115930dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 116030dc78e1SJohan Hedberg struct inquiry_entry *e; 116130dc78e1SJohan Hedberg 11626ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 116330dc78e1SJohan Hedberg 116430dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 116530dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 116630dc78e1SJohan Hedberg return e; 116730dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 116830dc78e1SJohan Hedberg return e; 116930dc78e1SJohan Hedberg } 117030dc78e1SJohan Hedberg 117130dc78e1SJohan Hedberg return NULL; 117230dc78e1SJohan Hedberg } 117330dc78e1SJohan Hedberg 1174a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1175a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1176a3d4e20aSJohan Hedberg { 1177a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1178a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1179a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1180a3d4e20aSJohan Hedberg 1181a3d4e20aSJohan Hedberg list_del(&ie->list); 1182a3d4e20aSJohan Hedberg 1183a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1184a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1185a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1186a3d4e20aSJohan Hedberg break; 1187a3d4e20aSJohan Hedberg pos = &p->list; 1188a3d4e20aSJohan Hedberg } 1189a3d4e20aSJohan Hedberg 1190a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1191a3d4e20aSJohan Hedberg } 1192a3d4e20aSJohan Hedberg 1193af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1194af58925cSMarcel Holtmann bool name_known) 11951da177e4SLinus Torvalds { 119630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 119770f23020SAndrei Emeltchenko struct inquiry_entry *ie; 1198af58925cSMarcel Holtmann u32 flags = 0; 11991da177e4SLinus Torvalds 12006ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 12011da177e4SLinus Torvalds 12026928a924SJohan Hedberg hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR); 12032b2fec4dSSzymon Janc 1204af58925cSMarcel Holtmann if (!data->ssp_mode) 1205af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1206388fc8faSJohan Hedberg 120770f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1208a3d4e20aSJohan Hedberg if (ie) { 1209af58925cSMarcel Holtmann if (!ie->data.ssp_mode) 1210af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1211388fc8faSJohan Hedberg 1212a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1213a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1214a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1215a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1216a3d4e20aSJohan Hedberg } 1217a3d4e20aSJohan Hedberg 1218561aafbcSJohan Hedberg goto update; 1219a3d4e20aSJohan Hedberg } 1220561aafbcSJohan Hedberg 12211da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 122227f70f3eSJohan Hedberg ie = kzalloc(sizeof(*ie), GFP_KERNEL); 1223af58925cSMarcel Holtmann if (!ie) { 1224af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 1225af58925cSMarcel Holtmann goto done; 1226af58925cSMarcel Holtmann } 122770f23020SAndrei Emeltchenko 1228561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1229561aafbcSJohan Hedberg 1230561aafbcSJohan Hedberg if (name_known) { 1231561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1232561aafbcSJohan Hedberg } else { 1233561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1234561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1235561aafbcSJohan Hedberg } 1236561aafbcSJohan Hedberg 1237561aafbcSJohan Hedberg update: 1238561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1239561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1240561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1241561aafbcSJohan Hedberg list_del(&ie->list); 12421da177e4SLinus Torvalds } 12431da177e4SLinus Torvalds 124470f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 124570f23020SAndrei Emeltchenko ie->timestamp = jiffies; 12461da177e4SLinus Torvalds cache->timestamp = jiffies; 12473175405bSJohan Hedberg 12483175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 1249af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 12503175405bSJohan Hedberg 1251af58925cSMarcel Holtmann done: 1252af58925cSMarcel Holtmann return flags; 12531da177e4SLinus Torvalds } 12541da177e4SLinus Torvalds 12551da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 12561da177e4SLinus Torvalds { 125730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 12581da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 12591da177e4SLinus Torvalds struct inquiry_entry *e; 12601da177e4SLinus Torvalds int copied = 0; 12611da177e4SLinus Torvalds 1262561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 12631da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1264b57c1a56SJohan Hedberg 1265b57c1a56SJohan Hedberg if (copied >= num) 1266b57c1a56SJohan Hedberg break; 1267b57c1a56SJohan Hedberg 12681da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 12691da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 12701da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 12711da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 12721da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 12731da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1274b57c1a56SJohan Hedberg 12751da177e4SLinus Torvalds info++; 1276b57c1a56SJohan Hedberg copied++; 12771da177e4SLinus Torvalds } 12781da177e4SLinus Torvalds 12791da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 12801da177e4SLinus Torvalds return copied; 12811da177e4SLinus Torvalds } 12821da177e4SLinus Torvalds 1283a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt) 12841da177e4SLinus Torvalds { 12851da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 128642c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 12871da177e4SLinus Torvalds struct hci_cp_inquiry cp; 12881da177e4SLinus Torvalds 12891da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 12901da177e4SLinus Torvalds 12911da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 1292a1d01db1SJohan Hedberg return 0; 12931da177e4SLinus Torvalds 12941da177e4SLinus Torvalds /* Start Inquiry */ 12951da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 12961da177e4SLinus Torvalds cp.length = ir->length; 12971da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 129842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 1299a1d01db1SJohan Hedberg 1300a1d01db1SJohan Hedberg return 0; 13011da177e4SLinus Torvalds } 13021da177e4SLinus Torvalds 13031da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 13041da177e4SLinus Torvalds { 13051da177e4SLinus Torvalds __u8 __user *ptr = arg; 13061da177e4SLinus Torvalds struct hci_inquiry_req ir; 13071da177e4SLinus Torvalds struct hci_dev *hdev; 13081da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 13091da177e4SLinus Torvalds long timeo; 13101da177e4SLinus Torvalds __u8 *buf; 13111da177e4SLinus Torvalds 13121da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 13131da177e4SLinus Torvalds return -EFAULT; 13141da177e4SLinus Torvalds 13155a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 13165a08ecceSAndrei Emeltchenko if (!hdev) 13171da177e4SLinus Torvalds return -ENODEV; 13181da177e4SLinus Torvalds 1319d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 13200736cfa8SMarcel Holtmann err = -EBUSY; 13210736cfa8SMarcel Holtmann goto done; 13220736cfa8SMarcel Holtmann } 13230736cfa8SMarcel Holtmann 1324d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1325fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1326fee746b0SMarcel Holtmann goto done; 1327fee746b0SMarcel Holtmann } 1328fee746b0SMarcel Holtmann 1329ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 13305b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 13315b69bef5SMarcel Holtmann goto done; 13325b69bef5SMarcel Holtmann } 13335b69bef5SMarcel Holtmann 1334d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 133556f87901SJohan Hedberg err = -EOPNOTSUPP; 133656f87901SJohan Hedberg goto done; 133756f87901SJohan Hedberg } 133856f87901SJohan Hedberg 133909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 13401da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1341a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 13421f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 13431da177e4SLinus Torvalds do_inquiry = 1; 13441da177e4SLinus Torvalds } 134509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13461da177e4SLinus Torvalds 134704837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 134870f23020SAndrei Emeltchenko 134970f23020SAndrei Emeltchenko if (do_inquiry) { 135001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 13514ebeee2dSJohan Hedberg timeo, NULL); 135270f23020SAndrei Emeltchenko if (err < 0) 13531da177e4SLinus Torvalds goto done; 13543e13fa1eSAndre Guedes 13553e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 13563e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 13573e13fa1eSAndre Guedes */ 135874316201SNeilBrown if (wait_on_bit(&hdev->flags, HCI_INQUIRY, 13593e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 13603e13fa1eSAndre Guedes return -EINTR; 136170f23020SAndrei Emeltchenko } 13621da177e4SLinus Torvalds 13638fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 13648fc9ced3SGustavo Padovan * 255 entries 13658fc9ced3SGustavo Padovan */ 13661da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 13671da177e4SLinus Torvalds 13681da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 13691da177e4SLinus Torvalds * copy it to the user space. 13701da177e4SLinus Torvalds */ 13716da2ec56SKees Cook buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL); 137270f23020SAndrei Emeltchenko if (!buf) { 13731da177e4SLinus Torvalds err = -ENOMEM; 13741da177e4SLinus Torvalds goto done; 13751da177e4SLinus Torvalds } 13761da177e4SLinus Torvalds 137709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 13781da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 137909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13801da177e4SLinus Torvalds 13811da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 13821da177e4SLinus Torvalds 13831da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 13841da177e4SLinus Torvalds ptr += sizeof(ir); 13851da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 13861da177e4SLinus Torvalds ir.num_rsp)) 13871da177e4SLinus Torvalds err = -EFAULT; 13881da177e4SLinus Torvalds } else 13891da177e4SLinus Torvalds err = -EFAULT; 13901da177e4SLinus Torvalds 13911da177e4SLinus Torvalds kfree(buf); 13921da177e4SLinus Torvalds 13931da177e4SLinus Torvalds done: 13941da177e4SLinus Torvalds hci_dev_put(hdev); 13951da177e4SLinus Torvalds return err; 13961da177e4SLinus Torvalds } 13971da177e4SLinus Torvalds 13987a0e5b15SMatthias Kaehlcke /** 13997a0e5b15SMatthias Kaehlcke * hci_dev_get_bd_addr_from_property - Get the Bluetooth Device Address 14007a0e5b15SMatthias Kaehlcke * (BD_ADDR) for a HCI device from 14017a0e5b15SMatthias Kaehlcke * a firmware node property. 14027a0e5b15SMatthias Kaehlcke * @hdev: The HCI device 14037a0e5b15SMatthias Kaehlcke * 14047a0e5b15SMatthias Kaehlcke * Search the firmware node for 'local-bd-address'. 14057a0e5b15SMatthias Kaehlcke * 14067a0e5b15SMatthias Kaehlcke * All-zero BD addresses are rejected, because those could be properties 14077a0e5b15SMatthias Kaehlcke * that exist in the firmware tables, but were not updated by the firmware. For 14087a0e5b15SMatthias Kaehlcke * example, the DTS could define 'local-bd-address', with zero BD addresses. 14097a0e5b15SMatthias Kaehlcke */ 14107a0e5b15SMatthias Kaehlcke static void hci_dev_get_bd_addr_from_property(struct hci_dev *hdev) 14117a0e5b15SMatthias Kaehlcke { 14127a0e5b15SMatthias Kaehlcke struct fwnode_handle *fwnode = dev_fwnode(hdev->dev.parent); 14137a0e5b15SMatthias Kaehlcke bdaddr_t ba; 14147a0e5b15SMatthias Kaehlcke int ret; 14157a0e5b15SMatthias Kaehlcke 14167a0e5b15SMatthias Kaehlcke ret = fwnode_property_read_u8_array(fwnode, "local-bd-address", 14177a0e5b15SMatthias Kaehlcke (u8 *)&ba, sizeof(ba)); 14187a0e5b15SMatthias Kaehlcke if (ret < 0 || !bacmp(&ba, BDADDR_ANY)) 14197a0e5b15SMatthias Kaehlcke return; 14207a0e5b15SMatthias Kaehlcke 14217a0e5b15SMatthias Kaehlcke bacpy(&hdev->public_addr, &ba); 14227a0e5b15SMatthias Kaehlcke } 14237a0e5b15SMatthias Kaehlcke 1424cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 14251da177e4SLinus Torvalds { 14261da177e4SLinus Torvalds int ret = 0; 14271da177e4SLinus Torvalds 14281da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 14291da177e4SLinus Torvalds 1430b504430cSJohan Hedberg hci_req_sync_lock(hdev); 14311da177e4SLinus Torvalds 1432d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) { 143394324962SJohan Hovold ret = -ENODEV; 143494324962SJohan Hovold goto done; 143594324962SJohan Hovold } 143694324962SJohan Hovold 1437d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 1438d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 1439a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1440a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1441bf543036SJohan Hedberg */ 1442d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED)) { 1443611b30f7SMarcel Holtmann ret = -ERFKILL; 1444611b30f7SMarcel Holtmann goto done; 1445611b30f7SMarcel Holtmann } 1446611b30f7SMarcel Holtmann 1447a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 1448a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 1449a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1450a5c8f270SMarcel Holtmann * or not. 1451a5c8f270SMarcel Holtmann * 1452c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 1453c6beca0eSMarcel Holtmann * if a public address or static random address is 1454c6beca0eSMarcel Holtmann * available. 1455c6beca0eSMarcel Holtmann * 1456a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1457a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1458a5c8f270SMarcel Holtmann */ 1459d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1460ca8bee5dSMarcel Holtmann hdev->dev_type == HCI_PRIMARY && 1461a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1462a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1463a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1464a5c8f270SMarcel Holtmann goto done; 1465a5c8f270SMarcel Holtmann } 1466a5c8f270SMarcel Holtmann } 1467a5c8f270SMarcel Holtmann 14681da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 14691da177e4SLinus Torvalds ret = -EALREADY; 14701da177e4SLinus Torvalds goto done; 14711da177e4SLinus Torvalds } 14721da177e4SLinus Torvalds 14731da177e4SLinus Torvalds if (hdev->open(hdev)) { 14741da177e4SLinus Torvalds ret = -EIO; 14751da177e4SLinus Torvalds goto done; 14761da177e4SLinus Torvalds } 14771da177e4SLinus Torvalds 1478e9ca8bf1SMarcel Holtmann set_bit(HCI_RUNNING, &hdev->flags); 147905fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_OPEN); 14804a3f95b7SMarcel Holtmann 14811da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 14821da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1483f41c70c4SMarcel Holtmann 1484740011cfSSean Wang if (hci_dev_test_flag(hdev, HCI_SETUP) || 1485740011cfSSean Wang test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) { 14867fdf6c6aSMarcel Holtmann bool invalid_bdaddr; 14877fdf6c6aSMarcel Holtmann 1488e131d74aSMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_SETUP); 1489e131d74aSMarcel Holtmann 1490af202f84SMarcel Holtmann if (hdev->setup) 1491f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1492f41c70c4SMarcel Holtmann 14937fdf6c6aSMarcel Holtmann /* The transport driver can set the quirk to mark the 14947fdf6c6aSMarcel Holtmann * BD_ADDR invalid before creating the HCI device or in 14957fdf6c6aSMarcel Holtmann * its setup callback. 14967fdf6c6aSMarcel Holtmann */ 14977fdf6c6aSMarcel Holtmann invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR, 14987fdf6c6aSMarcel Holtmann &hdev->quirks); 14997fdf6c6aSMarcel Holtmann 15007a0e5b15SMatthias Kaehlcke if (ret) 15017a0e5b15SMatthias Kaehlcke goto setup_failed; 15027a0e5b15SMatthias Kaehlcke 15037a0e5b15SMatthias Kaehlcke if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) { 15047a0e5b15SMatthias Kaehlcke if (!bacmp(&hdev->public_addr, BDADDR_ANY)) 15057a0e5b15SMatthias Kaehlcke hci_dev_get_bd_addr_from_property(hdev); 15067a0e5b15SMatthias Kaehlcke 15077a0e5b15SMatthias Kaehlcke if (bacmp(&hdev->public_addr, BDADDR_ANY) && 15087fdf6c6aSMarcel Holtmann hdev->set_bdaddr) { 15097a0e5b15SMatthias Kaehlcke ret = hdev->set_bdaddr(hdev, 15107a0e5b15SMatthias Kaehlcke &hdev->public_addr); 15117fdf6c6aSMarcel Holtmann 15127fdf6c6aSMarcel Holtmann /* If setting of the BD_ADDR from the device 15137fdf6c6aSMarcel Holtmann * property succeeds, then treat the address 15147fdf6c6aSMarcel Holtmann * as valid even if the invalid BD_ADDR 15157fdf6c6aSMarcel Holtmann * quirk indicates otherwise. 15167fdf6c6aSMarcel Holtmann */ 15177fdf6c6aSMarcel Holtmann if (!ret) 15187fdf6c6aSMarcel Holtmann invalid_bdaddr = false; 15197fdf6c6aSMarcel Holtmann } 15207a0e5b15SMatthias Kaehlcke } 15217a0e5b15SMatthias Kaehlcke 15227a0e5b15SMatthias Kaehlcke setup_failed: 1523af202f84SMarcel Holtmann /* The transport driver can set these quirks before 1524af202f84SMarcel Holtmann * creating the HCI device or in its setup callback. 1525af202f84SMarcel Holtmann * 15267fdf6c6aSMarcel Holtmann * For the invalid BD_ADDR quirk it is possible that 15277fdf6c6aSMarcel Holtmann * it becomes a valid address if the bootloader does 15287fdf6c6aSMarcel Holtmann * provide it (see above). 15297fdf6c6aSMarcel Holtmann * 1530af202f84SMarcel Holtmann * In case any of them is set, the controller has to 1531af202f84SMarcel Holtmann * start up as unconfigured. 1532af202f84SMarcel Holtmann */ 1533eb1904f4SMarcel Holtmann if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) || 15347fdf6c6aSMarcel Holtmann invalid_bdaddr) 1535a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 1536f41c70c4SMarcel Holtmann 15370ebca7d6SMarcel Holtmann /* For an unconfigured controller it is required to 15380ebca7d6SMarcel Holtmann * read at least the version information provided by 15390ebca7d6SMarcel Holtmann * the Read Local Version Information command. 15400ebca7d6SMarcel Holtmann * 15410ebca7d6SMarcel Holtmann * If the set_bdaddr driver callback is provided, then 15420ebca7d6SMarcel Holtmann * also the original Bluetooth public device address 15430ebca7d6SMarcel Holtmann * will be read using the Read BD Address command. 15440ebca7d6SMarcel Holtmann */ 1545d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 15460ebca7d6SMarcel Holtmann ret = __hci_unconf_init(hdev); 154789bc22d2SMarcel Holtmann } 154889bc22d2SMarcel Holtmann 1549d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_CONFIG)) { 15509713c17bSMarcel Holtmann /* If public address change is configured, ensure that 15519713c17bSMarcel Holtmann * the address gets programmed. If the driver does not 15529713c17bSMarcel Holtmann * support changing the public address, fail the power 15539713c17bSMarcel Holtmann * on procedure. 155424c457e2SMarcel Holtmann */ 15559713c17bSMarcel Holtmann if (bacmp(&hdev->public_addr, BDADDR_ANY) && 15569713c17bSMarcel Holtmann hdev->set_bdaddr) 155724c457e2SMarcel Holtmann ret = hdev->set_bdaddr(hdev, &hdev->public_addr); 155824c457e2SMarcel Holtmann else 155924c457e2SMarcel Holtmann ret = -EADDRNOTAVAIL; 156024c457e2SMarcel Holtmann } 156124c457e2SMarcel Holtmann 1562f41c70c4SMarcel Holtmann if (!ret) { 1563d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 156498a63aafSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 15652177bab5SJohan Hedberg ret = __hci_init(hdev); 156698a63aafSMarcel Holtmann if (!ret && hdev->post_init) 156798a63aafSMarcel Holtmann ret = hdev->post_init(hdev); 156898a63aafSMarcel Holtmann } 15691da177e4SLinus Torvalds } 15701da177e4SLinus Torvalds 15717e995b9eSMarcel Holtmann /* If the HCI Reset command is clearing all diagnostic settings, 15727e995b9eSMarcel Holtmann * then they need to be reprogrammed after the init procedure 15737e995b9eSMarcel Holtmann * completed. 15747e995b9eSMarcel Holtmann */ 15757e995b9eSMarcel Holtmann if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) && 1576b56c7b25SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 15777e995b9eSMarcel Holtmann hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag) 15787e995b9eSMarcel Holtmann ret = hdev->set_diag(hdev, true); 15797e995b9eSMarcel Holtmann 1580145373cbSMiao-chen Chou msft_do_open(hdev); 1581145373cbSMiao-chen Chou 1582f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1583f41c70c4SMarcel Holtmann 15841da177e4SLinus Torvalds if (!ret) { 15851da177e4SLinus Torvalds hci_dev_hold(hdev); 1586a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); 1587a73c046aSJaganath Kanakkassery hci_adv_instances_set_rpa_expired(hdev, true); 15881da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 158905fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UP); 15906d5d2ee6SHeiner Kallweit hci_leds_update_powered(hdev, true); 1591d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 1592d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG) && 1593d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 1594d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 15952ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 1596ca8bee5dSMarcel Holtmann hdev->dev_type == HCI_PRIMARY) { 15972ff13894SJohan Hedberg ret = __hci_req_hci_power_on(hdev); 15982ff13894SJohan Hedberg mgmt_power_on(hdev, ret); 159956e5cb86SJohan Hedberg } 16001da177e4SLinus Torvalds } else { 16011da177e4SLinus Torvalds /* Init failed, cleanup */ 16023eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1603c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 1604b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 16051da177e4SLinus Torvalds 16061da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 16071da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 16081da177e4SLinus Torvalds 16091da177e4SLinus Torvalds if (hdev->flush) 16101da177e4SLinus Torvalds hdev->flush(hdev); 16111da177e4SLinus Torvalds 16121da177e4SLinus Torvalds if (hdev->sent_cmd) { 16131da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 16141da177e4SLinus Torvalds hdev->sent_cmd = NULL; 16151da177e4SLinus Torvalds } 16161da177e4SLinus Torvalds 1617e9ca8bf1SMarcel Holtmann clear_bit(HCI_RUNNING, &hdev->flags); 161805fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_CLOSE); 16194a3f95b7SMarcel Holtmann 16201da177e4SLinus Torvalds hdev->close(hdev); 1621fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 16221da177e4SLinus Torvalds } 16231da177e4SLinus Torvalds 16241da177e4SLinus Torvalds done: 1625b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 16261da177e4SLinus Torvalds return ret; 16271da177e4SLinus Torvalds } 16281da177e4SLinus Torvalds 1629cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 1630cbed0ca1SJohan Hedberg 1631cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 1632cbed0ca1SJohan Hedberg { 1633cbed0ca1SJohan Hedberg struct hci_dev *hdev; 1634cbed0ca1SJohan Hedberg int err; 1635cbed0ca1SJohan Hedberg 1636cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 1637cbed0ca1SJohan Hedberg if (!hdev) 1638cbed0ca1SJohan Hedberg return -ENODEV; 1639cbed0ca1SJohan Hedberg 16404a964404SMarcel Holtmann /* Devices that are marked as unconfigured can only be powered 1641fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices 1642fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is 1643fee746b0SMarcel Holtmann * possible. 1644fee746b0SMarcel Holtmann * 1645fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag 1646fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to 1647fee746b0SMarcel Holtmann * open the device. 1648fee746b0SMarcel Holtmann */ 1649d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 1650d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 1651fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1652fee746b0SMarcel Holtmann goto done; 1653fee746b0SMarcel Holtmann } 1654fee746b0SMarcel Holtmann 1655e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 1656e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 1657e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 1658e1d08f40SJohan Hedberg * completed. 1659e1d08f40SJohan Hedberg */ 1660a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 1661e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 1662e1d08f40SJohan Hedberg 1663a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 1664a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 1665a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 1666a5c8f270SMarcel Holtmann */ 1667e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 1668e1d08f40SJohan Hedberg 166912aa4f0aSMarcel Holtmann /* For controllers not using the management interface and that 1670b6ae8457SJohan Hedberg * are brought up using legacy ioctl, set the HCI_BONDABLE bit 167112aa4f0aSMarcel Holtmann * so that pairing works for them. Once the management interface 167212aa4f0aSMarcel Holtmann * is in use this bit will be cleared again and userspace has 167312aa4f0aSMarcel Holtmann * to explicitly enable it. 167412aa4f0aSMarcel Holtmann */ 1675d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1676d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_MGMT)) 1677a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BONDABLE); 167812aa4f0aSMarcel Holtmann 1679cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 1680cbed0ca1SJohan Hedberg 1681fee746b0SMarcel Holtmann done: 1682cbed0ca1SJohan Hedberg hci_dev_put(hdev); 1683cbed0ca1SJohan Hedberg return err; 1684cbed0ca1SJohan Hedberg } 1685cbed0ca1SJohan Hedberg 1686d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */ 1687d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev) 1688d7347f3cSJohan Hedberg { 1689d7347f3cSJohan Hedberg struct hci_conn_params *p; 1690d7347f3cSJohan Hedberg 1691f161dd41SJohan Hedberg list_for_each_entry(p, &hdev->le_conn_params, list) { 1692f161dd41SJohan Hedberg if (p->conn) { 1693f161dd41SJohan Hedberg hci_conn_drop(p->conn); 1694f8aaf9b6SJohan Hedberg hci_conn_put(p->conn); 1695f161dd41SJohan Hedberg p->conn = NULL; 1696f161dd41SJohan Hedberg } 1697d7347f3cSJohan Hedberg list_del_init(&p->action); 1698f161dd41SJohan Hedberg } 1699d7347f3cSJohan Hedberg 1700d7347f3cSJohan Hedberg BT_DBG("All LE pending actions cleared"); 1701d7347f3cSJohan Hedberg } 1702d7347f3cSJohan Hedberg 17036b3cc1dbSSimon Fels int hci_dev_do_close(struct hci_dev *hdev) 17041da177e4SLinus Torvalds { 1705acc649c6SMarcel Holtmann bool auto_off; 1706acc649c6SMarcel Holtmann 17071da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 17081da177e4SLinus Torvalds 1709d24d8144SGabriele Mazzotta if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && 1710867146a0SLoic Poulain !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1711d24d8144SGabriele Mazzotta test_bit(HCI_UP, &hdev->flags)) { 1712a44fecbdSTedd Ho-Jeong An /* Execute vendor specific shutdown routine */ 1713a44fecbdSTedd Ho-Jeong An if (hdev->shutdown) 1714a44fecbdSTedd Ho-Jeong An hdev->shutdown(hdev); 1715a44fecbdSTedd Ho-Jeong An } 1716a44fecbdSTedd Ho-Jeong An 171778c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 171878c04c0bSVinicius Costa Gomes 17197df0f73eSJohan Hedberg hci_request_cancel_all(hdev); 1720b504430cSJohan Hedberg hci_req_sync_lock(hdev); 17211da177e4SLinus Torvalds 17221da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 172365cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 1724b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 17251da177e4SLinus Torvalds return 0; 17261da177e4SLinus Torvalds } 17271da177e4SLinus Torvalds 17286d5d2ee6SHeiner Kallweit hci_leds_update_powered(hdev, false); 17296d5d2ee6SHeiner Kallweit 17303eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 17313eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1732b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 17331da177e4SLinus Torvalds 173416ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 173516ab91abSJohan Hedberg hdev->discov_timeout = 0; 1736a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_DISCOVERABLE); 1737a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 173816ab91abSJohan Hedberg } 173916ab91abSJohan Hedberg 1740a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE)) 17417d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 17427d78525dSJohan Hedberg 1743a73c046aSJaganath Kanakkassery if (hci_dev_test_flag(hdev, HCI_MGMT)) { 1744a73c046aSJaganath Kanakkassery struct adv_info *adv_instance; 1745a73c046aSJaganath Kanakkassery 1746d6bfd59cSJohan Hedberg cancel_delayed_work_sync(&hdev->rpa_expired); 17477ba8b4beSAndre Guedes 1748a73c046aSJaganath Kanakkassery list_for_each_entry(adv_instance, &hdev->adv_instances, list) 1749a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 1750a73c046aSJaganath Kanakkassery } 1751a73c046aSJaganath Kanakkassery 175276727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 175376727c02SJohan Hedberg * ensuring the workqueue is empty up front. 175476727c02SJohan Hedberg */ 175576727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 175676727c02SJohan Hedberg 175709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 17581aeb9c65SJohan Hedberg 17598f502f84SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 17608f502f84SJohan Hedberg 1761acc649c6SMarcel Holtmann auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF); 1762acc649c6SMarcel Holtmann 1763ca8bee5dSMarcel Holtmann if (!auto_off && hdev->dev_type == HCI_PRIMARY && 1764baab7932SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 17652ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT)) 17662ff13894SJohan Hedberg __mgmt_power_off(hdev); 17671aeb9c65SJohan Hedberg 17681f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 1769d7347f3cSJohan Hedberg hci_pend_le_actions_clear(hdev); 1770f161dd41SJohan Hedberg hci_conn_hash_flush(hdev); 177109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 17721da177e4SLinus Torvalds 177364dae967SMarcel Holtmann smp_unregister(hdev); 177464dae967SMarcel Holtmann 177505fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_DOWN); 17761da177e4SLinus Torvalds 1777145373cbSMiao-chen Chou msft_do_close(hdev); 1778145373cbSMiao-chen Chou 17791da177e4SLinus Torvalds if (hdev->flush) 17801da177e4SLinus Torvalds hdev->flush(hdev); 17811da177e4SLinus Torvalds 17821da177e4SLinus Torvalds /* Reset device */ 17831da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 17841da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 1785acc649c6SMarcel Holtmann if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) && 1786acc649c6SMarcel Holtmann !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 17871da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 17884ebeee2dSJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL); 17891da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 17901da177e4SLinus Torvalds } 17911da177e4SLinus Torvalds 1792c347b765SGustavo F. Padovan /* flush cmd work */ 1793c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 17941da177e4SLinus Torvalds 17951da177e4SLinus Torvalds /* Drop queues */ 17961da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 17971da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 17981da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 17991da177e4SLinus Torvalds 18001da177e4SLinus Torvalds /* Drop last sent command */ 18011da177e4SLinus Torvalds if (hdev->sent_cmd) { 180265cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 18031da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 18041da177e4SLinus Torvalds hdev->sent_cmd = NULL; 18051da177e4SLinus Torvalds } 18061da177e4SLinus Torvalds 1807e9ca8bf1SMarcel Holtmann clear_bit(HCI_RUNNING, &hdev->flags); 180805fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_CLOSE); 18094a3f95b7SMarcel Holtmann 18109952d90eSAbhishek Pandit-Subedi if (test_and_clear_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks)) 18119952d90eSAbhishek Pandit-Subedi wake_up(&hdev->suspend_wait_q); 18129952d90eSAbhishek Pandit-Subedi 18131da177e4SLinus Torvalds /* After this point our queues are empty 18141da177e4SLinus Torvalds * and no tasks are scheduled. */ 18151da177e4SLinus Torvalds hdev->close(hdev); 18161da177e4SLinus Torvalds 181735b973c9SJohan Hedberg /* Clear flags */ 1818fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 1819eacb44dfSMarcel Holtmann hci_dev_clear_volatile_flags(hdev); 182035b973c9SJohan Hedberg 1821ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 1822536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 1823ced5c338SAndrei Emeltchenko 1824e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 182509b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 18267a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, BDADDR_ANY); 1827e59fda8dSJohan Hedberg 1828b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 18291da177e4SLinus Torvalds 18301da177e4SLinus Torvalds hci_dev_put(hdev); 18311da177e4SLinus Torvalds return 0; 18321da177e4SLinus Torvalds } 18331da177e4SLinus Torvalds 18341da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 18351da177e4SLinus Torvalds { 18361da177e4SLinus Torvalds struct hci_dev *hdev; 18371da177e4SLinus Torvalds int err; 18381da177e4SLinus Torvalds 183970f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 184070f23020SAndrei Emeltchenko if (!hdev) 18411da177e4SLinus Torvalds return -ENODEV; 18428ee56540SMarcel Holtmann 1843d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 18440736cfa8SMarcel Holtmann err = -EBUSY; 18450736cfa8SMarcel Holtmann goto done; 18460736cfa8SMarcel Holtmann } 18470736cfa8SMarcel Holtmann 1848a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 18498ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 18508ee56540SMarcel Holtmann 18511da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 18528ee56540SMarcel Holtmann 18530736cfa8SMarcel Holtmann done: 18541da177e4SLinus Torvalds hci_dev_put(hdev); 18551da177e4SLinus Torvalds return err; 18561da177e4SLinus Torvalds } 18571da177e4SLinus Torvalds 18585c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev) 18591da177e4SLinus Torvalds { 18605c912495SMarcel Holtmann int ret; 18611da177e4SLinus Torvalds 18625c912495SMarcel Holtmann BT_DBG("%s %p", hdev->name, hdev); 18631da177e4SLinus Torvalds 1864b504430cSJohan Hedberg hci_req_sync_lock(hdev); 18651da177e4SLinus Torvalds 18661da177e4SLinus Torvalds /* Drop queues */ 18671da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 18681da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 18691da177e4SLinus Torvalds 187076727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 187176727c02SJohan Hedberg * ensuring the workqueue is empty up front. 187276727c02SJohan Hedberg */ 187376727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 187476727c02SJohan Hedberg 187509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 18761f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 18771da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 187809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18791da177e4SLinus Torvalds 18801da177e4SLinus Torvalds if (hdev->flush) 18811da177e4SLinus Torvalds hdev->flush(hdev); 18821da177e4SLinus Torvalds 18831da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 18846ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 18851da177e4SLinus Torvalds 18864ebeee2dSJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT, NULL); 18871da177e4SLinus Torvalds 1888b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 18891da177e4SLinus Torvalds return ret; 18901da177e4SLinus Torvalds } 18911da177e4SLinus Torvalds 18925c912495SMarcel Holtmann int hci_dev_reset(__u16 dev) 18935c912495SMarcel Holtmann { 18945c912495SMarcel Holtmann struct hci_dev *hdev; 18955c912495SMarcel Holtmann int err; 18965c912495SMarcel Holtmann 18975c912495SMarcel Holtmann hdev = hci_dev_get(dev); 18985c912495SMarcel Holtmann if (!hdev) 18995c912495SMarcel Holtmann return -ENODEV; 19005c912495SMarcel Holtmann 19015c912495SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 19025c912495SMarcel Holtmann err = -ENETDOWN; 19035c912495SMarcel Holtmann goto done; 19045c912495SMarcel Holtmann } 19055c912495SMarcel Holtmann 1906d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 19075c912495SMarcel Holtmann err = -EBUSY; 19085c912495SMarcel Holtmann goto done; 19095c912495SMarcel Holtmann } 19105c912495SMarcel Holtmann 1911d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 19125c912495SMarcel Holtmann err = -EOPNOTSUPP; 19135c912495SMarcel Holtmann goto done; 19145c912495SMarcel Holtmann } 19155c912495SMarcel Holtmann 19165c912495SMarcel Holtmann err = hci_dev_do_reset(hdev); 19175c912495SMarcel Holtmann 19185c912495SMarcel Holtmann done: 19195c912495SMarcel Holtmann hci_dev_put(hdev); 19205c912495SMarcel Holtmann return err; 19215c912495SMarcel Holtmann } 19225c912495SMarcel Holtmann 19231da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 19241da177e4SLinus Torvalds { 19251da177e4SLinus Torvalds struct hci_dev *hdev; 19261da177e4SLinus Torvalds int ret = 0; 19271da177e4SLinus Torvalds 192870f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 192970f23020SAndrei Emeltchenko if (!hdev) 19301da177e4SLinus Torvalds return -ENODEV; 19311da177e4SLinus Torvalds 1932d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 19330736cfa8SMarcel Holtmann ret = -EBUSY; 19340736cfa8SMarcel Holtmann goto done; 19350736cfa8SMarcel Holtmann } 19360736cfa8SMarcel Holtmann 1937d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1938fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 1939fee746b0SMarcel Holtmann goto done; 1940fee746b0SMarcel Holtmann } 1941fee746b0SMarcel Holtmann 19421da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 19431da177e4SLinus Torvalds 19440736cfa8SMarcel Holtmann done: 19451da177e4SLinus Torvalds hci_dev_put(hdev); 19461da177e4SLinus Torvalds return ret; 19471da177e4SLinus Torvalds } 19481da177e4SLinus Torvalds 1949123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan) 1950123abc08SJohan Hedberg { 1951bc6d2d04SJohan Hedberg bool conn_changed, discov_changed; 1952123abc08SJohan Hedberg 1953123abc08SJohan Hedberg BT_DBG("%s scan 0x%02x", hdev->name, scan); 1954123abc08SJohan Hedberg 1955123abc08SJohan Hedberg if ((scan & SCAN_PAGE)) 1956238be788SMarcel Holtmann conn_changed = !hci_dev_test_and_set_flag(hdev, 1957238be788SMarcel Holtmann HCI_CONNECTABLE); 1958123abc08SJohan Hedberg else 1959a69d8927SMarcel Holtmann conn_changed = hci_dev_test_and_clear_flag(hdev, 1960a69d8927SMarcel Holtmann HCI_CONNECTABLE); 1961123abc08SJohan Hedberg 1962bc6d2d04SJohan Hedberg if ((scan & SCAN_INQUIRY)) { 1963238be788SMarcel Holtmann discov_changed = !hci_dev_test_and_set_flag(hdev, 1964238be788SMarcel Holtmann HCI_DISCOVERABLE); 1965bc6d2d04SJohan Hedberg } else { 1966a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 1967a69d8927SMarcel Holtmann discov_changed = hci_dev_test_and_clear_flag(hdev, 1968a69d8927SMarcel Holtmann HCI_DISCOVERABLE); 1969bc6d2d04SJohan Hedberg } 1970bc6d2d04SJohan Hedberg 1971d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 1972123abc08SJohan Hedberg return; 1973123abc08SJohan Hedberg 1974bc6d2d04SJohan Hedberg if (conn_changed || discov_changed) { 1975bc6d2d04SJohan Hedberg /* In case this was disabled through mgmt */ 1976a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 1977bc6d2d04SJohan Hedberg 1978d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 1979cab054abSJohan Hedberg hci_req_update_adv_data(hdev, hdev->cur_adv_instance); 1980bc6d2d04SJohan Hedberg 1981123abc08SJohan Hedberg mgmt_new_settings(hdev); 1982123abc08SJohan Hedberg } 1983bc6d2d04SJohan Hedberg } 1984123abc08SJohan Hedberg 19851da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 19861da177e4SLinus Torvalds { 19871da177e4SLinus Torvalds struct hci_dev *hdev; 19881da177e4SLinus Torvalds struct hci_dev_req dr; 19891da177e4SLinus Torvalds int err = 0; 19901da177e4SLinus Torvalds 19911da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 19921da177e4SLinus Torvalds return -EFAULT; 19931da177e4SLinus Torvalds 199470f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 199570f23020SAndrei Emeltchenko if (!hdev) 19961da177e4SLinus Torvalds return -ENODEV; 19971da177e4SLinus Torvalds 1998d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 19990736cfa8SMarcel Holtmann err = -EBUSY; 20000736cfa8SMarcel Holtmann goto done; 20010736cfa8SMarcel Holtmann } 20020736cfa8SMarcel Holtmann 2003d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 2004fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2005fee746b0SMarcel Holtmann goto done; 2006fee746b0SMarcel Holtmann } 2007fee746b0SMarcel Holtmann 2008ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 20095b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 20105b69bef5SMarcel Holtmann goto done; 20115b69bef5SMarcel Holtmann } 20125b69bef5SMarcel Holtmann 2013d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 201456f87901SJohan Hedberg err = -EOPNOTSUPP; 201556f87901SJohan Hedberg goto done; 201656f87901SJohan Hedberg } 201756f87901SJohan Hedberg 20181da177e4SLinus Torvalds switch (cmd) { 20191da177e4SLinus Torvalds case HCISETAUTH: 202001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 20214ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20221da177e4SLinus Torvalds break; 20231da177e4SLinus Torvalds 20241da177e4SLinus Torvalds case HCISETENCRYPT: 20251da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 20261da177e4SLinus Torvalds err = -EOPNOTSUPP; 20271da177e4SLinus Torvalds break; 20281da177e4SLinus Torvalds } 20291da177e4SLinus Torvalds 20301da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 20311da177e4SLinus Torvalds /* Auth must be enabled first */ 203201178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 20334ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20341da177e4SLinus Torvalds if (err) 20351da177e4SLinus Torvalds break; 20361da177e4SLinus Torvalds } 20371da177e4SLinus Torvalds 203801178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 20394ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20401da177e4SLinus Torvalds break; 20411da177e4SLinus Torvalds 20421da177e4SLinus Torvalds case HCISETSCAN: 204301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 20444ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 204591a668b0SJohan Hedberg 2046bc6d2d04SJohan Hedberg /* Ensure that the connectable and discoverable states 2047bc6d2d04SJohan Hedberg * get correctly modified as this was a non-mgmt change. 204891a668b0SJohan Hedberg */ 2049123abc08SJohan Hedberg if (!err) 2050123abc08SJohan Hedberg hci_update_scan_state(hdev, dr.dev_opt); 20511da177e4SLinus Torvalds break; 20521da177e4SLinus Torvalds 20531da177e4SLinus Torvalds case HCISETLINKPOL: 205401178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 20554ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20561da177e4SLinus Torvalds break; 20571da177e4SLinus Torvalds 20581da177e4SLinus Torvalds case HCISETLINKMODE: 2059e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2060e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2061e4e8e37cSMarcel Holtmann break; 2062e4e8e37cSMarcel Holtmann 2063e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2064b7c23df8SJaganath Kanakkassery if (hdev->pkt_type == (__u16) dr.dev_opt) 2065b7c23df8SJaganath Kanakkassery break; 2066b7c23df8SJaganath Kanakkassery 2067e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 2068b7c23df8SJaganath Kanakkassery mgmt_phy_configuration_changed(hdev, NULL); 20691da177e4SLinus Torvalds break; 20701da177e4SLinus Torvalds 20711da177e4SLinus Torvalds case HCISETACLMTU: 20721da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 20731da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 20741da177e4SLinus Torvalds break; 20751da177e4SLinus Torvalds 20761da177e4SLinus Torvalds case HCISETSCOMTU: 20771da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 20781da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 20791da177e4SLinus Torvalds break; 20801da177e4SLinus Torvalds 20811da177e4SLinus Torvalds default: 20821da177e4SLinus Torvalds err = -EINVAL; 20831da177e4SLinus Torvalds break; 20841da177e4SLinus Torvalds } 2085e4e8e37cSMarcel Holtmann 20860736cfa8SMarcel Holtmann done: 20871da177e4SLinus Torvalds hci_dev_put(hdev); 20881da177e4SLinus Torvalds return err; 20891da177e4SLinus Torvalds } 20901da177e4SLinus Torvalds 20911da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 20921da177e4SLinus Torvalds { 20938035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 20941da177e4SLinus Torvalds struct hci_dev_list_req *dl; 20951da177e4SLinus Torvalds struct hci_dev_req *dr; 20961da177e4SLinus Torvalds int n = 0, size, err; 20971da177e4SLinus Torvalds __u16 dev_num; 20981da177e4SLinus Torvalds 20991da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 21001da177e4SLinus Torvalds return -EFAULT; 21011da177e4SLinus Torvalds 21021da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 21031da177e4SLinus Torvalds return -EINVAL; 21041da177e4SLinus Torvalds 21051da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 21061da177e4SLinus Torvalds 210770f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 210870f23020SAndrei Emeltchenko if (!dl) 21091da177e4SLinus Torvalds return -ENOMEM; 21101da177e4SLinus Torvalds 21111da177e4SLinus Torvalds dr = dl->dev_req; 21121da177e4SLinus Torvalds 2113f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 21148035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 21152e84d8dbSMarcel Holtmann unsigned long flags = hdev->flags; 2116c542a06cSJohan Hedberg 21172e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 21182e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 21192e84d8dbSMarcel Holtmann * device is actually down. 21202e84d8dbSMarcel Holtmann */ 2121d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 21222e84d8dbSMarcel Holtmann flags &= ~BIT(HCI_UP); 2123c542a06cSJohan Hedberg 21241da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 21252e84d8dbSMarcel Holtmann (dr + n)->dev_opt = flags; 2126c542a06cSJohan Hedberg 21271da177e4SLinus Torvalds if (++n >= dev_num) 21281da177e4SLinus Torvalds break; 21291da177e4SLinus Torvalds } 2130f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 21311da177e4SLinus Torvalds 21321da177e4SLinus Torvalds dl->dev_num = n; 21331da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 21341da177e4SLinus Torvalds 21351da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 21361da177e4SLinus Torvalds kfree(dl); 21371da177e4SLinus Torvalds 21381da177e4SLinus Torvalds return err ? -EFAULT : 0; 21391da177e4SLinus Torvalds } 21401da177e4SLinus Torvalds 21411da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 21421da177e4SLinus Torvalds { 21431da177e4SLinus Torvalds struct hci_dev *hdev; 21441da177e4SLinus Torvalds struct hci_dev_info di; 21452e84d8dbSMarcel Holtmann unsigned long flags; 21461da177e4SLinus Torvalds int err = 0; 21471da177e4SLinus Torvalds 21481da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 21491da177e4SLinus Torvalds return -EFAULT; 21501da177e4SLinus Torvalds 215170f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 215270f23020SAndrei Emeltchenko if (!hdev) 21531da177e4SLinus Torvalds return -ENODEV; 21541da177e4SLinus Torvalds 21552e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 21562e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 21572e84d8dbSMarcel Holtmann * device is actually down. 21582e84d8dbSMarcel Holtmann */ 2159d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 21602e84d8dbSMarcel Holtmann flags = hdev->flags & ~BIT(HCI_UP); 21612e84d8dbSMarcel Holtmann else 21622e84d8dbSMarcel Holtmann flags = hdev->flags; 2163c542a06cSJohan Hedberg 21641da177e4SLinus Torvalds strcpy(di.name, hdev->name); 21651da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 216660f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 21672e84d8dbSMarcel Holtmann di.flags = flags; 21681da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2169572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 21701da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 21711da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 21721da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 21731da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2174572c7f84SJohan Hedberg } else { 2175572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2176572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2177572c7f84SJohan Hedberg di.sco_mtu = 0; 2178572c7f84SJohan Hedberg di.sco_pkts = 0; 2179572c7f84SJohan Hedberg } 21801da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 21811da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 21821da177e4SLinus Torvalds 21831da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 21841da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 21851da177e4SLinus Torvalds 21861da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 21871da177e4SLinus Torvalds err = -EFAULT; 21881da177e4SLinus Torvalds 21891da177e4SLinus Torvalds hci_dev_put(hdev); 21901da177e4SLinus Torvalds 21911da177e4SLinus Torvalds return err; 21921da177e4SLinus Torvalds } 21931da177e4SLinus Torvalds 21941da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 21951da177e4SLinus Torvalds 2196611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2197611b30f7SMarcel Holtmann { 2198611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2199611b30f7SMarcel Holtmann 2200611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2201611b30f7SMarcel Holtmann 2202d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) 22030736cfa8SMarcel Holtmann return -EBUSY; 22040736cfa8SMarcel Holtmann 22055e130367SJohan Hedberg if (blocked) { 2206a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 2207d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 2208d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 2209611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 22105e130367SJohan Hedberg } else { 2211a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_RFKILLED); 22125e130367SJohan Hedberg } 2213611b30f7SMarcel Holtmann 2214611b30f7SMarcel Holtmann return 0; 2215611b30f7SMarcel Holtmann } 2216611b30f7SMarcel Holtmann 2217611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2218611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2219611b30f7SMarcel Holtmann }; 2220611b30f7SMarcel Holtmann 2221ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2222ab81cbf9SJohan Hedberg { 2223ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 222496570ffcSJohan Hedberg int err; 2225ab81cbf9SJohan Hedberg 2226ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2227ab81cbf9SJohan Hedberg 22282ff13894SJohan Hedberg if (test_bit(HCI_UP, &hdev->flags) && 22292ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 22302ff13894SJohan Hedberg hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) { 2231d82142a8SWei-Ning Huang cancel_delayed_work(&hdev->power_off); 22322ff13894SJohan Hedberg hci_req_sync_lock(hdev); 22332ff13894SJohan Hedberg err = __hci_req_hci_power_on(hdev); 22342ff13894SJohan Hedberg hci_req_sync_unlock(hdev); 22352ff13894SJohan Hedberg mgmt_power_on(hdev, err); 22362ff13894SJohan Hedberg return; 22372ff13894SJohan Hedberg } 22382ff13894SJohan Hedberg 2239cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 224096570ffcSJohan Hedberg if (err < 0) { 22413ad67582SJaganath Kanakkassery hci_dev_lock(hdev); 224296570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 22433ad67582SJaganath Kanakkassery hci_dev_unlock(hdev); 2244ab81cbf9SJohan Hedberg return; 224596570ffcSJohan Hedberg } 2246ab81cbf9SJohan Hedberg 2247a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2248a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2249a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2250a5c8f270SMarcel Holtmann */ 2251d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED) || 2252d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_UNCONFIGURED) || 2253ca8bee5dSMarcel Holtmann (hdev->dev_type == HCI_PRIMARY && 2254a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2255a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2256a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_AUTO_OFF); 2257bf543036SJohan Hedberg hci_dev_do_close(hdev); 2258d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) { 225919202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 226019202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2261bf543036SJohan Hedberg } 2262ab81cbf9SJohan Hedberg 2263a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) { 22644a964404SMarcel Holtmann /* For unconfigured devices, set the HCI_RAW flag 22654a964404SMarcel Holtmann * so that userspace can easily identify them. 22664a964404SMarcel Holtmann */ 2267d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 22684a964404SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 22690602a8adSMarcel Holtmann 22700602a8adSMarcel Holtmann /* For fully configured devices, this will send 22710602a8adSMarcel Holtmann * the Index Added event. For unconfigured devices, 22720602a8adSMarcel Holtmann * it will send Unconfigued Index Added event. 22730602a8adSMarcel Holtmann * 22740602a8adSMarcel Holtmann * Devices with HCI_QUIRK_RAW_DEVICE are ignored 22750602a8adSMarcel Holtmann * and no event will be send. 22760602a8adSMarcel Holtmann */ 2277744cf19eSJohan Hedberg mgmt_index_added(hdev); 2278a69d8927SMarcel Holtmann } else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) { 22795ea234d3SMarcel Holtmann /* When the controller is now configured, then it 22805ea234d3SMarcel Holtmann * is important to clear the HCI_RAW flag. 22815ea234d3SMarcel Holtmann */ 2282d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 22835ea234d3SMarcel Holtmann clear_bit(HCI_RAW, &hdev->flags); 22845ea234d3SMarcel Holtmann 2285d603b76bSMarcel Holtmann /* Powering on the controller with HCI_CONFIG set only 2286d603b76bSMarcel Holtmann * happens with the transition from unconfigured to 2287d603b76bSMarcel Holtmann * configured. This will send the Index Added event. 2288d603b76bSMarcel Holtmann */ 2289d603b76bSMarcel Holtmann mgmt_index_added(hdev); 2290ab81cbf9SJohan Hedberg } 2291ab81cbf9SJohan Hedberg } 2292ab81cbf9SJohan Hedberg 2293ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2294ab81cbf9SJohan Hedberg { 22953243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 22963243553fSJohan Hedberg power_off.work); 2297ab81cbf9SJohan Hedberg 2298ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2299ab81cbf9SJohan Hedberg 23008ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2301ab81cbf9SJohan Hedberg } 2302ab81cbf9SJohan Hedberg 2303c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work) 2304c7741d16SMarcel Holtmann { 2305c7741d16SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset); 2306c7741d16SMarcel Holtmann 2307c7741d16SMarcel Holtmann BT_DBG("%s", hdev->name); 2308c7741d16SMarcel Holtmann 2309c7741d16SMarcel Holtmann if (hdev->hw_error) 2310c7741d16SMarcel Holtmann hdev->hw_error(hdev, hdev->hw_error_code); 2311c7741d16SMarcel Holtmann else 23122064ee33SMarcel Holtmann bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code); 2313c7741d16SMarcel Holtmann 2314c7741d16SMarcel Holtmann if (hci_dev_do_close(hdev)) 2315c7741d16SMarcel Holtmann return; 2316c7741d16SMarcel Holtmann 2317c7741d16SMarcel Holtmann hci_dev_do_open(hdev); 2318c7741d16SMarcel Holtmann } 2319c7741d16SMarcel Holtmann 232035f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 23212aeb9a1aSJohan Hedberg { 23224821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 23232aeb9a1aSJohan Hedberg 23244821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 23254821002cSJohan Hedberg list_del(&uuid->list); 23262aeb9a1aSJohan Hedberg kfree(uuid); 23272aeb9a1aSJohan Hedberg } 23282aeb9a1aSJohan Hedberg } 23292aeb9a1aSJohan Hedberg 233035f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 233155ed8ca1SJohan Hedberg { 233255ed8ca1SJohan Hedberg struct link_key *key; 233355ed8ca1SJohan Hedberg 2334d7d41682SMadhuparna Bhowmik list_for_each_entry(key, &hdev->link_keys, list) { 23350378b597SJohan Hedberg list_del_rcu(&key->list); 23360378b597SJohan Hedberg kfree_rcu(key, rcu); 233755ed8ca1SJohan Hedberg } 233855ed8ca1SJohan Hedberg } 233955ed8ca1SJohan Hedberg 234035f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2341b899efafSVinicius Costa Gomes { 2342970d0f1bSJohan Hedberg struct smp_ltk *k; 2343b899efafSVinicius Costa Gomes 2344d7d41682SMadhuparna Bhowmik list_for_each_entry(k, &hdev->long_term_keys, list) { 2345970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2346970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2347b899efafSVinicius Costa Gomes } 2348b899efafSVinicius Costa Gomes } 2349b899efafSVinicius Costa Gomes 2350970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2351970c4e46SJohan Hedberg { 2352adae20cbSJohan Hedberg struct smp_irk *k; 2353970c4e46SJohan Hedberg 2354d7d41682SMadhuparna Bhowmik list_for_each_entry(k, &hdev->identity_resolving_keys, list) { 2355adae20cbSJohan Hedberg list_del_rcu(&k->list); 2356adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2357970c4e46SJohan Hedberg } 2358970c4e46SJohan Hedberg } 2359970c4e46SJohan Hedberg 2360600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev) 2361600a8749SAlain Michaud { 2362600a8749SAlain Michaud struct blocked_key *b; 2363600a8749SAlain Michaud 2364d7d41682SMadhuparna Bhowmik list_for_each_entry(b, &hdev->blocked_keys, list) { 2365600a8749SAlain Michaud list_del_rcu(&b->list); 2366600a8749SAlain Michaud kfree_rcu(b, rcu); 2367600a8749SAlain Michaud } 2368600a8749SAlain Michaud } 2369600a8749SAlain Michaud 2370600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16]) 2371600a8749SAlain Michaud { 2372600a8749SAlain Michaud bool blocked = false; 2373600a8749SAlain Michaud struct blocked_key *b; 2374600a8749SAlain Michaud 2375600a8749SAlain Michaud rcu_read_lock(); 23760c2ac7d4SMadhuparna Bhowmik list_for_each_entry_rcu(b, &hdev->blocked_keys, list) { 2377600a8749SAlain Michaud if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) { 2378600a8749SAlain Michaud blocked = true; 2379600a8749SAlain Michaud break; 2380600a8749SAlain Michaud } 2381600a8749SAlain Michaud } 2382600a8749SAlain Michaud 2383600a8749SAlain Michaud rcu_read_unlock(); 2384600a8749SAlain Michaud return blocked; 2385600a8749SAlain Michaud } 2386600a8749SAlain Michaud 238755ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 238855ed8ca1SJohan Hedberg { 238955ed8ca1SJohan Hedberg struct link_key *k; 239055ed8ca1SJohan Hedberg 23910378b597SJohan Hedberg rcu_read_lock(); 23920378b597SJohan Hedberg list_for_each_entry_rcu(k, &hdev->link_keys, list) { 23930378b597SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) { 23940378b597SJohan Hedberg rcu_read_unlock(); 2395600a8749SAlain Michaud 2396600a8749SAlain Michaud if (hci_is_blocked_key(hdev, 2397600a8749SAlain Michaud HCI_BLOCKED_KEY_TYPE_LINKKEY, 2398600a8749SAlain Michaud k->val)) { 2399600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, 2400600a8749SAlain Michaud "Link key blocked for %pMR", 2401600a8749SAlain Michaud &k->bdaddr); 2402600a8749SAlain Michaud return NULL; 2403600a8749SAlain Michaud } 2404600a8749SAlain Michaud 240555ed8ca1SJohan Hedberg return k; 24060378b597SJohan Hedberg } 24070378b597SJohan Hedberg } 24080378b597SJohan Hedberg rcu_read_unlock(); 240955ed8ca1SJohan Hedberg 241055ed8ca1SJohan Hedberg return NULL; 241155ed8ca1SJohan Hedberg } 241255ed8ca1SJohan Hedberg 2413745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2414d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2415d25e28abSJohan Hedberg { 2416d25e28abSJohan Hedberg /* Legacy key */ 2417d25e28abSJohan Hedberg if (key_type < 0x03) 2418745c0ce3SVishal Agarwal return true; 2419d25e28abSJohan Hedberg 2420d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2421d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2422745c0ce3SVishal Agarwal return false; 2423d25e28abSJohan Hedberg 2424d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2425d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2426745c0ce3SVishal Agarwal return false; 2427d25e28abSJohan Hedberg 2428d25e28abSJohan Hedberg /* Security mode 3 case */ 2429d25e28abSJohan Hedberg if (!conn) 2430745c0ce3SVishal Agarwal return true; 2431d25e28abSJohan Hedberg 2432e3befab9SJohan Hedberg /* BR/EDR key derived using SC from an LE link */ 2433e3befab9SJohan Hedberg if (conn->type == LE_LINK) 2434e3befab9SJohan Hedberg return true; 2435e3befab9SJohan Hedberg 2436d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2437d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2438745c0ce3SVishal Agarwal return true; 2439d25e28abSJohan Hedberg 2440d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2441d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2442745c0ce3SVishal Agarwal return true; 2443d25e28abSJohan Hedberg 2444d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2445d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2446745c0ce3SVishal Agarwal return true; 2447d25e28abSJohan Hedberg 2448d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2449d25e28abSJohan Hedberg * persistently */ 2450745c0ce3SVishal Agarwal return false; 2451d25e28abSJohan Hedberg } 2452d25e28abSJohan Hedberg 2453e804d25dSJohan Hedberg static u8 ltk_role(u8 type) 245498a0b845SJohan Hedberg { 2455e804d25dSJohan Hedberg if (type == SMP_LTK) 2456e804d25dSJohan Hedberg return HCI_ROLE_MASTER; 245798a0b845SJohan Hedberg 2458e804d25dSJohan Hedberg return HCI_ROLE_SLAVE; 245998a0b845SJohan Hedberg } 246098a0b845SJohan Hedberg 2461f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2462e804d25dSJohan Hedberg u8 addr_type, u8 role) 246375d262c2SVinicius Costa Gomes { 2464c9839a11SVinicius Costa Gomes struct smp_ltk *k; 246575d262c2SVinicius Costa Gomes 2466970d0f1bSJohan Hedberg rcu_read_lock(); 2467970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 24685378bc56SJohan Hedberg if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr)) 24695378bc56SJohan Hedberg continue; 24705378bc56SJohan Hedberg 2471923e2414SJohan Hedberg if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) { 2472970d0f1bSJohan Hedberg rcu_read_unlock(); 2473600a8749SAlain Michaud 2474600a8749SAlain Michaud if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK, 2475600a8749SAlain Michaud k->val)) { 2476600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, 2477600a8749SAlain Michaud "LTK blocked for %pMR", 2478600a8749SAlain Michaud &k->bdaddr); 2479600a8749SAlain Michaud return NULL; 2480600a8749SAlain Michaud } 2481600a8749SAlain Michaud 248275d262c2SVinicius Costa Gomes return k; 2483970d0f1bSJohan Hedberg } 2484970d0f1bSJohan Hedberg } 2485970d0f1bSJohan Hedberg rcu_read_unlock(); 248675d262c2SVinicius Costa Gomes 248775d262c2SVinicius Costa Gomes return NULL; 248875d262c2SVinicius Costa Gomes } 248975d262c2SVinicius Costa Gomes 2490970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 2491970c4e46SJohan Hedberg { 2492600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL; 2493970c4e46SJohan Hedberg struct smp_irk *irk; 2494970c4e46SJohan Hedberg 2495adae20cbSJohan Hedberg rcu_read_lock(); 2496adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2497adae20cbSJohan Hedberg if (!bacmp(&irk->rpa, rpa)) { 2498600a8749SAlain Michaud irk_to_return = irk; 2499600a8749SAlain Michaud goto done; 2500970c4e46SJohan Hedberg } 2501adae20cbSJohan Hedberg } 2502970c4e46SJohan Hedberg 2503adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2504defce9e8SJohan Hedberg if (smp_irk_matches(hdev, irk->val, rpa)) { 2505970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2506600a8749SAlain Michaud irk_to_return = irk; 2507600a8749SAlain Michaud goto done; 2508970c4e46SJohan Hedberg } 2509970c4e46SJohan Hedberg } 2510600a8749SAlain Michaud 2511600a8749SAlain Michaud done: 2512600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK, 2513600a8749SAlain Michaud irk_to_return->val)) { 2514600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR", 2515600a8749SAlain Michaud &irk_to_return->bdaddr); 2516600a8749SAlain Michaud irk_to_return = NULL; 2517600a8749SAlain Michaud } 2518600a8749SAlain Michaud 2519adae20cbSJohan Hedberg rcu_read_unlock(); 2520970c4e46SJohan Hedberg 2521600a8749SAlain Michaud return irk_to_return; 2522970c4e46SJohan Hedberg } 2523970c4e46SJohan Hedberg 2524970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2525970c4e46SJohan Hedberg u8 addr_type) 2526970c4e46SJohan Hedberg { 2527600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL; 2528970c4e46SJohan Hedberg struct smp_irk *irk; 2529970c4e46SJohan Hedberg 25306cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 25316cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 25326cfc9988SJohan Hedberg return NULL; 25336cfc9988SJohan Hedberg 2534adae20cbSJohan Hedberg rcu_read_lock(); 2535adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2536970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 2537adae20cbSJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) { 2538600a8749SAlain Michaud irk_to_return = irk; 2539600a8749SAlain Michaud goto done; 2540970c4e46SJohan Hedberg } 2541adae20cbSJohan Hedberg } 2542600a8749SAlain Michaud 2543600a8749SAlain Michaud done: 2544600a8749SAlain Michaud 2545600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK, 2546600a8749SAlain Michaud irk_to_return->val)) { 2547600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR", 2548600a8749SAlain Michaud &irk_to_return->bdaddr); 2549600a8749SAlain Michaud irk_to_return = NULL; 2550600a8749SAlain Michaud } 2551600a8749SAlain Michaud 2552adae20cbSJohan Hedberg rcu_read_unlock(); 2553970c4e46SJohan Hedberg 2554600a8749SAlain Michaud return irk_to_return; 2555970c4e46SJohan Hedberg } 2556970c4e46SJohan Hedberg 2557567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 25587652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 25597652ff6aSJohan Hedberg u8 pin_len, bool *persistent) 256055ed8ca1SJohan Hedberg { 256155ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2562745c0ce3SVishal Agarwal u8 old_key_type; 256355ed8ca1SJohan Hedberg 256455ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 256555ed8ca1SJohan Hedberg if (old_key) { 256655ed8ca1SJohan Hedberg old_key_type = old_key->type; 256755ed8ca1SJohan Hedberg key = old_key; 256855ed8ca1SJohan Hedberg } else { 256912adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 25700a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 257155ed8ca1SJohan Hedberg if (!key) 2572567fa2aaSJohan Hedberg return NULL; 25730378b597SJohan Hedberg list_add_rcu(&key->list, &hdev->link_keys); 257455ed8ca1SJohan Hedberg } 257555ed8ca1SJohan Hedberg 25766ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 257755ed8ca1SJohan Hedberg 2578d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2579d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2580d25e28abSJohan Hedberg * previous key */ 2581d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2582a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2583d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2584655fe6ecSJohan Hedberg if (conn) 2585655fe6ecSJohan Hedberg conn->key_type = type; 2586655fe6ecSJohan Hedberg } 2587d25e28abSJohan Hedberg 258855ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 25899b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 259055ed8ca1SJohan Hedberg key->pin_len = pin_len; 259155ed8ca1SJohan Hedberg 2592b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 259355ed8ca1SJohan Hedberg key->type = old_key_type; 25944748fed2SJohan Hedberg else 25954748fed2SJohan Hedberg key->type = type; 25964748fed2SJohan Hedberg 25977652ff6aSJohan Hedberg if (persistent) 25987652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type, 25997652ff6aSJohan Hedberg old_key_type); 26004df378a1SJohan Hedberg 2601567fa2aaSJohan Hedberg return key; 260255ed8ca1SJohan Hedberg } 260355ed8ca1SJohan Hedberg 2604ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 260535d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 2606fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand) 260775d262c2SVinicius Costa Gomes { 2608c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 2609e804d25dSJohan Hedberg u8 role = ltk_role(type); 261075d262c2SVinicius Costa Gomes 2611f3a73d97SJohan Hedberg old_key = hci_find_ltk(hdev, bdaddr, addr_type, role); 2612c9839a11SVinicius Costa Gomes if (old_key) 261375d262c2SVinicius Costa Gomes key = old_key; 2614c9839a11SVinicius Costa Gomes else { 26150a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 261675d262c2SVinicius Costa Gomes if (!key) 2617ca9142b8SJohan Hedberg return NULL; 2618970d0f1bSJohan Hedberg list_add_rcu(&key->list, &hdev->long_term_keys); 261975d262c2SVinicius Costa Gomes } 262075d262c2SVinicius Costa Gomes 262175d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2622c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2623c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2624c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2625c9839a11SVinicius Costa Gomes key->ediv = ediv; 2626fe39c7b2SMarcel Holtmann key->rand = rand; 2627c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2628c9839a11SVinicius Costa Gomes key->type = type; 262975d262c2SVinicius Costa Gomes 2630ca9142b8SJohan Hedberg return key; 263175d262c2SVinicius Costa Gomes } 263275d262c2SVinicius Costa Gomes 2633ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2634ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 2635970c4e46SJohan Hedberg { 2636970c4e46SJohan Hedberg struct smp_irk *irk; 2637970c4e46SJohan Hedberg 2638970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 2639970c4e46SJohan Hedberg if (!irk) { 2640970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 2641970c4e46SJohan Hedberg if (!irk) 2642ca9142b8SJohan Hedberg return NULL; 2643970c4e46SJohan Hedberg 2644970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 2645970c4e46SJohan Hedberg irk->addr_type = addr_type; 2646970c4e46SJohan Hedberg 2647adae20cbSJohan Hedberg list_add_rcu(&irk->list, &hdev->identity_resolving_keys); 2648970c4e46SJohan Hedberg } 2649970c4e46SJohan Hedberg 2650970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 2651970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2652970c4e46SJohan Hedberg 2653ca9142b8SJohan Hedberg return irk; 2654970c4e46SJohan Hedberg } 2655970c4e46SJohan Hedberg 265655ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 265755ed8ca1SJohan Hedberg { 265855ed8ca1SJohan Hedberg struct link_key *key; 265955ed8ca1SJohan Hedberg 266055ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 266155ed8ca1SJohan Hedberg if (!key) 266255ed8ca1SJohan Hedberg return -ENOENT; 266355ed8ca1SJohan Hedberg 26646ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 266555ed8ca1SJohan Hedberg 26660378b597SJohan Hedberg list_del_rcu(&key->list); 26670378b597SJohan Hedberg kfree_rcu(key, rcu); 266855ed8ca1SJohan Hedberg 266955ed8ca1SJohan Hedberg return 0; 267055ed8ca1SJohan Hedberg } 267155ed8ca1SJohan Hedberg 2672e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 2673b899efafSVinicius Costa Gomes { 2674970d0f1bSJohan Hedberg struct smp_ltk *k; 2675c51ffa0bSJohan Hedberg int removed = 0; 2676b899efafSVinicius Costa Gomes 2677970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 2678e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 2679b899efafSVinicius Costa Gomes continue; 2680b899efafSVinicius Costa Gomes 26816ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2682b899efafSVinicius Costa Gomes 2683970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2684970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2685c51ffa0bSJohan Hedberg removed++; 2686b899efafSVinicius Costa Gomes } 2687b899efafSVinicius Costa Gomes 2688c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 2689b899efafSVinicius Costa Gomes } 2690b899efafSVinicius Costa Gomes 2691a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 2692a7ec7338SJohan Hedberg { 2693adae20cbSJohan Hedberg struct smp_irk *k; 2694a7ec7338SJohan Hedberg 2695adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 2696a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 2697a7ec7338SJohan Hedberg continue; 2698a7ec7338SJohan Hedberg 2699a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2700a7ec7338SJohan Hedberg 2701adae20cbSJohan Hedberg list_del_rcu(&k->list); 2702adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2703a7ec7338SJohan Hedberg } 2704a7ec7338SJohan Hedberg } 2705a7ec7338SJohan Hedberg 270655e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 270755e76b38SJohan Hedberg { 270855e76b38SJohan Hedberg struct smp_ltk *k; 27094ba9faf3SJohan Hedberg struct smp_irk *irk; 271055e76b38SJohan Hedberg u8 addr_type; 271155e76b38SJohan Hedberg 271255e76b38SJohan Hedberg if (type == BDADDR_BREDR) { 271355e76b38SJohan Hedberg if (hci_find_link_key(hdev, bdaddr)) 271455e76b38SJohan Hedberg return true; 271555e76b38SJohan Hedberg return false; 271655e76b38SJohan Hedberg } 271755e76b38SJohan Hedberg 271855e76b38SJohan Hedberg /* Convert to HCI addr type which struct smp_ltk uses */ 271955e76b38SJohan Hedberg if (type == BDADDR_LE_PUBLIC) 272055e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_PUBLIC; 272155e76b38SJohan Hedberg else 272255e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_RANDOM; 272355e76b38SJohan Hedberg 27244ba9faf3SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, addr_type); 27254ba9faf3SJohan Hedberg if (irk) { 27264ba9faf3SJohan Hedberg bdaddr = &irk->bdaddr; 27274ba9faf3SJohan Hedberg addr_type = irk->addr_type; 27284ba9faf3SJohan Hedberg } 27294ba9faf3SJohan Hedberg 273055e76b38SJohan Hedberg rcu_read_lock(); 273155e76b38SJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 273287c8b28dSJohan Hedberg if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) { 273387c8b28dSJohan Hedberg rcu_read_unlock(); 273455e76b38SJohan Hedberg return true; 273555e76b38SJohan Hedberg } 273687c8b28dSJohan Hedberg } 273755e76b38SJohan Hedberg rcu_read_unlock(); 273855e76b38SJohan Hedberg 273955e76b38SJohan Hedberg return false; 274055e76b38SJohan Hedberg } 274155e76b38SJohan Hedberg 27426bd32326SVille Tervo /* HCI command timer function */ 274365cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work) 27446bd32326SVille Tervo { 274565cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, 274665cc2b49SMarcel Holtmann cmd_timer.work); 27476bd32326SVille Tervo 2748bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2749bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2750bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2751bda4f23aSAndrei Emeltchenko 27522064ee33SMarcel Holtmann bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); 2753bda4f23aSAndrei Emeltchenko } else { 27542064ee33SMarcel Holtmann bt_dev_err(hdev, "command tx timeout"); 2755bda4f23aSAndrei Emeltchenko } 2756bda4f23aSAndrei Emeltchenko 2757e2bef384SRajat Jain if (hdev->cmd_timeout) 2758e2bef384SRajat Jain hdev->cmd_timeout(hdev); 2759e2bef384SRajat Jain 27606bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2761c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 27626bd32326SVille Tervo } 27636bd32326SVille Tervo 27642763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 27656928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type) 27662763eda6SSzymon Janc { 27672763eda6SSzymon Janc struct oob_data *data; 27682763eda6SSzymon Janc 27696928a924SJohan Hedberg list_for_each_entry(data, &hdev->remote_oob_data, list) { 27706928a924SJohan Hedberg if (bacmp(bdaddr, &data->bdaddr) != 0) 27716928a924SJohan Hedberg continue; 27726928a924SJohan Hedberg if (data->bdaddr_type != bdaddr_type) 27736928a924SJohan Hedberg continue; 27742763eda6SSzymon Janc return data; 27756928a924SJohan Hedberg } 27762763eda6SSzymon Janc 27772763eda6SSzymon Janc return NULL; 27782763eda6SSzymon Janc } 27792763eda6SSzymon Janc 27806928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 27816928a924SJohan Hedberg u8 bdaddr_type) 27822763eda6SSzymon Janc { 27832763eda6SSzymon Janc struct oob_data *data; 27842763eda6SSzymon Janc 27856928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 27862763eda6SSzymon Janc if (!data) 27872763eda6SSzymon Janc return -ENOENT; 27882763eda6SSzymon Janc 27896928a924SJohan Hedberg BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type); 27902763eda6SSzymon Janc 27912763eda6SSzymon Janc list_del(&data->list); 27922763eda6SSzymon Janc kfree(data); 27932763eda6SSzymon Janc 27942763eda6SSzymon Janc return 0; 27952763eda6SSzymon Janc } 27962763eda6SSzymon Janc 279735f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 27982763eda6SSzymon Janc { 27992763eda6SSzymon Janc struct oob_data *data, *n; 28002763eda6SSzymon Janc 28012763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 28022763eda6SSzymon Janc list_del(&data->list); 28032763eda6SSzymon Janc kfree(data); 28042763eda6SSzymon Janc } 28052763eda6SSzymon Janc } 28062763eda6SSzymon Janc 28070798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 28086928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192, 280938da1703SJohan Hedberg u8 *hash256, u8 *rand256) 28100798872eSMarcel Holtmann { 28110798872eSMarcel Holtmann struct oob_data *data; 28120798872eSMarcel Holtmann 28136928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 28140798872eSMarcel Holtmann if (!data) { 28150a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 28160798872eSMarcel Holtmann if (!data) 28170798872eSMarcel Holtmann return -ENOMEM; 28180798872eSMarcel Holtmann 28190798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 28206928a924SJohan Hedberg data->bdaddr_type = bdaddr_type; 28210798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 28220798872eSMarcel Holtmann } 28230798872eSMarcel Holtmann 282481328d5cSJohan Hedberg if (hash192 && rand192) { 28250798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 282638da1703SJohan Hedberg memcpy(data->rand192, rand192, sizeof(data->rand192)); 2827f7697b16SMarcel Holtmann if (hash256 && rand256) 2828f7697b16SMarcel Holtmann data->present = 0x03; 282981328d5cSJohan Hedberg } else { 283081328d5cSJohan Hedberg memset(data->hash192, 0, sizeof(data->hash192)); 283181328d5cSJohan Hedberg memset(data->rand192, 0, sizeof(data->rand192)); 2832f7697b16SMarcel Holtmann if (hash256 && rand256) 2833f7697b16SMarcel Holtmann data->present = 0x02; 2834f7697b16SMarcel Holtmann else 2835f7697b16SMarcel Holtmann data->present = 0x00; 283681328d5cSJohan Hedberg } 28370798872eSMarcel Holtmann 283881328d5cSJohan Hedberg if (hash256 && rand256) { 28390798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 284038da1703SJohan Hedberg memcpy(data->rand256, rand256, sizeof(data->rand256)); 284181328d5cSJohan Hedberg } else { 284281328d5cSJohan Hedberg memset(data->hash256, 0, sizeof(data->hash256)); 284381328d5cSJohan Hedberg memset(data->rand256, 0, sizeof(data->rand256)); 2844f7697b16SMarcel Holtmann if (hash192 && rand192) 2845f7697b16SMarcel Holtmann data->present = 0x01; 284681328d5cSJohan Hedberg } 28470798872eSMarcel Holtmann 28486ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 28492763eda6SSzymon Janc 28502763eda6SSzymon Janc return 0; 28512763eda6SSzymon Janc } 28522763eda6SSzymon Janc 2853d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2854d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance) 2855d2609b34SFlorian Grandel { 2856d2609b34SFlorian Grandel struct adv_info *adv_instance; 2857d2609b34SFlorian Grandel 2858d2609b34SFlorian Grandel list_for_each_entry(adv_instance, &hdev->adv_instances, list) { 2859d2609b34SFlorian Grandel if (adv_instance->instance == instance) 2860d2609b34SFlorian Grandel return adv_instance; 2861d2609b34SFlorian Grandel } 2862d2609b34SFlorian Grandel 2863d2609b34SFlorian Grandel return NULL; 2864d2609b34SFlorian Grandel } 2865d2609b34SFlorian Grandel 2866d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 286774b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance) 286874b93e9fSPrasanna Karthik { 2869d2609b34SFlorian Grandel struct adv_info *cur_instance; 2870d2609b34SFlorian Grandel 2871d2609b34SFlorian Grandel cur_instance = hci_find_adv_instance(hdev, instance); 2872d2609b34SFlorian Grandel if (!cur_instance) 2873d2609b34SFlorian Grandel return NULL; 2874d2609b34SFlorian Grandel 2875d2609b34SFlorian Grandel if (cur_instance == list_last_entry(&hdev->adv_instances, 2876d2609b34SFlorian Grandel struct adv_info, list)) 2877d2609b34SFlorian Grandel return list_first_entry(&hdev->adv_instances, 2878d2609b34SFlorian Grandel struct adv_info, list); 2879d2609b34SFlorian Grandel else 2880d2609b34SFlorian Grandel return list_next_entry(cur_instance, list); 2881d2609b34SFlorian Grandel } 2882d2609b34SFlorian Grandel 2883d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2884d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance) 2885d2609b34SFlorian Grandel { 2886d2609b34SFlorian Grandel struct adv_info *adv_instance; 2887d2609b34SFlorian Grandel 2888d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 2889d2609b34SFlorian Grandel if (!adv_instance) 2890d2609b34SFlorian Grandel return -ENOENT; 2891d2609b34SFlorian Grandel 2892d2609b34SFlorian Grandel BT_DBG("%s removing %dMR", hdev->name, instance); 2893d2609b34SFlorian Grandel 2894cab054abSJohan Hedberg if (hdev->cur_adv_instance == instance) { 2895cab054abSJohan Hedberg if (hdev->adv_instance_timeout) { 28965d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 28975d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 28985d900e46SFlorian Grandel } 2899cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 2900cab054abSJohan Hedberg } 29015d900e46SFlorian Grandel 2902a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 2903a73c046aSJaganath Kanakkassery 2904d2609b34SFlorian Grandel list_del(&adv_instance->list); 2905d2609b34SFlorian Grandel kfree(adv_instance); 2906d2609b34SFlorian Grandel 2907d2609b34SFlorian Grandel hdev->adv_instance_cnt--; 2908d2609b34SFlorian Grandel 2909d2609b34SFlorian Grandel return 0; 2910d2609b34SFlorian Grandel } 2911d2609b34SFlorian Grandel 2912a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired) 2913a73c046aSJaganath Kanakkassery { 2914a73c046aSJaganath Kanakkassery struct adv_info *adv_instance, *n; 2915a73c046aSJaganath Kanakkassery 2916a73c046aSJaganath Kanakkassery list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) 2917a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = rpa_expired; 2918a73c046aSJaganath Kanakkassery } 2919a73c046aSJaganath Kanakkassery 2920d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2921d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev) 2922d2609b34SFlorian Grandel { 2923d2609b34SFlorian Grandel struct adv_info *adv_instance, *n; 2924d2609b34SFlorian Grandel 29255d900e46SFlorian Grandel if (hdev->adv_instance_timeout) { 29265d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 29275d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 29285d900e46SFlorian Grandel } 29295d900e46SFlorian Grandel 2930d2609b34SFlorian Grandel list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) { 2931a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 2932d2609b34SFlorian Grandel list_del(&adv_instance->list); 2933d2609b34SFlorian Grandel kfree(adv_instance); 2934d2609b34SFlorian Grandel } 2935d2609b34SFlorian Grandel 2936d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 2937cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 2938d2609b34SFlorian Grandel } 2939d2609b34SFlorian Grandel 2940a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work) 2941a73c046aSJaganath Kanakkassery { 2942a73c046aSJaganath Kanakkassery struct adv_info *adv_instance = container_of(work, struct adv_info, 2943a73c046aSJaganath Kanakkassery rpa_expired_cb.work); 2944a73c046aSJaganath Kanakkassery 2945a73c046aSJaganath Kanakkassery BT_DBG(""); 2946a73c046aSJaganath Kanakkassery 2947a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = true; 2948a73c046aSJaganath Kanakkassery } 2949a73c046aSJaganath Kanakkassery 2950d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2951d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags, 2952d2609b34SFlorian Grandel u16 adv_data_len, u8 *adv_data, 2953d2609b34SFlorian Grandel u16 scan_rsp_len, u8 *scan_rsp_data, 2954d2609b34SFlorian Grandel u16 timeout, u16 duration) 2955d2609b34SFlorian Grandel { 2956d2609b34SFlorian Grandel struct adv_info *adv_instance; 2957d2609b34SFlorian Grandel 2958d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 2959d2609b34SFlorian Grandel if (adv_instance) { 2960d2609b34SFlorian Grandel memset(adv_instance->adv_data, 0, 2961d2609b34SFlorian Grandel sizeof(adv_instance->adv_data)); 2962d2609b34SFlorian Grandel memset(adv_instance->scan_rsp_data, 0, 2963d2609b34SFlorian Grandel sizeof(adv_instance->scan_rsp_data)); 2964d2609b34SFlorian Grandel } else { 29651d0fac2cSLuiz Augusto von Dentz if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets || 2966d2609b34SFlorian Grandel instance < 1 || instance > HCI_MAX_ADV_INSTANCES) 2967d2609b34SFlorian Grandel return -EOVERFLOW; 2968d2609b34SFlorian Grandel 296939ecfad6SJohan Hedberg adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL); 2970d2609b34SFlorian Grandel if (!adv_instance) 2971d2609b34SFlorian Grandel return -ENOMEM; 2972d2609b34SFlorian Grandel 2973fffd38bcSFlorian Grandel adv_instance->pending = true; 2974d2609b34SFlorian Grandel adv_instance->instance = instance; 2975d2609b34SFlorian Grandel list_add(&adv_instance->list, &hdev->adv_instances); 2976d2609b34SFlorian Grandel hdev->adv_instance_cnt++; 2977d2609b34SFlorian Grandel } 2978d2609b34SFlorian Grandel 2979d2609b34SFlorian Grandel adv_instance->flags = flags; 2980d2609b34SFlorian Grandel adv_instance->adv_data_len = adv_data_len; 2981d2609b34SFlorian Grandel adv_instance->scan_rsp_len = scan_rsp_len; 2982d2609b34SFlorian Grandel 2983d2609b34SFlorian Grandel if (adv_data_len) 2984d2609b34SFlorian Grandel memcpy(adv_instance->adv_data, adv_data, adv_data_len); 2985d2609b34SFlorian Grandel 2986d2609b34SFlorian Grandel if (scan_rsp_len) 2987d2609b34SFlorian Grandel memcpy(adv_instance->scan_rsp_data, 2988d2609b34SFlorian Grandel scan_rsp_data, scan_rsp_len); 2989d2609b34SFlorian Grandel 2990d2609b34SFlorian Grandel adv_instance->timeout = timeout; 29915d900e46SFlorian Grandel adv_instance->remaining_time = timeout; 2992d2609b34SFlorian Grandel 2993d2609b34SFlorian Grandel if (duration == 0) 299410873f99SAlain Michaud adv_instance->duration = hdev->def_multi_adv_rotation_duration; 2995d2609b34SFlorian Grandel else 2996d2609b34SFlorian Grandel adv_instance->duration = duration; 2997d2609b34SFlorian Grandel 2998de181e88SJaganath Kanakkassery adv_instance->tx_power = HCI_TX_POWER_INVALID; 2999de181e88SJaganath Kanakkassery 3000a73c046aSJaganath Kanakkassery INIT_DELAYED_WORK(&adv_instance->rpa_expired_cb, 3001a73c046aSJaganath Kanakkassery adv_instance_rpa_expired); 3002a73c046aSJaganath Kanakkassery 3003d2609b34SFlorian Grandel BT_DBG("%s for %dMR", hdev->name, instance); 3004d2609b34SFlorian Grandel 3005d2609b34SFlorian Grandel return 0; 3006d2609b34SFlorian Grandel } 3007d2609b34SFlorian Grandel 3008e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */ 3009e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev) 3010e5e1e7fdSMiao-chen Chou { 3011b139553dSMiao-chen Chou struct adv_monitor *monitor; 3012b139553dSMiao-chen Chou int handle; 3013b139553dSMiao-chen Chou 3014b139553dSMiao-chen Chou idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle) 3015b139553dSMiao-chen Chou hci_free_adv_monitor(monitor); 3016b139553dSMiao-chen Chou 3017e5e1e7fdSMiao-chen Chou idr_destroy(&hdev->adv_monitors_idr); 3018e5e1e7fdSMiao-chen Chou } 3019e5e1e7fdSMiao-chen Chou 3020b139553dSMiao-chen Chou void hci_free_adv_monitor(struct adv_monitor *monitor) 3021b139553dSMiao-chen Chou { 3022b139553dSMiao-chen Chou struct adv_pattern *pattern; 3023b139553dSMiao-chen Chou struct adv_pattern *tmp; 3024b139553dSMiao-chen Chou 3025b139553dSMiao-chen Chou if (!monitor) 3026b139553dSMiao-chen Chou return; 3027b139553dSMiao-chen Chou 3028b139553dSMiao-chen Chou list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) 3029b139553dSMiao-chen Chou kfree(pattern); 3030b139553dSMiao-chen Chou 3031b139553dSMiao-chen Chou kfree(monitor); 3032b139553dSMiao-chen Chou } 3033b139553dSMiao-chen Chou 3034b139553dSMiao-chen Chou /* This function requires the caller holds hdev->lock */ 3035b139553dSMiao-chen Chou int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor) 3036b139553dSMiao-chen Chou { 3037b139553dSMiao-chen Chou int min, max, handle; 3038b139553dSMiao-chen Chou 3039b139553dSMiao-chen Chou if (!monitor) 3040b139553dSMiao-chen Chou return -EINVAL; 3041b139553dSMiao-chen Chou 3042b139553dSMiao-chen Chou min = HCI_MIN_ADV_MONITOR_HANDLE; 3043b139553dSMiao-chen Chou max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES; 3044b139553dSMiao-chen Chou handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max, 3045b139553dSMiao-chen Chou GFP_KERNEL); 3046b139553dSMiao-chen Chou if (handle < 0) 3047b139553dSMiao-chen Chou return handle; 3048b139553dSMiao-chen Chou 3049b139553dSMiao-chen Chou hdev->adv_monitors_cnt++; 3050b139553dSMiao-chen Chou monitor->handle = handle; 30518208f5a9SMiao-chen Chou 30528208f5a9SMiao-chen Chou hci_update_background_scan(hdev); 30538208f5a9SMiao-chen Chou 3054b139553dSMiao-chen Chou return 0; 3055b139553dSMiao-chen Chou } 3056b139553dSMiao-chen Chou 3057bd2fbc6cSMiao-chen Chou static int free_adv_monitor(int id, void *ptr, void *data) 3058bd2fbc6cSMiao-chen Chou { 3059bd2fbc6cSMiao-chen Chou struct hci_dev *hdev = data; 3060bd2fbc6cSMiao-chen Chou struct adv_monitor *monitor = ptr; 3061bd2fbc6cSMiao-chen Chou 3062bd2fbc6cSMiao-chen Chou idr_remove(&hdev->adv_monitors_idr, monitor->handle); 3063bd2fbc6cSMiao-chen Chou hci_free_adv_monitor(monitor); 3064bd2fbc6cSMiao-chen Chou 3065bd2fbc6cSMiao-chen Chou return 0; 3066bd2fbc6cSMiao-chen Chou } 3067bd2fbc6cSMiao-chen Chou 3068bd2fbc6cSMiao-chen Chou /* This function requires the caller holds hdev->lock */ 3069bd2fbc6cSMiao-chen Chou int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle) 3070bd2fbc6cSMiao-chen Chou { 3071bd2fbc6cSMiao-chen Chou struct adv_monitor *monitor; 3072bd2fbc6cSMiao-chen Chou 3073bd2fbc6cSMiao-chen Chou if (handle) { 3074bd2fbc6cSMiao-chen Chou monitor = idr_find(&hdev->adv_monitors_idr, handle); 3075bd2fbc6cSMiao-chen Chou if (!monitor) 3076bd2fbc6cSMiao-chen Chou return -ENOENT; 3077bd2fbc6cSMiao-chen Chou 3078bd2fbc6cSMiao-chen Chou idr_remove(&hdev->adv_monitors_idr, monitor->handle); 3079bd2fbc6cSMiao-chen Chou hci_free_adv_monitor(monitor); 3080bd2fbc6cSMiao-chen Chou } else { 3081bd2fbc6cSMiao-chen Chou /* Remove all monitors if handle is 0. */ 3082bd2fbc6cSMiao-chen Chou idr_for_each(&hdev->adv_monitors_idr, &free_adv_monitor, hdev); 3083bd2fbc6cSMiao-chen Chou } 3084bd2fbc6cSMiao-chen Chou 30858208f5a9SMiao-chen Chou hci_update_background_scan(hdev); 30868208f5a9SMiao-chen Chou 3087bd2fbc6cSMiao-chen Chou return 0; 3088bd2fbc6cSMiao-chen Chou } 3089bd2fbc6cSMiao-chen Chou 30908208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */ 30918208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev) 30928208f5a9SMiao-chen Chou { 30938208f5a9SMiao-chen Chou return !idr_is_empty(&hdev->adv_monitors_idr); 30948208f5a9SMiao-chen Chou } 30958208f5a9SMiao-chen Chou 3096dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list, 3097b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 3098b2a66aadSAntti Julku { 3099b2a66aadSAntti Julku struct bdaddr_list *b; 3100b2a66aadSAntti Julku 3101dcc36c16SJohan Hedberg list_for_each_entry(b, bdaddr_list, list) { 3102b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3103b2a66aadSAntti Julku return b; 3104b9ee0a78SMarcel Holtmann } 3105b2a66aadSAntti Julku 3106b2a66aadSAntti Julku return NULL; 3107b2a66aadSAntti Julku } 3108b2a66aadSAntti Julku 3109b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk( 3110b950aa88SAnkit Navik struct list_head *bdaddr_list, bdaddr_t *bdaddr, 3111b950aa88SAnkit Navik u8 type) 3112b950aa88SAnkit Navik { 3113b950aa88SAnkit Navik struct bdaddr_list_with_irk *b; 3114b950aa88SAnkit Navik 3115b950aa88SAnkit Navik list_for_each_entry(b, bdaddr_list, list) { 3116b950aa88SAnkit Navik if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3117b950aa88SAnkit Navik return b; 3118b950aa88SAnkit Navik } 3119b950aa88SAnkit Navik 3120b950aa88SAnkit Navik return NULL; 3121b950aa88SAnkit Navik } 3122b950aa88SAnkit Navik 31238baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags * 31248baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list, 31258baaa403SAbhishek Pandit-Subedi bdaddr_t *bdaddr, u8 type) 31268baaa403SAbhishek Pandit-Subedi { 31278baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *b; 31288baaa403SAbhishek Pandit-Subedi 31298baaa403SAbhishek Pandit-Subedi list_for_each_entry(b, bdaddr_list, list) { 31308baaa403SAbhishek Pandit-Subedi if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 31318baaa403SAbhishek Pandit-Subedi return b; 31328baaa403SAbhishek Pandit-Subedi } 31338baaa403SAbhishek Pandit-Subedi 31348baaa403SAbhishek Pandit-Subedi return NULL; 31358baaa403SAbhishek Pandit-Subedi } 31368baaa403SAbhishek Pandit-Subedi 3137dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list) 3138b2a66aadSAntti Julku { 31397eb7404fSGeliang Tang struct bdaddr_list *b, *n; 3140b2a66aadSAntti Julku 31417eb7404fSGeliang Tang list_for_each_entry_safe(b, n, bdaddr_list, list) { 31427eb7404fSGeliang Tang list_del(&b->list); 3143b2a66aadSAntti Julku kfree(b); 3144b2a66aadSAntti Julku } 3145b2a66aadSAntti Julku } 3146b2a66aadSAntti Julku 3147dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type) 3148b2a66aadSAntti Julku { 3149b2a66aadSAntti Julku struct bdaddr_list *entry; 3150b2a66aadSAntti Julku 3151b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3152b2a66aadSAntti Julku return -EBADF; 3153b2a66aadSAntti Julku 3154dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(list, bdaddr, type)) 31555e762444SAntti Julku return -EEXIST; 3156b2a66aadSAntti Julku 315727f70f3eSJohan Hedberg entry = kzalloc(sizeof(*entry), GFP_KERNEL); 31585e762444SAntti Julku if (!entry) 31595e762444SAntti Julku return -ENOMEM; 3160b2a66aadSAntti Julku 3161b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 3162b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 3163b2a66aadSAntti Julku 3164dcc36c16SJohan Hedberg list_add(&entry->list, list); 3165b2a66aadSAntti Julku 31662a8357f2SJohan Hedberg return 0; 3167b2a66aadSAntti Julku } 3168b2a66aadSAntti Julku 3169b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr, 3170b950aa88SAnkit Navik u8 type, u8 *peer_irk, u8 *local_irk) 3171b950aa88SAnkit Navik { 3172b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 3173b950aa88SAnkit Navik 3174b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) 3175b950aa88SAnkit Navik return -EBADF; 3176b950aa88SAnkit Navik 3177b950aa88SAnkit Navik if (hci_bdaddr_list_lookup(list, bdaddr, type)) 3178b950aa88SAnkit Navik return -EEXIST; 3179b950aa88SAnkit Navik 3180b950aa88SAnkit Navik entry = kzalloc(sizeof(*entry), GFP_KERNEL); 3181b950aa88SAnkit Navik if (!entry) 3182b950aa88SAnkit Navik return -ENOMEM; 3183b950aa88SAnkit Navik 3184b950aa88SAnkit Navik bacpy(&entry->bdaddr, bdaddr); 3185b950aa88SAnkit Navik entry->bdaddr_type = type; 3186b950aa88SAnkit Navik 3187b950aa88SAnkit Navik if (peer_irk) 3188b950aa88SAnkit Navik memcpy(entry->peer_irk, peer_irk, 16); 3189b950aa88SAnkit Navik 3190b950aa88SAnkit Navik if (local_irk) 3191b950aa88SAnkit Navik memcpy(entry->local_irk, local_irk, 16); 3192b950aa88SAnkit Navik 3193b950aa88SAnkit Navik list_add(&entry->list, list); 3194b950aa88SAnkit Navik 3195b950aa88SAnkit Navik return 0; 3196b950aa88SAnkit Navik } 3197b950aa88SAnkit Navik 31988baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr, 31998baaa403SAbhishek Pandit-Subedi u8 type, u32 flags) 32008baaa403SAbhishek Pandit-Subedi { 32018baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *entry; 32028baaa403SAbhishek Pandit-Subedi 32038baaa403SAbhishek Pandit-Subedi if (!bacmp(bdaddr, BDADDR_ANY)) 32048baaa403SAbhishek Pandit-Subedi return -EBADF; 32058baaa403SAbhishek Pandit-Subedi 32068baaa403SAbhishek Pandit-Subedi if (hci_bdaddr_list_lookup(list, bdaddr, type)) 32078baaa403SAbhishek Pandit-Subedi return -EEXIST; 32088baaa403SAbhishek Pandit-Subedi 32098baaa403SAbhishek Pandit-Subedi entry = kzalloc(sizeof(*entry), GFP_KERNEL); 32108baaa403SAbhishek Pandit-Subedi if (!entry) 32118baaa403SAbhishek Pandit-Subedi return -ENOMEM; 32128baaa403SAbhishek Pandit-Subedi 32138baaa403SAbhishek Pandit-Subedi bacpy(&entry->bdaddr, bdaddr); 32148baaa403SAbhishek Pandit-Subedi entry->bdaddr_type = type; 32158baaa403SAbhishek Pandit-Subedi entry->current_flags = flags; 32168baaa403SAbhishek Pandit-Subedi 32178baaa403SAbhishek Pandit-Subedi list_add(&entry->list, list); 32188baaa403SAbhishek Pandit-Subedi 32198baaa403SAbhishek Pandit-Subedi return 0; 32208baaa403SAbhishek Pandit-Subedi } 32218baaa403SAbhishek Pandit-Subedi 3222dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type) 3223b2a66aadSAntti Julku { 3224b2a66aadSAntti Julku struct bdaddr_list *entry; 3225b2a66aadSAntti Julku 322635f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 3227dcc36c16SJohan Hedberg hci_bdaddr_list_clear(list); 322835f7498aSJohan Hedberg return 0; 322935f7498aSJohan Hedberg } 3230b2a66aadSAntti Julku 3231dcc36c16SJohan Hedberg entry = hci_bdaddr_list_lookup(list, bdaddr, type); 3232d2ab0ac1SMarcel Holtmann if (!entry) 3233d2ab0ac1SMarcel Holtmann return -ENOENT; 3234d2ab0ac1SMarcel Holtmann 3235d2ab0ac1SMarcel Holtmann list_del(&entry->list); 3236d2ab0ac1SMarcel Holtmann kfree(entry); 3237d2ab0ac1SMarcel Holtmann 3238d2ab0ac1SMarcel Holtmann return 0; 3239d2ab0ac1SMarcel Holtmann } 3240d2ab0ac1SMarcel Holtmann 3241b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr, 3242b950aa88SAnkit Navik u8 type) 3243b950aa88SAnkit Navik { 3244b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 3245b950aa88SAnkit Navik 3246b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) { 3247b950aa88SAnkit Navik hci_bdaddr_list_clear(list); 3248b950aa88SAnkit Navik return 0; 3249b950aa88SAnkit Navik } 3250b950aa88SAnkit Navik 3251b950aa88SAnkit Navik entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type); 3252b950aa88SAnkit Navik if (!entry) 3253b950aa88SAnkit Navik return -ENOENT; 3254b950aa88SAnkit Navik 3255b950aa88SAnkit Navik list_del(&entry->list); 3256b950aa88SAnkit Navik kfree(entry); 3257b950aa88SAnkit Navik 3258b950aa88SAnkit Navik return 0; 3259b950aa88SAnkit Navik } 3260b950aa88SAnkit Navik 32618baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr, 32628baaa403SAbhishek Pandit-Subedi u8 type) 32638baaa403SAbhishek Pandit-Subedi { 32648baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *entry; 32658baaa403SAbhishek Pandit-Subedi 32668baaa403SAbhishek Pandit-Subedi if (!bacmp(bdaddr, BDADDR_ANY)) { 32678baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_clear(list); 32688baaa403SAbhishek Pandit-Subedi return 0; 32698baaa403SAbhishek Pandit-Subedi } 32708baaa403SAbhishek Pandit-Subedi 32718baaa403SAbhishek Pandit-Subedi entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type); 32728baaa403SAbhishek Pandit-Subedi if (!entry) 32738baaa403SAbhishek Pandit-Subedi return -ENOENT; 32748baaa403SAbhishek Pandit-Subedi 32758baaa403SAbhishek Pandit-Subedi list_del(&entry->list); 32768baaa403SAbhishek Pandit-Subedi kfree(entry); 32778baaa403SAbhishek Pandit-Subedi 32788baaa403SAbhishek Pandit-Subedi return 0; 32798baaa403SAbhishek Pandit-Subedi } 32808baaa403SAbhishek Pandit-Subedi 328115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 328215819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 328315819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 328415819a70SAndre Guedes { 328515819a70SAndre Guedes struct hci_conn_params *params; 328615819a70SAndre Guedes 328715819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 328815819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 328915819a70SAndre Guedes params->addr_type == addr_type) { 329015819a70SAndre Guedes return params; 329115819a70SAndre Guedes } 329215819a70SAndre Guedes } 329315819a70SAndre Guedes 329415819a70SAndre Guedes return NULL; 329515819a70SAndre Guedes } 329615819a70SAndre Guedes 329715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 3298501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 32994b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type) 330015819a70SAndre Guedes { 3301912b42efSJohan Hedberg struct hci_conn_params *param; 330215819a70SAndre Guedes 33036540351eSMarcel Holtmann switch (addr_type) { 33046540351eSMarcel Holtmann case ADDR_LE_DEV_PUBLIC_RESOLVED: 33056540351eSMarcel Holtmann addr_type = ADDR_LE_DEV_PUBLIC; 33066540351eSMarcel Holtmann break; 33076540351eSMarcel Holtmann case ADDR_LE_DEV_RANDOM_RESOLVED: 33086540351eSMarcel Holtmann addr_type = ADDR_LE_DEV_RANDOM; 33096540351eSMarcel Holtmann break; 33106540351eSMarcel Holtmann } 33116540351eSMarcel Holtmann 3312501f8827SJohan Hedberg list_for_each_entry(param, list, action) { 3313912b42efSJohan Hedberg if (bacmp(¶m->addr, addr) == 0 && 3314912b42efSJohan Hedberg param->addr_type == addr_type) 3315912b42efSJohan Hedberg return param; 33164b10966fSMarcel Holtmann } 33174b10966fSMarcel Holtmann 33184b10966fSMarcel Holtmann return NULL; 331915819a70SAndre Guedes } 332015819a70SAndre Guedes 332115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 332251d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 332351d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type) 332415819a70SAndre Guedes { 332515819a70SAndre Guedes struct hci_conn_params *params; 332615819a70SAndre Guedes 332715819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 3328cef952ceSAndre Guedes if (params) 332951d167c0SMarcel Holtmann return params; 333015819a70SAndre Guedes 333115819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 333215819a70SAndre Guedes if (!params) { 33332064ee33SMarcel Holtmann bt_dev_err(hdev, "out of memory"); 333451d167c0SMarcel Holtmann return NULL; 333515819a70SAndre Guedes } 333615819a70SAndre Guedes 333715819a70SAndre Guedes bacpy(¶ms->addr, addr); 333815819a70SAndre Guedes params->addr_type = addr_type; 3339cef952ceSAndre Guedes 3340cef952ceSAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 334193450c75SJohan Hedberg INIT_LIST_HEAD(¶ms->action); 3342cef952ceSAndre Guedes 3343bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval; 3344bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval; 3345bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency; 3346bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout; 3347bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED; 3348bf5b3c8bSMarcel Holtmann 3349bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 3350bf5b3c8bSMarcel Holtmann 335151d167c0SMarcel Holtmann return params; 3352bf5b3c8bSMarcel Holtmann } 3353bf5b3c8bSMarcel Holtmann 3354f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params) 3355f6c63249SJohan Hedberg { 3356f6c63249SJohan Hedberg if (params->conn) { 3357f6c63249SJohan Hedberg hci_conn_drop(params->conn); 3358f6c63249SJohan Hedberg hci_conn_put(params->conn); 3359f6c63249SJohan Hedberg } 3360f6c63249SJohan Hedberg 3361f6c63249SJohan Hedberg list_del(¶ms->action); 3362f6c63249SJohan Hedberg list_del(¶ms->list); 3363f6c63249SJohan Hedberg kfree(params); 3364f6c63249SJohan Hedberg } 3365f6c63249SJohan Hedberg 336615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 336715819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 336815819a70SAndre Guedes { 336915819a70SAndre Guedes struct hci_conn_params *params; 337015819a70SAndre Guedes 337115819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 337215819a70SAndre Guedes if (!params) 337315819a70SAndre Guedes return; 337415819a70SAndre Guedes 3375f6c63249SJohan Hedberg hci_conn_params_free(params); 337615819a70SAndre Guedes 337795305baaSJohan Hedberg hci_update_background_scan(hdev); 337895305baaSJohan Hedberg 337915819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 338015819a70SAndre Guedes } 338115819a70SAndre Guedes 338215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 338355af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev) 338415819a70SAndre Guedes { 338515819a70SAndre Guedes struct hci_conn_params *params, *tmp; 338615819a70SAndre Guedes 338715819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 338855af49a8SJohan Hedberg if (params->auto_connect != HCI_AUTO_CONN_DISABLED) 338955af49a8SJohan Hedberg continue; 3390f75113a2SJakub Pawlowski 3391f75113a2SJakub Pawlowski /* If trying to estabilish one time connection to disabled 3392f75113a2SJakub Pawlowski * device, leave the params, but mark them as just once. 3393f75113a2SJakub Pawlowski */ 3394f75113a2SJakub Pawlowski if (params->explicit_connect) { 3395f75113a2SJakub Pawlowski params->auto_connect = HCI_AUTO_CONN_EXPLICIT; 3396f75113a2SJakub Pawlowski continue; 3397f75113a2SJakub Pawlowski } 3398f75113a2SJakub Pawlowski 339915819a70SAndre Guedes list_del(¶ms->list); 340015819a70SAndre Guedes kfree(params); 340115819a70SAndre Guedes } 340215819a70SAndre Guedes 340355af49a8SJohan Hedberg BT_DBG("All LE disabled connection parameters were removed"); 340455af49a8SJohan Hedberg } 340555af49a8SJohan Hedberg 340655af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */ 3407030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev) 340815819a70SAndre Guedes { 340915819a70SAndre Guedes struct hci_conn_params *params, *tmp; 341015819a70SAndre Guedes 3411f6c63249SJohan Hedberg list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) 3412f6c63249SJohan Hedberg hci_conn_params_free(params); 341315819a70SAndre Guedes 341415819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 341515819a70SAndre Guedes } 341615819a70SAndre Guedes 3417a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 3418a1f4c318SJohan Hedberg * 3419a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 3420a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 3421a1f4c318SJohan Hedberg * the static random address. 3422a1f4c318SJohan Hedberg * 3423a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 3424a1f4c318SJohan Hedberg * public address to use the static random address instead. 342550b5b952SMarcel Holtmann * 342650b5b952SMarcel Holtmann * In case BR/EDR has been disabled on a dual-mode controller and 342750b5b952SMarcel Holtmann * userspace has configured a static address, then that address 342850b5b952SMarcel Holtmann * becomes the identity address instead of the public BR/EDR address. 3429a1f4c318SJohan Hedberg */ 3430a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 3431a1f4c318SJohan Hedberg u8 *bdaddr_type) 3432a1f4c318SJohan Hedberg { 3433b7cb93e5SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) || 343450b5b952SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) || 3435d7a5a11dSMarcel Holtmann (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) && 343650b5b952SMarcel Holtmann bacmp(&hdev->static_addr, BDADDR_ANY))) { 3437a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 3438a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 3439a1f4c318SJohan Hedberg } else { 3440a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 3441a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 3442a1f4c318SJohan Hedberg } 3443a1f4c318SJohan Hedberg } 3444a1f4c318SJohan Hedberg 34459952d90eSAbhishek Pandit-Subedi static int hci_suspend_wait_event(struct hci_dev *hdev) 34469952d90eSAbhishek Pandit-Subedi { 34479952d90eSAbhishek Pandit-Subedi #define WAKE_COND \ 34489952d90eSAbhishek Pandit-Subedi (find_first_bit(hdev->suspend_tasks, __SUSPEND_NUM_TASKS) == \ 34499952d90eSAbhishek Pandit-Subedi __SUSPEND_NUM_TASKS) 34509952d90eSAbhishek Pandit-Subedi 34519952d90eSAbhishek Pandit-Subedi int i; 34529952d90eSAbhishek Pandit-Subedi int ret = wait_event_timeout(hdev->suspend_wait_q, 34539952d90eSAbhishek Pandit-Subedi WAKE_COND, SUSPEND_NOTIFIER_TIMEOUT); 34549952d90eSAbhishek Pandit-Subedi 34559952d90eSAbhishek Pandit-Subedi if (ret == 0) { 3456a9ec8423SAbhishek Pandit-Subedi bt_dev_err(hdev, "Timed out waiting for suspend events"); 34579952d90eSAbhishek Pandit-Subedi for (i = 0; i < __SUSPEND_NUM_TASKS; ++i) { 34589952d90eSAbhishek Pandit-Subedi if (test_bit(i, hdev->suspend_tasks)) 3459a9ec8423SAbhishek Pandit-Subedi bt_dev_err(hdev, "Suspend timeout bit: %d", i); 34609952d90eSAbhishek Pandit-Subedi clear_bit(i, hdev->suspend_tasks); 34619952d90eSAbhishek Pandit-Subedi } 34629952d90eSAbhishek Pandit-Subedi 34639952d90eSAbhishek Pandit-Subedi ret = -ETIMEDOUT; 34649952d90eSAbhishek Pandit-Subedi } else { 34659952d90eSAbhishek Pandit-Subedi ret = 0; 34669952d90eSAbhishek Pandit-Subedi } 34679952d90eSAbhishek Pandit-Subedi 34689952d90eSAbhishek Pandit-Subedi return ret; 34699952d90eSAbhishek Pandit-Subedi } 34709952d90eSAbhishek Pandit-Subedi 34719952d90eSAbhishek Pandit-Subedi static void hci_prepare_suspend(struct work_struct *work) 34729952d90eSAbhishek Pandit-Subedi { 34739952d90eSAbhishek Pandit-Subedi struct hci_dev *hdev = 34749952d90eSAbhishek Pandit-Subedi container_of(work, struct hci_dev, suspend_prepare); 34759952d90eSAbhishek Pandit-Subedi 34769952d90eSAbhishek Pandit-Subedi hci_dev_lock(hdev); 34779952d90eSAbhishek Pandit-Subedi hci_req_prepare_suspend(hdev, hdev->suspend_state_next); 34789952d90eSAbhishek Pandit-Subedi hci_dev_unlock(hdev); 34799952d90eSAbhishek Pandit-Subedi } 34809952d90eSAbhishek Pandit-Subedi 34818731840aSAbhishek Pandit-Subedi static int hci_change_suspend_state(struct hci_dev *hdev, 34828731840aSAbhishek Pandit-Subedi enum suspended_state next) 34838731840aSAbhishek Pandit-Subedi { 34848731840aSAbhishek Pandit-Subedi hdev->suspend_state_next = next; 34858731840aSAbhishek Pandit-Subedi set_bit(SUSPEND_PREPARE_NOTIFIER, hdev->suspend_tasks); 34868731840aSAbhishek Pandit-Subedi queue_work(hdev->req_workqueue, &hdev->suspend_prepare); 34878731840aSAbhishek Pandit-Subedi return hci_suspend_wait_event(hdev); 34888731840aSAbhishek Pandit-Subedi } 34898731840aSAbhishek Pandit-Subedi 34909952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, 34919952d90eSAbhishek Pandit-Subedi void *data) 34929952d90eSAbhishek Pandit-Subedi { 34939952d90eSAbhishek Pandit-Subedi struct hci_dev *hdev = 34949952d90eSAbhishek Pandit-Subedi container_of(nb, struct hci_dev, suspend_notifier); 34959952d90eSAbhishek Pandit-Subedi int ret = 0; 34969952d90eSAbhishek Pandit-Subedi 34979952d90eSAbhishek Pandit-Subedi /* If powering down, wait for completion. */ 34989952d90eSAbhishek Pandit-Subedi if (mgmt_powering_down(hdev)) { 34999952d90eSAbhishek Pandit-Subedi set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks); 35009952d90eSAbhishek Pandit-Subedi ret = hci_suspend_wait_event(hdev); 35019952d90eSAbhishek Pandit-Subedi if (ret) 35029952d90eSAbhishek Pandit-Subedi goto done; 35039952d90eSAbhishek Pandit-Subedi } 35049952d90eSAbhishek Pandit-Subedi 35059952d90eSAbhishek Pandit-Subedi /* Suspend notifier should only act on events when powered. */ 35069952d90eSAbhishek Pandit-Subedi if (!hdev_is_powered(hdev)) 35079952d90eSAbhishek Pandit-Subedi goto done; 35089952d90eSAbhishek Pandit-Subedi 35099952d90eSAbhishek Pandit-Subedi if (action == PM_SUSPEND_PREPARE) { 35104f40afc6SAbhishek Pandit-Subedi /* Suspend consists of two actions: 35114f40afc6SAbhishek Pandit-Subedi * - First, disconnect everything and make the controller not 35124f40afc6SAbhishek Pandit-Subedi * connectable (disabling scanning) 35134f40afc6SAbhishek Pandit-Subedi * - Second, program event filter/whitelist and enable scan 35144f40afc6SAbhishek Pandit-Subedi */ 35158731840aSAbhishek Pandit-Subedi ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT); 35164f40afc6SAbhishek Pandit-Subedi 351781dafad5SAbhishek Pandit-Subedi /* Only configure whitelist if disconnect succeeded and wake 351881dafad5SAbhishek Pandit-Subedi * isn't being prevented. 351981dafad5SAbhishek Pandit-Subedi */ 352081dafad5SAbhishek Pandit-Subedi if (!ret && !(hdev->prevent_wake && hdev->prevent_wake(hdev))) 35218731840aSAbhishek Pandit-Subedi ret = hci_change_suspend_state(hdev, 35220d2c9825SAbhishek Pandit-Subedi BT_SUSPEND_CONFIGURE_WAKE); 35239952d90eSAbhishek Pandit-Subedi } else if (action == PM_POST_SUSPEND) { 35248731840aSAbhishek Pandit-Subedi ret = hci_change_suspend_state(hdev, BT_RUNNING); 35259952d90eSAbhishek Pandit-Subedi } 35269952d90eSAbhishek Pandit-Subedi 35279952d90eSAbhishek Pandit-Subedi done: 3528a9ec8423SAbhishek Pandit-Subedi /* We always allow suspend even if suspend preparation failed and 3529a9ec8423SAbhishek Pandit-Subedi * attempt to recover in resume. 3530a9ec8423SAbhishek Pandit-Subedi */ 3531a9ec8423SAbhishek Pandit-Subedi if (ret) 3532a9ec8423SAbhishek Pandit-Subedi bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d", 3533a9ec8423SAbhishek Pandit-Subedi action, ret); 3534a9ec8423SAbhishek Pandit-Subedi 353524b06572SMax Chou return NOTIFY_DONE; 35369952d90eSAbhishek Pandit-Subedi } 35378731840aSAbhishek Pandit-Subedi 35389be0dab7SDavid Herrmann /* Alloc HCI device */ 35399be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 35409be0dab7SDavid Herrmann { 35419be0dab7SDavid Herrmann struct hci_dev *hdev; 35429be0dab7SDavid Herrmann 354327f70f3eSJohan Hedberg hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); 35449be0dab7SDavid Herrmann if (!hdev) 35459be0dab7SDavid Herrmann return NULL; 35469be0dab7SDavid Herrmann 3547b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3548b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3549b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3550b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3551b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 355296c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */ 3553bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3554bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3555d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 3556d2609b34SFlorian Grandel hdev->cur_adv_instance = 0x00; 35575d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 3558b1b813d4SDavid Herrmann 3559b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3560b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3561b1b813d4SDavid Herrmann 35623f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 3563628531c9SGeorg Lukas hdev->le_adv_min_interval = 0x0800; 3564628531c9SGeorg Lukas hdev->le_adv_max_interval = 0x0800; 3565bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3566bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 356710873f99SAlain Michaud hdev->le_scan_int_suspend = 0x0400; 356810873f99SAlain Michaud hdev->le_scan_window_suspend = 0x0012; 356910873f99SAlain Michaud hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT; 357010873f99SAlain Michaud hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN; 357110873f99SAlain Michaud hdev->le_scan_int_connect = 0x0060; 357210873f99SAlain Michaud hdev->le_scan_window_connect = 0x0060; 3573b48c3b59SJonas Holmberg hdev->le_conn_min_interval = 0x0018; 3574b48c3b59SJonas Holmberg hdev->le_conn_max_interval = 0x0028; 357504fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000; 357604fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a; 3577a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = 0x001b; 3578a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = 0x0148; 3579a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = 0x001b; 3580a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = 0x0148; 3581a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = 0x001b; 3582a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = 0x0148; 358330d65e08SMatias Karhumaa hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE; 358430d65e08SMatias Karhumaa hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE; 35856decb5b4SJaganath Kanakkassery hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M; 35866decb5b4SJaganath Kanakkassery hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M; 35871d0fac2cSLuiz Augusto von Dentz hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES; 358810873f99SAlain Michaud hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION; 358949b020c1SAlain Michaud hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT; 3590bef64738SMarcel Holtmann 3591d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 3592b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 359331ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 359431ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 3595302975cbSSpoorthi Ravishankar Koppad hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT; 359658a96fc3SMarcel Holtmann hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE; 3597d6bfd59cSJohan Hedberg 359810873f99SAlain Michaud /* default 1.28 sec page scan */ 359910873f99SAlain Michaud hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD; 360010873f99SAlain Michaud hdev->def_page_scan_int = 0x0800; 360110873f99SAlain Michaud hdev->def_page_scan_window = 0x0012; 360210873f99SAlain Michaud 3603b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3604b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3605b1b813d4SDavid Herrmann 3606b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3607b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 36086659358eSJohan Hedberg INIT_LIST_HEAD(&hdev->whitelist); 3609b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3610b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3611b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3612970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3613b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 3614d2ab0ac1SMarcel Holtmann INIT_LIST_HEAD(&hdev->le_white_list); 3615cfdb0c2dSAnkit Navik INIT_LIST_HEAD(&hdev->le_resolv_list); 361615819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 361777a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 361866f8455aSJohan Hedberg INIT_LIST_HEAD(&hdev->pend_le_reports); 36196b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3620d2609b34SFlorian Grandel INIT_LIST_HEAD(&hdev->adv_instances); 3621600a8749SAlain Michaud INIT_LIST_HEAD(&hdev->blocked_keys); 3622b1b813d4SDavid Herrmann 3623b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3624b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3625b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3626b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3627c7741d16SMarcel Holtmann INIT_WORK(&hdev->error_reset, hci_error_reset); 36289952d90eSAbhishek Pandit-Subedi INIT_WORK(&hdev->suspend_prepare, hci_prepare_suspend); 3629b1b813d4SDavid Herrmann 3630b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3631b1b813d4SDavid Herrmann 3632b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3633b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3634b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3635b1b813d4SDavid Herrmann 3636b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 36379952d90eSAbhishek Pandit-Subedi init_waitqueue_head(&hdev->suspend_wait_q); 3638b1b813d4SDavid Herrmann 363965cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout); 3640b1b813d4SDavid Herrmann 36415fc16cc4SJohan Hedberg hci_request_setup(hdev); 36425fc16cc4SJohan Hedberg 3643b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3644b1b813d4SDavid Herrmann discovery_init(hdev); 36459be0dab7SDavid Herrmann 36469be0dab7SDavid Herrmann return hdev; 36479be0dab7SDavid Herrmann } 36489be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 36499be0dab7SDavid Herrmann 36509be0dab7SDavid Herrmann /* Free HCI device */ 36519be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 36529be0dab7SDavid Herrmann { 36539be0dab7SDavid Herrmann /* will free via device release */ 36549be0dab7SDavid Herrmann put_device(&hdev->dev); 36559be0dab7SDavid Herrmann } 36569be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 36579be0dab7SDavid Herrmann 36581da177e4SLinus Torvalds /* Register HCI device */ 36591da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 36601da177e4SLinus Torvalds { 3661b1b813d4SDavid Herrmann int id, error; 36621da177e4SLinus Torvalds 366374292d5aSMarcel Holtmann if (!hdev->open || !hdev->close || !hdev->send) 36641da177e4SLinus Torvalds return -EINVAL; 36651da177e4SLinus Torvalds 366608add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 366708add513SMat Martineau * so the index can be used as the AMP controller ID. 366808add513SMat Martineau */ 36693df92b31SSasha Levin switch (hdev->dev_type) { 3670ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 36713df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 36721da177e4SLinus Torvalds break; 36733df92b31SSasha Levin case HCI_AMP: 36743df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 36753df92b31SSasha Levin break; 36763df92b31SSasha Levin default: 36773df92b31SSasha Levin return -EINVAL; 36781da177e4SLinus Torvalds } 36791da177e4SLinus Torvalds 36803df92b31SSasha Levin if (id < 0) 36813df92b31SSasha Levin return id; 36823df92b31SSasha Levin 36831da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 36841da177e4SLinus Torvalds hdev->id = id; 36852d8b3a11SAndrei Emeltchenko 36862d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 36872d8b3a11SAndrei Emeltchenko 368829e2dd0dSTejun Heo hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name); 368933ca954dSDavid Herrmann if (!hdev->workqueue) { 369033ca954dSDavid Herrmann error = -ENOMEM; 369133ca954dSDavid Herrmann goto err; 369233ca954dSDavid Herrmann } 3693f48fd9c8SMarcel Holtmann 369429e2dd0dSTejun Heo hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, 369529e2dd0dSTejun Heo hdev->name); 36966ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 36976ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 36986ead1bbcSJohan Hedberg error = -ENOMEM; 36996ead1bbcSJohan Hedberg goto err; 37006ead1bbcSJohan Hedberg } 37016ead1bbcSJohan Hedberg 37020153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 37030153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 37040153e2ecSMarcel Holtmann 3705bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3706bdc3e0f1SMarcel Holtmann 3707bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 370833ca954dSDavid Herrmann if (error < 0) 370954506918SJohan Hedberg goto err_wqueue; 37101da177e4SLinus Torvalds 37116d5d2ee6SHeiner Kallweit hci_leds_init(hdev); 37126d5d2ee6SHeiner Kallweit 3713611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3714a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3715a8c5fb1aSGustavo Padovan hdev); 3716611b30f7SMarcel Holtmann if (hdev->rfkill) { 3717611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3718611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3719611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3720611b30f7SMarcel Holtmann } 3721611b30f7SMarcel Holtmann } 3722611b30f7SMarcel Holtmann 37235e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 3724a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 37255e130367SJohan Hedberg 3726a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SETUP); 3727a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_AUTO_OFF); 3728ce2be9acSAndrei Emeltchenko 3729ca8bee5dSMarcel Holtmann if (hdev->dev_type == HCI_PRIMARY) { 373056f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 373156f87901SJohan Hedberg * through reading supported features during init. 373256f87901SJohan Hedberg */ 3733a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 373456f87901SJohan Hedberg } 3735ce2be9acSAndrei Emeltchenko 3736fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3737fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3738fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3739fcee3377SGustavo Padovan 37404a964404SMarcel Holtmann /* Devices that are marked for raw-only usage are unconfigured 37414a964404SMarcel Holtmann * and should not be included in normal operation. 3742fee746b0SMarcel Holtmann */ 3743fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 3744a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 3745fee746b0SMarcel Holtmann 374605fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_REG); 3747dc946bd8SDavid Herrmann hci_dev_hold(hdev); 37481da177e4SLinus Torvalds 37499952d90eSAbhishek Pandit-Subedi hdev->suspend_notifier.notifier_call = hci_suspend_notifier; 37509952d90eSAbhishek Pandit-Subedi error = register_pm_notifier(&hdev->suspend_notifier); 37519952d90eSAbhishek Pandit-Subedi if (error) 37529952d90eSAbhishek Pandit-Subedi goto err_wqueue; 37539952d90eSAbhishek Pandit-Subedi 375419202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3755fbe96d6fSMarcel Holtmann 3756e5e1e7fdSMiao-chen Chou idr_init(&hdev->adv_monitors_idr); 3757e5e1e7fdSMiao-chen Chou 37581da177e4SLinus Torvalds return id; 3759f48fd9c8SMarcel Holtmann 376033ca954dSDavid Herrmann err_wqueue: 376133ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 37626ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 376333ca954dSDavid Herrmann err: 37643df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3765f48fd9c8SMarcel Holtmann 376633ca954dSDavid Herrmann return error; 37671da177e4SLinus Torvalds } 37681da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 37691da177e4SLinus Torvalds 37701da177e4SLinus Torvalds /* Unregister HCI device */ 377159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 37721da177e4SLinus Torvalds { 37732d7cc19eSMarcel Holtmann int id; 3774ef222013SMarcel Holtmann 3775c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 37761da177e4SLinus Torvalds 3777a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNREGISTER); 377894324962SJohan Hovold 37793df92b31SSasha Levin id = hdev->id; 37803df92b31SSasha Levin 3781f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 37821da177e4SLinus Torvalds list_del(&hdev->list); 3783f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 37841da177e4SLinus Torvalds 3785b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 3786b9b5ef18SGustavo Padovan 37879952d90eSAbhishek Pandit-Subedi unregister_pm_notifier(&hdev->suspend_notifier); 37884e8c36c3SAbhishek Pandit-Subedi cancel_work_sync(&hdev->suspend_prepare); 37894e8c36c3SAbhishek Pandit-Subedi 37904e8c36c3SAbhishek Pandit-Subedi hci_dev_do_close(hdev); 37919952d90eSAbhishek Pandit-Subedi 3792ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 3793d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_SETUP) && 3794d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 379509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3796744cf19eSJohan Hedberg mgmt_index_removed(hdev); 379709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 379856e5cb86SJohan Hedberg } 3799ab81cbf9SJohan Hedberg 38002e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 38012e58ef3eSJohan Hedberg * pending list */ 38022e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 38032e58ef3eSJohan Hedberg 380405fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UNREG); 38051da177e4SLinus Torvalds 3806611b30f7SMarcel Holtmann if (hdev->rfkill) { 3807611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 3808611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3809611b30f7SMarcel Holtmann } 3810611b30f7SMarcel Holtmann 3811bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 3812147e2d59SDave Young 38130153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 38145177a838SMarcel Holtmann kfree_const(hdev->hw_info); 38155177a838SMarcel Holtmann kfree_const(hdev->fw_info); 38160153e2ecSMarcel Holtmann 3817f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 38186ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 3819f48fd9c8SMarcel Holtmann 382009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3821dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->blacklist); 38226659358eSJohan Hedberg hci_bdaddr_list_clear(&hdev->whitelist); 38232aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 382455ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 3825b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 3826970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 38272763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 3828d2609b34SFlorian Grandel hci_adv_instances_clear(hdev); 3829e5e1e7fdSMiao-chen Chou hci_adv_monitors_clear(hdev); 3830dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->le_white_list); 3831cfdb0c2dSAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 3832373110c5SJohan Hedberg hci_conn_params_clear_all(hdev); 383322078800SMarcel Holtmann hci_discovery_filter_clear(hdev); 3834600a8749SAlain Michaud hci_blocked_keys_clear(hdev); 383509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 3836e2e0cacbSJohan Hedberg 3837dc946bd8SDavid Herrmann hci_dev_put(hdev); 38383df92b31SSasha Levin 38393df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 38401da177e4SLinus Torvalds } 38411da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 38421da177e4SLinus Torvalds 38431da177e4SLinus Torvalds /* Suspend HCI device */ 38441da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 38451da177e4SLinus Torvalds { 384605fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_SUSPEND); 38471da177e4SLinus Torvalds return 0; 38481da177e4SLinus Torvalds } 38491da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 38501da177e4SLinus Torvalds 38511da177e4SLinus Torvalds /* Resume HCI device */ 38521da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 38531da177e4SLinus Torvalds { 385405fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_RESUME); 38551da177e4SLinus Torvalds return 0; 38561da177e4SLinus Torvalds } 38571da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 38581da177e4SLinus Torvalds 385975e0569fSMarcel Holtmann /* Reset HCI device */ 386075e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev) 386175e0569fSMarcel Holtmann { 38621e4b6e91SColin Ian King static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; 386375e0569fSMarcel Holtmann struct sk_buff *skb; 386475e0569fSMarcel Holtmann 386575e0569fSMarcel Holtmann skb = bt_skb_alloc(3, GFP_ATOMIC); 386675e0569fSMarcel Holtmann if (!skb) 386775e0569fSMarcel Holtmann return -ENOMEM; 386875e0569fSMarcel Holtmann 3869d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_EVENT_PKT; 387059ae1d12SJohannes Berg skb_put_data(skb, hw_err, 3); 387175e0569fSMarcel Holtmann 387275e0569fSMarcel Holtmann /* Send Hardware Error to upper stack */ 387375e0569fSMarcel Holtmann return hci_recv_frame(hdev, skb); 387475e0569fSMarcel Holtmann } 387575e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev); 387675e0569fSMarcel Holtmann 387776bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 3878e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 387976bca880SMarcel Holtmann { 388076bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 388176bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 388276bca880SMarcel Holtmann kfree_skb(skb); 388376bca880SMarcel Holtmann return -ENXIO; 388476bca880SMarcel Holtmann } 388576bca880SMarcel Holtmann 3886d79f34e3SMarcel Holtmann if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT && 3887d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && 3888cc974003SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_SCODATA_PKT && 3889cc974003SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) { 3890fe806dceSMarcel Holtmann kfree_skb(skb); 3891fe806dceSMarcel Holtmann return -EINVAL; 3892fe806dceSMarcel Holtmann } 3893fe806dceSMarcel Holtmann 3894d82603c6SJorrit Schippers /* Incoming skb */ 389576bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 389676bca880SMarcel Holtmann 389776bca880SMarcel Holtmann /* Time stamp */ 389876bca880SMarcel Holtmann __net_timestamp(skb); 389976bca880SMarcel Holtmann 390076bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3901b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3902c78ae283SMarcel Holtmann 390376bca880SMarcel Holtmann return 0; 390476bca880SMarcel Holtmann } 390576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 390676bca880SMarcel Holtmann 3907e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */ 3908e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb) 3909e875ff84SMarcel Holtmann { 3910581d6fd6SMarcel Holtmann /* Mark as diagnostic packet */ 3911d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_DIAG_PKT; 3912581d6fd6SMarcel Holtmann 3913e875ff84SMarcel Holtmann /* Time stamp */ 3914e875ff84SMarcel Holtmann __net_timestamp(skb); 3915e875ff84SMarcel Holtmann 3916581d6fd6SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3917581d6fd6SMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3918e875ff84SMarcel Holtmann 3919e875ff84SMarcel Holtmann return 0; 3920e875ff84SMarcel Holtmann } 3921e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag); 3922e875ff84SMarcel Holtmann 39235177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...) 39245177a838SMarcel Holtmann { 39255177a838SMarcel Holtmann va_list vargs; 39265177a838SMarcel Holtmann 39275177a838SMarcel Holtmann va_start(vargs, fmt); 39285177a838SMarcel Holtmann kfree_const(hdev->hw_info); 39295177a838SMarcel Holtmann hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 39305177a838SMarcel Holtmann va_end(vargs); 39315177a838SMarcel Holtmann } 39325177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info); 39335177a838SMarcel Holtmann 39345177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...) 39355177a838SMarcel Holtmann { 39365177a838SMarcel Holtmann va_list vargs; 39375177a838SMarcel Holtmann 39385177a838SMarcel Holtmann va_start(vargs, fmt); 39395177a838SMarcel Holtmann kfree_const(hdev->fw_info); 39405177a838SMarcel Holtmann hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 39415177a838SMarcel Holtmann va_end(vargs); 39425177a838SMarcel Holtmann } 39435177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info); 39445177a838SMarcel Holtmann 39451da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 39461da177e4SLinus Torvalds 39471da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 39481da177e4SLinus Torvalds { 39491da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 39501da177e4SLinus Torvalds 3951fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 395200629e0fSJohan Hedberg list_add_tail(&cb->list, &hci_cb_list); 3953fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 39541da177e4SLinus Torvalds 39551da177e4SLinus Torvalds return 0; 39561da177e4SLinus Torvalds } 39571da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 39581da177e4SLinus Torvalds 39591da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 39601da177e4SLinus Torvalds { 39611da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 39621da177e4SLinus Torvalds 3963fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 39641da177e4SLinus Torvalds list_del(&cb->list); 3965fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 39661da177e4SLinus Torvalds 39671da177e4SLinus Torvalds return 0; 39681da177e4SLinus Torvalds } 39691da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 39701da177e4SLinus Torvalds 397151086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 39721da177e4SLinus Torvalds { 3973cdc52faaSMarcel Holtmann int err; 3974cdc52faaSMarcel Holtmann 3975d79f34e3SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb), 3976d79f34e3SMarcel Holtmann skb->len); 39771da177e4SLinus Torvalds 39781da177e4SLinus Torvalds /* Time stamp */ 3979a61bbcf2SPatrick McHardy __net_timestamp(skb); 39801da177e4SLinus Torvalds 3981cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3982cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3983cd82e61cSMarcel Holtmann 3984cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3985cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3986470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 39871da177e4SLinus Torvalds } 39881da177e4SLinus Torvalds 39891da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 39901da177e4SLinus Torvalds skb_orphan(skb); 39911da177e4SLinus Torvalds 399273d0d3c8SMarcel Holtmann if (!test_bit(HCI_RUNNING, &hdev->flags)) { 399373d0d3c8SMarcel Holtmann kfree_skb(skb); 399473d0d3c8SMarcel Holtmann return; 399573d0d3c8SMarcel Holtmann } 399673d0d3c8SMarcel Holtmann 3997cdc52faaSMarcel Holtmann err = hdev->send(hdev, skb); 3998cdc52faaSMarcel Holtmann if (err < 0) { 39992064ee33SMarcel Holtmann bt_dev_err(hdev, "sending frame failed (%d)", err); 4000cdc52faaSMarcel Holtmann kfree_skb(skb); 4001cdc52faaSMarcel Holtmann } 40021da177e4SLinus Torvalds } 40031da177e4SLinus Torvalds 40041ca3a9d0SJohan Hedberg /* Send HCI command */ 400507dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 400607dc93ddSJohan Hedberg const void *param) 40071ca3a9d0SJohan Hedberg { 40081ca3a9d0SJohan Hedberg struct sk_buff *skb; 40091ca3a9d0SJohan Hedberg 40101ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 40111ca3a9d0SJohan Hedberg 40121ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 40131ca3a9d0SJohan Hedberg if (!skb) { 40142064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for command"); 40151ca3a9d0SJohan Hedberg return -ENOMEM; 40161ca3a9d0SJohan Hedberg } 40171ca3a9d0SJohan Hedberg 401849c922bbSStephen Hemminger /* Stand-alone HCI commands must be flagged as 401911714b3dSJohan Hedberg * single-command requests. 402011714b3dSJohan Hedberg */ 402144d27137SJohan Hedberg bt_cb(skb)->hci.req_flags |= HCI_REQ_START; 402211714b3dSJohan Hedberg 40231da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 4024c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 40251da177e4SLinus Torvalds 40261da177e4SLinus Torvalds return 0; 40271da177e4SLinus Torvalds } 40281da177e4SLinus Torvalds 4029d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen, 4030d6ee6ad7SLoic Poulain const void *param) 4031d6ee6ad7SLoic Poulain { 4032d6ee6ad7SLoic Poulain struct sk_buff *skb; 4033d6ee6ad7SLoic Poulain 4034d6ee6ad7SLoic Poulain if (hci_opcode_ogf(opcode) != 0x3f) { 4035d6ee6ad7SLoic Poulain /* A controller receiving a command shall respond with either 4036d6ee6ad7SLoic Poulain * a Command Status Event or a Command Complete Event. 4037d6ee6ad7SLoic Poulain * Therefore, all standard HCI commands must be sent via the 4038d6ee6ad7SLoic Poulain * standard API, using hci_send_cmd or hci_cmd_sync helpers. 4039d6ee6ad7SLoic Poulain * Some vendors do not comply with this rule for vendor-specific 4040d6ee6ad7SLoic Poulain * commands and do not return any event. We want to support 4041d6ee6ad7SLoic Poulain * unresponded commands for such cases only. 4042d6ee6ad7SLoic Poulain */ 4043d6ee6ad7SLoic Poulain bt_dev_err(hdev, "unresponded command not supported"); 4044d6ee6ad7SLoic Poulain return -EINVAL; 4045d6ee6ad7SLoic Poulain } 4046d6ee6ad7SLoic Poulain 4047d6ee6ad7SLoic Poulain skb = hci_prepare_cmd(hdev, opcode, plen, param); 4048d6ee6ad7SLoic Poulain if (!skb) { 4049d6ee6ad7SLoic Poulain bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)", 4050d6ee6ad7SLoic Poulain opcode); 4051d6ee6ad7SLoic Poulain return -ENOMEM; 4052d6ee6ad7SLoic Poulain } 4053d6ee6ad7SLoic Poulain 4054d6ee6ad7SLoic Poulain hci_send_frame(hdev, skb); 4055d6ee6ad7SLoic Poulain 4056d6ee6ad7SLoic Poulain return 0; 4057d6ee6ad7SLoic Poulain } 4058d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send); 4059d6ee6ad7SLoic Poulain 40601da177e4SLinus Torvalds /* Get data from the previously sent command */ 4061a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 40621da177e4SLinus Torvalds { 40631da177e4SLinus Torvalds struct hci_command_hdr *hdr; 40641da177e4SLinus Torvalds 40651da177e4SLinus Torvalds if (!hdev->sent_cmd) 40661da177e4SLinus Torvalds return NULL; 40671da177e4SLinus Torvalds 40681da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 40691da177e4SLinus Torvalds 4070a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 40711da177e4SLinus Torvalds return NULL; 40721da177e4SLinus Torvalds 4073f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 40741da177e4SLinus Torvalds 40751da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 40761da177e4SLinus Torvalds } 40771da177e4SLinus Torvalds 4078fbef168fSLoic Poulain /* Send HCI command and wait for command commplete event */ 4079fbef168fSLoic Poulain struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 4080fbef168fSLoic Poulain const void *param, u32 timeout) 4081fbef168fSLoic Poulain { 4082fbef168fSLoic Poulain struct sk_buff *skb; 4083fbef168fSLoic Poulain 4084fbef168fSLoic Poulain if (!test_bit(HCI_UP, &hdev->flags)) 4085fbef168fSLoic Poulain return ERR_PTR(-ENETDOWN); 4086fbef168fSLoic Poulain 4087fbef168fSLoic Poulain bt_dev_dbg(hdev, "opcode 0x%4.4x plen %d", opcode, plen); 4088fbef168fSLoic Poulain 4089b504430cSJohan Hedberg hci_req_sync_lock(hdev); 4090fbef168fSLoic Poulain skb = __hci_cmd_sync(hdev, opcode, plen, param, timeout); 4091b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 4092fbef168fSLoic Poulain 4093fbef168fSLoic Poulain return skb; 4094fbef168fSLoic Poulain } 4095fbef168fSLoic Poulain EXPORT_SYMBOL(hci_cmd_sync); 4096fbef168fSLoic Poulain 40971da177e4SLinus Torvalds /* Send ACL data */ 40981da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 40991da177e4SLinus Torvalds { 41001da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 41011da177e4SLinus Torvalds int len = skb->len; 41021da177e4SLinus Torvalds 4103badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 4104badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 41059c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 4106aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 4107aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 41081da177e4SLinus Torvalds } 41091da177e4SLinus Torvalds 4110ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 411173d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 41121da177e4SLinus Torvalds { 4113ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 41141da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 41151da177e4SLinus Torvalds struct sk_buff *list; 41161da177e4SLinus Torvalds 4117087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 4118087bfd99SGustavo Padovan skb->data_len = 0; 4119087bfd99SGustavo Padovan 4120d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 4121204a6e54SAndrei Emeltchenko 4122204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 4123ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 4124087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 4125204a6e54SAndrei Emeltchenko break; 4126204a6e54SAndrei Emeltchenko case HCI_AMP: 4127204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 4128204a6e54SAndrei Emeltchenko break; 4129204a6e54SAndrei Emeltchenko default: 41302064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type); 4131204a6e54SAndrei Emeltchenko return; 4132204a6e54SAndrei Emeltchenko } 4133087bfd99SGustavo Padovan 413470f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 413570f23020SAndrei Emeltchenko if (!list) { 41361da177e4SLinus Torvalds /* Non fragmented */ 41371da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 41381da177e4SLinus Torvalds 413973d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 41401da177e4SLinus Torvalds } else { 41411da177e4SLinus Torvalds /* Fragmented */ 41421da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 41431da177e4SLinus Torvalds 41441da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 41451da177e4SLinus Torvalds 41469cfd5a23SJukka Rissanen /* Queue all fragments atomically. We need to use spin_lock_bh 41479cfd5a23SJukka Rissanen * here because of 6LoWPAN links, as there this function is 41489cfd5a23SJukka Rissanen * called from softirq and using normal spin lock could cause 41499cfd5a23SJukka Rissanen * deadlocks. 41509cfd5a23SJukka Rissanen */ 41519cfd5a23SJukka Rissanen spin_lock_bh(&queue->lock); 41521da177e4SLinus Torvalds 415373d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 4154e702112fSAndrei Emeltchenko 4155e702112fSAndrei Emeltchenko flags &= ~ACL_START; 4156e702112fSAndrei Emeltchenko flags |= ACL_CONT; 41571da177e4SLinus Torvalds do { 41581da177e4SLinus Torvalds skb = list; list = list->next; 41591da177e4SLinus Torvalds 4160d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 4161e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 41621da177e4SLinus Torvalds 41631da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 41641da177e4SLinus Torvalds 416573d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 41661da177e4SLinus Torvalds } while (list); 41671da177e4SLinus Torvalds 41689cfd5a23SJukka Rissanen spin_unlock_bh(&queue->lock); 41691da177e4SLinus Torvalds } 417073d80debSLuiz Augusto von Dentz } 417173d80debSLuiz Augusto von Dentz 417273d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 417373d80debSLuiz Augusto von Dentz { 4174ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 417573d80debSLuiz Augusto von Dentz 4176f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 417773d80debSLuiz Augusto von Dentz 4178ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 41791da177e4SLinus Torvalds 41803eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 41811da177e4SLinus Torvalds } 41821da177e4SLinus Torvalds 41831da177e4SLinus Torvalds /* Send SCO data */ 41840d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 41851da177e4SLinus Torvalds { 41861da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 41871da177e4SLinus Torvalds struct hci_sco_hdr hdr; 41881da177e4SLinus Torvalds 41891da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 41901da177e4SLinus Torvalds 4191aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 41921da177e4SLinus Torvalds hdr.dlen = skb->len; 41931da177e4SLinus Torvalds 4194badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 4195badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 41969c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 41971da177e4SLinus Torvalds 4198d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_SCODATA_PKT; 4199c78ae283SMarcel Holtmann 42001da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 42013eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 42021da177e4SLinus Torvalds } 42031da177e4SLinus Torvalds 42041da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 42051da177e4SLinus Torvalds 42061da177e4SLinus Torvalds /* HCI Connection scheduler */ 42076039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 4208a8c5fb1aSGustavo Padovan int *quote) 42091da177e4SLinus Torvalds { 42101da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 42118035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 4212abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 42131da177e4SLinus Torvalds 42141da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 42151da177e4SLinus Torvalds * added and removed with TX task disabled. */ 4216bf4c6325SGustavo F. Padovan 4217bf4c6325SGustavo F. Padovan rcu_read_lock(); 4218bf4c6325SGustavo F. Padovan 4219bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4220769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 42211da177e4SLinus Torvalds continue; 4222769be974SMarcel Holtmann 4223769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 4224769be974SMarcel Holtmann continue; 4225769be974SMarcel Holtmann 42261da177e4SLinus Torvalds num++; 42271da177e4SLinus Torvalds 42281da177e4SLinus Torvalds if (c->sent < min) { 42291da177e4SLinus Torvalds min = c->sent; 42301da177e4SLinus Torvalds conn = c; 42311da177e4SLinus Torvalds } 423252087a79SLuiz Augusto von Dentz 423352087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 423452087a79SLuiz Augusto von Dentz break; 42351da177e4SLinus Torvalds } 42361da177e4SLinus Torvalds 4237bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4238bf4c6325SGustavo F. Padovan 42391da177e4SLinus Torvalds if (conn) { 42406ed58ec5SVille Tervo int cnt, q; 42416ed58ec5SVille Tervo 42426ed58ec5SVille Tervo switch (conn->type) { 42436ed58ec5SVille Tervo case ACL_LINK: 42446ed58ec5SVille Tervo cnt = hdev->acl_cnt; 42456ed58ec5SVille Tervo break; 42466ed58ec5SVille Tervo case SCO_LINK: 42476ed58ec5SVille Tervo case ESCO_LINK: 42486ed58ec5SVille Tervo cnt = hdev->sco_cnt; 42496ed58ec5SVille Tervo break; 42506ed58ec5SVille Tervo case LE_LINK: 42516ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 42526ed58ec5SVille Tervo break; 42536ed58ec5SVille Tervo default: 42546ed58ec5SVille Tervo cnt = 0; 42552064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown link type %d", conn->type); 42566ed58ec5SVille Tervo } 42576ed58ec5SVille Tervo 42586ed58ec5SVille Tervo q = cnt / num; 42591da177e4SLinus Torvalds *quote = q ? q : 1; 42601da177e4SLinus Torvalds } else 42611da177e4SLinus Torvalds *quote = 0; 42621da177e4SLinus Torvalds 42631da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 42641da177e4SLinus Torvalds return conn; 42651da177e4SLinus Torvalds } 42661da177e4SLinus Torvalds 42676039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 42681da177e4SLinus Torvalds { 42691da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 42701da177e4SLinus Torvalds struct hci_conn *c; 42711da177e4SLinus Torvalds 42722064ee33SMarcel Holtmann bt_dev_err(hdev, "link tx timeout"); 42731da177e4SLinus Torvalds 4274bf4c6325SGustavo F. Padovan rcu_read_lock(); 4275bf4c6325SGustavo F. Padovan 42761da177e4SLinus Torvalds /* Kill stalled connections */ 4277bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4278bae1f5d9SVille Tervo if (c->type == type && c->sent) { 42792064ee33SMarcel Holtmann bt_dev_err(hdev, "killing stalled connection %pMR", 42802064ee33SMarcel Holtmann &c->dst); 4281bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 42821da177e4SLinus Torvalds } 42831da177e4SLinus Torvalds } 4284bf4c6325SGustavo F. Padovan 4285bf4c6325SGustavo F. Padovan rcu_read_unlock(); 42861da177e4SLinus Torvalds } 42871da177e4SLinus Torvalds 42886039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 428973d80debSLuiz Augusto von Dentz int *quote) 429073d80debSLuiz Augusto von Dentz { 429173d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 429273d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 4293abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 429473d80debSLuiz Augusto von Dentz struct hci_conn *conn; 429573d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 429673d80debSLuiz Augusto von Dentz 429773d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 429873d80debSLuiz Augusto von Dentz 4299bf4c6325SGustavo F. Padovan rcu_read_lock(); 4300bf4c6325SGustavo F. Padovan 4301bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 430273d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 430373d80debSLuiz Augusto von Dentz 430473d80debSLuiz Augusto von Dentz if (conn->type != type) 430573d80debSLuiz Augusto von Dentz continue; 430673d80debSLuiz Augusto von Dentz 430773d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 430873d80debSLuiz Augusto von Dentz continue; 430973d80debSLuiz Augusto von Dentz 431073d80debSLuiz Augusto von Dentz conn_num++; 431173d80debSLuiz Augusto von Dentz 43128192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 431373d80debSLuiz Augusto von Dentz struct sk_buff *skb; 431473d80debSLuiz Augusto von Dentz 431573d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 431673d80debSLuiz Augusto von Dentz continue; 431773d80debSLuiz Augusto von Dentz 431873d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 431973d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 432073d80debSLuiz Augusto von Dentz continue; 432173d80debSLuiz Augusto von Dentz 432273d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 432373d80debSLuiz Augusto von Dentz num = 0; 432473d80debSLuiz Augusto von Dentz min = ~0; 432573d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 432673d80debSLuiz Augusto von Dentz } 432773d80debSLuiz Augusto von Dentz 432873d80debSLuiz Augusto von Dentz num++; 432973d80debSLuiz Augusto von Dentz 433073d80debSLuiz Augusto von Dentz if (conn->sent < min) { 433173d80debSLuiz Augusto von Dentz min = conn->sent; 433273d80debSLuiz Augusto von Dentz chan = tmp; 433373d80debSLuiz Augusto von Dentz } 433473d80debSLuiz Augusto von Dentz } 433573d80debSLuiz Augusto von Dentz 433673d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 433773d80debSLuiz Augusto von Dentz break; 433873d80debSLuiz Augusto von Dentz } 433973d80debSLuiz Augusto von Dentz 4340bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4341bf4c6325SGustavo F. Padovan 434273d80debSLuiz Augusto von Dentz if (!chan) 434373d80debSLuiz Augusto von Dentz return NULL; 434473d80debSLuiz Augusto von Dentz 434573d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 434673d80debSLuiz Augusto von Dentz case ACL_LINK: 434773d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 434873d80debSLuiz Augusto von Dentz break; 4349bd1eb66bSAndrei Emeltchenko case AMP_LINK: 4350bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 4351bd1eb66bSAndrei Emeltchenko break; 435273d80debSLuiz Augusto von Dentz case SCO_LINK: 435373d80debSLuiz Augusto von Dentz case ESCO_LINK: 435473d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 435573d80debSLuiz Augusto von Dentz break; 435673d80debSLuiz Augusto von Dentz case LE_LINK: 435773d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 435873d80debSLuiz Augusto von Dentz break; 435973d80debSLuiz Augusto von Dentz default: 436073d80debSLuiz Augusto von Dentz cnt = 0; 43612064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown link type %d", chan->conn->type); 436273d80debSLuiz Augusto von Dentz } 436373d80debSLuiz Augusto von Dentz 436473d80debSLuiz Augusto von Dentz q = cnt / num; 436573d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 436673d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 436773d80debSLuiz Augusto von Dentz return chan; 436873d80debSLuiz Augusto von Dentz } 436973d80debSLuiz Augusto von Dentz 437002b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 437102b20f0bSLuiz Augusto von Dentz { 437202b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 437302b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 437402b20f0bSLuiz Augusto von Dentz int num = 0; 437502b20f0bSLuiz Augusto von Dentz 437602b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 437702b20f0bSLuiz Augusto von Dentz 4378bf4c6325SGustavo F. Padovan rcu_read_lock(); 4379bf4c6325SGustavo F. Padovan 4380bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 438102b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 438202b20f0bSLuiz Augusto von Dentz 438302b20f0bSLuiz Augusto von Dentz if (conn->type != type) 438402b20f0bSLuiz Augusto von Dentz continue; 438502b20f0bSLuiz Augusto von Dentz 438602b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 438702b20f0bSLuiz Augusto von Dentz continue; 438802b20f0bSLuiz Augusto von Dentz 438902b20f0bSLuiz Augusto von Dentz num++; 439002b20f0bSLuiz Augusto von Dentz 43918192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 439202b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 439302b20f0bSLuiz Augusto von Dentz 439402b20f0bSLuiz Augusto von Dentz if (chan->sent) { 439502b20f0bSLuiz Augusto von Dentz chan->sent = 0; 439602b20f0bSLuiz Augusto von Dentz continue; 439702b20f0bSLuiz Augusto von Dentz } 439802b20f0bSLuiz Augusto von Dentz 439902b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 440002b20f0bSLuiz Augusto von Dentz continue; 440102b20f0bSLuiz Augusto von Dentz 440202b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 440302b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 440402b20f0bSLuiz Augusto von Dentz continue; 440502b20f0bSLuiz Augusto von Dentz 440602b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 440702b20f0bSLuiz Augusto von Dentz 440802b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 440902b20f0bSLuiz Augusto von Dentz skb->priority); 441002b20f0bSLuiz Augusto von Dentz } 441102b20f0bSLuiz Augusto von Dentz 441202b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 441302b20f0bSLuiz Augusto von Dentz break; 441402b20f0bSLuiz Augusto von Dentz } 4415bf4c6325SGustavo F. Padovan 4416bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4417bf4c6325SGustavo F. Padovan 441802b20f0bSLuiz Augusto von Dentz } 441902b20f0bSLuiz Augusto von Dentz 4420b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4421b71d385aSAndrei Emeltchenko { 4422b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4423b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4424b71d385aSAndrei Emeltchenko } 4425b71d385aSAndrei Emeltchenko 44266039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 44271da177e4SLinus Torvalds { 4428d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 44291da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 44301da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 443163d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 44325f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 4433bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 44341da177e4SLinus Torvalds } 443563d2bc1bSAndrei Emeltchenko } 44361da177e4SLinus Torvalds 44377fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */ 44387fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev) 44397fedd3bbSAbhishek Pandit-Subedi { 44407fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn; 44417fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb; 44427fedd3bbSAbhishek Pandit-Subedi int quote; 44437fedd3bbSAbhishek Pandit-Subedi 44447fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name); 44457fedd3bbSAbhishek Pandit-Subedi 44467fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, SCO_LINK)) 44477fedd3bbSAbhishek Pandit-Subedi return; 44487fedd3bbSAbhishek Pandit-Subedi 44497fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 44507fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 44517fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len); 44527fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb); 44537fedd3bbSAbhishek Pandit-Subedi 44547fedd3bbSAbhishek Pandit-Subedi conn->sent++; 44557fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0) 44567fedd3bbSAbhishek Pandit-Subedi conn->sent = 0; 44577fedd3bbSAbhishek Pandit-Subedi } 44587fedd3bbSAbhishek Pandit-Subedi } 44597fedd3bbSAbhishek Pandit-Subedi } 44607fedd3bbSAbhishek Pandit-Subedi 44617fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev) 44627fedd3bbSAbhishek Pandit-Subedi { 44637fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn; 44647fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb; 44657fedd3bbSAbhishek Pandit-Subedi int quote; 44667fedd3bbSAbhishek Pandit-Subedi 44677fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name); 44687fedd3bbSAbhishek Pandit-Subedi 44697fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, ESCO_LINK)) 44707fedd3bbSAbhishek Pandit-Subedi return; 44717fedd3bbSAbhishek Pandit-Subedi 44727fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 44737fedd3bbSAbhishek Pandit-Subedi "e))) { 44747fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 44757fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len); 44767fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb); 44777fedd3bbSAbhishek Pandit-Subedi 44787fedd3bbSAbhishek Pandit-Subedi conn->sent++; 44797fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0) 44807fedd3bbSAbhishek Pandit-Subedi conn->sent = 0; 44817fedd3bbSAbhishek Pandit-Subedi } 44827fedd3bbSAbhishek Pandit-Subedi } 44837fedd3bbSAbhishek Pandit-Subedi } 44847fedd3bbSAbhishek Pandit-Subedi 44856039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 448663d2bc1bSAndrei Emeltchenko { 448763d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 448863d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 448963d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 449063d2bc1bSAndrei Emeltchenko int quote; 449163d2bc1bSAndrei Emeltchenko 449263d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 449304837f64SMarcel Holtmann 449473d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 449573d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 4496ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4497ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 449873d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 449973d80debSLuiz Augusto von Dentz skb->len, skb->priority); 450073d80debSLuiz Augusto von Dentz 4501ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4502ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4503ec1cce24SLuiz Augusto von Dentz break; 4504ec1cce24SLuiz Augusto von Dentz 4505ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4506ec1cce24SLuiz Augusto von Dentz 450773d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 450873d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 450904837f64SMarcel Holtmann 451057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 45111da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 45121da177e4SLinus Torvalds 45131da177e4SLinus Torvalds hdev->acl_cnt--; 451473d80debSLuiz Augusto von Dentz chan->sent++; 451573d80debSLuiz Augusto von Dentz chan->conn->sent++; 45167fedd3bbSAbhishek Pandit-Subedi 45177fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */ 45187fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev); 45197fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev); 45201da177e4SLinus Torvalds } 45211da177e4SLinus Torvalds } 452202b20f0bSLuiz Augusto von Dentz 452302b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 452402b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 45251da177e4SLinus Torvalds } 45261da177e4SLinus Torvalds 45276039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4528b71d385aSAndrei Emeltchenko { 452963d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4530b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4531b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4532b71d385aSAndrei Emeltchenko int quote; 4533bd1eb66bSAndrei Emeltchenko u8 type; 4534b71d385aSAndrei Emeltchenko 453563d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4536b71d385aSAndrei Emeltchenko 4537bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4538bd1eb66bSAndrei Emeltchenko 4539bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4540bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4541bd1eb66bSAndrei Emeltchenko else 4542bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4543bd1eb66bSAndrei Emeltchenko 4544b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4545bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4546b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4547b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4548b71d385aSAndrei Emeltchenko int blocks; 4549b71d385aSAndrei Emeltchenko 4550b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4551b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4552b71d385aSAndrei Emeltchenko 4553b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4554b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4555b71d385aSAndrei Emeltchenko break; 4556b71d385aSAndrei Emeltchenko 4557b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4558b71d385aSAndrei Emeltchenko 4559b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4560b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4561b71d385aSAndrei Emeltchenko return; 4562b71d385aSAndrei Emeltchenko 4563b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4564b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4565b71d385aSAndrei Emeltchenko 456657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4567b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4568b71d385aSAndrei Emeltchenko 4569b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4570b71d385aSAndrei Emeltchenko quote -= blocks; 4571b71d385aSAndrei Emeltchenko 4572b71d385aSAndrei Emeltchenko chan->sent += blocks; 4573b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4574b71d385aSAndrei Emeltchenko } 4575b71d385aSAndrei Emeltchenko } 4576b71d385aSAndrei Emeltchenko 4577b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4578bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4579b71d385aSAndrei Emeltchenko } 4580b71d385aSAndrei Emeltchenko 45816039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4582b71d385aSAndrei Emeltchenko { 4583b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4584b71d385aSAndrei Emeltchenko 4585bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4586ca8bee5dSMarcel Holtmann if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY) 4587bd1eb66bSAndrei Emeltchenko return; 4588bd1eb66bSAndrei Emeltchenko 4589bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4590bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4591b71d385aSAndrei Emeltchenko return; 4592b71d385aSAndrei Emeltchenko 4593b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4594b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4595b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4596b71d385aSAndrei Emeltchenko break; 4597b71d385aSAndrei Emeltchenko 4598b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4599b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4600b71d385aSAndrei Emeltchenko break; 4601b71d385aSAndrei Emeltchenko } 4602b71d385aSAndrei Emeltchenko } 4603b71d385aSAndrei Emeltchenko 46046039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 46056ed58ec5SVille Tervo { 460673d80debSLuiz Augusto von Dentz struct hci_chan *chan; 46076ed58ec5SVille Tervo struct sk_buff *skb; 460802b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 46096ed58ec5SVille Tervo 46106ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 46116ed58ec5SVille Tervo 461252087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 461352087a79SLuiz Augusto von Dentz return; 461452087a79SLuiz Augusto von Dentz 46156ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 46161b1d29e5SLuiz Augusto von Dentz 46171b1d29e5SLuiz Augusto von Dentz __check_timeout(hdev, cnt); 46181b1d29e5SLuiz Augusto von Dentz 461902b20f0bSLuiz Augusto von Dentz tmp = cnt; 462073d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 4621ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4622ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 462373d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 462473d80debSLuiz Augusto von Dentz skb->len, skb->priority); 46256ed58ec5SVille Tervo 4626ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4627ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4628ec1cce24SLuiz Augusto von Dentz break; 4629ec1cce24SLuiz Augusto von Dentz 4630ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4631ec1cce24SLuiz Augusto von Dentz 463257d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 46336ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 46346ed58ec5SVille Tervo 46356ed58ec5SVille Tervo cnt--; 463673d80debSLuiz Augusto von Dentz chan->sent++; 463773d80debSLuiz Augusto von Dentz chan->conn->sent++; 46387fedd3bbSAbhishek Pandit-Subedi 46397fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */ 46407fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev); 46417fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev); 46426ed58ec5SVille Tervo } 46436ed58ec5SVille Tervo } 464473d80debSLuiz Augusto von Dentz 46456ed58ec5SVille Tervo if (hdev->le_pkts) 46466ed58ec5SVille Tervo hdev->le_cnt = cnt; 46476ed58ec5SVille Tervo else 46486ed58ec5SVille Tervo hdev->acl_cnt = cnt; 464902b20f0bSLuiz Augusto von Dentz 465002b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 465102b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 46526ed58ec5SVille Tervo } 46536ed58ec5SVille Tervo 46543eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 46551da177e4SLinus Torvalds { 46563eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 46571da177e4SLinus Torvalds struct sk_buff *skb; 46581da177e4SLinus Torvalds 46596ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 46606ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 46611da177e4SLinus Torvalds 4662d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 46631da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 46641da177e4SLinus Torvalds hci_sched_sco(hdev); 4665b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 46667fedd3bbSAbhishek Pandit-Subedi hci_sched_acl(hdev); 46676ed58ec5SVille Tervo hci_sched_le(hdev); 466852de599eSMarcel Holtmann } 46696ed58ec5SVille Tervo 46701da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 46711da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 467257d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 46731da177e4SLinus Torvalds } 46741da177e4SLinus Torvalds 467525985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 46761da177e4SLinus Torvalds 46771da177e4SLinus Torvalds /* ACL data packet */ 46786039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 46791da177e4SLinus Torvalds { 46801da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 46811da177e4SLinus Torvalds struct hci_conn *conn; 46821da177e4SLinus Torvalds __u16 handle, flags; 46831da177e4SLinus Torvalds 46841da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 46851da177e4SLinus Torvalds 46861da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 46871da177e4SLinus Torvalds flags = hci_flags(handle); 46881da177e4SLinus Torvalds handle = hci_handle(handle); 46891da177e4SLinus Torvalds 4690f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4691a8c5fb1aSGustavo Padovan handle, flags); 46921da177e4SLinus Torvalds 46931da177e4SLinus Torvalds hdev->stat.acl_rx++; 46941da177e4SLinus Torvalds 46951da177e4SLinus Torvalds hci_dev_lock(hdev); 46961da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 46971da177e4SLinus Torvalds hci_dev_unlock(hdev); 46981da177e4SLinus Torvalds 46991da177e4SLinus Torvalds if (conn) { 470065983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 470104837f64SMarcel Holtmann 47021da177e4SLinus Torvalds /* Send to upper protocol */ 4703686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 47041da177e4SLinus Torvalds return; 47051da177e4SLinus Torvalds } else { 47062064ee33SMarcel Holtmann bt_dev_err(hdev, "ACL packet for unknown connection handle %d", 47072064ee33SMarcel Holtmann handle); 47081da177e4SLinus Torvalds } 47091da177e4SLinus Torvalds 47101da177e4SLinus Torvalds kfree_skb(skb); 47111da177e4SLinus Torvalds } 47121da177e4SLinus Torvalds 47131da177e4SLinus Torvalds /* SCO data packet */ 47146039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 47151da177e4SLinus Torvalds { 47161da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 47171da177e4SLinus Torvalds struct hci_conn *conn; 4718debdedf2SMarcel Holtmann __u16 handle, flags; 47191da177e4SLinus Torvalds 47201da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 47211da177e4SLinus Torvalds 47221da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 4723debdedf2SMarcel Holtmann flags = hci_flags(handle); 4724debdedf2SMarcel Holtmann handle = hci_handle(handle); 47251da177e4SLinus Torvalds 4726debdedf2SMarcel Holtmann BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4727debdedf2SMarcel Holtmann handle, flags); 47281da177e4SLinus Torvalds 47291da177e4SLinus Torvalds hdev->stat.sco_rx++; 47301da177e4SLinus Torvalds 47311da177e4SLinus Torvalds hci_dev_lock(hdev); 47321da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 47331da177e4SLinus Torvalds hci_dev_unlock(hdev); 47341da177e4SLinus Torvalds 47351da177e4SLinus Torvalds if (conn) { 47361da177e4SLinus Torvalds /* Send to upper protocol */ 473700398e1dSAlain Michaud bt_cb(skb)->sco.pkt_status = flags & 0x03; 4738686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 47391da177e4SLinus Torvalds return; 47401da177e4SLinus Torvalds } else { 47412064ee33SMarcel Holtmann bt_dev_err(hdev, "SCO packet for unknown connection handle %d", 47422064ee33SMarcel Holtmann handle); 47431da177e4SLinus Torvalds } 47441da177e4SLinus Torvalds 47451da177e4SLinus Torvalds kfree_skb(skb); 47461da177e4SLinus Torvalds } 47471da177e4SLinus Torvalds 47489238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 47499238f36aSJohan Hedberg { 47509238f36aSJohan Hedberg struct sk_buff *skb; 47519238f36aSJohan Hedberg 47529238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 47539238f36aSJohan Hedberg if (!skb) 47549238f36aSJohan Hedberg return true; 47559238f36aSJohan Hedberg 475644d27137SJohan Hedberg return (bt_cb(skb)->hci.req_flags & HCI_REQ_START); 47579238f36aSJohan Hedberg } 47589238f36aSJohan Hedberg 475942c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 476042c6b129SJohan Hedberg { 476142c6b129SJohan Hedberg struct hci_command_hdr *sent; 476242c6b129SJohan Hedberg struct sk_buff *skb; 476342c6b129SJohan Hedberg u16 opcode; 476442c6b129SJohan Hedberg 476542c6b129SJohan Hedberg if (!hdev->sent_cmd) 476642c6b129SJohan Hedberg return; 476742c6b129SJohan Hedberg 476842c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 476942c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 477042c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 477142c6b129SJohan Hedberg return; 477242c6b129SJohan Hedberg 477342c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 477442c6b129SJohan Hedberg if (!skb) 477542c6b129SJohan Hedberg return; 477642c6b129SJohan Hedberg 477742c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 477842c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 477942c6b129SJohan Hedberg } 478042c6b129SJohan Hedberg 4781e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, 4782e6214487SJohan Hedberg hci_req_complete_t *req_complete, 4783e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 47849238f36aSJohan Hedberg { 47859238f36aSJohan Hedberg struct sk_buff *skb; 47869238f36aSJohan Hedberg unsigned long flags; 47879238f36aSJohan Hedberg 47889238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 47899238f36aSJohan Hedberg 479042c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 479142c6b129SJohan Hedberg * sent we need to do special handling of it. 47929238f36aSJohan Hedberg */ 479342c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 479442c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 479542c6b129SJohan Hedberg * reset complete event during init and any pending 479642c6b129SJohan Hedberg * command will never be completed. In such a case we 479742c6b129SJohan Hedberg * need to resend whatever was the last sent 479842c6b129SJohan Hedberg * command. 479942c6b129SJohan Hedberg */ 480042c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 480142c6b129SJohan Hedberg hci_resend_last(hdev); 480242c6b129SJohan Hedberg 48039238f36aSJohan Hedberg return; 480442c6b129SJohan Hedberg } 48059238f36aSJohan Hedberg 4806f80c5dadSJoão Paulo Rechi Vita /* If we reach this point this event matches the last command sent */ 4807f80c5dadSJoão Paulo Rechi Vita hci_dev_clear_flag(hdev, HCI_CMD_PENDING); 4808f80c5dadSJoão Paulo Rechi Vita 48099238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 48109238f36aSJohan Hedberg * this request the request is not yet complete. 48119238f36aSJohan Hedberg */ 48129238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 48139238f36aSJohan Hedberg return; 48149238f36aSJohan Hedberg 48159238f36aSJohan Hedberg /* If this was the last command in a request the complete 48169238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 48179238f36aSJohan Hedberg * command queue (hdev->cmd_q). 48189238f36aSJohan Hedberg */ 481944d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) { 482044d27137SJohan Hedberg *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb; 4821e6214487SJohan Hedberg return; 48229238f36aSJohan Hedberg } 4823e6214487SJohan Hedberg 482444d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_complete) { 482544d27137SJohan Hedberg *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete; 4826e6214487SJohan Hedberg return; 482753e21fbcSJohan Hedberg } 48289238f36aSJohan Hedberg 48299238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 48309238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 48319238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 483244d27137SJohan Hedberg if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) { 48339238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 48349238f36aSJohan Hedberg break; 48359238f36aSJohan Hedberg } 48369238f36aSJohan Hedberg 48373bd7594eSDouglas Anderson if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) 4838242c0ebdSMarcel Holtmann *req_complete_skb = bt_cb(skb)->hci.req_complete_skb; 48393bd7594eSDouglas Anderson else 48403bd7594eSDouglas Anderson *req_complete = bt_cb(skb)->hci.req_complete; 48419238f36aSJohan Hedberg kfree_skb(skb); 48429238f36aSJohan Hedberg } 48439238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 48449238f36aSJohan Hedberg } 48459238f36aSJohan Hedberg 4846b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 48471da177e4SLinus Torvalds { 4848b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 48491da177e4SLinus Torvalds struct sk_buff *skb; 48501da177e4SLinus Torvalds 48511da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 48521da177e4SLinus Torvalds 48531da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 4854cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4855cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4856cd82e61cSMarcel Holtmann 48571da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 48581da177e4SLinus Torvalds /* Send copy to the sockets */ 4859470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 48601da177e4SLinus Torvalds } 48611da177e4SLinus Torvalds 4862eb8c101eSMattijs Korpershoek /* If the device has been opened in HCI_USER_CHANNEL, 4863eb8c101eSMattijs Korpershoek * the userspace has exclusive access to device. 4864eb8c101eSMattijs Korpershoek * When device is HCI_INIT, we still need to process 4865eb8c101eSMattijs Korpershoek * the data packets to the driver in order 4866eb8c101eSMattijs Korpershoek * to complete its setup(). 4867eb8c101eSMattijs Korpershoek */ 4868eb8c101eSMattijs Korpershoek if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 4869eb8c101eSMattijs Korpershoek !test_bit(HCI_INIT, &hdev->flags)) { 48701da177e4SLinus Torvalds kfree_skb(skb); 48711da177e4SLinus Torvalds continue; 48721da177e4SLinus Torvalds } 48731da177e4SLinus Torvalds 48741da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 48751da177e4SLinus Torvalds /* Don't process data packets in this states. */ 4876d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 48771da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 48781da177e4SLinus Torvalds case HCI_SCODATA_PKT: 4879cc974003SMarcel Holtmann case HCI_ISODATA_PKT: 48801da177e4SLinus Torvalds kfree_skb(skb); 48811da177e4SLinus Torvalds continue; 48823ff50b79SStephen Hemminger } 48831da177e4SLinus Torvalds } 48841da177e4SLinus Torvalds 48851da177e4SLinus Torvalds /* Process frame */ 4886d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 48871da177e4SLinus Torvalds case HCI_EVENT_PKT: 4888b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 48891da177e4SLinus Torvalds hci_event_packet(hdev, skb); 48901da177e4SLinus Torvalds break; 48911da177e4SLinus Torvalds 48921da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 48931da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 48941da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 48951da177e4SLinus Torvalds break; 48961da177e4SLinus Torvalds 48971da177e4SLinus Torvalds case HCI_SCODATA_PKT: 48981da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 48991da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 49001da177e4SLinus Torvalds break; 49011da177e4SLinus Torvalds 49021da177e4SLinus Torvalds default: 49031da177e4SLinus Torvalds kfree_skb(skb); 49041da177e4SLinus Torvalds break; 49051da177e4SLinus Torvalds } 49061da177e4SLinus Torvalds } 49071da177e4SLinus Torvalds } 49081da177e4SLinus Torvalds 4909c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 49101da177e4SLinus Torvalds { 4911c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 49121da177e4SLinus Torvalds struct sk_buff *skb; 49131da177e4SLinus Torvalds 49142104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 49152104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 49161da177e4SLinus Torvalds 49171da177e4SLinus Torvalds /* Send queued commands */ 49185a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 49195a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 49205a08ecceSAndrei Emeltchenko if (!skb) 49215a08ecceSAndrei Emeltchenko return; 49225a08ecceSAndrei Emeltchenko 49231da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 49241da177e4SLinus Torvalds 4925a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 492670f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 4927f80c5dadSJoão Paulo Rechi Vita if (hci_req_status_pend(hdev)) 4928f80c5dadSJoão Paulo Rechi Vita hci_dev_set_flag(hdev, HCI_CMD_PENDING); 49291da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 493057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 49317bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 493265cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 49337bdb8a5cSSzymon Janc else 493465cc2b49SMarcel Holtmann schedule_delayed_work(&hdev->cmd_timer, 493565cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT); 49361da177e4SLinus Torvalds } else { 49371da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4938c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 49391da177e4SLinus Torvalds } 49401da177e4SLinus Torvalds } 49411da177e4SLinus Torvalds } 4942