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> 293df92b31SSasha Levin #include <linux/idr.h> 30611b30f7SMarcel Holtmann #include <linux/rfkill.h> 31baf27f6eSMarcel Holtmann #include <linux/debugfs.h> 3299780a7bSJohan Hedberg #include <linux/crypto.h> 3347219839SMarcel Holtmann #include <asm/unaligned.h> 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 361da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 374bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h> 38af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h> 391da177e4SLinus Torvalds 400857dd3bSJohan Hedberg #include "hci_request.h" 4160c5f5fbSMarcel Holtmann #include "hci_debugfs.h" 42970c4e46SJohan Hedberg #include "smp.h" 436d5d2ee6SHeiner Kallweit #include "leds.h" 44970c4e46SJohan Hedberg 45b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 46c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 473eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds /* HCI device list */ 501da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 511da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 521da177e4SLinus Torvalds 531da177e4SLinus Torvalds /* HCI callback list */ 541da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 55fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock); 561da177e4SLinus Torvalds 573df92b31SSasha Levin /* HCI ID Numbering */ 583df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 593df92b31SSasha Levin 60baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */ 61baf27f6eSMarcel Holtmann 624b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf, 634b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 644b4148e9SMarcel Holtmann { 654b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 664b4148e9SMarcel Holtmann char buf[3]; 674b4148e9SMarcel Holtmann 68b7cb93e5SMarcel Holtmann buf[0] = hci_dev_test_flag(hdev, HCI_DUT_MODE) ? 'Y' : 'N'; 694b4148e9SMarcel Holtmann buf[1] = '\n'; 704b4148e9SMarcel Holtmann buf[2] = '\0'; 714b4148e9SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 724b4148e9SMarcel Holtmann } 734b4148e9SMarcel Holtmann 744b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf, 754b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 764b4148e9SMarcel Holtmann { 774b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 784b4148e9SMarcel Holtmann struct sk_buff *skb; 794b4148e9SMarcel Holtmann bool enable; 803bf5e97dSAndy Shevchenko int err; 814b4148e9SMarcel Holtmann 824b4148e9SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 834b4148e9SMarcel Holtmann return -ENETDOWN; 844b4148e9SMarcel Holtmann 853bf5e97dSAndy Shevchenko err = kstrtobool_from_user(user_buf, count, &enable); 863bf5e97dSAndy Shevchenko if (err) 873bf5e97dSAndy Shevchenko return err; 884b4148e9SMarcel Holtmann 89b7cb93e5SMarcel Holtmann if (enable == hci_dev_test_flag(hdev, HCI_DUT_MODE)) 904b4148e9SMarcel Holtmann return -EALREADY; 914b4148e9SMarcel Holtmann 92b504430cSJohan Hedberg hci_req_sync_lock(hdev); 934b4148e9SMarcel Holtmann if (enable) 944b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL, 954b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 964b4148e9SMarcel Holtmann else 974b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, 984b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 99b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 1004b4148e9SMarcel Holtmann 1014b4148e9SMarcel Holtmann if (IS_ERR(skb)) 1024b4148e9SMarcel Holtmann return PTR_ERR(skb); 1034b4148e9SMarcel Holtmann 1044b4148e9SMarcel Holtmann kfree_skb(skb); 1054b4148e9SMarcel Holtmann 106b7cb93e5SMarcel Holtmann hci_dev_change_flag(hdev, HCI_DUT_MODE); 1074b4148e9SMarcel Holtmann 1084b4148e9SMarcel Holtmann return count; 1094b4148e9SMarcel Holtmann } 1104b4148e9SMarcel Holtmann 1114b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = { 1124b4148e9SMarcel Holtmann .open = simple_open, 1134b4148e9SMarcel Holtmann .read = dut_mode_read, 1144b4148e9SMarcel Holtmann .write = dut_mode_write, 1154b4148e9SMarcel Holtmann .llseek = default_llseek, 1164b4148e9SMarcel Holtmann }; 1174b4148e9SMarcel Holtmann 1184b4113d6SMarcel Holtmann static ssize_t vendor_diag_read(struct file *file, char __user *user_buf, 1194b4113d6SMarcel Holtmann size_t count, loff_t *ppos) 1204b4113d6SMarcel Holtmann { 1214b4113d6SMarcel Holtmann struct hci_dev *hdev = file->private_data; 1224b4113d6SMarcel Holtmann char buf[3]; 1234b4113d6SMarcel Holtmann 1244b4113d6SMarcel Holtmann buf[0] = hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) ? 'Y' : 'N'; 1254b4113d6SMarcel Holtmann buf[1] = '\n'; 1264b4113d6SMarcel Holtmann buf[2] = '\0'; 1274b4113d6SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 1284b4113d6SMarcel Holtmann } 1294b4113d6SMarcel Holtmann 1304b4113d6SMarcel Holtmann static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf, 1314b4113d6SMarcel Holtmann size_t count, loff_t *ppos) 1324b4113d6SMarcel Holtmann { 1334b4113d6SMarcel Holtmann struct hci_dev *hdev = file->private_data; 1344b4113d6SMarcel Holtmann bool enable; 1354b4113d6SMarcel Holtmann int err; 1364b4113d6SMarcel Holtmann 1373bf5e97dSAndy Shevchenko err = kstrtobool_from_user(user_buf, count, &enable); 1383bf5e97dSAndy Shevchenko if (err) 1393bf5e97dSAndy Shevchenko return err; 1404b4113d6SMarcel Holtmann 1417e995b9eSMarcel Holtmann /* When the diagnostic flags are not persistent and the transport 142b56c7b25SMarcel Holtmann * is not active or in user channel operation, then there is no need 143b56c7b25SMarcel Holtmann * for the vendor callback. Instead just store the desired value and 144b56c7b25SMarcel Holtmann * the setting will be programmed when the controller gets powered on. 1457e995b9eSMarcel Holtmann */ 1467e995b9eSMarcel Holtmann if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) && 147b56c7b25SMarcel Holtmann (!test_bit(HCI_RUNNING, &hdev->flags) || 148b56c7b25SMarcel Holtmann hci_dev_test_flag(hdev, HCI_USER_CHANNEL))) 1497e995b9eSMarcel Holtmann goto done; 1507e995b9eSMarcel Holtmann 151b504430cSJohan Hedberg hci_req_sync_lock(hdev); 1524b4113d6SMarcel Holtmann err = hdev->set_diag(hdev, enable); 153b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 1544b4113d6SMarcel Holtmann 1554b4113d6SMarcel Holtmann if (err < 0) 1564b4113d6SMarcel Holtmann return err; 1574b4113d6SMarcel Holtmann 1587e995b9eSMarcel Holtmann done: 1594b4113d6SMarcel Holtmann if (enable) 1604b4113d6SMarcel Holtmann hci_dev_set_flag(hdev, HCI_VENDOR_DIAG); 1614b4113d6SMarcel Holtmann else 1624b4113d6SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_VENDOR_DIAG); 1634b4113d6SMarcel Holtmann 1644b4113d6SMarcel Holtmann return count; 1654b4113d6SMarcel Holtmann } 1664b4113d6SMarcel Holtmann 1674b4113d6SMarcel Holtmann static const struct file_operations vendor_diag_fops = { 1684b4113d6SMarcel Holtmann .open = simple_open, 1694b4113d6SMarcel Holtmann .read = vendor_diag_read, 1704b4113d6SMarcel Holtmann .write = vendor_diag_write, 1714b4113d6SMarcel Holtmann .llseek = default_llseek, 1724b4113d6SMarcel Holtmann }; 1734b4113d6SMarcel Holtmann 174f640ee98SMarcel Holtmann static void hci_debugfs_create_basic(struct hci_dev *hdev) 175f640ee98SMarcel Holtmann { 176f640ee98SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 177f640ee98SMarcel Holtmann &dut_mode_fops); 178f640ee98SMarcel Holtmann 179f640ee98SMarcel Holtmann if (hdev->set_diag) 180f640ee98SMarcel Holtmann debugfs_create_file("vendor_diag", 0644, hdev->debugfs, hdev, 181f640ee98SMarcel Holtmann &vendor_diag_fops); 182f640ee98SMarcel Holtmann } 183f640ee98SMarcel Holtmann 184a1d01db1SJohan Hedberg static int hci_reset_req(struct hci_request *req, unsigned long opt) 1851da177e4SLinus Torvalds { 18642c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 1871da177e4SLinus Torvalds 1881da177e4SLinus Torvalds /* Reset device */ 18942c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 19042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 191a1d01db1SJohan Hedberg return 0; 1921da177e4SLinus Torvalds } 1931da177e4SLinus Torvalds 19442c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 1951da177e4SLinus Torvalds { 19642c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 1972455a3eaSAndrei Emeltchenko 1981da177e4SLinus Torvalds /* Read Local Supported Features */ 19942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 2001da177e4SLinus Torvalds 2011143e5a6SMarcel Holtmann /* Read Local Version */ 20242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2032177bab5SJohan Hedberg 2042177bab5SJohan Hedberg /* Read BD Address */ 20542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 2061da177e4SLinus Torvalds } 2071da177e4SLinus Torvalds 2080af801b9SJohan Hedberg static void amp_init1(struct hci_request *req) 209e61ef499SAndrei Emeltchenko { 21042c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 2112455a3eaSAndrei Emeltchenko 212e61ef499SAndrei Emeltchenko /* Read Local Version */ 21342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2146bcbc489SAndrei Emeltchenko 215f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 216f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 217f6996cfeSMarcel Holtmann 2186bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 21942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 220e71dfabaSAndrei Emeltchenko 221e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 22242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 2237528ca1cSMarcel Holtmann 224f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 225f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 226f38ba941SMarcel Holtmann 2277528ca1cSMarcel Holtmann /* Read Location Data */ 2287528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 229e61ef499SAndrei Emeltchenko } 230e61ef499SAndrei Emeltchenko 231a1d01db1SJohan Hedberg static int amp_init2(struct hci_request *req) 2320af801b9SJohan Hedberg { 2330af801b9SJohan Hedberg /* Read Local Supported Features. Not all AMP controllers 2340af801b9SJohan Hedberg * support this so it's placed conditionally in the second 2350af801b9SJohan Hedberg * stage init. 2360af801b9SJohan Hedberg */ 2370af801b9SJohan Hedberg if (req->hdev->commands[14] & 0x20) 2380af801b9SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 239a1d01db1SJohan Hedberg 240a1d01db1SJohan Hedberg return 0; 2410af801b9SJohan Hedberg } 2420af801b9SJohan Hedberg 243a1d01db1SJohan Hedberg static int hci_init1_req(struct hci_request *req, unsigned long opt) 244e61ef499SAndrei Emeltchenko { 24542c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 246e61ef499SAndrei Emeltchenko 247e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 248e61ef499SAndrei Emeltchenko 24911778716SAndrei Emeltchenko /* Reset */ 25011778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 25142c6b129SJohan Hedberg hci_reset_req(req, 0); 25211778716SAndrei Emeltchenko 253e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 254ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 25542c6b129SJohan Hedberg bredr_init(req); 256e61ef499SAndrei Emeltchenko break; 257e61ef499SAndrei Emeltchenko case HCI_AMP: 2580af801b9SJohan Hedberg amp_init1(req); 259e61ef499SAndrei Emeltchenko break; 260e61ef499SAndrei Emeltchenko default: 2612064ee33SMarcel Holtmann bt_dev_err(hdev, "Unknown device type %d", hdev->dev_type); 262e61ef499SAndrei Emeltchenko break; 263e61ef499SAndrei Emeltchenko } 264a1d01db1SJohan Hedberg 265a1d01db1SJohan Hedberg return 0; 266e61ef499SAndrei Emeltchenko } 267e61ef499SAndrei Emeltchenko 26842c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 2692177bab5SJohan Hedberg { 2702177bab5SJohan Hedberg __le16 param; 2712177bab5SJohan Hedberg __u8 flt_type; 2722177bab5SJohan Hedberg 2732177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 27442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 2752177bab5SJohan Hedberg 2762177bab5SJohan Hedberg /* Read Class of Device */ 27742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 2782177bab5SJohan Hedberg 2792177bab5SJohan Hedberg /* Read Local Name */ 28042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 2812177bab5SJohan Hedberg 2822177bab5SJohan Hedberg /* Read Voice Setting */ 28342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 2842177bab5SJohan Hedberg 285b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 286b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 287b4cb9fb2SMarcel Holtmann 2884b836f39SMarcel Holtmann /* Read Current IAC LAP */ 2894b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 2904b836f39SMarcel Holtmann 2912177bab5SJohan Hedberg /* Clear Event Filters */ 2922177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 29342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 2942177bab5SJohan Hedberg 2952177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 296dcf4adbfSJoe Perches param = cpu_to_le16(0x7d00); 29742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 2982177bab5SJohan Hedberg } 2992177bab5SJohan Hedberg 30042c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 3012177bab5SJohan Hedberg { 302c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 303c73eee91SJohan Hedberg 3042177bab5SJohan Hedberg /* Read LE Buffer Size */ 30542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 3062177bab5SJohan Hedberg 3072177bab5SJohan Hedberg /* Read LE Local Supported Features */ 30842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 3092177bab5SJohan Hedberg 310747d3f03SMarcel Holtmann /* Read LE Supported States */ 311747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 312747d3f03SMarcel Holtmann 313c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 314c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 315a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ENABLED); 3162177bab5SJohan Hedberg } 3172177bab5SJohan Hedberg 31842c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 3192177bab5SJohan Hedberg { 32042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 32142c6b129SJohan Hedberg 3222177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 3232177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 3242177bab5SJohan Hedberg * command otherwise. 3252177bab5SJohan Hedberg */ 3262177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 3272177bab5SJohan Hedberg 3282177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 3292177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 3302177bab5SJohan Hedberg */ 3312177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 3322177bab5SJohan Hedberg return; 3332177bab5SJohan Hedberg 3342177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 3352177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 336c7882cbdSMarcel Holtmann } else { 337c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 338c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 339c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 340c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 341c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 3425c3d3b4cSMarcel Holtmann 3435c3d3b4cSMarcel Holtmann /* If the controller supports the Disconnect command, enable 3445c3d3b4cSMarcel Holtmann * the corresponding event. In addition enable packet flow 3455c3d3b4cSMarcel Holtmann * control related events. 3465c3d3b4cSMarcel Holtmann */ 3475c3d3b4cSMarcel Holtmann if (hdev->commands[0] & 0x20) { 3485c3d3b4cSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 349c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 350c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 3515c3d3b4cSMarcel Holtmann } 3525c3d3b4cSMarcel Holtmann 3535c3d3b4cSMarcel Holtmann /* If the controller supports the Read Remote Version 3545c3d3b4cSMarcel Holtmann * Information command, enable the corresponding event. 3555c3d3b4cSMarcel Holtmann */ 3565c3d3b4cSMarcel Holtmann if (hdev->commands[2] & 0x80) 3575c3d3b4cSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information 3585c3d3b4cSMarcel Holtmann * Complete 3595c3d3b4cSMarcel Holtmann */ 3600da71f1bSMarcel Holtmann 3610da71f1bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) { 3620da71f1bSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 363c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 3642177bab5SJohan Hedberg } 3650da71f1bSMarcel Holtmann } 3662177bab5SJohan Hedberg 3679fe759ceSMarcel Holtmann if (lmp_inq_rssi_capable(hdev) || 3689fe759ceSMarcel Holtmann test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) 3692177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 3702177bab5SJohan Hedberg 37170f56aa2SMarcel Holtmann if (lmp_ext_feat_capable(hdev)) 37270f56aa2SMarcel Holtmann events[4] |= 0x04; /* Read Remote Extended Features Complete */ 37370f56aa2SMarcel Holtmann 37470f56aa2SMarcel Holtmann if (lmp_esco_capable(hdev)) { 37570f56aa2SMarcel Holtmann events[5] |= 0x08; /* Synchronous Connection Complete */ 37670f56aa2SMarcel Holtmann events[5] |= 0x10; /* Synchronous Connection Changed */ 37770f56aa2SMarcel Holtmann } 37870f56aa2SMarcel Holtmann 3792177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 3802177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 3812177bab5SJohan Hedberg 3822177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 3832177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 3842177bab5SJohan Hedberg 3852177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 3862177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 3872177bab5SJohan Hedberg 3882177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 3892177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 3902177bab5SJohan Hedberg 3912177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 3922177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 3932177bab5SJohan Hedberg 3942177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 3952177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 3962177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 3972177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 3982177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 3992177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 4002177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 4012177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 4022177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 4032177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 4042177bab5SJohan Hedberg * Features Notification 4052177bab5SJohan Hedberg */ 4062177bab5SJohan Hedberg } 4072177bab5SJohan Hedberg 4082177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 4092177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 4102177bab5SJohan Hedberg 41142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 4122177bab5SJohan Hedberg } 4132177bab5SJohan Hedberg 414a1d01db1SJohan Hedberg static int hci_init2_req(struct hci_request *req, unsigned long opt) 4152177bab5SJohan Hedberg { 41642c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 41742c6b129SJohan Hedberg 4180af801b9SJohan Hedberg if (hdev->dev_type == HCI_AMP) 4190af801b9SJohan Hedberg return amp_init2(req); 4200af801b9SJohan Hedberg 4212177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 42242c6b129SJohan Hedberg bredr_setup(req); 42356f87901SJohan Hedberg else 424a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED); 4252177bab5SJohan Hedberg 4262177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 42742c6b129SJohan Hedberg le_setup(req); 4282177bab5SJohan Hedberg 4290f3adeaeSMarcel Holtmann /* All Bluetooth 1.2 and later controllers should support the 4300f3adeaeSMarcel Holtmann * HCI command for reading the local supported commands. 4310f3adeaeSMarcel Holtmann * 4320f3adeaeSMarcel Holtmann * Unfortunately some controllers indicate Bluetooth 1.2 support, 4330f3adeaeSMarcel Holtmann * but do not have support for this command. If that is the case, 4340f3adeaeSMarcel Holtmann * the driver can quirk the behavior and skip reading the local 4350f3adeaeSMarcel Holtmann * supported commands. 4363f8e2d75SJohan Hedberg */ 4370f3adeaeSMarcel Holtmann if (hdev->hci_ver > BLUETOOTH_VER_1_1 && 4380f3adeaeSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks)) 43942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 4402177bab5SJohan Hedberg 4412177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 44257af75a8SMarcel Holtmann /* When SSP is available, then the host features page 44357af75a8SMarcel Holtmann * should also be available as well. However some 44457af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 44557af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 44657af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 44757af75a8SMarcel Holtmann */ 44857af75a8SMarcel Holtmann hdev->max_page = 0x01; 44957af75a8SMarcel Holtmann 450d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) { 4512177bab5SJohan Hedberg u8 mode = 0x01; 452574ea3c7SMarcel Holtmann 45342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 4542177bab5SJohan Hedberg sizeof(mode), &mode); 4552177bab5SJohan Hedberg } else { 4562177bab5SJohan Hedberg struct hci_cp_write_eir cp; 4572177bab5SJohan Hedberg 4582177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 4592177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 4602177bab5SJohan Hedberg 46142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 4622177bab5SJohan Hedberg } 4632177bab5SJohan Hedberg } 4642177bab5SJohan Hedberg 465043ec9bfSMarcel Holtmann if (lmp_inq_rssi_capable(hdev) || 466043ec9bfSMarcel Holtmann test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) { 46704422da9SMarcel Holtmann u8 mode; 46804422da9SMarcel Holtmann 46904422da9SMarcel Holtmann /* If Extended Inquiry Result events are supported, then 47004422da9SMarcel Holtmann * they are clearly preferred over Inquiry Result with RSSI 47104422da9SMarcel Holtmann * events. 47204422da9SMarcel Holtmann */ 47304422da9SMarcel Holtmann mode = lmp_ext_inq_capable(hdev) ? 0x02 : 0x01; 47404422da9SMarcel Holtmann 47504422da9SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 47604422da9SMarcel Holtmann } 4772177bab5SJohan Hedberg 4782177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 47942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 4802177bab5SJohan Hedberg 4812177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 4822177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 4832177bab5SJohan Hedberg 4842177bab5SJohan Hedberg cp.page = 0x01; 48542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 48642c6b129SJohan Hedberg sizeof(cp), &cp); 4872177bab5SJohan Hedberg } 4882177bab5SJohan Hedberg 489d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LINK_SECURITY)) { 4902177bab5SJohan Hedberg u8 enable = 1; 49142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 4922177bab5SJohan Hedberg &enable); 4932177bab5SJohan Hedberg } 494a1d01db1SJohan Hedberg 495a1d01db1SJohan Hedberg return 0; 4962177bab5SJohan Hedberg } 4972177bab5SJohan Hedberg 49842c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 4992177bab5SJohan Hedberg { 50042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 5012177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 5022177bab5SJohan Hedberg u16 link_policy = 0; 5032177bab5SJohan Hedberg 5042177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 5052177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 5062177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 5072177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 5082177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 5092177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 5102177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 5112177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 5122177bab5SJohan Hedberg 5132177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 51442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 5152177bab5SJohan Hedberg } 5162177bab5SJohan Hedberg 51742c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 5182177bab5SJohan Hedberg { 51942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 5202177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 5212177bab5SJohan Hedberg 522c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 523c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 524c73eee91SJohan Hedberg return; 525c73eee91SJohan Hedberg 5262177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 5272177bab5SJohan Hedberg 528d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) { 5292177bab5SJohan Hedberg cp.le = 0x01; 53032226e4fSMarcel Holtmann cp.simul = 0x00; 5312177bab5SJohan Hedberg } 5322177bab5SJohan Hedberg 5332177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 53442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 5352177bab5SJohan Hedberg &cp); 5362177bab5SJohan Hedberg } 5372177bab5SJohan Hedberg 538d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 539d62e6d67SJohan Hedberg { 540d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 541d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 542313f6888SMarcel Holtmann bool changed = false; 543d62e6d67SJohan Hedberg 544d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 545d62e6d67SJohan Hedberg * enable all necessary events for it. 546d62e6d67SJohan Hedberg */ 54753b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 548d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 549d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 550d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 551d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 552313f6888SMarcel Holtmann changed = true; 553d62e6d67SJohan Hedberg } 554d62e6d67SJohan Hedberg 555d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 556d62e6d67SJohan Hedberg * enable all necessary events for it. 557d62e6d67SJohan Hedberg */ 55853b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 559d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 560d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 561d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 562d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 563313f6888SMarcel Holtmann changed = true; 564d62e6d67SJohan Hedberg } 565d62e6d67SJohan Hedberg 56640c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 567313f6888SMarcel Holtmann if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) { 56840c59fcbSMarcel Holtmann events[2] |= 0x80; 569313f6888SMarcel Holtmann changed = true; 570313f6888SMarcel Holtmann } 57140c59fcbSMarcel Holtmann 572313f6888SMarcel Holtmann /* Some Broadcom based controllers indicate support for Set Event 573313f6888SMarcel Holtmann * Mask Page 2 command, but then actually do not support it. Since 574313f6888SMarcel Holtmann * the default value is all bits set to zero, the command is only 575313f6888SMarcel Holtmann * required if the event mask has to be changed. In case no change 576313f6888SMarcel Holtmann * to the event mask is needed, skip this command. 577313f6888SMarcel Holtmann */ 578313f6888SMarcel Holtmann if (changed) 579313f6888SMarcel Holtmann hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, 580313f6888SMarcel Holtmann sizeof(events), events); 581d62e6d67SJohan Hedberg } 582d62e6d67SJohan Hedberg 583a1d01db1SJohan Hedberg static int hci_init3_req(struct hci_request *req, unsigned long opt) 5842177bab5SJohan Hedberg { 58542c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 586d2c5d77fSJohan Hedberg u8 p; 58742c6b129SJohan Hedberg 5880da71f1bSMarcel Holtmann hci_setup_event_mask(req); 5890da71f1bSMarcel Holtmann 590e81be90bSJohan Hedberg if (hdev->commands[6] & 0x20 && 591e81be90bSJohan Hedberg !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 59248ce62c4SMarcel Holtmann struct hci_cp_read_stored_link_key cp; 59348ce62c4SMarcel Holtmann 59448ce62c4SMarcel Holtmann bacpy(&cp.bdaddr, BDADDR_ANY); 59548ce62c4SMarcel Holtmann cp.read_all = 0x01; 59648ce62c4SMarcel Holtmann hci_req_add(req, HCI_OP_READ_STORED_LINK_KEY, sizeof(cp), &cp); 59748ce62c4SMarcel Holtmann } 59848ce62c4SMarcel Holtmann 5992177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 60042c6b129SJohan Hedberg hci_setup_link_policy(req); 6012177bab5SJohan Hedberg 602417287deSMarcel Holtmann if (hdev->commands[8] & 0x01) 603417287deSMarcel Holtmann hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 604417287deSMarcel Holtmann 605417287deSMarcel Holtmann /* Some older Broadcom based Bluetooth 1.2 controllers do not 606417287deSMarcel Holtmann * support the Read Page Scan Type command. Check support for 607417287deSMarcel Holtmann * this command in the bit mask of supported commands. 608417287deSMarcel Holtmann */ 609417287deSMarcel Holtmann if (hdev->commands[13] & 0x01) 610417287deSMarcel Holtmann hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 611417287deSMarcel Holtmann 6129193c6e8SAndre Guedes if (lmp_le_capable(hdev)) { 6139193c6e8SAndre Guedes u8 events[8]; 6149193c6e8SAndre Guedes 6159193c6e8SAndre Guedes memset(events, 0, sizeof(events)); 6164d6c705bSMarcel Holtmann 6174d6c705bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) 6184d6c705bSMarcel Holtmann events[0] |= 0x10; /* LE Long Term Key Request */ 619662bc2e6SAndre Guedes 620662bc2e6SAndre Guedes /* If controller supports the Connection Parameters Request 621662bc2e6SAndre Guedes * Link Layer Procedure, enable the corresponding event. 622662bc2e6SAndre Guedes */ 623662bc2e6SAndre Guedes if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC) 624662bc2e6SAndre Guedes events[0] |= 0x20; /* LE Remote Connection 625662bc2e6SAndre Guedes * Parameter Request 626662bc2e6SAndre Guedes */ 627662bc2e6SAndre Guedes 628a9f6068eSMarcel Holtmann /* If the controller supports the Data Length Extension 629a9f6068eSMarcel Holtmann * feature, enable the corresponding event. 630a9f6068eSMarcel Holtmann */ 631a9f6068eSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) 632a9f6068eSMarcel Holtmann events[0] |= 0x40; /* LE Data Length Change */ 633a9f6068eSMarcel Holtmann 6344b71bba4SMarcel Holtmann /* If the controller supports Extended Scanner Filter 6354b71bba4SMarcel Holtmann * Policies, enable the correspondig event. 6364b71bba4SMarcel Holtmann */ 6374b71bba4SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY) 6384b71bba4SMarcel Holtmann events[1] |= 0x04; /* LE Direct Advertising 6394b71bba4SMarcel Holtmann * Report 6404b71bba4SMarcel Holtmann */ 6414b71bba4SMarcel Holtmann 6429756d33bSMarcel Holtmann /* If the controller supports Channel Selection Algorithm #2 6439756d33bSMarcel Holtmann * feature, enable the corresponding event. 6449756d33bSMarcel Holtmann */ 6459756d33bSMarcel Holtmann if (hdev->le_features[1] & HCI_LE_CHAN_SEL_ALG2) 6469756d33bSMarcel Holtmann events[2] |= 0x08; /* LE Channel Selection 6479756d33bSMarcel Holtmann * Algorithm 6489756d33bSMarcel Holtmann */ 6499756d33bSMarcel Holtmann 6507d26f5c4SMarcel Holtmann /* If the controller supports the LE Set Scan Enable command, 6517d26f5c4SMarcel Holtmann * enable the corresponding advertising report event. 6527d26f5c4SMarcel Holtmann */ 6537d26f5c4SMarcel Holtmann if (hdev->commands[26] & 0x08) 6547d26f5c4SMarcel Holtmann events[0] |= 0x02; /* LE Advertising Report */ 6557d26f5c4SMarcel Holtmann 6567d26f5c4SMarcel Holtmann /* If the controller supports the LE Create Connection 6577d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6587d26f5c4SMarcel Holtmann */ 6597d26f5c4SMarcel Holtmann if (hdev->commands[26] & 0x10) 6607d26f5c4SMarcel Holtmann events[0] |= 0x01; /* LE Connection Complete */ 6617d26f5c4SMarcel Holtmann 6627d26f5c4SMarcel Holtmann /* If the controller supports the LE Connection Update 6637d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6647d26f5c4SMarcel Holtmann */ 6657d26f5c4SMarcel Holtmann if (hdev->commands[27] & 0x04) 6667d26f5c4SMarcel Holtmann events[0] |= 0x04; /* LE Connection Update 6677d26f5c4SMarcel Holtmann * Complete 6687d26f5c4SMarcel Holtmann */ 6697d26f5c4SMarcel Holtmann 6707d26f5c4SMarcel Holtmann /* If the controller supports the LE Read Remote Used Features 6717d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6727d26f5c4SMarcel Holtmann */ 6737d26f5c4SMarcel Holtmann if (hdev->commands[27] & 0x20) 6747d26f5c4SMarcel Holtmann events[0] |= 0x08; /* LE Read Remote Used 6757d26f5c4SMarcel Holtmann * Features Complete 6767d26f5c4SMarcel Holtmann */ 6777d26f5c4SMarcel Holtmann 6785a34bd5fSMarcel Holtmann /* If the controller supports the LE Read Local P-256 6795a34bd5fSMarcel Holtmann * Public Key command, enable the corresponding event. 6805a34bd5fSMarcel Holtmann */ 6815a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x02) 6825a34bd5fSMarcel Holtmann events[0] |= 0x80; /* LE Read Local P-256 6835a34bd5fSMarcel Holtmann * Public Key Complete 6845a34bd5fSMarcel Holtmann */ 6855a34bd5fSMarcel Holtmann 6865a34bd5fSMarcel Holtmann /* If the controller supports the LE Generate DHKey 6875a34bd5fSMarcel Holtmann * command, enable the corresponding event. 6885a34bd5fSMarcel Holtmann */ 6895a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x04) 6905a34bd5fSMarcel Holtmann events[1] |= 0x01; /* LE Generate DHKey Complete */ 6915a34bd5fSMarcel Holtmann 69227bbca44SMarcel Holtmann /* If the controller supports the LE Set Default PHY or 69327bbca44SMarcel Holtmann * LE Set PHY commands, enable the corresponding event. 69427bbca44SMarcel Holtmann */ 69527bbca44SMarcel Holtmann if (hdev->commands[35] & (0x20 | 0x40)) 69627bbca44SMarcel Holtmann events[1] |= 0x08; /* LE PHY Update Complete */ 69727bbca44SMarcel Holtmann 698c215e939SJaganath Kanakkassery /* If the controller supports LE Set Extended Scan Parameters 699c215e939SJaganath Kanakkassery * and LE Set Extended Scan Enable commands, enable the 700c215e939SJaganath Kanakkassery * corresponding event. 701c215e939SJaganath Kanakkassery */ 702c215e939SJaganath Kanakkassery if (use_ext_scan(hdev)) 703c215e939SJaganath Kanakkassery events[1] |= 0x10; /* LE Extended Advertising 704c215e939SJaganath Kanakkassery * Report 705c215e939SJaganath Kanakkassery */ 706c215e939SJaganath Kanakkassery 7074d94f95dSJaganath Kanakkassery /* If the controller supports the LE Extended Create Connection 7084d94f95dSJaganath Kanakkassery * command, enable the corresponding event. 7094d94f95dSJaganath Kanakkassery */ 7104d94f95dSJaganath Kanakkassery if (use_ext_conn(hdev)) 7114d94f95dSJaganath Kanakkassery events[1] |= 0x02; /* LE Enhanced Connection 7124d94f95dSJaganath Kanakkassery * Complete 7134d94f95dSJaganath Kanakkassery */ 7144d94f95dSJaganath Kanakkassery 715acf0aeaeSJaganath Kanakkassery /* If the controller supports the LE Extended Advertising 716acf0aeaeSJaganath Kanakkassery * command, enable the corresponding event. 717acf0aeaeSJaganath Kanakkassery */ 718acf0aeaeSJaganath Kanakkassery if (ext_adv_capable(hdev)) 719acf0aeaeSJaganath Kanakkassery events[2] |= 0x02; /* LE Advertising Set 720acf0aeaeSJaganath Kanakkassery * Terminated 721acf0aeaeSJaganath Kanakkassery */ 722acf0aeaeSJaganath Kanakkassery 7239193c6e8SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), 7249193c6e8SAndre Guedes events); 7259193c6e8SAndre Guedes 72615a49ccaSMarcel Holtmann /* Read LE Advertising Channel TX Power */ 7276b49bcb4SJaganath Kanakkassery if ((hdev->commands[25] & 0x40) && !ext_adv_capable(hdev)) { 7286b49bcb4SJaganath Kanakkassery /* HCI TS spec forbids mixing of legacy and extended 7296b49bcb4SJaganath Kanakkassery * advertising commands wherein READ_ADV_TX_POWER is 7306b49bcb4SJaganath Kanakkassery * also included. So do not call it if extended adv 7316b49bcb4SJaganath Kanakkassery * is supported otherwise controller will return 7326b49bcb4SJaganath Kanakkassery * COMMAND_DISALLOWED for extended commands. 7336b49bcb4SJaganath Kanakkassery */ 73415a49ccaSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 73515a49ccaSMarcel Holtmann } 73615a49ccaSMarcel Holtmann 7372ab216a7SMarcel Holtmann if (hdev->commands[26] & 0x40) { 7382ab216a7SMarcel Holtmann /* Read LE White List Size */ 7392ab216a7SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 7402ab216a7SMarcel Holtmann 0, NULL); 7412ab216a7SMarcel Holtmann } 7422ab216a7SMarcel Holtmann 7432ab216a7SMarcel Holtmann if (hdev->commands[26] & 0x80) { 7442ab216a7SMarcel Holtmann /* Clear LE White List */ 7452ab216a7SMarcel Holtmann hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL); 7462ab216a7SMarcel Holtmann } 7472ab216a7SMarcel Holtmann 748cfdb0c2dSAnkit Navik if (hdev->commands[34] & 0x40) { 749cfdb0c2dSAnkit Navik /* Read LE Resolving List Size */ 750cfdb0c2dSAnkit Navik hci_req_add(req, HCI_OP_LE_READ_RESOLV_LIST_SIZE, 751cfdb0c2dSAnkit Navik 0, NULL); 752cfdb0c2dSAnkit Navik } 753cfdb0c2dSAnkit Navik 754545f2596SAnkit Navik if (hdev->commands[34] & 0x20) { 755545f2596SAnkit Navik /* Clear LE Resolving List */ 756545f2596SAnkit Navik hci_req_add(req, HCI_OP_LE_CLEAR_RESOLV_LIST, 0, NULL); 757545f2596SAnkit Navik } 758545f2596SAnkit Navik 759a9f6068eSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { 760a9f6068eSMarcel Holtmann /* Read LE Maximum Data Length */ 761a9f6068eSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL); 762a9f6068eSMarcel Holtmann 763a9f6068eSMarcel Holtmann /* Read LE Suggested Default Data Length */ 764a9f6068eSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL); 765a9f6068eSMarcel Holtmann } 766a9f6068eSMarcel Holtmann 7676b49bcb4SJaganath Kanakkassery if (ext_adv_capable(hdev)) { 7686b49bcb4SJaganath Kanakkassery /* Read LE Number of Supported Advertising Sets */ 7696b49bcb4SJaganath Kanakkassery hci_req_add(req, HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS, 7706b49bcb4SJaganath Kanakkassery 0, NULL); 7716b49bcb4SJaganath Kanakkassery } 7726b49bcb4SJaganath Kanakkassery 77342c6b129SJohan Hedberg hci_set_le_support(req); 7749193c6e8SAndre Guedes } 775d2c5d77fSJohan Hedberg 776d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 777d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 778d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 779d2c5d77fSJohan Hedberg 780d2c5d77fSJohan Hedberg cp.page = p; 781d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 782d2c5d77fSJohan Hedberg sizeof(cp), &cp); 783d2c5d77fSJohan Hedberg } 784a1d01db1SJohan Hedberg 785a1d01db1SJohan Hedberg return 0; 7862177bab5SJohan Hedberg } 7872177bab5SJohan Hedberg 788a1d01db1SJohan Hedberg static int hci_init4_req(struct hci_request *req, unsigned long opt) 7895d4e7e8dSJohan Hedberg { 7905d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 7915d4e7e8dSJohan Hedberg 79236f260ceSMarcel Holtmann /* Some Broadcom based Bluetooth controllers do not support the 79336f260ceSMarcel Holtmann * Delete Stored Link Key command. They are clearly indicating its 79436f260ceSMarcel Holtmann * absence in the bit mask of supported commands. 79536f260ceSMarcel Holtmann * 79636f260ceSMarcel Holtmann * Check the supported commands and only if the the command is marked 79736f260ceSMarcel Holtmann * as supported send it. If not supported assume that the controller 79836f260ceSMarcel Holtmann * does not have actual support for stored link keys which makes this 79936f260ceSMarcel Holtmann * command redundant anyway. 80036f260ceSMarcel Holtmann * 80136f260ceSMarcel Holtmann * Some controllers indicate that they support handling deleting 80236f260ceSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 80336f260ceSMarcel Holtmann * just disable this command. 80436f260ceSMarcel Holtmann */ 80536f260ceSMarcel Holtmann if (hdev->commands[6] & 0x80 && 80636f260ceSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 80736f260ceSMarcel Holtmann struct hci_cp_delete_stored_link_key cp; 80836f260ceSMarcel Holtmann 80936f260ceSMarcel Holtmann bacpy(&cp.bdaddr, BDADDR_ANY); 81036f260ceSMarcel Holtmann cp.delete_all = 0x01; 81136f260ceSMarcel Holtmann hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 81236f260ceSMarcel Holtmann sizeof(cp), &cp); 81336f260ceSMarcel Holtmann } 81436f260ceSMarcel Holtmann 815d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 816d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 817d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 818d62e6d67SJohan Hedberg 819109e3191SMarcel Holtmann /* Read local codec list if the HCI command is supported */ 820109e3191SMarcel Holtmann if (hdev->commands[29] & 0x20) 821109e3191SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL); 822109e3191SMarcel Holtmann 823f4fe73edSMarcel Holtmann /* Get MWS transport configuration if the HCI command is supported */ 824f4fe73edSMarcel Holtmann if (hdev->commands[30] & 0x08) 825f4fe73edSMarcel Holtmann hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL); 826f4fe73edSMarcel Holtmann 8275d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 82853b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 8295d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 830a6d0d690SMarcel Holtmann 831a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 832d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) && 833574ea3c7SMarcel Holtmann bredr_sc_enabled(hdev)) { 834a6d0d690SMarcel Holtmann u8 support = 0x01; 835574ea3c7SMarcel Holtmann 836a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 837a6d0d690SMarcel Holtmann sizeof(support), &support); 838a6d0d690SMarcel Holtmann } 839a1d01db1SJohan Hedberg 84012204875SMarcel Holtmann /* Set Suggested Default Data Length to maximum if supported */ 84112204875SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { 84212204875SMarcel Holtmann struct hci_cp_le_write_def_data_len cp; 84312204875SMarcel Holtmann 84412204875SMarcel Holtmann cp.tx_len = hdev->le_max_tx_len; 84512204875SMarcel Holtmann cp.tx_time = hdev->le_max_tx_time; 84612204875SMarcel Holtmann hci_req_add(req, HCI_OP_LE_WRITE_DEF_DATA_LEN, sizeof(cp), &cp); 84712204875SMarcel Holtmann } 84812204875SMarcel Holtmann 849de2ba303SMarcel Holtmann /* Set Default PHY parameters if command is supported */ 850de2ba303SMarcel Holtmann if (hdev->commands[35] & 0x20) { 851de2ba303SMarcel Holtmann struct hci_cp_le_set_default_phy cp; 852de2ba303SMarcel Holtmann 8536decb5b4SJaganath Kanakkassery cp.all_phys = 0x00; 8546decb5b4SJaganath Kanakkassery cp.tx_phys = hdev->le_tx_def_phys; 8556decb5b4SJaganath Kanakkassery cp.rx_phys = hdev->le_rx_def_phys; 856de2ba303SMarcel Holtmann 857de2ba303SMarcel Holtmann hci_req_add(req, HCI_OP_LE_SET_DEFAULT_PHY, sizeof(cp), &cp); 858de2ba303SMarcel Holtmann } 859de2ba303SMarcel Holtmann 860a1d01db1SJohan Hedberg return 0; 8615d4e7e8dSJohan Hedberg } 8625d4e7e8dSJohan Hedberg 8632177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 8642177bab5SJohan Hedberg { 8652177bab5SJohan Hedberg int err; 8662177bab5SJohan Hedberg 8674ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT, NULL); 8682177bab5SJohan Hedberg if (err < 0) 8692177bab5SJohan Hedberg return err; 8702177bab5SJohan Hedberg 871f640ee98SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 872f640ee98SMarcel Holtmann hci_debugfs_create_basic(hdev); 8734b4148e9SMarcel Holtmann 8744ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT, NULL); 8752177bab5SJohan Hedberg if (err < 0) 8762177bab5SJohan Hedberg return err; 8772177bab5SJohan Hedberg 878ca8bee5dSMarcel Holtmann /* HCI_PRIMARY covers both single-mode LE, BR/EDR and dual-mode 8790af801b9SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 8800af801b9SJohan Hedberg * first two stages of init. 8810af801b9SJohan Hedberg */ 882ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) 8830af801b9SJohan Hedberg return 0; 8840af801b9SJohan Hedberg 8854ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT, NULL); 8865d4e7e8dSJohan Hedberg if (err < 0) 8875d4e7e8dSJohan Hedberg return err; 8885d4e7e8dSJohan Hedberg 8894ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT, NULL); 890baf27f6eSMarcel Holtmann if (err < 0) 891baf27f6eSMarcel Holtmann return err; 892baf27f6eSMarcel Holtmann 893ec6cef9cSMarcel Holtmann /* This function is only called when the controller is actually in 894ec6cef9cSMarcel Holtmann * configured state. When the controller is marked as unconfigured, 895ec6cef9cSMarcel Holtmann * this initialization procedure is not run. 896ec6cef9cSMarcel Holtmann * 897ec6cef9cSMarcel Holtmann * It means that it is possible that a controller runs through its 898ec6cef9cSMarcel Holtmann * setup phase and then discovers missing settings. If that is the 899ec6cef9cSMarcel Holtmann * case, then this function will not be called. It then will only 900ec6cef9cSMarcel Holtmann * be called during the config phase. 901ec6cef9cSMarcel Holtmann * 902ec6cef9cSMarcel Holtmann * So only when in setup phase or config phase, create the debugfs 903ec6cef9cSMarcel Holtmann * entries and register the SMP channels. 904baf27f6eSMarcel Holtmann */ 905d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 906d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 907baf27f6eSMarcel Holtmann return 0; 908baf27f6eSMarcel Holtmann 90960c5f5fbSMarcel Holtmann hci_debugfs_create_common(hdev); 91060c5f5fbSMarcel Holtmann 91171c3b60eSMarcel Holtmann if (lmp_bredr_capable(hdev)) 91260c5f5fbSMarcel Holtmann hci_debugfs_create_bredr(hdev); 9132bfa3531SMarcel Holtmann 914162a3bacSMarcel Holtmann if (lmp_le_capable(hdev)) 91560c5f5fbSMarcel Holtmann hci_debugfs_create_le(hdev); 916e7b8fc92SMarcel Holtmann 917baf27f6eSMarcel Holtmann return 0; 9182177bab5SJohan Hedberg } 9192177bab5SJohan Hedberg 920a1d01db1SJohan Hedberg static int hci_init0_req(struct hci_request *req, unsigned long opt) 9210ebca7d6SMarcel Holtmann { 9220ebca7d6SMarcel Holtmann struct hci_dev *hdev = req->hdev; 9230ebca7d6SMarcel Holtmann 9240ebca7d6SMarcel Holtmann BT_DBG("%s %ld", hdev->name, opt); 9250ebca7d6SMarcel Holtmann 9260ebca7d6SMarcel Holtmann /* Reset */ 9270ebca7d6SMarcel Holtmann if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 9280ebca7d6SMarcel Holtmann hci_reset_req(req, 0); 9290ebca7d6SMarcel Holtmann 9300ebca7d6SMarcel Holtmann /* Read Local Version */ 9310ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 9320ebca7d6SMarcel Holtmann 9330ebca7d6SMarcel Holtmann /* Read BD Address */ 9340ebca7d6SMarcel Holtmann if (hdev->set_bdaddr) 9350ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 936a1d01db1SJohan Hedberg 937a1d01db1SJohan Hedberg return 0; 9380ebca7d6SMarcel Holtmann } 9390ebca7d6SMarcel Holtmann 9400ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev) 9410ebca7d6SMarcel Holtmann { 9420ebca7d6SMarcel Holtmann int err; 9430ebca7d6SMarcel Holtmann 944cc78b44bSMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 945cc78b44bSMarcel Holtmann return 0; 946cc78b44bSMarcel Holtmann 9474ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT, NULL); 9480ebca7d6SMarcel Holtmann if (err < 0) 9490ebca7d6SMarcel Holtmann return err; 9500ebca7d6SMarcel Holtmann 951f640ee98SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 952f640ee98SMarcel Holtmann hci_debugfs_create_basic(hdev); 953f640ee98SMarcel Holtmann 9540ebca7d6SMarcel Holtmann return 0; 9550ebca7d6SMarcel Holtmann } 9560ebca7d6SMarcel Holtmann 957a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt) 9581da177e4SLinus Torvalds { 9591da177e4SLinus Torvalds __u8 scan = opt; 9601da177e4SLinus Torvalds 96142c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 9621da177e4SLinus Torvalds 9631da177e4SLinus Torvalds /* Inquiry and Page scans */ 96442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 965a1d01db1SJohan Hedberg return 0; 9661da177e4SLinus Torvalds } 9671da177e4SLinus Torvalds 968a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt) 9691da177e4SLinus Torvalds { 9701da177e4SLinus Torvalds __u8 auth = opt; 9711da177e4SLinus Torvalds 97242c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 9731da177e4SLinus Torvalds 9741da177e4SLinus Torvalds /* Authentication */ 97542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 976a1d01db1SJohan Hedberg return 0; 9771da177e4SLinus Torvalds } 9781da177e4SLinus Torvalds 979a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt) 9801da177e4SLinus Torvalds { 9811da177e4SLinus Torvalds __u8 encrypt = opt; 9821da177e4SLinus Torvalds 98342c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 9841da177e4SLinus Torvalds 985e4e8e37cSMarcel Holtmann /* Encryption */ 98642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 987a1d01db1SJohan Hedberg return 0; 9881da177e4SLinus Torvalds } 9891da177e4SLinus Torvalds 990a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt) 991e4e8e37cSMarcel Holtmann { 992e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 993e4e8e37cSMarcel Holtmann 99442c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 995e4e8e37cSMarcel Holtmann 996e4e8e37cSMarcel Holtmann /* Default link policy */ 99742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 998a1d01db1SJohan Hedberg return 0; 999e4e8e37cSMarcel Holtmann } 1000e4e8e37cSMarcel Holtmann 10011da177e4SLinus Torvalds /* Get HCI device by index. 10021da177e4SLinus Torvalds * Device is held on return. */ 10031da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 10041da177e4SLinus Torvalds { 10058035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 10061da177e4SLinus Torvalds 10071da177e4SLinus Torvalds BT_DBG("%d", index); 10081da177e4SLinus Torvalds 10091da177e4SLinus Torvalds if (index < 0) 10101da177e4SLinus Torvalds return NULL; 10111da177e4SLinus Torvalds 10121da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 10138035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 10141da177e4SLinus Torvalds if (d->id == index) { 10151da177e4SLinus Torvalds hdev = hci_dev_hold(d); 10161da177e4SLinus Torvalds break; 10171da177e4SLinus Torvalds } 10181da177e4SLinus Torvalds } 10191da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 10201da177e4SLinus Torvalds return hdev; 10211da177e4SLinus Torvalds } 10221da177e4SLinus Torvalds 10231da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1024ff9ef578SJohan Hedberg 102530dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 102630dc78e1SJohan Hedberg { 102730dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 102830dc78e1SJohan Hedberg 10296fbe195dSAndre Guedes switch (discov->state) { 1030343f935bSAndre Guedes case DISCOVERY_FINDING: 10316fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 103230dc78e1SJohan Hedberg return true; 103330dc78e1SJohan Hedberg 10346fbe195dSAndre Guedes default: 103530dc78e1SJohan Hedberg return false; 103630dc78e1SJohan Hedberg } 10376fbe195dSAndre Guedes } 103830dc78e1SJohan Hedberg 1039ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1040ff9ef578SJohan Hedberg { 1041bb3e0a33SJohan Hedberg int old_state = hdev->discovery.state; 1042bb3e0a33SJohan Hedberg 1043ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1044ff9ef578SJohan Hedberg 1045bb3e0a33SJohan Hedberg if (old_state == state) 1046ff9ef578SJohan Hedberg return; 1047ff9ef578SJohan Hedberg 1048bb3e0a33SJohan Hedberg hdev->discovery.state = state; 1049bb3e0a33SJohan Hedberg 1050ff9ef578SJohan Hedberg switch (state) { 1051ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 1052c54c3860SAndre Guedes hci_update_background_scan(hdev); 1053c54c3860SAndre Guedes 1054bb3e0a33SJohan Hedberg if (old_state != DISCOVERY_STARTING) 1055ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1056ff9ef578SJohan Hedberg break; 1057ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1058ff9ef578SJohan Hedberg break; 1059343f935bSAndre Guedes case DISCOVERY_FINDING: 1060ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1061ff9ef578SJohan Hedberg break; 106230dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 106330dc78e1SJohan Hedberg break; 1064ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1065ff9ef578SJohan Hedberg break; 1066ff9ef578SJohan Hedberg } 1067ff9ef578SJohan Hedberg } 1068ff9ef578SJohan Hedberg 10691f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 10701da177e4SLinus Torvalds { 107130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1072b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 10731da177e4SLinus Torvalds 1074561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1075561aafbcSJohan Hedberg list_del(&p->all); 1076b57c1a56SJohan Hedberg kfree(p); 10771da177e4SLinus Torvalds } 1078561aafbcSJohan Hedberg 1079561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1080561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 10811da177e4SLinus Torvalds } 10821da177e4SLinus Torvalds 1083a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1084a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 10851da177e4SLinus Torvalds { 108630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 10871da177e4SLinus Torvalds struct inquiry_entry *e; 10881da177e4SLinus Torvalds 10896ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 10901da177e4SLinus Torvalds 1091561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 10921da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 10931da177e4SLinus Torvalds return e; 10941da177e4SLinus Torvalds } 10951da177e4SLinus Torvalds 1096b57c1a56SJohan Hedberg return NULL; 1097b57c1a56SJohan Hedberg } 1098b57c1a56SJohan Hedberg 1099561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1100561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1101561aafbcSJohan Hedberg { 110230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1103561aafbcSJohan Hedberg struct inquiry_entry *e; 1104561aafbcSJohan Hedberg 11056ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1106561aafbcSJohan Hedberg 1107561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1108561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1109561aafbcSJohan Hedberg return e; 1110561aafbcSJohan Hedberg } 1111561aafbcSJohan Hedberg 1112561aafbcSJohan Hedberg return NULL; 1113561aafbcSJohan Hedberg } 1114561aafbcSJohan Hedberg 111530dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 111630dc78e1SJohan Hedberg bdaddr_t *bdaddr, 111730dc78e1SJohan Hedberg int state) 111830dc78e1SJohan Hedberg { 111930dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 112030dc78e1SJohan Hedberg struct inquiry_entry *e; 112130dc78e1SJohan Hedberg 11226ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 112330dc78e1SJohan Hedberg 112430dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 112530dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 112630dc78e1SJohan Hedberg return e; 112730dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 112830dc78e1SJohan Hedberg return e; 112930dc78e1SJohan Hedberg } 113030dc78e1SJohan Hedberg 113130dc78e1SJohan Hedberg return NULL; 113230dc78e1SJohan Hedberg } 113330dc78e1SJohan Hedberg 1134a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1135a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1136a3d4e20aSJohan Hedberg { 1137a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1138a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1139a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1140a3d4e20aSJohan Hedberg 1141a3d4e20aSJohan Hedberg list_del(&ie->list); 1142a3d4e20aSJohan Hedberg 1143a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1144a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1145a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1146a3d4e20aSJohan Hedberg break; 1147a3d4e20aSJohan Hedberg pos = &p->list; 1148a3d4e20aSJohan Hedberg } 1149a3d4e20aSJohan Hedberg 1150a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1151a3d4e20aSJohan Hedberg } 1152a3d4e20aSJohan Hedberg 1153af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1154af58925cSMarcel Holtmann bool name_known) 11551da177e4SLinus Torvalds { 115630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 115770f23020SAndrei Emeltchenko struct inquiry_entry *ie; 1158af58925cSMarcel Holtmann u32 flags = 0; 11591da177e4SLinus Torvalds 11606ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 11611da177e4SLinus Torvalds 11626928a924SJohan Hedberg hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR); 11632b2fec4dSSzymon Janc 1164af58925cSMarcel Holtmann if (!data->ssp_mode) 1165af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1166388fc8faSJohan Hedberg 116770f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1168a3d4e20aSJohan Hedberg if (ie) { 1169af58925cSMarcel Holtmann if (!ie->data.ssp_mode) 1170af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1171388fc8faSJohan Hedberg 1172a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1173a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1174a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1175a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1176a3d4e20aSJohan Hedberg } 1177a3d4e20aSJohan Hedberg 1178561aafbcSJohan Hedberg goto update; 1179a3d4e20aSJohan Hedberg } 1180561aafbcSJohan Hedberg 11811da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 118227f70f3eSJohan Hedberg ie = kzalloc(sizeof(*ie), GFP_KERNEL); 1183af58925cSMarcel Holtmann if (!ie) { 1184af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 1185af58925cSMarcel Holtmann goto done; 1186af58925cSMarcel Holtmann } 118770f23020SAndrei Emeltchenko 1188561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1189561aafbcSJohan Hedberg 1190561aafbcSJohan Hedberg if (name_known) { 1191561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1192561aafbcSJohan Hedberg } else { 1193561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1194561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1195561aafbcSJohan Hedberg } 1196561aafbcSJohan Hedberg 1197561aafbcSJohan Hedberg update: 1198561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1199561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1200561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1201561aafbcSJohan Hedberg list_del(&ie->list); 12021da177e4SLinus Torvalds } 12031da177e4SLinus Torvalds 120470f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 120570f23020SAndrei Emeltchenko ie->timestamp = jiffies; 12061da177e4SLinus Torvalds cache->timestamp = jiffies; 12073175405bSJohan Hedberg 12083175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 1209af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 12103175405bSJohan Hedberg 1211af58925cSMarcel Holtmann done: 1212af58925cSMarcel Holtmann return flags; 12131da177e4SLinus Torvalds } 12141da177e4SLinus Torvalds 12151da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 12161da177e4SLinus Torvalds { 121730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 12181da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 12191da177e4SLinus Torvalds struct inquiry_entry *e; 12201da177e4SLinus Torvalds int copied = 0; 12211da177e4SLinus Torvalds 1222561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 12231da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1224b57c1a56SJohan Hedberg 1225b57c1a56SJohan Hedberg if (copied >= num) 1226b57c1a56SJohan Hedberg break; 1227b57c1a56SJohan Hedberg 12281da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 12291da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 12301da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 12311da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 12321da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 12331da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1234b57c1a56SJohan Hedberg 12351da177e4SLinus Torvalds info++; 1236b57c1a56SJohan Hedberg copied++; 12371da177e4SLinus Torvalds } 12381da177e4SLinus Torvalds 12391da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 12401da177e4SLinus Torvalds return copied; 12411da177e4SLinus Torvalds } 12421da177e4SLinus Torvalds 1243a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt) 12441da177e4SLinus Torvalds { 12451da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 124642c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 12471da177e4SLinus Torvalds struct hci_cp_inquiry cp; 12481da177e4SLinus Torvalds 12491da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 12501da177e4SLinus Torvalds 12511da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 1252a1d01db1SJohan Hedberg return 0; 12531da177e4SLinus Torvalds 12541da177e4SLinus Torvalds /* Start Inquiry */ 12551da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 12561da177e4SLinus Torvalds cp.length = ir->length; 12571da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 125842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 1259a1d01db1SJohan Hedberg 1260a1d01db1SJohan Hedberg return 0; 12611da177e4SLinus Torvalds } 12621da177e4SLinus Torvalds 12631da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 12641da177e4SLinus Torvalds { 12651da177e4SLinus Torvalds __u8 __user *ptr = arg; 12661da177e4SLinus Torvalds struct hci_inquiry_req ir; 12671da177e4SLinus Torvalds struct hci_dev *hdev; 12681da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 12691da177e4SLinus Torvalds long timeo; 12701da177e4SLinus Torvalds __u8 *buf; 12711da177e4SLinus Torvalds 12721da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 12731da177e4SLinus Torvalds return -EFAULT; 12741da177e4SLinus Torvalds 12755a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 12765a08ecceSAndrei Emeltchenko if (!hdev) 12771da177e4SLinus Torvalds return -ENODEV; 12781da177e4SLinus Torvalds 1279d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 12800736cfa8SMarcel Holtmann err = -EBUSY; 12810736cfa8SMarcel Holtmann goto done; 12820736cfa8SMarcel Holtmann } 12830736cfa8SMarcel Holtmann 1284d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1285fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1286fee746b0SMarcel Holtmann goto done; 1287fee746b0SMarcel Holtmann } 1288fee746b0SMarcel Holtmann 1289ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 12905b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 12915b69bef5SMarcel Holtmann goto done; 12925b69bef5SMarcel Holtmann } 12935b69bef5SMarcel Holtmann 1294d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 129556f87901SJohan Hedberg err = -EOPNOTSUPP; 129656f87901SJohan Hedberg goto done; 129756f87901SJohan Hedberg } 129856f87901SJohan Hedberg 129909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 13001da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1301a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 13021f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 13031da177e4SLinus Torvalds do_inquiry = 1; 13041da177e4SLinus Torvalds } 130509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13061da177e4SLinus Torvalds 130704837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 130870f23020SAndrei Emeltchenko 130970f23020SAndrei Emeltchenko if (do_inquiry) { 131001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 13114ebeee2dSJohan Hedberg timeo, NULL); 131270f23020SAndrei Emeltchenko if (err < 0) 13131da177e4SLinus Torvalds goto done; 13143e13fa1eSAndre Guedes 13153e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 13163e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 13173e13fa1eSAndre Guedes */ 131874316201SNeilBrown if (wait_on_bit(&hdev->flags, HCI_INQUIRY, 13193e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 13203e13fa1eSAndre Guedes return -EINTR; 132170f23020SAndrei Emeltchenko } 13221da177e4SLinus Torvalds 13238fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 13248fc9ced3SGustavo Padovan * 255 entries 13258fc9ced3SGustavo Padovan */ 13261da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 13271da177e4SLinus Torvalds 13281da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 13291da177e4SLinus Torvalds * copy it to the user space. 13301da177e4SLinus Torvalds */ 13316da2ec56SKees Cook buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL); 133270f23020SAndrei Emeltchenko if (!buf) { 13331da177e4SLinus Torvalds err = -ENOMEM; 13341da177e4SLinus Torvalds goto done; 13351da177e4SLinus Torvalds } 13361da177e4SLinus Torvalds 133709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 13381da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 133909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13401da177e4SLinus Torvalds 13411da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 13421da177e4SLinus Torvalds 13431da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 13441da177e4SLinus Torvalds ptr += sizeof(ir); 13451da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 13461da177e4SLinus Torvalds ir.num_rsp)) 13471da177e4SLinus Torvalds err = -EFAULT; 13481da177e4SLinus Torvalds } else 13491da177e4SLinus Torvalds err = -EFAULT; 13501da177e4SLinus Torvalds 13511da177e4SLinus Torvalds kfree(buf); 13521da177e4SLinus Torvalds 13531da177e4SLinus Torvalds done: 13541da177e4SLinus Torvalds hci_dev_put(hdev); 13551da177e4SLinus Torvalds return err; 13561da177e4SLinus Torvalds } 13571da177e4SLinus Torvalds 1358cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 13591da177e4SLinus Torvalds { 13601da177e4SLinus Torvalds int ret = 0; 13611da177e4SLinus Torvalds 13621da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 13631da177e4SLinus Torvalds 1364b504430cSJohan Hedberg hci_req_sync_lock(hdev); 13651da177e4SLinus Torvalds 1366d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) { 136794324962SJohan Hovold ret = -ENODEV; 136894324962SJohan Hovold goto done; 136994324962SJohan Hovold } 137094324962SJohan Hovold 1371d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 1372d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 1373a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1374a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1375bf543036SJohan Hedberg */ 1376d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED)) { 1377611b30f7SMarcel Holtmann ret = -ERFKILL; 1378611b30f7SMarcel Holtmann goto done; 1379611b30f7SMarcel Holtmann } 1380611b30f7SMarcel Holtmann 1381a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 1382a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 1383a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1384a5c8f270SMarcel Holtmann * or not. 1385a5c8f270SMarcel Holtmann * 1386c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 1387c6beca0eSMarcel Holtmann * if a public address or static random address is 1388c6beca0eSMarcel Holtmann * available. 1389c6beca0eSMarcel Holtmann * 1390a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1391a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1392a5c8f270SMarcel Holtmann */ 1393d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1394ca8bee5dSMarcel Holtmann hdev->dev_type == HCI_PRIMARY && 1395a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1396a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1397a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1398a5c8f270SMarcel Holtmann goto done; 1399a5c8f270SMarcel Holtmann } 1400a5c8f270SMarcel Holtmann } 1401a5c8f270SMarcel Holtmann 14021da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 14031da177e4SLinus Torvalds ret = -EALREADY; 14041da177e4SLinus Torvalds goto done; 14051da177e4SLinus Torvalds } 14061da177e4SLinus Torvalds 14071da177e4SLinus Torvalds if (hdev->open(hdev)) { 14081da177e4SLinus Torvalds ret = -EIO; 14091da177e4SLinus Torvalds goto done; 14101da177e4SLinus Torvalds } 14111da177e4SLinus Torvalds 1412e9ca8bf1SMarcel Holtmann set_bit(HCI_RUNNING, &hdev->flags); 141305fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_OPEN); 14144a3f95b7SMarcel Holtmann 14151da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 14161da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1417f41c70c4SMarcel Holtmann 1418740011cfSSean Wang if (hci_dev_test_flag(hdev, HCI_SETUP) || 1419740011cfSSean Wang test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) { 1420e131d74aSMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_SETUP); 1421e131d74aSMarcel Holtmann 1422af202f84SMarcel Holtmann if (hdev->setup) 1423f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1424f41c70c4SMarcel Holtmann 1425af202f84SMarcel Holtmann /* The transport driver can set these quirks before 1426af202f84SMarcel Holtmann * creating the HCI device or in its setup callback. 1427af202f84SMarcel Holtmann * 1428af202f84SMarcel Holtmann * In case any of them is set, the controller has to 1429af202f84SMarcel Holtmann * start up as unconfigured. 1430af202f84SMarcel Holtmann */ 1431eb1904f4SMarcel Holtmann if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) || 1432eb1904f4SMarcel Holtmann test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks)) 1433a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 1434f41c70c4SMarcel Holtmann 14350ebca7d6SMarcel Holtmann /* For an unconfigured controller it is required to 14360ebca7d6SMarcel Holtmann * read at least the version information provided by 14370ebca7d6SMarcel Holtmann * the Read Local Version Information command. 14380ebca7d6SMarcel Holtmann * 14390ebca7d6SMarcel Holtmann * If the set_bdaddr driver callback is provided, then 14400ebca7d6SMarcel Holtmann * also the original Bluetooth public device address 14410ebca7d6SMarcel Holtmann * will be read using the Read BD Address command. 14420ebca7d6SMarcel Holtmann */ 1443d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 14440ebca7d6SMarcel Holtmann ret = __hci_unconf_init(hdev); 144589bc22d2SMarcel Holtmann } 144689bc22d2SMarcel Holtmann 1447d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_CONFIG)) { 14489713c17bSMarcel Holtmann /* If public address change is configured, ensure that 14499713c17bSMarcel Holtmann * the address gets programmed. If the driver does not 14509713c17bSMarcel Holtmann * support changing the public address, fail the power 14519713c17bSMarcel Holtmann * on procedure. 145224c457e2SMarcel Holtmann */ 14539713c17bSMarcel Holtmann if (bacmp(&hdev->public_addr, BDADDR_ANY) && 14549713c17bSMarcel Holtmann hdev->set_bdaddr) 145524c457e2SMarcel Holtmann ret = hdev->set_bdaddr(hdev, &hdev->public_addr); 145624c457e2SMarcel Holtmann else 145724c457e2SMarcel Holtmann ret = -EADDRNOTAVAIL; 145824c457e2SMarcel Holtmann } 145924c457e2SMarcel Holtmann 1460f41c70c4SMarcel Holtmann if (!ret) { 1461d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 146298a63aafSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 14632177bab5SJohan Hedberg ret = __hci_init(hdev); 146498a63aafSMarcel Holtmann if (!ret && hdev->post_init) 146598a63aafSMarcel Holtmann ret = hdev->post_init(hdev); 146698a63aafSMarcel Holtmann } 14671da177e4SLinus Torvalds } 14681da177e4SLinus Torvalds 14697e995b9eSMarcel Holtmann /* If the HCI Reset command is clearing all diagnostic settings, 14707e995b9eSMarcel Holtmann * then they need to be reprogrammed after the init procedure 14717e995b9eSMarcel Holtmann * completed. 14727e995b9eSMarcel Holtmann */ 14737e995b9eSMarcel Holtmann if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) && 1474b56c7b25SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 14757e995b9eSMarcel Holtmann hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag) 14767e995b9eSMarcel Holtmann ret = hdev->set_diag(hdev, true); 14777e995b9eSMarcel Holtmann 1478f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1479f41c70c4SMarcel Holtmann 14801da177e4SLinus Torvalds if (!ret) { 14811da177e4SLinus Torvalds hci_dev_hold(hdev); 1482a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); 1483a73c046aSJaganath Kanakkassery hci_adv_instances_set_rpa_expired(hdev, true); 14841da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 148505fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UP); 14866d5d2ee6SHeiner Kallweit hci_leds_update_powered(hdev, true); 1487d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 1488d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG) && 1489d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 1490d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 14912ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 1492ca8bee5dSMarcel Holtmann hdev->dev_type == HCI_PRIMARY) { 14932ff13894SJohan Hedberg ret = __hci_req_hci_power_on(hdev); 14942ff13894SJohan Hedberg mgmt_power_on(hdev, ret); 149556e5cb86SJohan Hedberg } 14961da177e4SLinus Torvalds } else { 14971da177e4SLinus Torvalds /* Init failed, cleanup */ 14983eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1499c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 1500b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 15011da177e4SLinus Torvalds 15021da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 15031da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 15041da177e4SLinus Torvalds 15051da177e4SLinus Torvalds if (hdev->flush) 15061da177e4SLinus Torvalds hdev->flush(hdev); 15071da177e4SLinus Torvalds 15081da177e4SLinus Torvalds if (hdev->sent_cmd) { 15091da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 15101da177e4SLinus Torvalds hdev->sent_cmd = NULL; 15111da177e4SLinus Torvalds } 15121da177e4SLinus Torvalds 1513e9ca8bf1SMarcel Holtmann clear_bit(HCI_RUNNING, &hdev->flags); 151405fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_CLOSE); 15154a3f95b7SMarcel Holtmann 15161da177e4SLinus Torvalds hdev->close(hdev); 1517fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 15181da177e4SLinus Torvalds } 15191da177e4SLinus Torvalds 15201da177e4SLinus Torvalds done: 1521b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 15221da177e4SLinus Torvalds return ret; 15231da177e4SLinus Torvalds } 15241da177e4SLinus Torvalds 1525cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 1526cbed0ca1SJohan Hedberg 1527cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 1528cbed0ca1SJohan Hedberg { 1529cbed0ca1SJohan Hedberg struct hci_dev *hdev; 1530cbed0ca1SJohan Hedberg int err; 1531cbed0ca1SJohan Hedberg 1532cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 1533cbed0ca1SJohan Hedberg if (!hdev) 1534cbed0ca1SJohan Hedberg return -ENODEV; 1535cbed0ca1SJohan Hedberg 15364a964404SMarcel Holtmann /* Devices that are marked as unconfigured can only be powered 1537fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices 1538fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is 1539fee746b0SMarcel Holtmann * possible. 1540fee746b0SMarcel Holtmann * 1541fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag 1542fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to 1543fee746b0SMarcel Holtmann * open the device. 1544fee746b0SMarcel Holtmann */ 1545d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 1546d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 1547fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1548fee746b0SMarcel Holtmann goto done; 1549fee746b0SMarcel Holtmann } 1550fee746b0SMarcel Holtmann 1551e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 1552e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 1553e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 1554e1d08f40SJohan Hedberg * completed. 1555e1d08f40SJohan Hedberg */ 1556a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 1557e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 1558e1d08f40SJohan Hedberg 1559a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 1560a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 1561a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 1562a5c8f270SMarcel Holtmann */ 1563e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 1564e1d08f40SJohan Hedberg 156512aa4f0aSMarcel Holtmann /* For controllers not using the management interface and that 1566b6ae8457SJohan Hedberg * are brought up using legacy ioctl, set the HCI_BONDABLE bit 156712aa4f0aSMarcel Holtmann * so that pairing works for them. Once the management interface 156812aa4f0aSMarcel Holtmann * is in use this bit will be cleared again and userspace has 156912aa4f0aSMarcel Holtmann * to explicitly enable it. 157012aa4f0aSMarcel Holtmann */ 1571d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1572d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_MGMT)) 1573a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BONDABLE); 157412aa4f0aSMarcel Holtmann 1575cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 1576cbed0ca1SJohan Hedberg 1577fee746b0SMarcel Holtmann done: 1578cbed0ca1SJohan Hedberg hci_dev_put(hdev); 1579cbed0ca1SJohan Hedberg return err; 1580cbed0ca1SJohan Hedberg } 1581cbed0ca1SJohan Hedberg 1582d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */ 1583d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev) 1584d7347f3cSJohan Hedberg { 1585d7347f3cSJohan Hedberg struct hci_conn_params *p; 1586d7347f3cSJohan Hedberg 1587f161dd41SJohan Hedberg list_for_each_entry(p, &hdev->le_conn_params, list) { 1588f161dd41SJohan Hedberg if (p->conn) { 1589f161dd41SJohan Hedberg hci_conn_drop(p->conn); 1590f8aaf9b6SJohan Hedberg hci_conn_put(p->conn); 1591f161dd41SJohan Hedberg p->conn = NULL; 1592f161dd41SJohan Hedberg } 1593d7347f3cSJohan Hedberg list_del_init(&p->action); 1594f161dd41SJohan Hedberg } 1595d7347f3cSJohan Hedberg 1596d7347f3cSJohan Hedberg BT_DBG("All LE pending actions cleared"); 1597d7347f3cSJohan Hedberg } 1598d7347f3cSJohan Hedberg 15996b3cc1dbSSimon Fels int hci_dev_do_close(struct hci_dev *hdev) 16001da177e4SLinus Torvalds { 1601acc649c6SMarcel Holtmann bool auto_off; 1602acc649c6SMarcel Holtmann 16031da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 16041da177e4SLinus Torvalds 1605d24d8144SGabriele Mazzotta if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && 1606867146a0SLoic Poulain !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1607d24d8144SGabriele Mazzotta test_bit(HCI_UP, &hdev->flags)) { 1608a44fecbdSTedd Ho-Jeong An /* Execute vendor specific shutdown routine */ 1609a44fecbdSTedd Ho-Jeong An if (hdev->shutdown) 1610a44fecbdSTedd Ho-Jeong An hdev->shutdown(hdev); 1611a44fecbdSTedd Ho-Jeong An } 1612a44fecbdSTedd Ho-Jeong An 161378c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 161478c04c0bSVinicius Costa Gomes 16157df0f73eSJohan Hedberg hci_request_cancel_all(hdev); 1616b504430cSJohan Hedberg hci_req_sync_lock(hdev); 16171da177e4SLinus Torvalds 16181da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 161965cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 1620b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 16211da177e4SLinus Torvalds return 0; 16221da177e4SLinus Torvalds } 16231da177e4SLinus Torvalds 16246d5d2ee6SHeiner Kallweit hci_leds_update_powered(hdev, false); 16256d5d2ee6SHeiner Kallweit 16263eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 16273eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1628b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 16291da177e4SLinus Torvalds 163016ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 163116ab91abSJohan Hedberg hdev->discov_timeout = 0; 1632a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_DISCOVERABLE); 1633a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 163416ab91abSJohan Hedberg } 163516ab91abSJohan Hedberg 1636a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE)) 16377d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 16387d78525dSJohan Hedberg 1639a73c046aSJaganath Kanakkassery if (hci_dev_test_flag(hdev, HCI_MGMT)) { 1640a73c046aSJaganath Kanakkassery struct adv_info *adv_instance; 1641a73c046aSJaganath Kanakkassery 1642d6bfd59cSJohan Hedberg cancel_delayed_work_sync(&hdev->rpa_expired); 16437ba8b4beSAndre Guedes 1644a73c046aSJaganath Kanakkassery list_for_each_entry(adv_instance, &hdev->adv_instances, list) 1645a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 1646a73c046aSJaganath Kanakkassery } 1647a73c046aSJaganath Kanakkassery 164876727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 164976727c02SJohan Hedberg * ensuring the workqueue is empty up front. 165076727c02SJohan Hedberg */ 165176727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 165276727c02SJohan Hedberg 165309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 16541aeb9c65SJohan Hedberg 16558f502f84SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 16568f502f84SJohan Hedberg 1657acc649c6SMarcel Holtmann auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF); 1658acc649c6SMarcel Holtmann 1659ca8bee5dSMarcel Holtmann if (!auto_off && hdev->dev_type == HCI_PRIMARY && 1660baab7932SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 16612ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT)) 16622ff13894SJohan Hedberg __mgmt_power_off(hdev); 16631aeb9c65SJohan Hedberg 16641f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 1665d7347f3cSJohan Hedberg hci_pend_le_actions_clear(hdev); 1666f161dd41SJohan Hedberg hci_conn_hash_flush(hdev); 166709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 16681da177e4SLinus Torvalds 166964dae967SMarcel Holtmann smp_unregister(hdev); 167064dae967SMarcel Holtmann 167105fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_DOWN); 16721da177e4SLinus Torvalds 16731da177e4SLinus Torvalds if (hdev->flush) 16741da177e4SLinus Torvalds hdev->flush(hdev); 16751da177e4SLinus Torvalds 16761da177e4SLinus Torvalds /* Reset device */ 16771da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 16781da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 1679acc649c6SMarcel Holtmann if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) && 1680acc649c6SMarcel Holtmann !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 16811da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 16824ebeee2dSJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL); 16831da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 16841da177e4SLinus Torvalds } 16851da177e4SLinus Torvalds 1686c347b765SGustavo F. Padovan /* flush cmd work */ 1687c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 16881da177e4SLinus Torvalds 16891da177e4SLinus Torvalds /* Drop queues */ 16901da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 16911da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 16921da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 16931da177e4SLinus Torvalds 16941da177e4SLinus Torvalds /* Drop last sent command */ 16951da177e4SLinus Torvalds if (hdev->sent_cmd) { 169665cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 16971da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 16981da177e4SLinus Torvalds hdev->sent_cmd = NULL; 16991da177e4SLinus Torvalds } 17001da177e4SLinus Torvalds 1701e9ca8bf1SMarcel Holtmann clear_bit(HCI_RUNNING, &hdev->flags); 170205fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_CLOSE); 17034a3f95b7SMarcel Holtmann 17041da177e4SLinus Torvalds /* After this point our queues are empty 17051da177e4SLinus Torvalds * and no tasks are scheduled. */ 17061da177e4SLinus Torvalds hdev->close(hdev); 17071da177e4SLinus Torvalds 170835b973c9SJohan Hedberg /* Clear flags */ 1709fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 1710eacb44dfSMarcel Holtmann hci_dev_clear_volatile_flags(hdev); 171135b973c9SJohan Hedberg 1712ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 1713536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 1714ced5c338SAndrei Emeltchenko 1715e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 171609b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 17177a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, BDADDR_ANY); 1718e59fda8dSJohan Hedberg 1719b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 17201da177e4SLinus Torvalds 17211da177e4SLinus Torvalds hci_dev_put(hdev); 17221da177e4SLinus Torvalds return 0; 17231da177e4SLinus Torvalds } 17241da177e4SLinus Torvalds 17251da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 17261da177e4SLinus Torvalds { 17271da177e4SLinus Torvalds struct hci_dev *hdev; 17281da177e4SLinus Torvalds int err; 17291da177e4SLinus Torvalds 173070f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 173170f23020SAndrei Emeltchenko if (!hdev) 17321da177e4SLinus Torvalds return -ENODEV; 17338ee56540SMarcel Holtmann 1734d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 17350736cfa8SMarcel Holtmann err = -EBUSY; 17360736cfa8SMarcel Holtmann goto done; 17370736cfa8SMarcel Holtmann } 17380736cfa8SMarcel Holtmann 1739a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 17408ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 17418ee56540SMarcel Holtmann 17421da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 17438ee56540SMarcel Holtmann 17440736cfa8SMarcel Holtmann done: 17451da177e4SLinus Torvalds hci_dev_put(hdev); 17461da177e4SLinus Torvalds return err; 17471da177e4SLinus Torvalds } 17481da177e4SLinus Torvalds 17495c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev) 17501da177e4SLinus Torvalds { 17515c912495SMarcel Holtmann int ret; 17521da177e4SLinus Torvalds 17535c912495SMarcel Holtmann BT_DBG("%s %p", hdev->name, hdev); 17541da177e4SLinus Torvalds 1755b504430cSJohan Hedberg hci_req_sync_lock(hdev); 17561da177e4SLinus Torvalds 17571da177e4SLinus Torvalds /* Drop queues */ 17581da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 17591da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 17601da177e4SLinus Torvalds 176176727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 176276727c02SJohan Hedberg * ensuring the workqueue is empty up front. 176376727c02SJohan Hedberg */ 176476727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 176576727c02SJohan Hedberg 176609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 17671f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 17681da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 176909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 17701da177e4SLinus Torvalds 17711da177e4SLinus Torvalds if (hdev->flush) 17721da177e4SLinus Torvalds hdev->flush(hdev); 17731da177e4SLinus Torvalds 17741da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 17756ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 17761da177e4SLinus Torvalds 17774ebeee2dSJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT, NULL); 17781da177e4SLinus Torvalds 1779b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 17801da177e4SLinus Torvalds return ret; 17811da177e4SLinus Torvalds } 17821da177e4SLinus Torvalds 17835c912495SMarcel Holtmann int hci_dev_reset(__u16 dev) 17845c912495SMarcel Holtmann { 17855c912495SMarcel Holtmann struct hci_dev *hdev; 17865c912495SMarcel Holtmann int err; 17875c912495SMarcel Holtmann 17885c912495SMarcel Holtmann hdev = hci_dev_get(dev); 17895c912495SMarcel Holtmann if (!hdev) 17905c912495SMarcel Holtmann return -ENODEV; 17915c912495SMarcel Holtmann 17925c912495SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 17935c912495SMarcel Holtmann err = -ENETDOWN; 17945c912495SMarcel Holtmann goto done; 17955c912495SMarcel Holtmann } 17965c912495SMarcel Holtmann 1797d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 17985c912495SMarcel Holtmann err = -EBUSY; 17995c912495SMarcel Holtmann goto done; 18005c912495SMarcel Holtmann } 18015c912495SMarcel Holtmann 1802d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 18035c912495SMarcel Holtmann err = -EOPNOTSUPP; 18045c912495SMarcel Holtmann goto done; 18055c912495SMarcel Holtmann } 18065c912495SMarcel Holtmann 18075c912495SMarcel Holtmann err = hci_dev_do_reset(hdev); 18085c912495SMarcel Holtmann 18095c912495SMarcel Holtmann done: 18105c912495SMarcel Holtmann hci_dev_put(hdev); 18115c912495SMarcel Holtmann return err; 18125c912495SMarcel Holtmann } 18135c912495SMarcel Holtmann 18141da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 18151da177e4SLinus Torvalds { 18161da177e4SLinus Torvalds struct hci_dev *hdev; 18171da177e4SLinus Torvalds int ret = 0; 18181da177e4SLinus Torvalds 181970f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 182070f23020SAndrei Emeltchenko if (!hdev) 18211da177e4SLinus Torvalds return -ENODEV; 18221da177e4SLinus Torvalds 1823d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 18240736cfa8SMarcel Holtmann ret = -EBUSY; 18250736cfa8SMarcel Holtmann goto done; 18260736cfa8SMarcel Holtmann } 18270736cfa8SMarcel Holtmann 1828d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1829fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 1830fee746b0SMarcel Holtmann goto done; 1831fee746b0SMarcel Holtmann } 1832fee746b0SMarcel Holtmann 18331da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 18341da177e4SLinus Torvalds 18350736cfa8SMarcel Holtmann done: 18361da177e4SLinus Torvalds hci_dev_put(hdev); 18371da177e4SLinus Torvalds return ret; 18381da177e4SLinus Torvalds } 18391da177e4SLinus Torvalds 1840123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan) 1841123abc08SJohan Hedberg { 1842bc6d2d04SJohan Hedberg bool conn_changed, discov_changed; 1843123abc08SJohan Hedberg 1844123abc08SJohan Hedberg BT_DBG("%s scan 0x%02x", hdev->name, scan); 1845123abc08SJohan Hedberg 1846123abc08SJohan Hedberg if ((scan & SCAN_PAGE)) 1847238be788SMarcel Holtmann conn_changed = !hci_dev_test_and_set_flag(hdev, 1848238be788SMarcel Holtmann HCI_CONNECTABLE); 1849123abc08SJohan Hedberg else 1850a69d8927SMarcel Holtmann conn_changed = hci_dev_test_and_clear_flag(hdev, 1851a69d8927SMarcel Holtmann HCI_CONNECTABLE); 1852123abc08SJohan Hedberg 1853bc6d2d04SJohan Hedberg if ((scan & SCAN_INQUIRY)) { 1854238be788SMarcel Holtmann discov_changed = !hci_dev_test_and_set_flag(hdev, 1855238be788SMarcel Holtmann HCI_DISCOVERABLE); 1856bc6d2d04SJohan Hedberg } else { 1857a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 1858a69d8927SMarcel Holtmann discov_changed = hci_dev_test_and_clear_flag(hdev, 1859a69d8927SMarcel Holtmann HCI_DISCOVERABLE); 1860bc6d2d04SJohan Hedberg } 1861bc6d2d04SJohan Hedberg 1862d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 1863123abc08SJohan Hedberg return; 1864123abc08SJohan Hedberg 1865bc6d2d04SJohan Hedberg if (conn_changed || discov_changed) { 1866bc6d2d04SJohan Hedberg /* In case this was disabled through mgmt */ 1867a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 1868bc6d2d04SJohan Hedberg 1869d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 1870cab054abSJohan Hedberg hci_req_update_adv_data(hdev, hdev->cur_adv_instance); 1871bc6d2d04SJohan Hedberg 1872123abc08SJohan Hedberg mgmt_new_settings(hdev); 1873123abc08SJohan Hedberg } 1874bc6d2d04SJohan Hedberg } 1875123abc08SJohan Hedberg 18761da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 18771da177e4SLinus Torvalds { 18781da177e4SLinus Torvalds struct hci_dev *hdev; 18791da177e4SLinus Torvalds struct hci_dev_req dr; 18801da177e4SLinus Torvalds int err = 0; 18811da177e4SLinus Torvalds 18821da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 18831da177e4SLinus Torvalds return -EFAULT; 18841da177e4SLinus Torvalds 188570f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 188670f23020SAndrei Emeltchenko if (!hdev) 18871da177e4SLinus Torvalds return -ENODEV; 18881da177e4SLinus Torvalds 1889d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 18900736cfa8SMarcel Holtmann err = -EBUSY; 18910736cfa8SMarcel Holtmann goto done; 18920736cfa8SMarcel Holtmann } 18930736cfa8SMarcel Holtmann 1894d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1895fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1896fee746b0SMarcel Holtmann goto done; 1897fee746b0SMarcel Holtmann } 1898fee746b0SMarcel Holtmann 1899ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 19005b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 19015b69bef5SMarcel Holtmann goto done; 19025b69bef5SMarcel Holtmann } 19035b69bef5SMarcel Holtmann 1904d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 190556f87901SJohan Hedberg err = -EOPNOTSUPP; 190656f87901SJohan Hedberg goto done; 190756f87901SJohan Hedberg } 190856f87901SJohan Hedberg 19091da177e4SLinus Torvalds switch (cmd) { 19101da177e4SLinus Torvalds case HCISETAUTH: 191101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 19124ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 19131da177e4SLinus Torvalds break; 19141da177e4SLinus Torvalds 19151da177e4SLinus Torvalds case HCISETENCRYPT: 19161da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 19171da177e4SLinus Torvalds err = -EOPNOTSUPP; 19181da177e4SLinus Torvalds break; 19191da177e4SLinus Torvalds } 19201da177e4SLinus Torvalds 19211da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 19221da177e4SLinus Torvalds /* Auth must be enabled first */ 192301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 19244ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 19251da177e4SLinus Torvalds if (err) 19261da177e4SLinus Torvalds break; 19271da177e4SLinus Torvalds } 19281da177e4SLinus Torvalds 192901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 19304ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 19311da177e4SLinus Torvalds break; 19321da177e4SLinus Torvalds 19331da177e4SLinus Torvalds case HCISETSCAN: 193401178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 19354ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 193691a668b0SJohan Hedberg 1937bc6d2d04SJohan Hedberg /* Ensure that the connectable and discoverable states 1938bc6d2d04SJohan Hedberg * get correctly modified as this was a non-mgmt change. 193991a668b0SJohan Hedberg */ 1940123abc08SJohan Hedberg if (!err) 1941123abc08SJohan Hedberg hci_update_scan_state(hdev, dr.dev_opt); 19421da177e4SLinus Torvalds break; 19431da177e4SLinus Torvalds 19441da177e4SLinus Torvalds case HCISETLINKPOL: 194501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 19464ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 19471da177e4SLinus Torvalds break; 19481da177e4SLinus Torvalds 19491da177e4SLinus Torvalds case HCISETLINKMODE: 1950e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 1951e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 1952e4e8e37cSMarcel Holtmann break; 1953e4e8e37cSMarcel Holtmann 1954e4e8e37cSMarcel Holtmann case HCISETPTYPE: 1955b7c23df8SJaganath Kanakkassery if (hdev->pkt_type == (__u16) dr.dev_opt) 1956b7c23df8SJaganath Kanakkassery break; 1957b7c23df8SJaganath Kanakkassery 1958e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 1959b7c23df8SJaganath Kanakkassery mgmt_phy_configuration_changed(hdev, NULL); 19601da177e4SLinus Torvalds break; 19611da177e4SLinus Torvalds 19621da177e4SLinus Torvalds case HCISETACLMTU: 19631da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 19641da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 19651da177e4SLinus Torvalds break; 19661da177e4SLinus Torvalds 19671da177e4SLinus Torvalds case HCISETSCOMTU: 19681da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 19691da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 19701da177e4SLinus Torvalds break; 19711da177e4SLinus Torvalds 19721da177e4SLinus Torvalds default: 19731da177e4SLinus Torvalds err = -EINVAL; 19741da177e4SLinus Torvalds break; 19751da177e4SLinus Torvalds } 1976e4e8e37cSMarcel Holtmann 19770736cfa8SMarcel Holtmann done: 19781da177e4SLinus Torvalds hci_dev_put(hdev); 19791da177e4SLinus Torvalds return err; 19801da177e4SLinus Torvalds } 19811da177e4SLinus Torvalds 19821da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 19831da177e4SLinus Torvalds { 19848035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 19851da177e4SLinus Torvalds struct hci_dev_list_req *dl; 19861da177e4SLinus Torvalds struct hci_dev_req *dr; 19871da177e4SLinus Torvalds int n = 0, size, err; 19881da177e4SLinus Torvalds __u16 dev_num; 19891da177e4SLinus Torvalds 19901da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 19911da177e4SLinus Torvalds return -EFAULT; 19921da177e4SLinus Torvalds 19931da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 19941da177e4SLinus Torvalds return -EINVAL; 19951da177e4SLinus Torvalds 19961da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 19971da177e4SLinus Torvalds 199870f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 199970f23020SAndrei Emeltchenko if (!dl) 20001da177e4SLinus Torvalds return -ENOMEM; 20011da177e4SLinus Torvalds 20021da177e4SLinus Torvalds dr = dl->dev_req; 20031da177e4SLinus Torvalds 2004f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 20058035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 20062e84d8dbSMarcel Holtmann unsigned long flags = hdev->flags; 2007c542a06cSJohan Hedberg 20082e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 20092e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 20102e84d8dbSMarcel Holtmann * device is actually down. 20112e84d8dbSMarcel Holtmann */ 2012d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 20132e84d8dbSMarcel Holtmann flags &= ~BIT(HCI_UP); 2014c542a06cSJohan Hedberg 20151da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 20162e84d8dbSMarcel Holtmann (dr + n)->dev_opt = flags; 2017c542a06cSJohan Hedberg 20181da177e4SLinus Torvalds if (++n >= dev_num) 20191da177e4SLinus Torvalds break; 20201da177e4SLinus Torvalds } 2021f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 20221da177e4SLinus Torvalds 20231da177e4SLinus Torvalds dl->dev_num = n; 20241da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 20251da177e4SLinus Torvalds 20261da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 20271da177e4SLinus Torvalds kfree(dl); 20281da177e4SLinus Torvalds 20291da177e4SLinus Torvalds return err ? -EFAULT : 0; 20301da177e4SLinus Torvalds } 20311da177e4SLinus Torvalds 20321da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 20331da177e4SLinus Torvalds { 20341da177e4SLinus Torvalds struct hci_dev *hdev; 20351da177e4SLinus Torvalds struct hci_dev_info di; 20362e84d8dbSMarcel Holtmann unsigned long flags; 20371da177e4SLinus Torvalds int err = 0; 20381da177e4SLinus Torvalds 20391da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 20401da177e4SLinus Torvalds return -EFAULT; 20411da177e4SLinus Torvalds 204270f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 204370f23020SAndrei Emeltchenko if (!hdev) 20441da177e4SLinus Torvalds return -ENODEV; 20451da177e4SLinus Torvalds 20462e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 20472e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 20482e84d8dbSMarcel Holtmann * device is actually down. 20492e84d8dbSMarcel Holtmann */ 2050d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 20512e84d8dbSMarcel Holtmann flags = hdev->flags & ~BIT(HCI_UP); 20522e84d8dbSMarcel Holtmann else 20532e84d8dbSMarcel Holtmann flags = hdev->flags; 2054c542a06cSJohan Hedberg 20551da177e4SLinus Torvalds strcpy(di.name, hdev->name); 20561da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 205760f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 20582e84d8dbSMarcel Holtmann di.flags = flags; 20591da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2060572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 20611da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 20621da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 20631da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 20641da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2065572c7f84SJohan Hedberg } else { 2066572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2067572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2068572c7f84SJohan Hedberg di.sco_mtu = 0; 2069572c7f84SJohan Hedberg di.sco_pkts = 0; 2070572c7f84SJohan Hedberg } 20711da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 20721da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 20731da177e4SLinus Torvalds 20741da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 20751da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 20761da177e4SLinus Torvalds 20771da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 20781da177e4SLinus Torvalds err = -EFAULT; 20791da177e4SLinus Torvalds 20801da177e4SLinus Torvalds hci_dev_put(hdev); 20811da177e4SLinus Torvalds 20821da177e4SLinus Torvalds return err; 20831da177e4SLinus Torvalds } 20841da177e4SLinus Torvalds 20851da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 20861da177e4SLinus Torvalds 2087611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2088611b30f7SMarcel Holtmann { 2089611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2090611b30f7SMarcel Holtmann 2091611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2092611b30f7SMarcel Holtmann 2093d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) 20940736cfa8SMarcel Holtmann return -EBUSY; 20950736cfa8SMarcel Holtmann 20965e130367SJohan Hedberg if (blocked) { 2097a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 2098d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 2099d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 2100611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 21015e130367SJohan Hedberg } else { 2102a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_RFKILLED); 21035e130367SJohan Hedberg } 2104611b30f7SMarcel Holtmann 2105611b30f7SMarcel Holtmann return 0; 2106611b30f7SMarcel Holtmann } 2107611b30f7SMarcel Holtmann 2108611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2109611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2110611b30f7SMarcel Holtmann }; 2111611b30f7SMarcel Holtmann 2112ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2113ab81cbf9SJohan Hedberg { 2114ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 211596570ffcSJohan Hedberg int err; 2116ab81cbf9SJohan Hedberg 2117ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2118ab81cbf9SJohan Hedberg 21192ff13894SJohan Hedberg if (test_bit(HCI_UP, &hdev->flags) && 21202ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 21212ff13894SJohan Hedberg hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) { 2122d82142a8SWei-Ning Huang cancel_delayed_work(&hdev->power_off); 21232ff13894SJohan Hedberg hci_req_sync_lock(hdev); 21242ff13894SJohan Hedberg err = __hci_req_hci_power_on(hdev); 21252ff13894SJohan Hedberg hci_req_sync_unlock(hdev); 21262ff13894SJohan Hedberg mgmt_power_on(hdev, err); 21272ff13894SJohan Hedberg return; 21282ff13894SJohan Hedberg } 21292ff13894SJohan Hedberg 2130cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 213196570ffcSJohan Hedberg if (err < 0) { 21323ad67582SJaganath Kanakkassery hci_dev_lock(hdev); 213396570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 21343ad67582SJaganath Kanakkassery hci_dev_unlock(hdev); 2135ab81cbf9SJohan Hedberg return; 213696570ffcSJohan Hedberg } 2137ab81cbf9SJohan Hedberg 2138a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2139a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2140a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2141a5c8f270SMarcel Holtmann */ 2142d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED) || 2143d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_UNCONFIGURED) || 2144ca8bee5dSMarcel Holtmann (hdev->dev_type == HCI_PRIMARY && 2145a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2146a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2147a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_AUTO_OFF); 2148bf543036SJohan Hedberg hci_dev_do_close(hdev); 2149d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) { 215019202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 215119202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2152bf543036SJohan Hedberg } 2153ab81cbf9SJohan Hedberg 2154a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) { 21554a964404SMarcel Holtmann /* For unconfigured devices, set the HCI_RAW flag 21564a964404SMarcel Holtmann * so that userspace can easily identify them. 21574a964404SMarcel Holtmann */ 2158d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 21594a964404SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 21600602a8adSMarcel Holtmann 21610602a8adSMarcel Holtmann /* For fully configured devices, this will send 21620602a8adSMarcel Holtmann * the Index Added event. For unconfigured devices, 21630602a8adSMarcel Holtmann * it will send Unconfigued Index Added event. 21640602a8adSMarcel Holtmann * 21650602a8adSMarcel Holtmann * Devices with HCI_QUIRK_RAW_DEVICE are ignored 21660602a8adSMarcel Holtmann * and no event will be send. 21670602a8adSMarcel Holtmann */ 2168744cf19eSJohan Hedberg mgmt_index_added(hdev); 2169a69d8927SMarcel Holtmann } else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) { 21705ea234d3SMarcel Holtmann /* When the controller is now configured, then it 21715ea234d3SMarcel Holtmann * is important to clear the HCI_RAW flag. 21725ea234d3SMarcel Holtmann */ 2173d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 21745ea234d3SMarcel Holtmann clear_bit(HCI_RAW, &hdev->flags); 21755ea234d3SMarcel Holtmann 2176d603b76bSMarcel Holtmann /* Powering on the controller with HCI_CONFIG set only 2177d603b76bSMarcel Holtmann * happens with the transition from unconfigured to 2178d603b76bSMarcel Holtmann * configured. This will send the Index Added event. 2179d603b76bSMarcel Holtmann */ 2180d603b76bSMarcel Holtmann mgmt_index_added(hdev); 2181ab81cbf9SJohan Hedberg } 2182ab81cbf9SJohan Hedberg } 2183ab81cbf9SJohan Hedberg 2184ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2185ab81cbf9SJohan Hedberg { 21863243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 21873243553fSJohan Hedberg power_off.work); 2188ab81cbf9SJohan Hedberg 2189ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2190ab81cbf9SJohan Hedberg 21918ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2192ab81cbf9SJohan Hedberg } 2193ab81cbf9SJohan Hedberg 2194c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work) 2195c7741d16SMarcel Holtmann { 2196c7741d16SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset); 2197c7741d16SMarcel Holtmann 2198c7741d16SMarcel Holtmann BT_DBG("%s", hdev->name); 2199c7741d16SMarcel Holtmann 2200c7741d16SMarcel Holtmann if (hdev->hw_error) 2201c7741d16SMarcel Holtmann hdev->hw_error(hdev, hdev->hw_error_code); 2202c7741d16SMarcel Holtmann else 22032064ee33SMarcel Holtmann bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code); 2204c7741d16SMarcel Holtmann 2205c7741d16SMarcel Holtmann if (hci_dev_do_close(hdev)) 2206c7741d16SMarcel Holtmann return; 2207c7741d16SMarcel Holtmann 2208c7741d16SMarcel Holtmann hci_dev_do_open(hdev); 2209c7741d16SMarcel Holtmann } 2210c7741d16SMarcel Holtmann 221135f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 22122aeb9a1aSJohan Hedberg { 22134821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 22142aeb9a1aSJohan Hedberg 22154821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 22164821002cSJohan Hedberg list_del(&uuid->list); 22172aeb9a1aSJohan Hedberg kfree(uuid); 22182aeb9a1aSJohan Hedberg } 22192aeb9a1aSJohan Hedberg } 22202aeb9a1aSJohan Hedberg 222135f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 222255ed8ca1SJohan Hedberg { 222355ed8ca1SJohan Hedberg struct link_key *key; 222455ed8ca1SJohan Hedberg 22250378b597SJohan Hedberg list_for_each_entry_rcu(key, &hdev->link_keys, list) { 22260378b597SJohan Hedberg list_del_rcu(&key->list); 22270378b597SJohan Hedberg kfree_rcu(key, rcu); 222855ed8ca1SJohan Hedberg } 222955ed8ca1SJohan Hedberg } 223055ed8ca1SJohan Hedberg 223135f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2232b899efafSVinicius Costa Gomes { 2233970d0f1bSJohan Hedberg struct smp_ltk *k; 2234b899efafSVinicius Costa Gomes 2235970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 2236970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2237970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2238b899efafSVinicius Costa Gomes } 2239b899efafSVinicius Costa Gomes } 2240b899efafSVinicius Costa Gomes 2241970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2242970c4e46SJohan Hedberg { 2243adae20cbSJohan Hedberg struct smp_irk *k; 2244970c4e46SJohan Hedberg 2245adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 2246adae20cbSJohan Hedberg list_del_rcu(&k->list); 2247adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2248970c4e46SJohan Hedberg } 2249970c4e46SJohan Hedberg } 2250970c4e46SJohan Hedberg 225155ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 225255ed8ca1SJohan Hedberg { 225355ed8ca1SJohan Hedberg struct link_key *k; 225455ed8ca1SJohan Hedberg 22550378b597SJohan Hedberg rcu_read_lock(); 22560378b597SJohan Hedberg list_for_each_entry_rcu(k, &hdev->link_keys, list) { 22570378b597SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) { 22580378b597SJohan Hedberg rcu_read_unlock(); 225955ed8ca1SJohan Hedberg return k; 22600378b597SJohan Hedberg } 22610378b597SJohan Hedberg } 22620378b597SJohan Hedberg rcu_read_unlock(); 226355ed8ca1SJohan Hedberg 226455ed8ca1SJohan Hedberg return NULL; 226555ed8ca1SJohan Hedberg } 226655ed8ca1SJohan Hedberg 2267745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2268d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2269d25e28abSJohan Hedberg { 2270d25e28abSJohan Hedberg /* Legacy key */ 2271d25e28abSJohan Hedberg if (key_type < 0x03) 2272745c0ce3SVishal Agarwal return true; 2273d25e28abSJohan Hedberg 2274d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2275d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2276745c0ce3SVishal Agarwal return false; 2277d25e28abSJohan Hedberg 2278d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2279d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2280745c0ce3SVishal Agarwal return false; 2281d25e28abSJohan Hedberg 2282d25e28abSJohan Hedberg /* Security mode 3 case */ 2283d25e28abSJohan Hedberg if (!conn) 2284745c0ce3SVishal Agarwal return true; 2285d25e28abSJohan Hedberg 2286e3befab9SJohan Hedberg /* BR/EDR key derived using SC from an LE link */ 2287e3befab9SJohan Hedberg if (conn->type == LE_LINK) 2288e3befab9SJohan Hedberg return true; 2289e3befab9SJohan Hedberg 2290d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2291d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2292745c0ce3SVishal Agarwal return true; 2293d25e28abSJohan Hedberg 2294d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2295d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2296745c0ce3SVishal Agarwal return true; 2297d25e28abSJohan Hedberg 2298d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2299d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2300745c0ce3SVishal Agarwal return true; 2301d25e28abSJohan Hedberg 2302d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2303d25e28abSJohan Hedberg * persistently */ 2304745c0ce3SVishal Agarwal return false; 2305d25e28abSJohan Hedberg } 2306d25e28abSJohan Hedberg 2307e804d25dSJohan Hedberg static u8 ltk_role(u8 type) 230898a0b845SJohan Hedberg { 2309e804d25dSJohan Hedberg if (type == SMP_LTK) 2310e804d25dSJohan Hedberg return HCI_ROLE_MASTER; 231198a0b845SJohan Hedberg 2312e804d25dSJohan Hedberg return HCI_ROLE_SLAVE; 231398a0b845SJohan Hedberg } 231498a0b845SJohan Hedberg 2315f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2316e804d25dSJohan Hedberg u8 addr_type, u8 role) 231775d262c2SVinicius Costa Gomes { 2318c9839a11SVinicius Costa Gomes struct smp_ltk *k; 231975d262c2SVinicius Costa Gomes 2320970d0f1bSJohan Hedberg rcu_read_lock(); 2321970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 23225378bc56SJohan Hedberg if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr)) 23235378bc56SJohan Hedberg continue; 23245378bc56SJohan Hedberg 2325923e2414SJohan Hedberg if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) { 2326970d0f1bSJohan Hedberg rcu_read_unlock(); 232775d262c2SVinicius Costa Gomes return k; 2328970d0f1bSJohan Hedberg } 2329970d0f1bSJohan Hedberg } 2330970d0f1bSJohan Hedberg rcu_read_unlock(); 233175d262c2SVinicius Costa Gomes 233275d262c2SVinicius Costa Gomes return NULL; 233375d262c2SVinicius Costa Gomes } 233475d262c2SVinicius Costa Gomes 2335970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 2336970c4e46SJohan Hedberg { 2337970c4e46SJohan Hedberg struct smp_irk *irk; 2338970c4e46SJohan Hedberg 2339adae20cbSJohan Hedberg rcu_read_lock(); 2340adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2341adae20cbSJohan Hedberg if (!bacmp(&irk->rpa, rpa)) { 2342adae20cbSJohan Hedberg rcu_read_unlock(); 2343970c4e46SJohan Hedberg return irk; 2344970c4e46SJohan Hedberg } 2345adae20cbSJohan Hedberg } 2346970c4e46SJohan Hedberg 2347adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2348defce9e8SJohan Hedberg if (smp_irk_matches(hdev, irk->val, rpa)) { 2349970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2350adae20cbSJohan Hedberg rcu_read_unlock(); 2351970c4e46SJohan Hedberg return irk; 2352970c4e46SJohan Hedberg } 2353970c4e46SJohan Hedberg } 2354adae20cbSJohan Hedberg rcu_read_unlock(); 2355970c4e46SJohan Hedberg 2356970c4e46SJohan Hedberg return NULL; 2357970c4e46SJohan Hedberg } 2358970c4e46SJohan Hedberg 2359970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2360970c4e46SJohan Hedberg u8 addr_type) 2361970c4e46SJohan Hedberg { 2362970c4e46SJohan Hedberg struct smp_irk *irk; 2363970c4e46SJohan Hedberg 23646cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 23656cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 23666cfc9988SJohan Hedberg return NULL; 23676cfc9988SJohan Hedberg 2368adae20cbSJohan Hedberg rcu_read_lock(); 2369adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2370970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 2371adae20cbSJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) { 2372adae20cbSJohan Hedberg rcu_read_unlock(); 2373970c4e46SJohan Hedberg return irk; 2374970c4e46SJohan Hedberg } 2375adae20cbSJohan Hedberg } 2376adae20cbSJohan Hedberg rcu_read_unlock(); 2377970c4e46SJohan Hedberg 2378970c4e46SJohan Hedberg return NULL; 2379970c4e46SJohan Hedberg } 2380970c4e46SJohan Hedberg 2381567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 23827652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 23837652ff6aSJohan Hedberg u8 pin_len, bool *persistent) 238455ed8ca1SJohan Hedberg { 238555ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2386745c0ce3SVishal Agarwal u8 old_key_type; 238755ed8ca1SJohan Hedberg 238855ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 238955ed8ca1SJohan Hedberg if (old_key) { 239055ed8ca1SJohan Hedberg old_key_type = old_key->type; 239155ed8ca1SJohan Hedberg key = old_key; 239255ed8ca1SJohan Hedberg } else { 239312adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 23940a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 239555ed8ca1SJohan Hedberg if (!key) 2396567fa2aaSJohan Hedberg return NULL; 23970378b597SJohan Hedberg list_add_rcu(&key->list, &hdev->link_keys); 239855ed8ca1SJohan Hedberg } 239955ed8ca1SJohan Hedberg 24006ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 240155ed8ca1SJohan Hedberg 2402d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2403d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2404d25e28abSJohan Hedberg * previous key */ 2405d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2406a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2407d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2408655fe6ecSJohan Hedberg if (conn) 2409655fe6ecSJohan Hedberg conn->key_type = type; 2410655fe6ecSJohan Hedberg } 2411d25e28abSJohan Hedberg 241255ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 24139b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 241455ed8ca1SJohan Hedberg key->pin_len = pin_len; 241555ed8ca1SJohan Hedberg 2416b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 241755ed8ca1SJohan Hedberg key->type = old_key_type; 24184748fed2SJohan Hedberg else 24194748fed2SJohan Hedberg key->type = type; 24204748fed2SJohan Hedberg 24217652ff6aSJohan Hedberg if (persistent) 24227652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type, 24237652ff6aSJohan Hedberg old_key_type); 24244df378a1SJohan Hedberg 2425567fa2aaSJohan Hedberg return key; 242655ed8ca1SJohan Hedberg } 242755ed8ca1SJohan Hedberg 2428ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 242935d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 2430fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand) 243175d262c2SVinicius Costa Gomes { 2432c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 2433e804d25dSJohan Hedberg u8 role = ltk_role(type); 243475d262c2SVinicius Costa Gomes 2435f3a73d97SJohan Hedberg old_key = hci_find_ltk(hdev, bdaddr, addr_type, role); 2436c9839a11SVinicius Costa Gomes if (old_key) 243775d262c2SVinicius Costa Gomes key = old_key; 2438c9839a11SVinicius Costa Gomes else { 24390a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 244075d262c2SVinicius Costa Gomes if (!key) 2441ca9142b8SJohan Hedberg return NULL; 2442970d0f1bSJohan Hedberg list_add_rcu(&key->list, &hdev->long_term_keys); 244375d262c2SVinicius Costa Gomes } 244475d262c2SVinicius Costa Gomes 244575d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2446c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2447c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2448c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2449c9839a11SVinicius Costa Gomes key->ediv = ediv; 2450fe39c7b2SMarcel Holtmann key->rand = rand; 2451c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2452c9839a11SVinicius Costa Gomes key->type = type; 245375d262c2SVinicius Costa Gomes 2454ca9142b8SJohan Hedberg return key; 245575d262c2SVinicius Costa Gomes } 245675d262c2SVinicius Costa Gomes 2457ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2458ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 2459970c4e46SJohan Hedberg { 2460970c4e46SJohan Hedberg struct smp_irk *irk; 2461970c4e46SJohan Hedberg 2462970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 2463970c4e46SJohan Hedberg if (!irk) { 2464970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 2465970c4e46SJohan Hedberg if (!irk) 2466ca9142b8SJohan Hedberg return NULL; 2467970c4e46SJohan Hedberg 2468970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 2469970c4e46SJohan Hedberg irk->addr_type = addr_type; 2470970c4e46SJohan Hedberg 2471adae20cbSJohan Hedberg list_add_rcu(&irk->list, &hdev->identity_resolving_keys); 2472970c4e46SJohan Hedberg } 2473970c4e46SJohan Hedberg 2474970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 2475970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2476970c4e46SJohan Hedberg 2477ca9142b8SJohan Hedberg return irk; 2478970c4e46SJohan Hedberg } 2479970c4e46SJohan Hedberg 248055ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 248155ed8ca1SJohan Hedberg { 248255ed8ca1SJohan Hedberg struct link_key *key; 248355ed8ca1SJohan Hedberg 248455ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 248555ed8ca1SJohan Hedberg if (!key) 248655ed8ca1SJohan Hedberg return -ENOENT; 248755ed8ca1SJohan Hedberg 24886ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 248955ed8ca1SJohan Hedberg 24900378b597SJohan Hedberg list_del_rcu(&key->list); 24910378b597SJohan Hedberg kfree_rcu(key, rcu); 249255ed8ca1SJohan Hedberg 249355ed8ca1SJohan Hedberg return 0; 249455ed8ca1SJohan Hedberg } 249555ed8ca1SJohan Hedberg 2496e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 2497b899efafSVinicius Costa Gomes { 2498970d0f1bSJohan Hedberg struct smp_ltk *k; 2499c51ffa0bSJohan Hedberg int removed = 0; 2500b899efafSVinicius Costa Gomes 2501970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 2502e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 2503b899efafSVinicius Costa Gomes continue; 2504b899efafSVinicius Costa Gomes 25056ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2506b899efafSVinicius Costa Gomes 2507970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2508970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2509c51ffa0bSJohan Hedberg removed++; 2510b899efafSVinicius Costa Gomes } 2511b899efafSVinicius Costa Gomes 2512c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 2513b899efafSVinicius Costa Gomes } 2514b899efafSVinicius Costa Gomes 2515a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 2516a7ec7338SJohan Hedberg { 2517adae20cbSJohan Hedberg struct smp_irk *k; 2518a7ec7338SJohan Hedberg 2519adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 2520a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 2521a7ec7338SJohan Hedberg continue; 2522a7ec7338SJohan Hedberg 2523a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2524a7ec7338SJohan Hedberg 2525adae20cbSJohan Hedberg list_del_rcu(&k->list); 2526adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2527a7ec7338SJohan Hedberg } 2528a7ec7338SJohan Hedberg } 2529a7ec7338SJohan Hedberg 253055e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 253155e76b38SJohan Hedberg { 253255e76b38SJohan Hedberg struct smp_ltk *k; 25334ba9faf3SJohan Hedberg struct smp_irk *irk; 253455e76b38SJohan Hedberg u8 addr_type; 253555e76b38SJohan Hedberg 253655e76b38SJohan Hedberg if (type == BDADDR_BREDR) { 253755e76b38SJohan Hedberg if (hci_find_link_key(hdev, bdaddr)) 253855e76b38SJohan Hedberg return true; 253955e76b38SJohan Hedberg return false; 254055e76b38SJohan Hedberg } 254155e76b38SJohan Hedberg 254255e76b38SJohan Hedberg /* Convert to HCI addr type which struct smp_ltk uses */ 254355e76b38SJohan Hedberg if (type == BDADDR_LE_PUBLIC) 254455e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_PUBLIC; 254555e76b38SJohan Hedberg else 254655e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_RANDOM; 254755e76b38SJohan Hedberg 25484ba9faf3SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, addr_type); 25494ba9faf3SJohan Hedberg if (irk) { 25504ba9faf3SJohan Hedberg bdaddr = &irk->bdaddr; 25514ba9faf3SJohan Hedberg addr_type = irk->addr_type; 25524ba9faf3SJohan Hedberg } 25534ba9faf3SJohan Hedberg 255455e76b38SJohan Hedberg rcu_read_lock(); 255555e76b38SJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 255687c8b28dSJohan Hedberg if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) { 255787c8b28dSJohan Hedberg rcu_read_unlock(); 255855e76b38SJohan Hedberg return true; 255955e76b38SJohan Hedberg } 256087c8b28dSJohan Hedberg } 256155e76b38SJohan Hedberg rcu_read_unlock(); 256255e76b38SJohan Hedberg 256355e76b38SJohan Hedberg return false; 256455e76b38SJohan Hedberg } 256555e76b38SJohan Hedberg 25666bd32326SVille Tervo /* HCI command timer function */ 256765cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work) 25686bd32326SVille Tervo { 256965cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, 257065cc2b49SMarcel Holtmann cmd_timer.work); 25716bd32326SVille Tervo 2572bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2573bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2574bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2575bda4f23aSAndrei Emeltchenko 25762064ee33SMarcel Holtmann bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); 2577bda4f23aSAndrei Emeltchenko } else { 25782064ee33SMarcel Holtmann bt_dev_err(hdev, "command tx timeout"); 2579bda4f23aSAndrei Emeltchenko } 2580bda4f23aSAndrei Emeltchenko 2581e2bef384SRajat Jain if (hdev->cmd_timeout) 2582e2bef384SRajat Jain hdev->cmd_timeout(hdev); 2583e2bef384SRajat Jain 25846bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2585c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 25866bd32326SVille Tervo } 25876bd32326SVille Tervo 25882763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 25896928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type) 25902763eda6SSzymon Janc { 25912763eda6SSzymon Janc struct oob_data *data; 25922763eda6SSzymon Janc 25936928a924SJohan Hedberg list_for_each_entry(data, &hdev->remote_oob_data, list) { 25946928a924SJohan Hedberg if (bacmp(bdaddr, &data->bdaddr) != 0) 25956928a924SJohan Hedberg continue; 25966928a924SJohan Hedberg if (data->bdaddr_type != bdaddr_type) 25976928a924SJohan Hedberg continue; 25982763eda6SSzymon Janc return data; 25996928a924SJohan Hedberg } 26002763eda6SSzymon Janc 26012763eda6SSzymon Janc return NULL; 26022763eda6SSzymon Janc } 26032763eda6SSzymon Janc 26046928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 26056928a924SJohan Hedberg u8 bdaddr_type) 26062763eda6SSzymon Janc { 26072763eda6SSzymon Janc struct oob_data *data; 26082763eda6SSzymon Janc 26096928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 26102763eda6SSzymon Janc if (!data) 26112763eda6SSzymon Janc return -ENOENT; 26122763eda6SSzymon Janc 26136928a924SJohan Hedberg BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type); 26142763eda6SSzymon Janc 26152763eda6SSzymon Janc list_del(&data->list); 26162763eda6SSzymon Janc kfree(data); 26172763eda6SSzymon Janc 26182763eda6SSzymon Janc return 0; 26192763eda6SSzymon Janc } 26202763eda6SSzymon Janc 262135f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 26222763eda6SSzymon Janc { 26232763eda6SSzymon Janc struct oob_data *data, *n; 26242763eda6SSzymon Janc 26252763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 26262763eda6SSzymon Janc list_del(&data->list); 26272763eda6SSzymon Janc kfree(data); 26282763eda6SSzymon Janc } 26292763eda6SSzymon Janc } 26302763eda6SSzymon Janc 26310798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 26326928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192, 263338da1703SJohan Hedberg u8 *hash256, u8 *rand256) 26340798872eSMarcel Holtmann { 26350798872eSMarcel Holtmann struct oob_data *data; 26360798872eSMarcel Holtmann 26376928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 26380798872eSMarcel Holtmann if (!data) { 26390a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 26400798872eSMarcel Holtmann if (!data) 26410798872eSMarcel Holtmann return -ENOMEM; 26420798872eSMarcel Holtmann 26430798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 26446928a924SJohan Hedberg data->bdaddr_type = bdaddr_type; 26450798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 26460798872eSMarcel Holtmann } 26470798872eSMarcel Holtmann 264881328d5cSJohan Hedberg if (hash192 && rand192) { 26490798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 265038da1703SJohan Hedberg memcpy(data->rand192, rand192, sizeof(data->rand192)); 2651f7697b16SMarcel Holtmann if (hash256 && rand256) 2652f7697b16SMarcel Holtmann data->present = 0x03; 265381328d5cSJohan Hedberg } else { 265481328d5cSJohan Hedberg memset(data->hash192, 0, sizeof(data->hash192)); 265581328d5cSJohan Hedberg memset(data->rand192, 0, sizeof(data->rand192)); 2656f7697b16SMarcel Holtmann if (hash256 && rand256) 2657f7697b16SMarcel Holtmann data->present = 0x02; 2658f7697b16SMarcel Holtmann else 2659f7697b16SMarcel Holtmann data->present = 0x00; 266081328d5cSJohan Hedberg } 26610798872eSMarcel Holtmann 266281328d5cSJohan Hedberg if (hash256 && rand256) { 26630798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 266438da1703SJohan Hedberg memcpy(data->rand256, rand256, sizeof(data->rand256)); 266581328d5cSJohan Hedberg } else { 266681328d5cSJohan Hedberg memset(data->hash256, 0, sizeof(data->hash256)); 266781328d5cSJohan Hedberg memset(data->rand256, 0, sizeof(data->rand256)); 2668f7697b16SMarcel Holtmann if (hash192 && rand192) 2669f7697b16SMarcel Holtmann data->present = 0x01; 267081328d5cSJohan Hedberg } 26710798872eSMarcel Holtmann 26726ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 26732763eda6SSzymon Janc 26742763eda6SSzymon Janc return 0; 26752763eda6SSzymon Janc } 26762763eda6SSzymon Janc 2677d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2678d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance) 2679d2609b34SFlorian Grandel { 2680d2609b34SFlorian Grandel struct adv_info *adv_instance; 2681d2609b34SFlorian Grandel 2682d2609b34SFlorian Grandel list_for_each_entry(adv_instance, &hdev->adv_instances, list) { 2683d2609b34SFlorian Grandel if (adv_instance->instance == instance) 2684d2609b34SFlorian Grandel return adv_instance; 2685d2609b34SFlorian Grandel } 2686d2609b34SFlorian Grandel 2687d2609b34SFlorian Grandel return NULL; 2688d2609b34SFlorian Grandel } 2689d2609b34SFlorian Grandel 2690d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 269174b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance) 269274b93e9fSPrasanna Karthik { 2693d2609b34SFlorian Grandel struct adv_info *cur_instance; 2694d2609b34SFlorian Grandel 2695d2609b34SFlorian Grandel cur_instance = hci_find_adv_instance(hdev, instance); 2696d2609b34SFlorian Grandel if (!cur_instance) 2697d2609b34SFlorian Grandel return NULL; 2698d2609b34SFlorian Grandel 2699d2609b34SFlorian Grandel if (cur_instance == list_last_entry(&hdev->adv_instances, 2700d2609b34SFlorian Grandel struct adv_info, list)) 2701d2609b34SFlorian Grandel return list_first_entry(&hdev->adv_instances, 2702d2609b34SFlorian Grandel struct adv_info, list); 2703d2609b34SFlorian Grandel else 2704d2609b34SFlorian Grandel return list_next_entry(cur_instance, list); 2705d2609b34SFlorian Grandel } 2706d2609b34SFlorian Grandel 2707d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2708d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance) 2709d2609b34SFlorian Grandel { 2710d2609b34SFlorian Grandel struct adv_info *adv_instance; 2711d2609b34SFlorian Grandel 2712d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 2713d2609b34SFlorian Grandel if (!adv_instance) 2714d2609b34SFlorian Grandel return -ENOENT; 2715d2609b34SFlorian Grandel 2716d2609b34SFlorian Grandel BT_DBG("%s removing %dMR", hdev->name, instance); 2717d2609b34SFlorian Grandel 2718cab054abSJohan Hedberg if (hdev->cur_adv_instance == instance) { 2719cab054abSJohan Hedberg if (hdev->adv_instance_timeout) { 27205d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 27215d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 27225d900e46SFlorian Grandel } 2723cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 2724cab054abSJohan Hedberg } 27255d900e46SFlorian Grandel 2726a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 2727a73c046aSJaganath Kanakkassery 2728d2609b34SFlorian Grandel list_del(&adv_instance->list); 2729d2609b34SFlorian Grandel kfree(adv_instance); 2730d2609b34SFlorian Grandel 2731d2609b34SFlorian Grandel hdev->adv_instance_cnt--; 2732d2609b34SFlorian Grandel 2733d2609b34SFlorian Grandel return 0; 2734d2609b34SFlorian Grandel } 2735d2609b34SFlorian Grandel 2736a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired) 2737a73c046aSJaganath Kanakkassery { 2738a73c046aSJaganath Kanakkassery struct adv_info *adv_instance, *n; 2739a73c046aSJaganath Kanakkassery 2740a73c046aSJaganath Kanakkassery list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) 2741a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = rpa_expired; 2742a73c046aSJaganath Kanakkassery } 2743a73c046aSJaganath Kanakkassery 2744d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2745d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev) 2746d2609b34SFlorian Grandel { 2747d2609b34SFlorian Grandel struct adv_info *adv_instance, *n; 2748d2609b34SFlorian Grandel 27495d900e46SFlorian Grandel if (hdev->adv_instance_timeout) { 27505d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 27515d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 27525d900e46SFlorian Grandel } 27535d900e46SFlorian Grandel 2754d2609b34SFlorian Grandel list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) { 2755a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 2756d2609b34SFlorian Grandel list_del(&adv_instance->list); 2757d2609b34SFlorian Grandel kfree(adv_instance); 2758d2609b34SFlorian Grandel } 2759d2609b34SFlorian Grandel 2760d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 2761cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 2762d2609b34SFlorian Grandel } 2763d2609b34SFlorian Grandel 2764a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work) 2765a73c046aSJaganath Kanakkassery { 2766a73c046aSJaganath Kanakkassery struct adv_info *adv_instance = container_of(work, struct adv_info, 2767a73c046aSJaganath Kanakkassery rpa_expired_cb.work); 2768a73c046aSJaganath Kanakkassery 2769a73c046aSJaganath Kanakkassery BT_DBG(""); 2770a73c046aSJaganath Kanakkassery 2771a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = true; 2772a73c046aSJaganath Kanakkassery } 2773a73c046aSJaganath Kanakkassery 2774d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2775d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags, 2776d2609b34SFlorian Grandel u16 adv_data_len, u8 *adv_data, 2777d2609b34SFlorian Grandel u16 scan_rsp_len, u8 *scan_rsp_data, 2778d2609b34SFlorian Grandel u16 timeout, u16 duration) 2779d2609b34SFlorian Grandel { 2780d2609b34SFlorian Grandel struct adv_info *adv_instance; 2781d2609b34SFlorian Grandel 2782d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 2783d2609b34SFlorian Grandel if (adv_instance) { 2784d2609b34SFlorian Grandel memset(adv_instance->adv_data, 0, 2785d2609b34SFlorian Grandel sizeof(adv_instance->adv_data)); 2786d2609b34SFlorian Grandel memset(adv_instance->scan_rsp_data, 0, 2787d2609b34SFlorian Grandel sizeof(adv_instance->scan_rsp_data)); 2788d2609b34SFlorian Grandel } else { 2789d2609b34SFlorian Grandel if (hdev->adv_instance_cnt >= HCI_MAX_ADV_INSTANCES || 2790d2609b34SFlorian Grandel instance < 1 || instance > HCI_MAX_ADV_INSTANCES) 2791d2609b34SFlorian Grandel return -EOVERFLOW; 2792d2609b34SFlorian Grandel 279339ecfad6SJohan Hedberg adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL); 2794d2609b34SFlorian Grandel if (!adv_instance) 2795d2609b34SFlorian Grandel return -ENOMEM; 2796d2609b34SFlorian Grandel 2797fffd38bcSFlorian Grandel adv_instance->pending = true; 2798d2609b34SFlorian Grandel adv_instance->instance = instance; 2799d2609b34SFlorian Grandel list_add(&adv_instance->list, &hdev->adv_instances); 2800d2609b34SFlorian Grandel hdev->adv_instance_cnt++; 2801d2609b34SFlorian Grandel } 2802d2609b34SFlorian Grandel 2803d2609b34SFlorian Grandel adv_instance->flags = flags; 2804d2609b34SFlorian Grandel adv_instance->adv_data_len = adv_data_len; 2805d2609b34SFlorian Grandel adv_instance->scan_rsp_len = scan_rsp_len; 2806d2609b34SFlorian Grandel 2807d2609b34SFlorian Grandel if (adv_data_len) 2808d2609b34SFlorian Grandel memcpy(adv_instance->adv_data, adv_data, adv_data_len); 2809d2609b34SFlorian Grandel 2810d2609b34SFlorian Grandel if (scan_rsp_len) 2811d2609b34SFlorian Grandel memcpy(adv_instance->scan_rsp_data, 2812d2609b34SFlorian Grandel scan_rsp_data, scan_rsp_len); 2813d2609b34SFlorian Grandel 2814d2609b34SFlorian Grandel adv_instance->timeout = timeout; 28155d900e46SFlorian Grandel adv_instance->remaining_time = timeout; 2816d2609b34SFlorian Grandel 2817d2609b34SFlorian Grandel if (duration == 0) 2818d2609b34SFlorian Grandel adv_instance->duration = HCI_DEFAULT_ADV_DURATION; 2819d2609b34SFlorian Grandel else 2820d2609b34SFlorian Grandel adv_instance->duration = duration; 2821d2609b34SFlorian Grandel 2822de181e88SJaganath Kanakkassery adv_instance->tx_power = HCI_TX_POWER_INVALID; 2823de181e88SJaganath Kanakkassery 2824a73c046aSJaganath Kanakkassery INIT_DELAYED_WORK(&adv_instance->rpa_expired_cb, 2825a73c046aSJaganath Kanakkassery adv_instance_rpa_expired); 2826a73c046aSJaganath Kanakkassery 2827d2609b34SFlorian Grandel BT_DBG("%s for %dMR", hdev->name, instance); 2828d2609b34SFlorian Grandel 2829d2609b34SFlorian Grandel return 0; 2830d2609b34SFlorian Grandel } 2831d2609b34SFlorian Grandel 2832dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list, 2833b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 2834b2a66aadSAntti Julku { 2835b2a66aadSAntti Julku struct bdaddr_list *b; 2836b2a66aadSAntti Julku 2837dcc36c16SJohan Hedberg list_for_each_entry(b, bdaddr_list, list) { 2838b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2839b2a66aadSAntti Julku return b; 2840b9ee0a78SMarcel Holtmann } 2841b2a66aadSAntti Julku 2842b2a66aadSAntti Julku return NULL; 2843b2a66aadSAntti Julku } 2844b2a66aadSAntti Julku 2845b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk( 2846b950aa88SAnkit Navik struct list_head *bdaddr_list, bdaddr_t *bdaddr, 2847b950aa88SAnkit Navik u8 type) 2848b950aa88SAnkit Navik { 2849b950aa88SAnkit Navik struct bdaddr_list_with_irk *b; 2850b950aa88SAnkit Navik 2851b950aa88SAnkit Navik list_for_each_entry(b, bdaddr_list, list) { 2852b950aa88SAnkit Navik if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2853b950aa88SAnkit Navik return b; 2854b950aa88SAnkit Navik } 2855b950aa88SAnkit Navik 2856b950aa88SAnkit Navik return NULL; 2857b950aa88SAnkit Navik } 2858b950aa88SAnkit Navik 2859dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list) 2860b2a66aadSAntti Julku { 28617eb7404fSGeliang Tang struct bdaddr_list *b, *n; 2862b2a66aadSAntti Julku 28637eb7404fSGeliang Tang list_for_each_entry_safe(b, n, bdaddr_list, list) { 28647eb7404fSGeliang Tang list_del(&b->list); 2865b2a66aadSAntti Julku kfree(b); 2866b2a66aadSAntti Julku } 2867b2a66aadSAntti Julku } 2868b2a66aadSAntti Julku 2869dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type) 2870b2a66aadSAntti Julku { 2871b2a66aadSAntti Julku struct bdaddr_list *entry; 2872b2a66aadSAntti Julku 2873b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 2874b2a66aadSAntti Julku return -EBADF; 2875b2a66aadSAntti Julku 2876dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(list, bdaddr, type)) 28775e762444SAntti Julku return -EEXIST; 2878b2a66aadSAntti Julku 287927f70f3eSJohan Hedberg entry = kzalloc(sizeof(*entry), GFP_KERNEL); 28805e762444SAntti Julku if (!entry) 28815e762444SAntti Julku return -ENOMEM; 2882b2a66aadSAntti Julku 2883b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 2884b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 2885b2a66aadSAntti Julku 2886dcc36c16SJohan Hedberg list_add(&entry->list, list); 2887b2a66aadSAntti Julku 28882a8357f2SJohan Hedberg return 0; 2889b2a66aadSAntti Julku } 2890b2a66aadSAntti Julku 2891b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr, 2892b950aa88SAnkit Navik u8 type, u8 *peer_irk, u8 *local_irk) 2893b950aa88SAnkit Navik { 2894b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 2895b950aa88SAnkit Navik 2896b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) 2897b950aa88SAnkit Navik return -EBADF; 2898b950aa88SAnkit Navik 2899b950aa88SAnkit Navik if (hci_bdaddr_list_lookup(list, bdaddr, type)) 2900b950aa88SAnkit Navik return -EEXIST; 2901b950aa88SAnkit Navik 2902b950aa88SAnkit Navik entry = kzalloc(sizeof(*entry), GFP_KERNEL); 2903b950aa88SAnkit Navik if (!entry) 2904b950aa88SAnkit Navik return -ENOMEM; 2905b950aa88SAnkit Navik 2906b950aa88SAnkit Navik bacpy(&entry->bdaddr, bdaddr); 2907b950aa88SAnkit Navik entry->bdaddr_type = type; 2908b950aa88SAnkit Navik 2909b950aa88SAnkit Navik if (peer_irk) 2910b950aa88SAnkit Navik memcpy(entry->peer_irk, peer_irk, 16); 2911b950aa88SAnkit Navik 2912b950aa88SAnkit Navik if (local_irk) 2913b950aa88SAnkit Navik memcpy(entry->local_irk, local_irk, 16); 2914b950aa88SAnkit Navik 2915b950aa88SAnkit Navik list_add(&entry->list, list); 2916b950aa88SAnkit Navik 2917b950aa88SAnkit Navik return 0; 2918b950aa88SAnkit Navik } 2919b950aa88SAnkit Navik 2920dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type) 2921b2a66aadSAntti Julku { 2922b2a66aadSAntti Julku struct bdaddr_list *entry; 2923b2a66aadSAntti Julku 292435f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 2925dcc36c16SJohan Hedberg hci_bdaddr_list_clear(list); 292635f7498aSJohan Hedberg return 0; 292735f7498aSJohan Hedberg } 2928b2a66aadSAntti Julku 2929dcc36c16SJohan Hedberg entry = hci_bdaddr_list_lookup(list, bdaddr, type); 2930d2ab0ac1SMarcel Holtmann if (!entry) 2931d2ab0ac1SMarcel Holtmann return -ENOENT; 2932d2ab0ac1SMarcel Holtmann 2933d2ab0ac1SMarcel Holtmann list_del(&entry->list); 2934d2ab0ac1SMarcel Holtmann kfree(entry); 2935d2ab0ac1SMarcel Holtmann 2936d2ab0ac1SMarcel Holtmann return 0; 2937d2ab0ac1SMarcel Holtmann } 2938d2ab0ac1SMarcel Holtmann 2939b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr, 2940b950aa88SAnkit Navik u8 type) 2941b950aa88SAnkit Navik { 2942b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 2943b950aa88SAnkit Navik 2944b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) { 2945b950aa88SAnkit Navik hci_bdaddr_list_clear(list); 2946b950aa88SAnkit Navik return 0; 2947b950aa88SAnkit Navik } 2948b950aa88SAnkit Navik 2949b950aa88SAnkit Navik entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type); 2950b950aa88SAnkit Navik if (!entry) 2951b950aa88SAnkit Navik return -ENOENT; 2952b950aa88SAnkit Navik 2953b950aa88SAnkit Navik list_del(&entry->list); 2954b950aa88SAnkit Navik kfree(entry); 2955b950aa88SAnkit Navik 2956b950aa88SAnkit Navik return 0; 2957b950aa88SAnkit Navik } 2958b950aa88SAnkit Navik 295915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 296015819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 296115819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 296215819a70SAndre Guedes { 296315819a70SAndre Guedes struct hci_conn_params *params; 296415819a70SAndre Guedes 296515819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 296615819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 296715819a70SAndre Guedes params->addr_type == addr_type) { 296815819a70SAndre Guedes return params; 296915819a70SAndre Guedes } 297015819a70SAndre Guedes } 297115819a70SAndre Guedes 297215819a70SAndre Guedes return NULL; 297315819a70SAndre Guedes } 297415819a70SAndre Guedes 297515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 2976501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 29774b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type) 297815819a70SAndre Guedes { 2979912b42efSJohan Hedberg struct hci_conn_params *param; 298015819a70SAndre Guedes 2981501f8827SJohan Hedberg list_for_each_entry(param, list, action) { 2982912b42efSJohan Hedberg if (bacmp(¶m->addr, addr) == 0 && 2983912b42efSJohan Hedberg param->addr_type == addr_type) 2984912b42efSJohan Hedberg return param; 29854b10966fSMarcel Holtmann } 29864b10966fSMarcel Holtmann 29874b10966fSMarcel Holtmann return NULL; 298815819a70SAndre Guedes } 298915819a70SAndre Guedes 299015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 299151d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 299251d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type) 299315819a70SAndre Guedes { 299415819a70SAndre Guedes struct hci_conn_params *params; 299515819a70SAndre Guedes 299615819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 2997cef952ceSAndre Guedes if (params) 299851d167c0SMarcel Holtmann return params; 299915819a70SAndre Guedes 300015819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 300115819a70SAndre Guedes if (!params) { 30022064ee33SMarcel Holtmann bt_dev_err(hdev, "out of memory"); 300351d167c0SMarcel Holtmann return NULL; 300415819a70SAndre Guedes } 300515819a70SAndre Guedes 300615819a70SAndre Guedes bacpy(¶ms->addr, addr); 300715819a70SAndre Guedes params->addr_type = addr_type; 3008cef952ceSAndre Guedes 3009cef952ceSAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 301093450c75SJohan Hedberg INIT_LIST_HEAD(¶ms->action); 3011cef952ceSAndre Guedes 3012bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval; 3013bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval; 3014bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency; 3015bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout; 3016bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED; 3017bf5b3c8bSMarcel Holtmann 3018bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 3019bf5b3c8bSMarcel Holtmann 302051d167c0SMarcel Holtmann return params; 3021bf5b3c8bSMarcel Holtmann } 3022bf5b3c8bSMarcel Holtmann 3023f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params) 3024f6c63249SJohan Hedberg { 3025f6c63249SJohan Hedberg if (params->conn) { 3026f6c63249SJohan Hedberg hci_conn_drop(params->conn); 3027f6c63249SJohan Hedberg hci_conn_put(params->conn); 3028f6c63249SJohan Hedberg } 3029f6c63249SJohan Hedberg 3030f6c63249SJohan Hedberg list_del(¶ms->action); 3031f6c63249SJohan Hedberg list_del(¶ms->list); 3032f6c63249SJohan Hedberg kfree(params); 3033f6c63249SJohan Hedberg } 3034f6c63249SJohan Hedberg 303515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 303615819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 303715819a70SAndre Guedes { 303815819a70SAndre Guedes struct hci_conn_params *params; 303915819a70SAndre Guedes 304015819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 304115819a70SAndre Guedes if (!params) 304215819a70SAndre Guedes return; 304315819a70SAndre Guedes 3044f6c63249SJohan Hedberg hci_conn_params_free(params); 304515819a70SAndre Guedes 304695305baaSJohan Hedberg hci_update_background_scan(hdev); 304795305baaSJohan Hedberg 304815819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 304915819a70SAndre Guedes } 305015819a70SAndre Guedes 305115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 305255af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev) 305315819a70SAndre Guedes { 305415819a70SAndre Guedes struct hci_conn_params *params, *tmp; 305515819a70SAndre Guedes 305615819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 305755af49a8SJohan Hedberg if (params->auto_connect != HCI_AUTO_CONN_DISABLED) 305855af49a8SJohan Hedberg continue; 3059f75113a2SJakub Pawlowski 3060f75113a2SJakub Pawlowski /* If trying to estabilish one time connection to disabled 3061f75113a2SJakub Pawlowski * device, leave the params, but mark them as just once. 3062f75113a2SJakub Pawlowski */ 3063f75113a2SJakub Pawlowski if (params->explicit_connect) { 3064f75113a2SJakub Pawlowski params->auto_connect = HCI_AUTO_CONN_EXPLICIT; 3065f75113a2SJakub Pawlowski continue; 3066f75113a2SJakub Pawlowski } 3067f75113a2SJakub Pawlowski 306815819a70SAndre Guedes list_del(¶ms->list); 306915819a70SAndre Guedes kfree(params); 307015819a70SAndre Guedes } 307115819a70SAndre Guedes 307255af49a8SJohan Hedberg BT_DBG("All LE disabled connection parameters were removed"); 307355af49a8SJohan Hedberg } 307455af49a8SJohan Hedberg 307555af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */ 3076030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev) 307715819a70SAndre Guedes { 307815819a70SAndre Guedes struct hci_conn_params *params, *tmp; 307915819a70SAndre Guedes 3080f6c63249SJohan Hedberg list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) 3081f6c63249SJohan Hedberg hci_conn_params_free(params); 308215819a70SAndre Guedes 308315819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 308415819a70SAndre Guedes } 308515819a70SAndre Guedes 3086a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 3087a1f4c318SJohan Hedberg * 3088a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 3089a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 3090a1f4c318SJohan Hedberg * the static random address. 3091a1f4c318SJohan Hedberg * 3092a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 3093a1f4c318SJohan Hedberg * public address to use the static random address instead. 309450b5b952SMarcel Holtmann * 309550b5b952SMarcel Holtmann * In case BR/EDR has been disabled on a dual-mode controller and 309650b5b952SMarcel Holtmann * userspace has configured a static address, then that address 309750b5b952SMarcel Holtmann * becomes the identity address instead of the public BR/EDR address. 3098a1f4c318SJohan Hedberg */ 3099a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 3100a1f4c318SJohan Hedberg u8 *bdaddr_type) 3101a1f4c318SJohan Hedberg { 3102b7cb93e5SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) || 310350b5b952SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) || 3104d7a5a11dSMarcel Holtmann (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) && 310550b5b952SMarcel Holtmann bacmp(&hdev->static_addr, BDADDR_ANY))) { 3106a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 3107a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 3108a1f4c318SJohan Hedberg } else { 3109a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 3110a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 3111a1f4c318SJohan Hedberg } 3112a1f4c318SJohan Hedberg } 3113a1f4c318SJohan Hedberg 31149be0dab7SDavid Herrmann /* Alloc HCI device */ 31159be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 31169be0dab7SDavid Herrmann { 31179be0dab7SDavid Herrmann struct hci_dev *hdev; 31189be0dab7SDavid Herrmann 311927f70f3eSJohan Hedberg hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); 31209be0dab7SDavid Herrmann if (!hdev) 31219be0dab7SDavid Herrmann return NULL; 31229be0dab7SDavid Herrmann 3123b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3124b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3125b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3126b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3127b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 312896c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */ 3129bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3130bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3131d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 3132d2609b34SFlorian Grandel hdev->cur_adv_instance = 0x00; 31335d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 3134b1b813d4SDavid Herrmann 3135b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3136b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3137b1b813d4SDavid Herrmann 31383f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 3139628531c9SGeorg Lukas hdev->le_adv_min_interval = 0x0800; 3140628531c9SGeorg Lukas hdev->le_adv_max_interval = 0x0800; 3141bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3142bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 3143b48c3b59SJonas Holmberg hdev->le_conn_min_interval = 0x0018; 3144b48c3b59SJonas Holmberg hdev->le_conn_max_interval = 0x0028; 314504fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000; 314604fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a; 3147a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = 0x001b; 3148a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = 0x0148; 3149a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = 0x001b; 3150a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = 0x0148; 3151a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = 0x001b; 3152a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = 0x0148; 315330d65e08SMatias Karhumaa hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE; 315430d65e08SMatias Karhumaa hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE; 31556decb5b4SJaganath Kanakkassery hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M; 31566decb5b4SJaganath Kanakkassery hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M; 3157bef64738SMarcel Holtmann 3158d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 3159b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 316031ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 316131ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 3162d6bfd59cSJohan Hedberg 3163b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3164b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3165b1b813d4SDavid Herrmann 3166b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3167b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 31686659358eSJohan Hedberg INIT_LIST_HEAD(&hdev->whitelist); 3169b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3170b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3171b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3172970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3173b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 3174d2ab0ac1SMarcel Holtmann INIT_LIST_HEAD(&hdev->le_white_list); 3175cfdb0c2dSAnkit Navik INIT_LIST_HEAD(&hdev->le_resolv_list); 317615819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 317777a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 317866f8455aSJohan Hedberg INIT_LIST_HEAD(&hdev->pend_le_reports); 31796b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3180d2609b34SFlorian Grandel INIT_LIST_HEAD(&hdev->adv_instances); 3181b1b813d4SDavid Herrmann 3182b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3183b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3184b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3185b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3186c7741d16SMarcel Holtmann INIT_WORK(&hdev->error_reset, hci_error_reset); 3187b1b813d4SDavid Herrmann 3188b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3189b1b813d4SDavid Herrmann 3190b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3191b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3192b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3193b1b813d4SDavid Herrmann 3194b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 3195b1b813d4SDavid Herrmann 319665cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout); 3197b1b813d4SDavid Herrmann 31985fc16cc4SJohan Hedberg hci_request_setup(hdev); 31995fc16cc4SJohan Hedberg 3200b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3201b1b813d4SDavid Herrmann discovery_init(hdev); 32029be0dab7SDavid Herrmann 32039be0dab7SDavid Herrmann return hdev; 32049be0dab7SDavid Herrmann } 32059be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 32069be0dab7SDavid Herrmann 32079be0dab7SDavid Herrmann /* Free HCI device */ 32089be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 32099be0dab7SDavid Herrmann { 32109be0dab7SDavid Herrmann /* will free via device release */ 32119be0dab7SDavid Herrmann put_device(&hdev->dev); 32129be0dab7SDavid Herrmann } 32139be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 32149be0dab7SDavid Herrmann 32151da177e4SLinus Torvalds /* Register HCI device */ 32161da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 32171da177e4SLinus Torvalds { 3218b1b813d4SDavid Herrmann int id, error; 32191da177e4SLinus Torvalds 322074292d5aSMarcel Holtmann if (!hdev->open || !hdev->close || !hdev->send) 32211da177e4SLinus Torvalds return -EINVAL; 32221da177e4SLinus Torvalds 322308add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 322408add513SMat Martineau * so the index can be used as the AMP controller ID. 322508add513SMat Martineau */ 32263df92b31SSasha Levin switch (hdev->dev_type) { 3227ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 32283df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 32291da177e4SLinus Torvalds break; 32303df92b31SSasha Levin case HCI_AMP: 32313df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 32323df92b31SSasha Levin break; 32333df92b31SSasha Levin default: 32343df92b31SSasha Levin return -EINVAL; 32351da177e4SLinus Torvalds } 32361da177e4SLinus Torvalds 32373df92b31SSasha Levin if (id < 0) 32383df92b31SSasha Levin return id; 32393df92b31SSasha Levin 32401da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 32411da177e4SLinus Torvalds hdev->id = id; 32422d8b3a11SAndrei Emeltchenko 32432d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 32442d8b3a11SAndrei Emeltchenko 324529e2dd0dSTejun Heo hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name); 324633ca954dSDavid Herrmann if (!hdev->workqueue) { 324733ca954dSDavid Herrmann error = -ENOMEM; 324833ca954dSDavid Herrmann goto err; 324933ca954dSDavid Herrmann } 3250f48fd9c8SMarcel Holtmann 325129e2dd0dSTejun Heo hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, 325229e2dd0dSTejun Heo hdev->name); 32536ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 32546ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 32556ead1bbcSJohan Hedberg error = -ENOMEM; 32566ead1bbcSJohan Hedberg goto err; 32576ead1bbcSJohan Hedberg } 32586ead1bbcSJohan Hedberg 32590153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 32600153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 32610153e2ecSMarcel Holtmann 3262bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3263bdc3e0f1SMarcel Holtmann 3264bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 326533ca954dSDavid Herrmann if (error < 0) 326654506918SJohan Hedberg goto err_wqueue; 32671da177e4SLinus Torvalds 32686d5d2ee6SHeiner Kallweit hci_leds_init(hdev); 32696d5d2ee6SHeiner Kallweit 3270611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3271a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3272a8c5fb1aSGustavo Padovan hdev); 3273611b30f7SMarcel Holtmann if (hdev->rfkill) { 3274611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3275611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3276611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3277611b30f7SMarcel Holtmann } 3278611b30f7SMarcel Holtmann } 3279611b30f7SMarcel Holtmann 32805e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 3281a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 32825e130367SJohan Hedberg 3283a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SETUP); 3284a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_AUTO_OFF); 3285ce2be9acSAndrei Emeltchenko 3286ca8bee5dSMarcel Holtmann if (hdev->dev_type == HCI_PRIMARY) { 328756f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 328856f87901SJohan Hedberg * through reading supported features during init. 328956f87901SJohan Hedberg */ 3290a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 329156f87901SJohan Hedberg } 3292ce2be9acSAndrei Emeltchenko 3293fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3294fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3295fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3296fcee3377SGustavo Padovan 32974a964404SMarcel Holtmann /* Devices that are marked for raw-only usage are unconfigured 32984a964404SMarcel Holtmann * and should not be included in normal operation. 3299fee746b0SMarcel Holtmann */ 3300fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 3301a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 3302fee746b0SMarcel Holtmann 330305fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_REG); 3304dc946bd8SDavid Herrmann hci_dev_hold(hdev); 33051da177e4SLinus Torvalds 330619202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3307fbe96d6fSMarcel Holtmann 33081da177e4SLinus Torvalds return id; 3309f48fd9c8SMarcel Holtmann 331033ca954dSDavid Herrmann err_wqueue: 331133ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 33126ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 331333ca954dSDavid Herrmann err: 33143df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3315f48fd9c8SMarcel Holtmann 331633ca954dSDavid Herrmann return error; 33171da177e4SLinus Torvalds } 33181da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 33191da177e4SLinus Torvalds 33201da177e4SLinus Torvalds /* Unregister HCI device */ 332159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 33221da177e4SLinus Torvalds { 33232d7cc19eSMarcel Holtmann int id; 3324ef222013SMarcel Holtmann 3325c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 33261da177e4SLinus Torvalds 3327a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNREGISTER); 332894324962SJohan Hovold 33293df92b31SSasha Levin id = hdev->id; 33303df92b31SSasha Levin 3331f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 33321da177e4SLinus Torvalds list_del(&hdev->list); 3333f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 33341da177e4SLinus Torvalds 3335b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 3336b9b5ef18SGustavo Padovan 3337bf389cabSJiri Slaby hci_dev_do_close(hdev); 3338bf389cabSJiri Slaby 3339ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 3340d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_SETUP) && 3341d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 334209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3343744cf19eSJohan Hedberg mgmt_index_removed(hdev); 334409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 334556e5cb86SJohan Hedberg } 3346ab81cbf9SJohan Hedberg 33472e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 33482e58ef3eSJohan Hedberg * pending list */ 33492e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 33502e58ef3eSJohan Hedberg 335105fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UNREG); 33521da177e4SLinus Torvalds 3353611b30f7SMarcel Holtmann if (hdev->rfkill) { 3354611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 3355611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3356611b30f7SMarcel Holtmann } 3357611b30f7SMarcel Holtmann 3358bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 3359147e2d59SDave Young 33600153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 33615177a838SMarcel Holtmann kfree_const(hdev->hw_info); 33625177a838SMarcel Holtmann kfree_const(hdev->fw_info); 33630153e2ecSMarcel Holtmann 3364f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 33656ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 3366f48fd9c8SMarcel Holtmann 336709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3368dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->blacklist); 33696659358eSJohan Hedberg hci_bdaddr_list_clear(&hdev->whitelist); 33702aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 337155ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 3372b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 3373970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 33742763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 3375d2609b34SFlorian Grandel hci_adv_instances_clear(hdev); 3376dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->le_white_list); 3377cfdb0c2dSAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 3378373110c5SJohan Hedberg hci_conn_params_clear_all(hdev); 337922078800SMarcel Holtmann hci_discovery_filter_clear(hdev); 338009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 3381e2e0cacbSJohan Hedberg 3382dc946bd8SDavid Herrmann hci_dev_put(hdev); 33833df92b31SSasha Levin 33843df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 33851da177e4SLinus Torvalds } 33861da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 33871da177e4SLinus Torvalds 33881da177e4SLinus Torvalds /* Suspend HCI device */ 33891da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 33901da177e4SLinus Torvalds { 339105fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_SUSPEND); 33921da177e4SLinus Torvalds return 0; 33931da177e4SLinus Torvalds } 33941da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 33951da177e4SLinus Torvalds 33961da177e4SLinus Torvalds /* Resume HCI device */ 33971da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 33981da177e4SLinus Torvalds { 339905fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_RESUME); 34001da177e4SLinus Torvalds return 0; 34011da177e4SLinus Torvalds } 34021da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 34031da177e4SLinus Torvalds 340475e0569fSMarcel Holtmann /* Reset HCI device */ 340575e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev) 340675e0569fSMarcel Holtmann { 340775e0569fSMarcel Holtmann const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; 340875e0569fSMarcel Holtmann struct sk_buff *skb; 340975e0569fSMarcel Holtmann 341075e0569fSMarcel Holtmann skb = bt_skb_alloc(3, GFP_ATOMIC); 341175e0569fSMarcel Holtmann if (!skb) 341275e0569fSMarcel Holtmann return -ENOMEM; 341375e0569fSMarcel Holtmann 3414d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_EVENT_PKT; 341559ae1d12SJohannes Berg skb_put_data(skb, hw_err, 3); 341675e0569fSMarcel Holtmann 341775e0569fSMarcel Holtmann /* Send Hardware Error to upper stack */ 341875e0569fSMarcel Holtmann return hci_recv_frame(hdev, skb); 341975e0569fSMarcel Holtmann } 342075e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev); 342175e0569fSMarcel Holtmann 342276bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 3423e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 342476bca880SMarcel Holtmann { 342576bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 342676bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 342776bca880SMarcel Holtmann kfree_skb(skb); 342876bca880SMarcel Holtmann return -ENXIO; 342976bca880SMarcel Holtmann } 343076bca880SMarcel Holtmann 3431d79f34e3SMarcel Holtmann if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT && 3432d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && 3433d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) { 3434fe806dceSMarcel Holtmann kfree_skb(skb); 3435fe806dceSMarcel Holtmann return -EINVAL; 3436fe806dceSMarcel Holtmann } 3437fe806dceSMarcel Holtmann 3438d82603c6SJorrit Schippers /* Incoming skb */ 343976bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 344076bca880SMarcel Holtmann 344176bca880SMarcel Holtmann /* Time stamp */ 344276bca880SMarcel Holtmann __net_timestamp(skb); 344376bca880SMarcel Holtmann 344476bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3445b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3446c78ae283SMarcel Holtmann 344776bca880SMarcel Holtmann return 0; 344876bca880SMarcel Holtmann } 344976bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 345076bca880SMarcel Holtmann 3451e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */ 3452e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb) 3453e875ff84SMarcel Holtmann { 3454581d6fd6SMarcel Holtmann /* Mark as diagnostic packet */ 3455d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_DIAG_PKT; 3456581d6fd6SMarcel Holtmann 3457e875ff84SMarcel Holtmann /* Time stamp */ 3458e875ff84SMarcel Holtmann __net_timestamp(skb); 3459e875ff84SMarcel Holtmann 3460581d6fd6SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3461581d6fd6SMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3462e875ff84SMarcel Holtmann 3463e875ff84SMarcel Holtmann return 0; 3464e875ff84SMarcel Holtmann } 3465e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag); 3466e875ff84SMarcel Holtmann 34675177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...) 34685177a838SMarcel Holtmann { 34695177a838SMarcel Holtmann va_list vargs; 34705177a838SMarcel Holtmann 34715177a838SMarcel Holtmann va_start(vargs, fmt); 34725177a838SMarcel Holtmann kfree_const(hdev->hw_info); 34735177a838SMarcel Holtmann hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 34745177a838SMarcel Holtmann va_end(vargs); 34755177a838SMarcel Holtmann } 34765177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info); 34775177a838SMarcel Holtmann 34785177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...) 34795177a838SMarcel Holtmann { 34805177a838SMarcel Holtmann va_list vargs; 34815177a838SMarcel Holtmann 34825177a838SMarcel Holtmann va_start(vargs, fmt); 34835177a838SMarcel Holtmann kfree_const(hdev->fw_info); 34845177a838SMarcel Holtmann hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 34855177a838SMarcel Holtmann va_end(vargs); 34865177a838SMarcel Holtmann } 34875177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info); 34885177a838SMarcel Holtmann 34891da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 34901da177e4SLinus Torvalds 34911da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 34921da177e4SLinus Torvalds { 34931da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 34941da177e4SLinus Torvalds 3495fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 349600629e0fSJohan Hedberg list_add_tail(&cb->list, &hci_cb_list); 3497fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 34981da177e4SLinus Torvalds 34991da177e4SLinus Torvalds return 0; 35001da177e4SLinus Torvalds } 35011da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 35021da177e4SLinus Torvalds 35031da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 35041da177e4SLinus Torvalds { 35051da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 35061da177e4SLinus Torvalds 3507fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 35081da177e4SLinus Torvalds list_del(&cb->list); 3509fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 35101da177e4SLinus Torvalds 35111da177e4SLinus Torvalds return 0; 35121da177e4SLinus Torvalds } 35131da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 35141da177e4SLinus Torvalds 351551086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 35161da177e4SLinus Torvalds { 3517cdc52faaSMarcel Holtmann int err; 3518cdc52faaSMarcel Holtmann 3519d79f34e3SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb), 3520d79f34e3SMarcel Holtmann skb->len); 35211da177e4SLinus Torvalds 35221da177e4SLinus Torvalds /* Time stamp */ 3523a61bbcf2SPatrick McHardy __net_timestamp(skb); 35241da177e4SLinus Torvalds 3525cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3526cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3527cd82e61cSMarcel Holtmann 3528cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3529cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3530470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 35311da177e4SLinus Torvalds } 35321da177e4SLinus Torvalds 35331da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 35341da177e4SLinus Torvalds skb_orphan(skb); 35351da177e4SLinus Torvalds 353673d0d3c8SMarcel Holtmann if (!test_bit(HCI_RUNNING, &hdev->flags)) { 353773d0d3c8SMarcel Holtmann kfree_skb(skb); 353873d0d3c8SMarcel Holtmann return; 353973d0d3c8SMarcel Holtmann } 354073d0d3c8SMarcel Holtmann 3541cdc52faaSMarcel Holtmann err = hdev->send(hdev, skb); 3542cdc52faaSMarcel Holtmann if (err < 0) { 35432064ee33SMarcel Holtmann bt_dev_err(hdev, "sending frame failed (%d)", err); 3544cdc52faaSMarcel Holtmann kfree_skb(skb); 3545cdc52faaSMarcel Holtmann } 35461da177e4SLinus Torvalds } 35471da177e4SLinus Torvalds 35481ca3a9d0SJohan Hedberg /* Send HCI command */ 354907dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 355007dc93ddSJohan Hedberg const void *param) 35511ca3a9d0SJohan Hedberg { 35521ca3a9d0SJohan Hedberg struct sk_buff *skb; 35531ca3a9d0SJohan Hedberg 35541ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 35551ca3a9d0SJohan Hedberg 35561ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 35571ca3a9d0SJohan Hedberg if (!skb) { 35582064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for command"); 35591ca3a9d0SJohan Hedberg return -ENOMEM; 35601ca3a9d0SJohan Hedberg } 35611ca3a9d0SJohan Hedberg 356249c922bbSStephen Hemminger /* Stand-alone HCI commands must be flagged as 356311714b3dSJohan Hedberg * single-command requests. 356411714b3dSJohan Hedberg */ 356544d27137SJohan Hedberg bt_cb(skb)->hci.req_flags |= HCI_REQ_START; 356611714b3dSJohan Hedberg 35671da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3568c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 35691da177e4SLinus Torvalds 35701da177e4SLinus Torvalds return 0; 35711da177e4SLinus Torvalds } 35721da177e4SLinus Torvalds 3573d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen, 3574d6ee6ad7SLoic Poulain const void *param) 3575d6ee6ad7SLoic Poulain { 3576d6ee6ad7SLoic Poulain struct sk_buff *skb; 3577d6ee6ad7SLoic Poulain 3578d6ee6ad7SLoic Poulain if (hci_opcode_ogf(opcode) != 0x3f) { 3579d6ee6ad7SLoic Poulain /* A controller receiving a command shall respond with either 3580d6ee6ad7SLoic Poulain * a Command Status Event or a Command Complete Event. 3581d6ee6ad7SLoic Poulain * Therefore, all standard HCI commands must be sent via the 3582d6ee6ad7SLoic Poulain * standard API, using hci_send_cmd or hci_cmd_sync helpers. 3583d6ee6ad7SLoic Poulain * Some vendors do not comply with this rule for vendor-specific 3584d6ee6ad7SLoic Poulain * commands and do not return any event. We want to support 3585d6ee6ad7SLoic Poulain * unresponded commands for such cases only. 3586d6ee6ad7SLoic Poulain */ 3587d6ee6ad7SLoic Poulain bt_dev_err(hdev, "unresponded command not supported"); 3588d6ee6ad7SLoic Poulain return -EINVAL; 3589d6ee6ad7SLoic Poulain } 3590d6ee6ad7SLoic Poulain 3591d6ee6ad7SLoic Poulain skb = hci_prepare_cmd(hdev, opcode, plen, param); 3592d6ee6ad7SLoic Poulain if (!skb) { 3593d6ee6ad7SLoic Poulain bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)", 3594d6ee6ad7SLoic Poulain opcode); 3595d6ee6ad7SLoic Poulain return -ENOMEM; 3596d6ee6ad7SLoic Poulain } 3597d6ee6ad7SLoic Poulain 3598d6ee6ad7SLoic Poulain hci_send_frame(hdev, skb); 3599d6ee6ad7SLoic Poulain 3600d6ee6ad7SLoic Poulain return 0; 3601d6ee6ad7SLoic Poulain } 3602d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send); 3603d6ee6ad7SLoic Poulain 36041da177e4SLinus Torvalds /* Get data from the previously sent command */ 3605a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 36061da177e4SLinus Torvalds { 36071da177e4SLinus Torvalds struct hci_command_hdr *hdr; 36081da177e4SLinus Torvalds 36091da177e4SLinus Torvalds if (!hdev->sent_cmd) 36101da177e4SLinus Torvalds return NULL; 36111da177e4SLinus Torvalds 36121da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 36131da177e4SLinus Torvalds 3614a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 36151da177e4SLinus Torvalds return NULL; 36161da177e4SLinus Torvalds 3617f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 36181da177e4SLinus Torvalds 36191da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 36201da177e4SLinus Torvalds } 36211da177e4SLinus Torvalds 3622fbef168fSLoic Poulain /* Send HCI command and wait for command commplete event */ 3623fbef168fSLoic Poulain struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 3624fbef168fSLoic Poulain const void *param, u32 timeout) 3625fbef168fSLoic Poulain { 3626fbef168fSLoic Poulain struct sk_buff *skb; 3627fbef168fSLoic Poulain 3628fbef168fSLoic Poulain if (!test_bit(HCI_UP, &hdev->flags)) 3629fbef168fSLoic Poulain return ERR_PTR(-ENETDOWN); 3630fbef168fSLoic Poulain 3631fbef168fSLoic Poulain bt_dev_dbg(hdev, "opcode 0x%4.4x plen %d", opcode, plen); 3632fbef168fSLoic Poulain 3633b504430cSJohan Hedberg hci_req_sync_lock(hdev); 3634fbef168fSLoic Poulain skb = __hci_cmd_sync(hdev, opcode, plen, param, timeout); 3635b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 3636fbef168fSLoic Poulain 3637fbef168fSLoic Poulain return skb; 3638fbef168fSLoic Poulain } 3639fbef168fSLoic Poulain EXPORT_SYMBOL(hci_cmd_sync); 3640fbef168fSLoic Poulain 36411da177e4SLinus Torvalds /* Send ACL data */ 36421da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 36431da177e4SLinus Torvalds { 36441da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 36451da177e4SLinus Torvalds int len = skb->len; 36461da177e4SLinus Torvalds 3647badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3648badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 36499c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3650aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3651aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 36521da177e4SLinus Torvalds } 36531da177e4SLinus Torvalds 3654ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 365573d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 36561da177e4SLinus Torvalds { 3657ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 36581da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 36591da177e4SLinus Torvalds struct sk_buff *list; 36601da177e4SLinus Torvalds 3661087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3662087bfd99SGustavo Padovan skb->data_len = 0; 3663087bfd99SGustavo Padovan 3664d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 3665204a6e54SAndrei Emeltchenko 3666204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3667ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 3668087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3669204a6e54SAndrei Emeltchenko break; 3670204a6e54SAndrei Emeltchenko case HCI_AMP: 3671204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3672204a6e54SAndrei Emeltchenko break; 3673204a6e54SAndrei Emeltchenko default: 36742064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type); 3675204a6e54SAndrei Emeltchenko return; 3676204a6e54SAndrei Emeltchenko } 3677087bfd99SGustavo Padovan 367870f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 367970f23020SAndrei Emeltchenko if (!list) { 36801da177e4SLinus Torvalds /* Non fragmented */ 36811da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 36821da177e4SLinus Torvalds 368373d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 36841da177e4SLinus Torvalds } else { 36851da177e4SLinus Torvalds /* Fragmented */ 36861da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 36871da177e4SLinus Torvalds 36881da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 36891da177e4SLinus Torvalds 36909cfd5a23SJukka Rissanen /* Queue all fragments atomically. We need to use spin_lock_bh 36919cfd5a23SJukka Rissanen * here because of 6LoWPAN links, as there this function is 36929cfd5a23SJukka Rissanen * called from softirq and using normal spin lock could cause 36939cfd5a23SJukka Rissanen * deadlocks. 36949cfd5a23SJukka Rissanen */ 36959cfd5a23SJukka Rissanen spin_lock_bh(&queue->lock); 36961da177e4SLinus Torvalds 369773d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3698e702112fSAndrei Emeltchenko 3699e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3700e702112fSAndrei Emeltchenko flags |= ACL_CONT; 37011da177e4SLinus Torvalds do { 37021da177e4SLinus Torvalds skb = list; list = list->next; 37031da177e4SLinus Torvalds 3704d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 3705e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 37061da177e4SLinus Torvalds 37071da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 37081da177e4SLinus Torvalds 370973d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 37101da177e4SLinus Torvalds } while (list); 37111da177e4SLinus Torvalds 37129cfd5a23SJukka Rissanen spin_unlock_bh(&queue->lock); 37131da177e4SLinus Torvalds } 371473d80debSLuiz Augusto von Dentz } 371573d80debSLuiz Augusto von Dentz 371673d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 371773d80debSLuiz Augusto von Dentz { 3718ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 371973d80debSLuiz Augusto von Dentz 3720f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 372173d80debSLuiz Augusto von Dentz 3722ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 37231da177e4SLinus Torvalds 37243eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 37251da177e4SLinus Torvalds } 37261da177e4SLinus Torvalds 37271da177e4SLinus Torvalds /* Send SCO data */ 37280d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 37291da177e4SLinus Torvalds { 37301da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 37311da177e4SLinus Torvalds struct hci_sco_hdr hdr; 37321da177e4SLinus Torvalds 37331da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 37341da177e4SLinus Torvalds 3735aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 37361da177e4SLinus Torvalds hdr.dlen = skb->len; 37371da177e4SLinus Torvalds 3738badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 3739badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 37409c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 37411da177e4SLinus Torvalds 3742d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_SCODATA_PKT; 3743c78ae283SMarcel Holtmann 37441da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 37453eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 37461da177e4SLinus Torvalds } 37471da177e4SLinus Torvalds 37481da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 37491da177e4SLinus Torvalds 37501da177e4SLinus Torvalds /* HCI Connection scheduler */ 37516039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 3752a8c5fb1aSGustavo Padovan int *quote) 37531da177e4SLinus Torvalds { 37541da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 37558035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 3756abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 37571da177e4SLinus Torvalds 37581da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 37591da177e4SLinus Torvalds * added and removed with TX task disabled. */ 3760bf4c6325SGustavo F. Padovan 3761bf4c6325SGustavo F. Padovan rcu_read_lock(); 3762bf4c6325SGustavo F. Padovan 3763bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3764769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 37651da177e4SLinus Torvalds continue; 3766769be974SMarcel Holtmann 3767769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 3768769be974SMarcel Holtmann continue; 3769769be974SMarcel Holtmann 37701da177e4SLinus Torvalds num++; 37711da177e4SLinus Torvalds 37721da177e4SLinus Torvalds if (c->sent < min) { 37731da177e4SLinus Torvalds min = c->sent; 37741da177e4SLinus Torvalds conn = c; 37751da177e4SLinus Torvalds } 377652087a79SLuiz Augusto von Dentz 377752087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 377852087a79SLuiz Augusto von Dentz break; 37791da177e4SLinus Torvalds } 37801da177e4SLinus Torvalds 3781bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3782bf4c6325SGustavo F. Padovan 37831da177e4SLinus Torvalds if (conn) { 37846ed58ec5SVille Tervo int cnt, q; 37856ed58ec5SVille Tervo 37866ed58ec5SVille Tervo switch (conn->type) { 37876ed58ec5SVille Tervo case ACL_LINK: 37886ed58ec5SVille Tervo cnt = hdev->acl_cnt; 37896ed58ec5SVille Tervo break; 37906ed58ec5SVille Tervo case SCO_LINK: 37916ed58ec5SVille Tervo case ESCO_LINK: 37926ed58ec5SVille Tervo cnt = hdev->sco_cnt; 37936ed58ec5SVille Tervo break; 37946ed58ec5SVille Tervo case LE_LINK: 37956ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 37966ed58ec5SVille Tervo break; 37976ed58ec5SVille Tervo default: 37986ed58ec5SVille Tervo cnt = 0; 37992064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown link type %d", conn->type); 38006ed58ec5SVille Tervo } 38016ed58ec5SVille Tervo 38026ed58ec5SVille Tervo q = cnt / num; 38031da177e4SLinus Torvalds *quote = q ? q : 1; 38041da177e4SLinus Torvalds } else 38051da177e4SLinus Torvalds *quote = 0; 38061da177e4SLinus Torvalds 38071da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 38081da177e4SLinus Torvalds return conn; 38091da177e4SLinus Torvalds } 38101da177e4SLinus Torvalds 38116039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 38121da177e4SLinus Torvalds { 38131da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 38141da177e4SLinus Torvalds struct hci_conn *c; 38151da177e4SLinus Torvalds 38162064ee33SMarcel Holtmann bt_dev_err(hdev, "link tx timeout"); 38171da177e4SLinus Torvalds 3818bf4c6325SGustavo F. Padovan rcu_read_lock(); 3819bf4c6325SGustavo F. Padovan 38201da177e4SLinus Torvalds /* Kill stalled connections */ 3821bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3822bae1f5d9SVille Tervo if (c->type == type && c->sent) { 38232064ee33SMarcel Holtmann bt_dev_err(hdev, "killing stalled connection %pMR", 38242064ee33SMarcel Holtmann &c->dst); 3825bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 38261da177e4SLinus Torvalds } 38271da177e4SLinus Torvalds } 3828bf4c6325SGustavo F. Padovan 3829bf4c6325SGustavo F. Padovan rcu_read_unlock(); 38301da177e4SLinus Torvalds } 38311da177e4SLinus Torvalds 38326039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 383373d80debSLuiz Augusto von Dentz int *quote) 383473d80debSLuiz Augusto von Dentz { 383573d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 383673d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 3837abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 383873d80debSLuiz Augusto von Dentz struct hci_conn *conn; 383973d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 384073d80debSLuiz Augusto von Dentz 384173d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 384273d80debSLuiz Augusto von Dentz 3843bf4c6325SGustavo F. Padovan rcu_read_lock(); 3844bf4c6325SGustavo F. Padovan 3845bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 384673d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 384773d80debSLuiz Augusto von Dentz 384873d80debSLuiz Augusto von Dentz if (conn->type != type) 384973d80debSLuiz Augusto von Dentz continue; 385073d80debSLuiz Augusto von Dentz 385173d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 385273d80debSLuiz Augusto von Dentz continue; 385373d80debSLuiz Augusto von Dentz 385473d80debSLuiz Augusto von Dentz conn_num++; 385573d80debSLuiz Augusto von Dentz 38568192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 385773d80debSLuiz Augusto von Dentz struct sk_buff *skb; 385873d80debSLuiz Augusto von Dentz 385973d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 386073d80debSLuiz Augusto von Dentz continue; 386173d80debSLuiz Augusto von Dentz 386273d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 386373d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 386473d80debSLuiz Augusto von Dentz continue; 386573d80debSLuiz Augusto von Dentz 386673d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 386773d80debSLuiz Augusto von Dentz num = 0; 386873d80debSLuiz Augusto von Dentz min = ~0; 386973d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 387073d80debSLuiz Augusto von Dentz } 387173d80debSLuiz Augusto von Dentz 387273d80debSLuiz Augusto von Dentz num++; 387373d80debSLuiz Augusto von Dentz 387473d80debSLuiz Augusto von Dentz if (conn->sent < min) { 387573d80debSLuiz Augusto von Dentz min = conn->sent; 387673d80debSLuiz Augusto von Dentz chan = tmp; 387773d80debSLuiz Augusto von Dentz } 387873d80debSLuiz Augusto von Dentz } 387973d80debSLuiz Augusto von Dentz 388073d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 388173d80debSLuiz Augusto von Dentz break; 388273d80debSLuiz Augusto von Dentz } 388373d80debSLuiz Augusto von Dentz 3884bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3885bf4c6325SGustavo F. Padovan 388673d80debSLuiz Augusto von Dentz if (!chan) 388773d80debSLuiz Augusto von Dentz return NULL; 388873d80debSLuiz Augusto von Dentz 388973d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 389073d80debSLuiz Augusto von Dentz case ACL_LINK: 389173d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 389273d80debSLuiz Augusto von Dentz break; 3893bd1eb66bSAndrei Emeltchenko case AMP_LINK: 3894bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 3895bd1eb66bSAndrei Emeltchenko break; 389673d80debSLuiz Augusto von Dentz case SCO_LINK: 389773d80debSLuiz Augusto von Dentz case ESCO_LINK: 389873d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 389973d80debSLuiz Augusto von Dentz break; 390073d80debSLuiz Augusto von Dentz case LE_LINK: 390173d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 390273d80debSLuiz Augusto von Dentz break; 390373d80debSLuiz Augusto von Dentz default: 390473d80debSLuiz Augusto von Dentz cnt = 0; 39052064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown link type %d", chan->conn->type); 390673d80debSLuiz Augusto von Dentz } 390773d80debSLuiz Augusto von Dentz 390873d80debSLuiz Augusto von Dentz q = cnt / num; 390973d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 391073d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 391173d80debSLuiz Augusto von Dentz return chan; 391273d80debSLuiz Augusto von Dentz } 391373d80debSLuiz Augusto von Dentz 391402b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 391502b20f0bSLuiz Augusto von Dentz { 391602b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 391702b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 391802b20f0bSLuiz Augusto von Dentz int num = 0; 391902b20f0bSLuiz Augusto von Dentz 392002b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 392102b20f0bSLuiz Augusto von Dentz 3922bf4c6325SGustavo F. Padovan rcu_read_lock(); 3923bf4c6325SGustavo F. Padovan 3924bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 392502b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 392602b20f0bSLuiz Augusto von Dentz 392702b20f0bSLuiz Augusto von Dentz if (conn->type != type) 392802b20f0bSLuiz Augusto von Dentz continue; 392902b20f0bSLuiz Augusto von Dentz 393002b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 393102b20f0bSLuiz Augusto von Dentz continue; 393202b20f0bSLuiz Augusto von Dentz 393302b20f0bSLuiz Augusto von Dentz num++; 393402b20f0bSLuiz Augusto von Dentz 39358192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 393602b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 393702b20f0bSLuiz Augusto von Dentz 393802b20f0bSLuiz Augusto von Dentz if (chan->sent) { 393902b20f0bSLuiz Augusto von Dentz chan->sent = 0; 394002b20f0bSLuiz Augusto von Dentz continue; 394102b20f0bSLuiz Augusto von Dentz } 394202b20f0bSLuiz Augusto von Dentz 394302b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 394402b20f0bSLuiz Augusto von Dentz continue; 394502b20f0bSLuiz Augusto von Dentz 394602b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 394702b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 394802b20f0bSLuiz Augusto von Dentz continue; 394902b20f0bSLuiz Augusto von Dentz 395002b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 395102b20f0bSLuiz Augusto von Dentz 395202b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 395302b20f0bSLuiz Augusto von Dentz skb->priority); 395402b20f0bSLuiz Augusto von Dentz } 395502b20f0bSLuiz Augusto von Dentz 395602b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 395702b20f0bSLuiz Augusto von Dentz break; 395802b20f0bSLuiz Augusto von Dentz } 3959bf4c6325SGustavo F. Padovan 3960bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3961bf4c6325SGustavo F. Padovan 396202b20f0bSLuiz Augusto von Dentz } 396302b20f0bSLuiz Augusto von Dentz 3964b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 3965b71d385aSAndrei Emeltchenko { 3966b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 3967b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 3968b71d385aSAndrei Emeltchenko } 3969b71d385aSAndrei Emeltchenko 39706039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 39711da177e4SLinus Torvalds { 3972d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 39731da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 39741da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 397563d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 39765f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 3977bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 39781da177e4SLinus Torvalds } 397963d2bc1bSAndrei Emeltchenko } 39801da177e4SLinus Torvalds 39816039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 398263d2bc1bSAndrei Emeltchenko { 398363d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 398463d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 398563d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 398663d2bc1bSAndrei Emeltchenko int quote; 398763d2bc1bSAndrei Emeltchenko 398863d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 398904837f64SMarcel Holtmann 399073d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 399173d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 3992ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3993ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 399473d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 399573d80debSLuiz Augusto von Dentz skb->len, skb->priority); 399673d80debSLuiz Augusto von Dentz 3997ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3998ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3999ec1cce24SLuiz Augusto von Dentz break; 4000ec1cce24SLuiz Augusto von Dentz 4001ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4002ec1cce24SLuiz Augusto von Dentz 400373d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 400473d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 400504837f64SMarcel Holtmann 400657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 40071da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 40081da177e4SLinus Torvalds 40091da177e4SLinus Torvalds hdev->acl_cnt--; 401073d80debSLuiz Augusto von Dentz chan->sent++; 401173d80debSLuiz Augusto von Dentz chan->conn->sent++; 40121da177e4SLinus Torvalds } 40131da177e4SLinus Torvalds } 401402b20f0bSLuiz Augusto von Dentz 401502b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 401602b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 40171da177e4SLinus Torvalds } 40181da177e4SLinus Torvalds 40196039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4020b71d385aSAndrei Emeltchenko { 402163d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4022b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4023b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4024b71d385aSAndrei Emeltchenko int quote; 4025bd1eb66bSAndrei Emeltchenko u8 type; 4026b71d385aSAndrei Emeltchenko 402763d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4028b71d385aSAndrei Emeltchenko 4029bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4030bd1eb66bSAndrei Emeltchenko 4031bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4032bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4033bd1eb66bSAndrei Emeltchenko else 4034bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4035bd1eb66bSAndrei Emeltchenko 4036b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4037bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4038b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4039b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4040b71d385aSAndrei Emeltchenko int blocks; 4041b71d385aSAndrei Emeltchenko 4042b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4043b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4044b71d385aSAndrei Emeltchenko 4045b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4046b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4047b71d385aSAndrei Emeltchenko break; 4048b71d385aSAndrei Emeltchenko 4049b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4050b71d385aSAndrei Emeltchenko 4051b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4052b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4053b71d385aSAndrei Emeltchenko return; 4054b71d385aSAndrei Emeltchenko 4055b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4056b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4057b71d385aSAndrei Emeltchenko 405857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4059b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4060b71d385aSAndrei Emeltchenko 4061b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4062b71d385aSAndrei Emeltchenko quote -= blocks; 4063b71d385aSAndrei Emeltchenko 4064b71d385aSAndrei Emeltchenko chan->sent += blocks; 4065b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4066b71d385aSAndrei Emeltchenko } 4067b71d385aSAndrei Emeltchenko } 4068b71d385aSAndrei Emeltchenko 4069b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4070bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4071b71d385aSAndrei Emeltchenko } 4072b71d385aSAndrei Emeltchenko 40736039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4074b71d385aSAndrei Emeltchenko { 4075b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4076b71d385aSAndrei Emeltchenko 4077bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4078ca8bee5dSMarcel Holtmann if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY) 4079bd1eb66bSAndrei Emeltchenko return; 4080bd1eb66bSAndrei Emeltchenko 4081bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4082bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4083b71d385aSAndrei Emeltchenko return; 4084b71d385aSAndrei Emeltchenko 4085b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4086b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4087b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4088b71d385aSAndrei Emeltchenko break; 4089b71d385aSAndrei Emeltchenko 4090b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4091b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4092b71d385aSAndrei Emeltchenko break; 4093b71d385aSAndrei Emeltchenko } 4094b71d385aSAndrei Emeltchenko } 4095b71d385aSAndrei Emeltchenko 40961da177e4SLinus Torvalds /* Schedule SCO */ 40976039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 40981da177e4SLinus Torvalds { 40991da177e4SLinus Torvalds struct hci_conn *conn; 41001da177e4SLinus Torvalds struct sk_buff *skb; 41011da177e4SLinus Torvalds int quote; 41021da177e4SLinus Torvalds 41031da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 41041da177e4SLinus Torvalds 410552087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 410652087a79SLuiz Augusto von Dentz return; 410752087a79SLuiz Augusto von Dentz 41081da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 41091da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 41101da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 411157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 41121da177e4SLinus Torvalds 41131da177e4SLinus Torvalds conn->sent++; 41141da177e4SLinus Torvalds if (conn->sent == ~0) 41151da177e4SLinus Torvalds conn->sent = 0; 41161da177e4SLinus Torvalds } 41171da177e4SLinus Torvalds } 41181da177e4SLinus Torvalds } 41191da177e4SLinus Torvalds 41206039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 4121b6a0dc82SMarcel Holtmann { 4122b6a0dc82SMarcel Holtmann struct hci_conn *conn; 4123b6a0dc82SMarcel Holtmann struct sk_buff *skb; 4124b6a0dc82SMarcel Holtmann int quote; 4125b6a0dc82SMarcel Holtmann 4126b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 4127b6a0dc82SMarcel Holtmann 412852087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 412952087a79SLuiz Augusto von Dentz return; 413052087a79SLuiz Augusto von Dentz 41318fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 41328fc9ced3SGustavo Padovan "e))) { 4133b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 4134b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 413557d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4136b6a0dc82SMarcel Holtmann 4137b6a0dc82SMarcel Holtmann conn->sent++; 4138b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 4139b6a0dc82SMarcel Holtmann conn->sent = 0; 4140b6a0dc82SMarcel Holtmann } 4141b6a0dc82SMarcel Holtmann } 4142b6a0dc82SMarcel Holtmann } 4143b6a0dc82SMarcel Holtmann 41446039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 41456ed58ec5SVille Tervo { 414673d80debSLuiz Augusto von Dentz struct hci_chan *chan; 41476ed58ec5SVille Tervo struct sk_buff *skb; 414802b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 41496ed58ec5SVille Tervo 41506ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 41516ed58ec5SVille Tervo 415252087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 415352087a79SLuiz Augusto von Dentz return; 415452087a79SLuiz Augusto von Dentz 4155d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 41566ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 41576ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 4158bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 41596ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 4160bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 41616ed58ec5SVille Tervo } 41626ed58ec5SVille Tervo 41636ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 416402b20f0bSLuiz Augusto von Dentz tmp = cnt; 416573d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 4166ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4167ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 416873d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 416973d80debSLuiz Augusto von Dentz skb->len, skb->priority); 41706ed58ec5SVille Tervo 4171ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4172ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4173ec1cce24SLuiz Augusto von Dentz break; 4174ec1cce24SLuiz Augusto von Dentz 4175ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4176ec1cce24SLuiz Augusto von Dentz 417757d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 41786ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 41796ed58ec5SVille Tervo 41806ed58ec5SVille Tervo cnt--; 418173d80debSLuiz Augusto von Dentz chan->sent++; 418273d80debSLuiz Augusto von Dentz chan->conn->sent++; 41836ed58ec5SVille Tervo } 41846ed58ec5SVille Tervo } 418573d80debSLuiz Augusto von Dentz 41866ed58ec5SVille Tervo if (hdev->le_pkts) 41876ed58ec5SVille Tervo hdev->le_cnt = cnt; 41886ed58ec5SVille Tervo else 41896ed58ec5SVille Tervo hdev->acl_cnt = cnt; 419002b20f0bSLuiz Augusto von Dentz 419102b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 419202b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 41936ed58ec5SVille Tervo } 41946ed58ec5SVille Tervo 41953eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 41961da177e4SLinus Torvalds { 41973eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 41981da177e4SLinus Torvalds struct sk_buff *skb; 41991da177e4SLinus Torvalds 42006ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 42016ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 42021da177e4SLinus Torvalds 4203d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 42041da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 42051da177e4SLinus Torvalds hci_sched_acl(hdev); 42061da177e4SLinus Torvalds hci_sched_sco(hdev); 4207b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 42086ed58ec5SVille Tervo hci_sched_le(hdev); 420952de599eSMarcel Holtmann } 42106ed58ec5SVille Tervo 42111da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 42121da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 421357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 42141da177e4SLinus Torvalds } 42151da177e4SLinus Torvalds 421625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 42171da177e4SLinus Torvalds 42181da177e4SLinus Torvalds /* ACL data packet */ 42196039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 42201da177e4SLinus Torvalds { 42211da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 42221da177e4SLinus Torvalds struct hci_conn *conn; 42231da177e4SLinus Torvalds __u16 handle, flags; 42241da177e4SLinus Torvalds 42251da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 42261da177e4SLinus Torvalds 42271da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 42281da177e4SLinus Torvalds flags = hci_flags(handle); 42291da177e4SLinus Torvalds handle = hci_handle(handle); 42301da177e4SLinus Torvalds 4231f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4232a8c5fb1aSGustavo Padovan handle, flags); 42331da177e4SLinus Torvalds 42341da177e4SLinus Torvalds hdev->stat.acl_rx++; 42351da177e4SLinus Torvalds 42361da177e4SLinus Torvalds hci_dev_lock(hdev); 42371da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 42381da177e4SLinus Torvalds hci_dev_unlock(hdev); 42391da177e4SLinus Torvalds 42401da177e4SLinus Torvalds if (conn) { 424165983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 424204837f64SMarcel Holtmann 42431da177e4SLinus Torvalds /* Send to upper protocol */ 4244686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 42451da177e4SLinus Torvalds return; 42461da177e4SLinus Torvalds } else { 42472064ee33SMarcel Holtmann bt_dev_err(hdev, "ACL packet for unknown connection handle %d", 42482064ee33SMarcel Holtmann handle); 42491da177e4SLinus Torvalds } 42501da177e4SLinus Torvalds 42511da177e4SLinus Torvalds kfree_skb(skb); 42521da177e4SLinus Torvalds } 42531da177e4SLinus Torvalds 42541da177e4SLinus Torvalds /* SCO data packet */ 42556039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 42561da177e4SLinus Torvalds { 42571da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 42581da177e4SLinus Torvalds struct hci_conn *conn; 42591da177e4SLinus Torvalds __u16 handle; 42601da177e4SLinus Torvalds 42611da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 42621da177e4SLinus Torvalds 42631da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 42641da177e4SLinus Torvalds 4265f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 42661da177e4SLinus Torvalds 42671da177e4SLinus Torvalds hdev->stat.sco_rx++; 42681da177e4SLinus Torvalds 42691da177e4SLinus Torvalds hci_dev_lock(hdev); 42701da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 42711da177e4SLinus Torvalds hci_dev_unlock(hdev); 42721da177e4SLinus Torvalds 42731da177e4SLinus Torvalds if (conn) { 42741da177e4SLinus Torvalds /* Send to upper protocol */ 4275686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 42761da177e4SLinus Torvalds return; 42771da177e4SLinus Torvalds } else { 42782064ee33SMarcel Holtmann bt_dev_err(hdev, "SCO packet for unknown connection handle %d", 42792064ee33SMarcel Holtmann handle); 42801da177e4SLinus Torvalds } 42811da177e4SLinus Torvalds 42821da177e4SLinus Torvalds kfree_skb(skb); 42831da177e4SLinus Torvalds } 42841da177e4SLinus Torvalds 42859238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 42869238f36aSJohan Hedberg { 42879238f36aSJohan Hedberg struct sk_buff *skb; 42889238f36aSJohan Hedberg 42899238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 42909238f36aSJohan Hedberg if (!skb) 42919238f36aSJohan Hedberg return true; 42929238f36aSJohan Hedberg 429344d27137SJohan Hedberg return (bt_cb(skb)->hci.req_flags & HCI_REQ_START); 42949238f36aSJohan Hedberg } 42959238f36aSJohan Hedberg 429642c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 429742c6b129SJohan Hedberg { 429842c6b129SJohan Hedberg struct hci_command_hdr *sent; 429942c6b129SJohan Hedberg struct sk_buff *skb; 430042c6b129SJohan Hedberg u16 opcode; 430142c6b129SJohan Hedberg 430242c6b129SJohan Hedberg if (!hdev->sent_cmd) 430342c6b129SJohan Hedberg return; 430442c6b129SJohan Hedberg 430542c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 430642c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 430742c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 430842c6b129SJohan Hedberg return; 430942c6b129SJohan Hedberg 431042c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 431142c6b129SJohan Hedberg if (!skb) 431242c6b129SJohan Hedberg return; 431342c6b129SJohan Hedberg 431442c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 431542c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 431642c6b129SJohan Hedberg } 431742c6b129SJohan Hedberg 4318e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, 4319e6214487SJohan Hedberg hci_req_complete_t *req_complete, 4320e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 43219238f36aSJohan Hedberg { 43229238f36aSJohan Hedberg struct sk_buff *skb; 43239238f36aSJohan Hedberg unsigned long flags; 43249238f36aSJohan Hedberg 43259238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 43269238f36aSJohan Hedberg 432742c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 432842c6b129SJohan Hedberg * sent we need to do special handling of it. 43299238f36aSJohan Hedberg */ 433042c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 433142c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 433242c6b129SJohan Hedberg * reset complete event during init and any pending 433342c6b129SJohan Hedberg * command will never be completed. In such a case we 433442c6b129SJohan Hedberg * need to resend whatever was the last sent 433542c6b129SJohan Hedberg * command. 433642c6b129SJohan Hedberg */ 433742c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 433842c6b129SJohan Hedberg hci_resend_last(hdev); 433942c6b129SJohan Hedberg 43409238f36aSJohan Hedberg return; 434142c6b129SJohan Hedberg } 43429238f36aSJohan Hedberg 43439238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 43449238f36aSJohan Hedberg * this request the request is not yet complete. 43459238f36aSJohan Hedberg */ 43469238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 43479238f36aSJohan Hedberg return; 43489238f36aSJohan Hedberg 43499238f36aSJohan Hedberg /* If this was the last command in a request the complete 43509238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 43519238f36aSJohan Hedberg * command queue (hdev->cmd_q). 43529238f36aSJohan Hedberg */ 435344d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) { 435444d27137SJohan Hedberg *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb; 4355e6214487SJohan Hedberg return; 43569238f36aSJohan Hedberg } 4357e6214487SJohan Hedberg 435844d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_complete) { 435944d27137SJohan Hedberg *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete; 4360e6214487SJohan Hedberg return; 436153e21fbcSJohan Hedberg } 43629238f36aSJohan Hedberg 43639238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 43649238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 43659238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 436644d27137SJohan Hedberg if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) { 43679238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 43689238f36aSJohan Hedberg break; 43699238f36aSJohan Hedberg } 43709238f36aSJohan Hedberg 43713bd7594eSDouglas Anderson if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) 4372242c0ebdSMarcel Holtmann *req_complete_skb = bt_cb(skb)->hci.req_complete_skb; 43733bd7594eSDouglas Anderson else 43743bd7594eSDouglas Anderson *req_complete = bt_cb(skb)->hci.req_complete; 43759238f36aSJohan Hedberg kfree_skb(skb); 43769238f36aSJohan Hedberg } 43779238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 43789238f36aSJohan Hedberg } 43799238f36aSJohan Hedberg 4380b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 43811da177e4SLinus Torvalds { 4382b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 43831da177e4SLinus Torvalds struct sk_buff *skb; 43841da177e4SLinus Torvalds 43851da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 43861da177e4SLinus Torvalds 43871da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 4388cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4389cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4390cd82e61cSMarcel Holtmann 43911da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 43921da177e4SLinus Torvalds /* Send copy to the sockets */ 4393470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 43941da177e4SLinus Torvalds } 43951da177e4SLinus Torvalds 4396d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 43971da177e4SLinus Torvalds kfree_skb(skb); 43981da177e4SLinus Torvalds continue; 43991da177e4SLinus Torvalds } 44001da177e4SLinus Torvalds 44011da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 44021da177e4SLinus Torvalds /* Don't process data packets in this states. */ 4403d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 44041da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 44051da177e4SLinus Torvalds case HCI_SCODATA_PKT: 44061da177e4SLinus Torvalds kfree_skb(skb); 44071da177e4SLinus Torvalds continue; 44083ff50b79SStephen Hemminger } 44091da177e4SLinus Torvalds } 44101da177e4SLinus Torvalds 44111da177e4SLinus Torvalds /* Process frame */ 4412d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 44131da177e4SLinus Torvalds case HCI_EVENT_PKT: 4414b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 44151da177e4SLinus Torvalds hci_event_packet(hdev, skb); 44161da177e4SLinus Torvalds break; 44171da177e4SLinus Torvalds 44181da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 44191da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 44201da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 44211da177e4SLinus Torvalds break; 44221da177e4SLinus Torvalds 44231da177e4SLinus Torvalds case HCI_SCODATA_PKT: 44241da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 44251da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 44261da177e4SLinus Torvalds break; 44271da177e4SLinus Torvalds 44281da177e4SLinus Torvalds default: 44291da177e4SLinus Torvalds kfree_skb(skb); 44301da177e4SLinus Torvalds break; 44311da177e4SLinus Torvalds } 44321da177e4SLinus Torvalds } 44331da177e4SLinus Torvalds } 44341da177e4SLinus Torvalds 4435c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 44361da177e4SLinus Torvalds { 4437c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 44381da177e4SLinus Torvalds struct sk_buff *skb; 44391da177e4SLinus Torvalds 44402104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 44412104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 44421da177e4SLinus Torvalds 44431da177e4SLinus Torvalds /* Send queued commands */ 44445a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 44455a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 44465a08ecceSAndrei Emeltchenko if (!skb) 44475a08ecceSAndrei Emeltchenko return; 44485a08ecceSAndrei Emeltchenko 44491da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 44501da177e4SLinus Torvalds 4451a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 445270f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 44531da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 445457d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 44557bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 445665cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 44577bdb8a5cSSzymon Janc else 445865cc2b49SMarcel Holtmann schedule_delayed_work(&hdev->cmd_timer, 445965cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT); 44601da177e4SLinus Torvalds } else { 44611da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4462c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 44631da177e4SLinus Torvalds } 44641da177e4SLinus Torvalds } 44651da177e4SLinus Torvalds } 4466