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> 337a0e5b15SMatthias Kaehlcke #include <linux/property.h> 349952d90eSAbhishek Pandit-Subedi #include <linux/suspend.h> 359952d90eSAbhishek Pandit-Subedi #include <linux/wait.h> 3647219839SMarcel Holtmann #include <asm/unaligned.h> 371da177e4SLinus Torvalds 381da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 391da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 404bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h> 41af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h> 421da177e4SLinus Torvalds 430857dd3bSJohan Hedberg #include "hci_request.h" 4460c5f5fbSMarcel Holtmann #include "hci_debugfs.h" 45970c4e46SJohan Hedberg #include "smp.h" 466d5d2ee6SHeiner Kallweit #include "leds.h" 47145373cbSMiao-chen Chou #include "msft.h" 48970c4e46SJohan Hedberg 49b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 50c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 513eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 521da177e4SLinus Torvalds 531da177e4SLinus Torvalds /* HCI device list */ 541da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 551da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds /* HCI callback list */ 581da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 59fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock); 601da177e4SLinus Torvalds 613df92b31SSasha Levin /* HCI ID Numbering */ 623df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 633df92b31SSasha Levin 64baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */ 65baf27f6eSMarcel Holtmann 664b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf, 674b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 684b4148e9SMarcel Holtmann { 694b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 704b4148e9SMarcel Holtmann char buf[3]; 714b4148e9SMarcel Holtmann 72b7cb93e5SMarcel Holtmann buf[0] = hci_dev_test_flag(hdev, HCI_DUT_MODE) ? 'Y' : 'N'; 734b4148e9SMarcel Holtmann buf[1] = '\n'; 744b4148e9SMarcel Holtmann buf[2] = '\0'; 754b4148e9SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 764b4148e9SMarcel Holtmann } 774b4148e9SMarcel Holtmann 784b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf, 794b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 804b4148e9SMarcel Holtmann { 814b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 824b4148e9SMarcel Holtmann struct sk_buff *skb; 834b4148e9SMarcel Holtmann bool enable; 843bf5e97dSAndy Shevchenko int err; 854b4148e9SMarcel Holtmann 864b4148e9SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 874b4148e9SMarcel Holtmann return -ENETDOWN; 884b4148e9SMarcel Holtmann 893bf5e97dSAndy Shevchenko err = kstrtobool_from_user(user_buf, count, &enable); 903bf5e97dSAndy Shevchenko if (err) 913bf5e97dSAndy Shevchenko return err; 924b4148e9SMarcel Holtmann 93b7cb93e5SMarcel Holtmann if (enable == hci_dev_test_flag(hdev, HCI_DUT_MODE)) 944b4148e9SMarcel Holtmann return -EALREADY; 954b4148e9SMarcel Holtmann 96b504430cSJohan Hedberg hci_req_sync_lock(hdev); 974b4148e9SMarcel Holtmann if (enable) 984b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL, 994b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1004b4148e9SMarcel Holtmann else 1014b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, 1024b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 103b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 1044b4148e9SMarcel Holtmann 1054b4148e9SMarcel Holtmann if (IS_ERR(skb)) 1064b4148e9SMarcel Holtmann return PTR_ERR(skb); 1074b4148e9SMarcel Holtmann 1084b4148e9SMarcel Holtmann kfree_skb(skb); 1094b4148e9SMarcel Holtmann 110b7cb93e5SMarcel Holtmann hci_dev_change_flag(hdev, HCI_DUT_MODE); 1114b4148e9SMarcel Holtmann 1124b4148e9SMarcel Holtmann return count; 1134b4148e9SMarcel Holtmann } 1144b4148e9SMarcel Holtmann 1154b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = { 1164b4148e9SMarcel Holtmann .open = simple_open, 1174b4148e9SMarcel Holtmann .read = dut_mode_read, 1184b4148e9SMarcel Holtmann .write = dut_mode_write, 1194b4148e9SMarcel Holtmann .llseek = default_llseek, 1204b4148e9SMarcel Holtmann }; 1214b4148e9SMarcel Holtmann 1224b4113d6SMarcel Holtmann static ssize_t vendor_diag_read(struct file *file, char __user *user_buf, 1234b4113d6SMarcel Holtmann size_t count, loff_t *ppos) 1244b4113d6SMarcel Holtmann { 1254b4113d6SMarcel Holtmann struct hci_dev *hdev = file->private_data; 1264b4113d6SMarcel Holtmann char buf[3]; 1274b4113d6SMarcel Holtmann 1284b4113d6SMarcel Holtmann buf[0] = hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) ? 'Y' : 'N'; 1294b4113d6SMarcel Holtmann buf[1] = '\n'; 1304b4113d6SMarcel Holtmann buf[2] = '\0'; 1314b4113d6SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 1324b4113d6SMarcel Holtmann } 1334b4113d6SMarcel Holtmann 1344b4113d6SMarcel Holtmann static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf, 1354b4113d6SMarcel Holtmann size_t count, loff_t *ppos) 1364b4113d6SMarcel Holtmann { 1374b4113d6SMarcel Holtmann struct hci_dev *hdev = file->private_data; 1384b4113d6SMarcel Holtmann bool enable; 1394b4113d6SMarcel Holtmann int err; 1404b4113d6SMarcel Holtmann 1413bf5e97dSAndy Shevchenko err = kstrtobool_from_user(user_buf, count, &enable); 1423bf5e97dSAndy Shevchenko if (err) 1433bf5e97dSAndy Shevchenko return err; 1444b4113d6SMarcel Holtmann 1457e995b9eSMarcel Holtmann /* When the diagnostic flags are not persistent and the transport 146b56c7b25SMarcel Holtmann * is not active or in user channel operation, then there is no need 147b56c7b25SMarcel Holtmann * for the vendor callback. Instead just store the desired value and 148b56c7b25SMarcel Holtmann * the setting will be programmed when the controller gets powered on. 1497e995b9eSMarcel Holtmann */ 1507e995b9eSMarcel Holtmann if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) && 151b56c7b25SMarcel Holtmann (!test_bit(HCI_RUNNING, &hdev->flags) || 152b56c7b25SMarcel Holtmann hci_dev_test_flag(hdev, HCI_USER_CHANNEL))) 1537e995b9eSMarcel Holtmann goto done; 1547e995b9eSMarcel Holtmann 155b504430cSJohan Hedberg hci_req_sync_lock(hdev); 1564b4113d6SMarcel Holtmann err = hdev->set_diag(hdev, enable); 157b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 1584b4113d6SMarcel Holtmann 1594b4113d6SMarcel Holtmann if (err < 0) 1604b4113d6SMarcel Holtmann return err; 1614b4113d6SMarcel Holtmann 1627e995b9eSMarcel Holtmann done: 1634b4113d6SMarcel Holtmann if (enable) 1644b4113d6SMarcel Holtmann hci_dev_set_flag(hdev, HCI_VENDOR_DIAG); 1654b4113d6SMarcel Holtmann else 1664b4113d6SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_VENDOR_DIAG); 1674b4113d6SMarcel Holtmann 1684b4113d6SMarcel Holtmann return count; 1694b4113d6SMarcel Holtmann } 1704b4113d6SMarcel Holtmann 1714b4113d6SMarcel Holtmann static const struct file_operations vendor_diag_fops = { 1724b4113d6SMarcel Holtmann .open = simple_open, 1734b4113d6SMarcel Holtmann .read = vendor_diag_read, 1744b4113d6SMarcel Holtmann .write = vendor_diag_write, 1754b4113d6SMarcel Holtmann .llseek = default_llseek, 1764b4113d6SMarcel Holtmann }; 1774b4113d6SMarcel Holtmann 178f640ee98SMarcel Holtmann static void hci_debugfs_create_basic(struct hci_dev *hdev) 179f640ee98SMarcel Holtmann { 180f640ee98SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 181f640ee98SMarcel Holtmann &dut_mode_fops); 182f640ee98SMarcel Holtmann 183f640ee98SMarcel Holtmann if (hdev->set_diag) 184f640ee98SMarcel Holtmann debugfs_create_file("vendor_diag", 0644, hdev->debugfs, hdev, 185f640ee98SMarcel Holtmann &vendor_diag_fops); 186f640ee98SMarcel Holtmann } 187f640ee98SMarcel Holtmann 188a1d01db1SJohan Hedberg static int hci_reset_req(struct hci_request *req, unsigned long opt) 1891da177e4SLinus Torvalds { 19042c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 1911da177e4SLinus Torvalds 1921da177e4SLinus Torvalds /* Reset device */ 19342c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 19442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 195a1d01db1SJohan Hedberg return 0; 1961da177e4SLinus Torvalds } 1971da177e4SLinus Torvalds 19842c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 1991da177e4SLinus Torvalds { 20042c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 2012455a3eaSAndrei Emeltchenko 2021da177e4SLinus Torvalds /* Read Local Supported Features */ 20342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 2041da177e4SLinus Torvalds 2051143e5a6SMarcel Holtmann /* Read Local Version */ 20642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2072177bab5SJohan Hedberg 2082177bab5SJohan Hedberg /* Read BD Address */ 20942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 2101da177e4SLinus Torvalds } 2111da177e4SLinus Torvalds 2120af801b9SJohan Hedberg static void amp_init1(struct hci_request *req) 213e61ef499SAndrei Emeltchenko { 21442c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 2152455a3eaSAndrei Emeltchenko 216e61ef499SAndrei Emeltchenko /* Read Local Version */ 21742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2186bcbc489SAndrei Emeltchenko 219f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 220f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 221f6996cfeSMarcel Holtmann 2226bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 22342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 224e71dfabaSAndrei Emeltchenko 225e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 22642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 2277528ca1cSMarcel Holtmann 228f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 229f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 230f38ba941SMarcel Holtmann 2317528ca1cSMarcel Holtmann /* Read Location Data */ 2327528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 233e61ef499SAndrei Emeltchenko } 234e61ef499SAndrei Emeltchenko 235a1d01db1SJohan Hedberg static int amp_init2(struct hci_request *req) 2360af801b9SJohan Hedberg { 2370af801b9SJohan Hedberg /* Read Local Supported Features. Not all AMP controllers 2380af801b9SJohan Hedberg * support this so it's placed conditionally in the second 2390af801b9SJohan Hedberg * stage init. 2400af801b9SJohan Hedberg */ 2410af801b9SJohan Hedberg if (req->hdev->commands[14] & 0x20) 2420af801b9SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 243a1d01db1SJohan Hedberg 244a1d01db1SJohan Hedberg return 0; 2450af801b9SJohan Hedberg } 2460af801b9SJohan Hedberg 247a1d01db1SJohan Hedberg static int hci_init1_req(struct hci_request *req, unsigned long opt) 248e61ef499SAndrei Emeltchenko { 24942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 250e61ef499SAndrei Emeltchenko 251e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 252e61ef499SAndrei Emeltchenko 25311778716SAndrei Emeltchenko /* Reset */ 25411778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 25542c6b129SJohan Hedberg hci_reset_req(req, 0); 25611778716SAndrei Emeltchenko 257e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 258ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 25942c6b129SJohan Hedberg bredr_init(req); 260e61ef499SAndrei Emeltchenko break; 261e61ef499SAndrei Emeltchenko case HCI_AMP: 2620af801b9SJohan Hedberg amp_init1(req); 263e61ef499SAndrei Emeltchenko break; 264e61ef499SAndrei Emeltchenko default: 2652064ee33SMarcel Holtmann bt_dev_err(hdev, "Unknown device type %d", hdev->dev_type); 266e61ef499SAndrei Emeltchenko break; 267e61ef499SAndrei Emeltchenko } 268a1d01db1SJohan Hedberg 269a1d01db1SJohan Hedberg return 0; 270e61ef499SAndrei Emeltchenko } 271e61ef499SAndrei Emeltchenko 27242c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 2732177bab5SJohan Hedberg { 2742177bab5SJohan Hedberg __le16 param; 2752177bab5SJohan Hedberg __u8 flt_type; 2762177bab5SJohan Hedberg 2772177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 27842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 2792177bab5SJohan Hedberg 2802177bab5SJohan Hedberg /* Read Class of Device */ 28142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 2822177bab5SJohan Hedberg 2832177bab5SJohan Hedberg /* Read Local Name */ 28442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 2852177bab5SJohan Hedberg 2862177bab5SJohan Hedberg /* Read Voice Setting */ 28742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 2882177bab5SJohan Hedberg 289b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 290b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 291b4cb9fb2SMarcel Holtmann 2924b836f39SMarcel Holtmann /* Read Current IAC LAP */ 2934b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 2944b836f39SMarcel Holtmann 2952177bab5SJohan Hedberg /* Clear Event Filters */ 2962177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 29742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 2982177bab5SJohan Hedberg 2992177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 300dcf4adbfSJoe Perches param = cpu_to_le16(0x7d00); 30142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 3022177bab5SJohan Hedberg } 3032177bab5SJohan Hedberg 30442c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 3052177bab5SJohan Hedberg { 306c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 307c73eee91SJohan Hedberg 3082177bab5SJohan Hedberg /* Read LE Buffer Size */ 30942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 3102177bab5SJohan Hedberg 3112177bab5SJohan Hedberg /* Read LE Local Supported Features */ 31242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 3132177bab5SJohan Hedberg 314747d3f03SMarcel Holtmann /* Read LE Supported States */ 315747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 316747d3f03SMarcel Holtmann 317c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 318c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 319a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ENABLED); 3202177bab5SJohan Hedberg } 3212177bab5SJohan Hedberg 32242c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 3232177bab5SJohan Hedberg { 32442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 32542c6b129SJohan Hedberg 3262177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 3272177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 3282177bab5SJohan Hedberg * command otherwise. 3292177bab5SJohan Hedberg */ 3302177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 3312177bab5SJohan Hedberg 3322177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 3332177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 3342177bab5SJohan Hedberg */ 3352177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 3362177bab5SJohan Hedberg return; 3372177bab5SJohan Hedberg 3382177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 3392177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 340c7882cbdSMarcel Holtmann } else { 341c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 342c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 343c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 344c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 345c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 3465c3d3b4cSMarcel Holtmann 3475c3d3b4cSMarcel Holtmann /* If the controller supports the Disconnect command, enable 3485c3d3b4cSMarcel Holtmann * the corresponding event. In addition enable packet flow 3495c3d3b4cSMarcel Holtmann * control related events. 3505c3d3b4cSMarcel Holtmann */ 3515c3d3b4cSMarcel Holtmann if (hdev->commands[0] & 0x20) { 3525c3d3b4cSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 353c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 354c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 3555c3d3b4cSMarcel Holtmann } 3565c3d3b4cSMarcel Holtmann 3575c3d3b4cSMarcel Holtmann /* If the controller supports the Read Remote Version 3585c3d3b4cSMarcel Holtmann * Information command, enable the corresponding event. 3595c3d3b4cSMarcel Holtmann */ 3605c3d3b4cSMarcel Holtmann if (hdev->commands[2] & 0x80) 3615c3d3b4cSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information 3625c3d3b4cSMarcel Holtmann * Complete 3635c3d3b4cSMarcel Holtmann */ 3640da71f1bSMarcel Holtmann 3650da71f1bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) { 3660da71f1bSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 367c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 3682177bab5SJohan Hedberg } 3690da71f1bSMarcel Holtmann } 3702177bab5SJohan Hedberg 3719fe759ceSMarcel Holtmann if (lmp_inq_rssi_capable(hdev) || 3729fe759ceSMarcel Holtmann test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) 3732177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 3742177bab5SJohan Hedberg 37570f56aa2SMarcel Holtmann if (lmp_ext_feat_capable(hdev)) 37670f56aa2SMarcel Holtmann events[4] |= 0x04; /* Read Remote Extended Features Complete */ 37770f56aa2SMarcel Holtmann 37870f56aa2SMarcel Holtmann if (lmp_esco_capable(hdev)) { 37970f56aa2SMarcel Holtmann events[5] |= 0x08; /* Synchronous Connection Complete */ 38070f56aa2SMarcel Holtmann events[5] |= 0x10; /* Synchronous Connection Changed */ 38170f56aa2SMarcel Holtmann } 38270f56aa2SMarcel Holtmann 3832177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 3842177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 3852177bab5SJohan Hedberg 3862177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 3872177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 3882177bab5SJohan Hedberg 3892177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 3902177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 3912177bab5SJohan Hedberg 3922177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 3932177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 3942177bab5SJohan Hedberg 3952177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 3962177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 3972177bab5SJohan Hedberg 3982177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 3992177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 4002177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 4012177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 4022177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 4032177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 4042177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 4052177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 4062177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 4072177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 4082177bab5SJohan Hedberg * Features Notification 4092177bab5SJohan Hedberg */ 4102177bab5SJohan Hedberg } 4112177bab5SJohan Hedberg 4122177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 4132177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 4142177bab5SJohan Hedberg 41542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 4162177bab5SJohan Hedberg } 4172177bab5SJohan Hedberg 418a1d01db1SJohan Hedberg static int hci_init2_req(struct hci_request *req, unsigned long opt) 4192177bab5SJohan Hedberg { 42042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 42142c6b129SJohan Hedberg 4220af801b9SJohan Hedberg if (hdev->dev_type == HCI_AMP) 4230af801b9SJohan Hedberg return amp_init2(req); 4240af801b9SJohan Hedberg 4252177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 42642c6b129SJohan Hedberg bredr_setup(req); 42756f87901SJohan Hedberg else 428a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED); 4292177bab5SJohan Hedberg 4302177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 43142c6b129SJohan Hedberg le_setup(req); 4322177bab5SJohan Hedberg 4330f3adeaeSMarcel Holtmann /* All Bluetooth 1.2 and later controllers should support the 4340f3adeaeSMarcel Holtmann * HCI command for reading the local supported commands. 4350f3adeaeSMarcel Holtmann * 4360f3adeaeSMarcel Holtmann * Unfortunately some controllers indicate Bluetooth 1.2 support, 4370f3adeaeSMarcel Holtmann * but do not have support for this command. If that is the case, 4380f3adeaeSMarcel Holtmann * the driver can quirk the behavior and skip reading the local 4390f3adeaeSMarcel Holtmann * supported commands. 4403f8e2d75SJohan Hedberg */ 4410f3adeaeSMarcel Holtmann if (hdev->hci_ver > BLUETOOTH_VER_1_1 && 4420f3adeaeSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks)) 44342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 4442177bab5SJohan Hedberg 4452177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 44657af75a8SMarcel Holtmann /* When SSP is available, then the host features page 44757af75a8SMarcel Holtmann * should also be available as well. However some 44857af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 44957af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 45057af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 45157af75a8SMarcel Holtmann */ 45257af75a8SMarcel Holtmann hdev->max_page = 0x01; 45357af75a8SMarcel Holtmann 454d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) { 4552177bab5SJohan Hedberg u8 mode = 0x01; 456574ea3c7SMarcel Holtmann 45742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 4582177bab5SJohan Hedberg sizeof(mode), &mode); 4592177bab5SJohan Hedberg } else { 4602177bab5SJohan Hedberg struct hci_cp_write_eir cp; 4612177bab5SJohan Hedberg 4622177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 4632177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 4642177bab5SJohan Hedberg 46542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 4662177bab5SJohan Hedberg } 4672177bab5SJohan Hedberg } 4682177bab5SJohan Hedberg 469043ec9bfSMarcel Holtmann if (lmp_inq_rssi_capable(hdev) || 470043ec9bfSMarcel Holtmann test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) { 47104422da9SMarcel Holtmann u8 mode; 47204422da9SMarcel Holtmann 47304422da9SMarcel Holtmann /* If Extended Inquiry Result events are supported, then 47404422da9SMarcel Holtmann * they are clearly preferred over Inquiry Result with RSSI 47504422da9SMarcel Holtmann * events. 47604422da9SMarcel Holtmann */ 47704422da9SMarcel Holtmann mode = lmp_ext_inq_capable(hdev) ? 0x02 : 0x01; 47804422da9SMarcel Holtmann 47904422da9SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 48004422da9SMarcel Holtmann } 4812177bab5SJohan Hedberg 4822177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 48342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 4842177bab5SJohan Hedberg 4852177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 4862177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 4872177bab5SJohan Hedberg 4882177bab5SJohan Hedberg cp.page = 0x01; 48942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 49042c6b129SJohan Hedberg sizeof(cp), &cp); 4912177bab5SJohan Hedberg } 4922177bab5SJohan Hedberg 493d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LINK_SECURITY)) { 4942177bab5SJohan Hedberg u8 enable = 1; 49542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 4962177bab5SJohan Hedberg &enable); 4972177bab5SJohan Hedberg } 498a1d01db1SJohan Hedberg 499a1d01db1SJohan Hedberg return 0; 5002177bab5SJohan Hedberg } 5012177bab5SJohan Hedberg 50242c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 5032177bab5SJohan Hedberg { 50442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 5052177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 5062177bab5SJohan Hedberg u16 link_policy = 0; 5072177bab5SJohan Hedberg 5082177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 5092177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 5102177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 5112177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 5122177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 5132177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 5142177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 5152177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 5162177bab5SJohan Hedberg 5172177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 51842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 5192177bab5SJohan Hedberg } 5202177bab5SJohan Hedberg 52142c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 5222177bab5SJohan Hedberg { 52342c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 5242177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 5252177bab5SJohan Hedberg 526c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 527c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 528c73eee91SJohan Hedberg return; 529c73eee91SJohan Hedberg 5302177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 5312177bab5SJohan Hedberg 532d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) { 5332177bab5SJohan Hedberg cp.le = 0x01; 53432226e4fSMarcel Holtmann cp.simul = 0x00; 5352177bab5SJohan Hedberg } 5362177bab5SJohan Hedberg 5372177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 53842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 5392177bab5SJohan Hedberg &cp); 5402177bab5SJohan Hedberg } 5412177bab5SJohan Hedberg 542d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 543d62e6d67SJohan Hedberg { 544d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 545d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 546313f6888SMarcel Holtmann bool changed = false; 547d62e6d67SJohan Hedberg 548d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 549d62e6d67SJohan Hedberg * enable all necessary events for it. 550d62e6d67SJohan Hedberg */ 55153b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 552d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 553d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 554d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 555d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 556313f6888SMarcel Holtmann changed = true; 557d62e6d67SJohan Hedberg } 558d62e6d67SJohan Hedberg 559d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 560d62e6d67SJohan Hedberg * enable all necessary events for it. 561d62e6d67SJohan Hedberg */ 56253b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 563d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 564d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 565d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 566d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 567313f6888SMarcel Holtmann changed = true; 568d62e6d67SJohan Hedberg } 569d62e6d67SJohan Hedberg 57040c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 571313f6888SMarcel Holtmann if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) { 57240c59fcbSMarcel Holtmann events[2] |= 0x80; 573313f6888SMarcel Holtmann changed = true; 574313f6888SMarcel Holtmann } 57540c59fcbSMarcel Holtmann 576313f6888SMarcel Holtmann /* Some Broadcom based controllers indicate support for Set Event 577313f6888SMarcel Holtmann * Mask Page 2 command, but then actually do not support it. Since 578313f6888SMarcel Holtmann * the default value is all bits set to zero, the command is only 579313f6888SMarcel Holtmann * required if the event mask has to be changed. In case no change 580313f6888SMarcel Holtmann * to the event mask is needed, skip this command. 581313f6888SMarcel Holtmann */ 582313f6888SMarcel Holtmann if (changed) 583313f6888SMarcel Holtmann hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, 584313f6888SMarcel Holtmann sizeof(events), events); 585d62e6d67SJohan Hedberg } 586d62e6d67SJohan Hedberg 587a1d01db1SJohan Hedberg static int hci_init3_req(struct hci_request *req, unsigned long opt) 5882177bab5SJohan Hedberg { 58942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 590d2c5d77fSJohan Hedberg u8 p; 59142c6b129SJohan Hedberg 5920da71f1bSMarcel Holtmann hci_setup_event_mask(req); 5930da71f1bSMarcel Holtmann 594e81be90bSJohan Hedberg if (hdev->commands[6] & 0x20 && 595e81be90bSJohan Hedberg !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 59648ce62c4SMarcel Holtmann struct hci_cp_read_stored_link_key cp; 59748ce62c4SMarcel Holtmann 59848ce62c4SMarcel Holtmann bacpy(&cp.bdaddr, BDADDR_ANY); 59948ce62c4SMarcel Holtmann cp.read_all = 0x01; 60048ce62c4SMarcel Holtmann hci_req_add(req, HCI_OP_READ_STORED_LINK_KEY, sizeof(cp), &cp); 60148ce62c4SMarcel Holtmann } 60248ce62c4SMarcel Holtmann 6032177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 60442c6b129SJohan Hedberg hci_setup_link_policy(req); 6052177bab5SJohan Hedberg 606417287deSMarcel Holtmann if (hdev->commands[8] & 0x01) 607417287deSMarcel Holtmann hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 608417287deSMarcel Holtmann 6098a595619SAlain Michaud if (hdev->commands[18] & 0x04) 61000bce3fbSAlain Michaud hci_req_add(req, HCI_OP_READ_DEF_ERR_DATA_REPORTING, 0, NULL); 61100bce3fbSAlain Michaud 612417287deSMarcel Holtmann /* Some older Broadcom based Bluetooth 1.2 controllers do not 613417287deSMarcel Holtmann * support the Read Page Scan Type command. Check support for 614417287deSMarcel Holtmann * this command in the bit mask of supported commands. 615417287deSMarcel Holtmann */ 616417287deSMarcel Holtmann if (hdev->commands[13] & 0x01) 617417287deSMarcel Holtmann hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 618417287deSMarcel Holtmann 6199193c6e8SAndre Guedes if (lmp_le_capable(hdev)) { 6209193c6e8SAndre Guedes u8 events[8]; 6219193c6e8SAndre Guedes 6229193c6e8SAndre Guedes memset(events, 0, sizeof(events)); 6234d6c705bSMarcel Holtmann 6244d6c705bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) 6254d6c705bSMarcel Holtmann events[0] |= 0x10; /* LE Long Term Key Request */ 626662bc2e6SAndre Guedes 627662bc2e6SAndre Guedes /* If controller supports the Connection Parameters Request 628662bc2e6SAndre Guedes * Link Layer Procedure, enable the corresponding event. 629662bc2e6SAndre Guedes */ 630662bc2e6SAndre Guedes if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC) 631662bc2e6SAndre Guedes events[0] |= 0x20; /* LE Remote Connection 632662bc2e6SAndre Guedes * Parameter Request 633662bc2e6SAndre Guedes */ 634662bc2e6SAndre Guedes 635a9f6068eSMarcel Holtmann /* If the controller supports the Data Length Extension 636a9f6068eSMarcel Holtmann * feature, enable the corresponding event. 637a9f6068eSMarcel Holtmann */ 638a9f6068eSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) 639a9f6068eSMarcel Holtmann events[0] |= 0x40; /* LE Data Length Change */ 640a9f6068eSMarcel Holtmann 6414b71bba4SMarcel Holtmann /* If the controller supports Extended Scanner Filter 6424b71bba4SMarcel Holtmann * Policies, enable the correspondig event. 6434b71bba4SMarcel Holtmann */ 6444b71bba4SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY) 6454b71bba4SMarcel Holtmann events[1] |= 0x04; /* LE Direct Advertising 6464b71bba4SMarcel Holtmann * Report 6474b71bba4SMarcel Holtmann */ 6484b71bba4SMarcel Holtmann 6499756d33bSMarcel Holtmann /* If the controller supports Channel Selection Algorithm #2 6509756d33bSMarcel Holtmann * feature, enable the corresponding event. 6519756d33bSMarcel Holtmann */ 6529756d33bSMarcel Holtmann if (hdev->le_features[1] & HCI_LE_CHAN_SEL_ALG2) 6539756d33bSMarcel Holtmann events[2] |= 0x08; /* LE Channel Selection 6549756d33bSMarcel Holtmann * Algorithm 6559756d33bSMarcel Holtmann */ 6569756d33bSMarcel Holtmann 6577d26f5c4SMarcel Holtmann /* If the controller supports the LE Set Scan Enable command, 6587d26f5c4SMarcel Holtmann * enable the corresponding advertising report event. 6597d26f5c4SMarcel Holtmann */ 6607d26f5c4SMarcel Holtmann if (hdev->commands[26] & 0x08) 6617d26f5c4SMarcel Holtmann events[0] |= 0x02; /* LE Advertising Report */ 6627d26f5c4SMarcel Holtmann 6637d26f5c4SMarcel Holtmann /* If the controller supports the LE Create Connection 6647d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6657d26f5c4SMarcel Holtmann */ 6667d26f5c4SMarcel Holtmann if (hdev->commands[26] & 0x10) 6677d26f5c4SMarcel Holtmann events[0] |= 0x01; /* LE Connection Complete */ 6687d26f5c4SMarcel Holtmann 6697d26f5c4SMarcel Holtmann /* If the controller supports the LE Connection Update 6707d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6717d26f5c4SMarcel Holtmann */ 6727d26f5c4SMarcel Holtmann if (hdev->commands[27] & 0x04) 6737d26f5c4SMarcel Holtmann events[0] |= 0x04; /* LE Connection Update 6747d26f5c4SMarcel Holtmann * Complete 6757d26f5c4SMarcel Holtmann */ 6767d26f5c4SMarcel Holtmann 6777d26f5c4SMarcel Holtmann /* If the controller supports the LE Read Remote Used Features 6787d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6797d26f5c4SMarcel Holtmann */ 6807d26f5c4SMarcel Holtmann if (hdev->commands[27] & 0x20) 6817d26f5c4SMarcel Holtmann events[0] |= 0x08; /* LE Read Remote Used 6827d26f5c4SMarcel Holtmann * Features Complete 6837d26f5c4SMarcel Holtmann */ 6847d26f5c4SMarcel Holtmann 6855a34bd5fSMarcel Holtmann /* If the controller supports the LE Read Local P-256 6865a34bd5fSMarcel Holtmann * Public Key command, enable the corresponding event. 6875a34bd5fSMarcel Holtmann */ 6885a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x02) 6895a34bd5fSMarcel Holtmann events[0] |= 0x80; /* LE Read Local P-256 6905a34bd5fSMarcel Holtmann * Public Key Complete 6915a34bd5fSMarcel Holtmann */ 6925a34bd5fSMarcel Holtmann 6935a34bd5fSMarcel Holtmann /* If the controller supports the LE Generate DHKey 6945a34bd5fSMarcel Holtmann * command, enable the corresponding event. 6955a34bd5fSMarcel Holtmann */ 6965a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x04) 6975a34bd5fSMarcel Holtmann events[1] |= 0x01; /* LE Generate DHKey Complete */ 6985a34bd5fSMarcel Holtmann 69927bbca44SMarcel Holtmann /* If the controller supports the LE Set Default PHY or 70027bbca44SMarcel Holtmann * LE Set PHY commands, enable the corresponding event. 70127bbca44SMarcel Holtmann */ 70227bbca44SMarcel Holtmann if (hdev->commands[35] & (0x20 | 0x40)) 70327bbca44SMarcel Holtmann events[1] |= 0x08; /* LE PHY Update Complete */ 70427bbca44SMarcel Holtmann 705c215e939SJaganath Kanakkassery /* If the controller supports LE Set Extended Scan Parameters 706c215e939SJaganath Kanakkassery * and LE Set Extended Scan Enable commands, enable the 707c215e939SJaganath Kanakkassery * corresponding event. 708c215e939SJaganath Kanakkassery */ 709c215e939SJaganath Kanakkassery if (use_ext_scan(hdev)) 710c215e939SJaganath Kanakkassery events[1] |= 0x10; /* LE Extended Advertising 711c215e939SJaganath Kanakkassery * Report 712c215e939SJaganath Kanakkassery */ 713c215e939SJaganath Kanakkassery 7144d94f95dSJaganath Kanakkassery /* If the controller supports the LE Extended Create Connection 7154d94f95dSJaganath Kanakkassery * command, enable the corresponding event. 7164d94f95dSJaganath Kanakkassery */ 7174d94f95dSJaganath Kanakkassery if (use_ext_conn(hdev)) 7184d94f95dSJaganath Kanakkassery events[1] |= 0x02; /* LE Enhanced Connection 7194d94f95dSJaganath Kanakkassery * Complete 7204d94f95dSJaganath Kanakkassery */ 7214d94f95dSJaganath Kanakkassery 722acf0aeaeSJaganath Kanakkassery /* If the controller supports the LE Extended Advertising 723acf0aeaeSJaganath Kanakkassery * command, enable the corresponding event. 724acf0aeaeSJaganath Kanakkassery */ 725acf0aeaeSJaganath Kanakkassery if (ext_adv_capable(hdev)) 726acf0aeaeSJaganath Kanakkassery events[2] |= 0x02; /* LE Advertising Set 727acf0aeaeSJaganath Kanakkassery * Terminated 728acf0aeaeSJaganath Kanakkassery */ 729acf0aeaeSJaganath Kanakkassery 7309193c6e8SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), 7319193c6e8SAndre Guedes events); 7329193c6e8SAndre Guedes 73315a49ccaSMarcel Holtmann /* Read LE Advertising Channel TX Power */ 7346b49bcb4SJaganath Kanakkassery if ((hdev->commands[25] & 0x40) && !ext_adv_capable(hdev)) { 7356b49bcb4SJaganath Kanakkassery /* HCI TS spec forbids mixing of legacy and extended 7366b49bcb4SJaganath Kanakkassery * advertising commands wherein READ_ADV_TX_POWER is 7376b49bcb4SJaganath Kanakkassery * also included. So do not call it if extended adv 7386b49bcb4SJaganath Kanakkassery * is supported otherwise controller will return 7396b49bcb4SJaganath Kanakkassery * COMMAND_DISALLOWED for extended commands. 7406b49bcb4SJaganath Kanakkassery */ 74115a49ccaSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 74215a49ccaSMarcel Holtmann } 74315a49ccaSMarcel Holtmann 7442ab216a7SMarcel Holtmann if (hdev->commands[26] & 0x40) { 7452ab216a7SMarcel Holtmann /* Read LE White List Size */ 7462ab216a7SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 7472ab216a7SMarcel Holtmann 0, NULL); 7482ab216a7SMarcel Holtmann } 7492ab216a7SMarcel Holtmann 7502ab216a7SMarcel Holtmann if (hdev->commands[26] & 0x80) { 7512ab216a7SMarcel Holtmann /* Clear LE White List */ 7522ab216a7SMarcel Holtmann hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL); 7532ab216a7SMarcel Holtmann } 7542ab216a7SMarcel Holtmann 755cfdb0c2dSAnkit Navik if (hdev->commands[34] & 0x40) { 756cfdb0c2dSAnkit Navik /* Read LE Resolving List Size */ 757cfdb0c2dSAnkit Navik hci_req_add(req, HCI_OP_LE_READ_RESOLV_LIST_SIZE, 758cfdb0c2dSAnkit Navik 0, NULL); 759cfdb0c2dSAnkit Navik } 760cfdb0c2dSAnkit Navik 761545f2596SAnkit Navik if (hdev->commands[34] & 0x20) { 762545f2596SAnkit Navik /* Clear LE Resolving List */ 763545f2596SAnkit Navik hci_req_add(req, HCI_OP_LE_CLEAR_RESOLV_LIST, 0, NULL); 764545f2596SAnkit Navik } 765545f2596SAnkit Navik 766a9f6068eSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { 767a9f6068eSMarcel Holtmann /* Read LE Maximum Data Length */ 768a9f6068eSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL); 769a9f6068eSMarcel Holtmann 770a9f6068eSMarcel Holtmann /* Read LE Suggested Default Data Length */ 771a9f6068eSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL); 772a9f6068eSMarcel Holtmann } 773a9f6068eSMarcel Holtmann 7746b49bcb4SJaganath Kanakkassery if (ext_adv_capable(hdev)) { 7756b49bcb4SJaganath Kanakkassery /* Read LE Number of Supported Advertising Sets */ 7766b49bcb4SJaganath Kanakkassery hci_req_add(req, HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS, 7776b49bcb4SJaganath Kanakkassery 0, NULL); 7786b49bcb4SJaganath Kanakkassery } 7796b49bcb4SJaganath Kanakkassery 78042c6b129SJohan Hedberg hci_set_le_support(req); 7819193c6e8SAndre Guedes } 782d2c5d77fSJohan Hedberg 783d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 784d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 785d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 786d2c5d77fSJohan Hedberg 787d2c5d77fSJohan Hedberg cp.page = p; 788d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 789d2c5d77fSJohan Hedberg sizeof(cp), &cp); 790d2c5d77fSJohan Hedberg } 791a1d01db1SJohan Hedberg 792a1d01db1SJohan Hedberg return 0; 7932177bab5SJohan Hedberg } 7942177bab5SJohan Hedberg 795a1d01db1SJohan Hedberg static int hci_init4_req(struct hci_request *req, unsigned long opt) 7965d4e7e8dSJohan Hedberg { 7975d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 7985d4e7e8dSJohan Hedberg 79936f260ceSMarcel Holtmann /* Some Broadcom based Bluetooth controllers do not support the 80036f260ceSMarcel Holtmann * Delete Stored Link Key command. They are clearly indicating its 80136f260ceSMarcel Holtmann * absence in the bit mask of supported commands. 80236f260ceSMarcel Holtmann * 80336f260ceSMarcel Holtmann * Check the supported commands and only if the the command is marked 80436f260ceSMarcel Holtmann * as supported send it. If not supported assume that the controller 80536f260ceSMarcel Holtmann * does not have actual support for stored link keys which makes this 80636f260ceSMarcel Holtmann * command redundant anyway. 80736f260ceSMarcel Holtmann * 80836f260ceSMarcel Holtmann * Some controllers indicate that they support handling deleting 80936f260ceSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 81036f260ceSMarcel Holtmann * just disable this command. 81136f260ceSMarcel Holtmann */ 81236f260ceSMarcel Holtmann if (hdev->commands[6] & 0x80 && 81336f260ceSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 81436f260ceSMarcel Holtmann struct hci_cp_delete_stored_link_key cp; 81536f260ceSMarcel Holtmann 81636f260ceSMarcel Holtmann bacpy(&cp.bdaddr, BDADDR_ANY); 81736f260ceSMarcel Holtmann cp.delete_all = 0x01; 81836f260ceSMarcel Holtmann hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 81936f260ceSMarcel Holtmann sizeof(cp), &cp); 82036f260ceSMarcel Holtmann } 82136f260ceSMarcel Holtmann 822d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 823d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 824d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 825d62e6d67SJohan Hedberg 826109e3191SMarcel Holtmann /* Read local codec list if the HCI command is supported */ 827109e3191SMarcel Holtmann if (hdev->commands[29] & 0x20) 828109e3191SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL); 829109e3191SMarcel Holtmann 830f4fe73edSMarcel Holtmann /* Get MWS transport configuration if the HCI command is supported */ 831f4fe73edSMarcel Holtmann if (hdev->commands[30] & 0x08) 832f4fe73edSMarcel Holtmann hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL); 833f4fe73edSMarcel Holtmann 8345d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 83553b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 8365d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 837a6d0d690SMarcel Holtmann 838a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 839d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) && 840574ea3c7SMarcel Holtmann bredr_sc_enabled(hdev)) { 841a6d0d690SMarcel Holtmann u8 support = 0x01; 842574ea3c7SMarcel Holtmann 843a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 844a6d0d690SMarcel Holtmann sizeof(support), &support); 845a6d0d690SMarcel Holtmann } 846a1d01db1SJohan Hedberg 84700bce3fbSAlain Michaud /* Set erroneous data reporting if supported to the wideband speech 84800bce3fbSAlain Michaud * setting value 84900bce3fbSAlain Michaud */ 8508a595619SAlain Michaud if (hdev->commands[18] & 0x08) { 85100bce3fbSAlain Michaud bool enabled = hci_dev_test_flag(hdev, 85200bce3fbSAlain Michaud HCI_WIDEBAND_SPEECH_ENABLED); 85300bce3fbSAlain Michaud 85400bce3fbSAlain Michaud if (enabled != 85500bce3fbSAlain Michaud (hdev->err_data_reporting == ERR_DATA_REPORTING_ENABLED)) { 85600bce3fbSAlain Michaud struct hci_cp_write_def_err_data_reporting cp; 85700bce3fbSAlain Michaud 85800bce3fbSAlain Michaud cp.err_data_reporting = enabled ? 85900bce3fbSAlain Michaud ERR_DATA_REPORTING_ENABLED : 86000bce3fbSAlain Michaud ERR_DATA_REPORTING_DISABLED; 86100bce3fbSAlain Michaud 86200bce3fbSAlain Michaud hci_req_add(req, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING, 86300bce3fbSAlain Michaud sizeof(cp), &cp); 86400bce3fbSAlain Michaud } 86500bce3fbSAlain Michaud } 86600bce3fbSAlain Michaud 86712204875SMarcel Holtmann /* Set Suggested Default Data Length to maximum if supported */ 86812204875SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { 86912204875SMarcel Holtmann struct hci_cp_le_write_def_data_len cp; 87012204875SMarcel Holtmann 871727ea61aSBen Dooks (Codethink) cp.tx_len = cpu_to_le16(hdev->le_max_tx_len); 872727ea61aSBen Dooks (Codethink) cp.tx_time = cpu_to_le16(hdev->le_max_tx_time); 87312204875SMarcel Holtmann hci_req_add(req, HCI_OP_LE_WRITE_DEF_DATA_LEN, sizeof(cp), &cp); 87412204875SMarcel Holtmann } 87512204875SMarcel Holtmann 876de2ba303SMarcel Holtmann /* Set Default PHY parameters if command is supported */ 877de2ba303SMarcel Holtmann if (hdev->commands[35] & 0x20) { 878de2ba303SMarcel Holtmann struct hci_cp_le_set_default_phy cp; 879de2ba303SMarcel Holtmann 8806decb5b4SJaganath Kanakkassery cp.all_phys = 0x00; 8816decb5b4SJaganath Kanakkassery cp.tx_phys = hdev->le_tx_def_phys; 8826decb5b4SJaganath Kanakkassery cp.rx_phys = hdev->le_rx_def_phys; 883de2ba303SMarcel Holtmann 884de2ba303SMarcel Holtmann hci_req_add(req, HCI_OP_LE_SET_DEFAULT_PHY, sizeof(cp), &cp); 885de2ba303SMarcel Holtmann } 886de2ba303SMarcel Holtmann 887a1d01db1SJohan Hedberg return 0; 8885d4e7e8dSJohan Hedberg } 8895d4e7e8dSJohan Hedberg 8902177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 8912177bab5SJohan Hedberg { 8922177bab5SJohan Hedberg int err; 8932177bab5SJohan Hedberg 8944ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT, NULL); 8952177bab5SJohan Hedberg if (err < 0) 8962177bab5SJohan Hedberg return err; 8972177bab5SJohan Hedberg 898f640ee98SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 899f640ee98SMarcel Holtmann hci_debugfs_create_basic(hdev); 9004b4148e9SMarcel Holtmann 9014ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT, NULL); 9022177bab5SJohan Hedberg if (err < 0) 9032177bab5SJohan Hedberg return err; 9042177bab5SJohan Hedberg 905ca8bee5dSMarcel Holtmann /* HCI_PRIMARY covers both single-mode LE, BR/EDR and dual-mode 9060af801b9SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 9070af801b9SJohan Hedberg * first two stages of init. 9080af801b9SJohan Hedberg */ 909ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) 9100af801b9SJohan Hedberg return 0; 9110af801b9SJohan Hedberg 9124ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT, NULL); 9135d4e7e8dSJohan Hedberg if (err < 0) 9145d4e7e8dSJohan Hedberg return err; 9155d4e7e8dSJohan Hedberg 9164ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT, NULL); 917baf27f6eSMarcel Holtmann if (err < 0) 918baf27f6eSMarcel Holtmann return err; 919baf27f6eSMarcel Holtmann 920ec6cef9cSMarcel Holtmann /* This function is only called when the controller is actually in 921ec6cef9cSMarcel Holtmann * configured state. When the controller is marked as unconfigured, 922ec6cef9cSMarcel Holtmann * this initialization procedure is not run. 923ec6cef9cSMarcel Holtmann * 924ec6cef9cSMarcel Holtmann * It means that it is possible that a controller runs through its 925ec6cef9cSMarcel Holtmann * setup phase and then discovers missing settings. If that is the 926ec6cef9cSMarcel Holtmann * case, then this function will not be called. It then will only 927ec6cef9cSMarcel Holtmann * be called during the config phase. 928ec6cef9cSMarcel Holtmann * 929ec6cef9cSMarcel Holtmann * So only when in setup phase or config phase, create the debugfs 930ec6cef9cSMarcel Holtmann * entries and register the SMP channels. 931baf27f6eSMarcel Holtmann */ 932d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 933d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 934baf27f6eSMarcel Holtmann return 0; 935baf27f6eSMarcel Holtmann 93660c5f5fbSMarcel Holtmann hci_debugfs_create_common(hdev); 93760c5f5fbSMarcel Holtmann 93871c3b60eSMarcel Holtmann if (lmp_bredr_capable(hdev)) 93960c5f5fbSMarcel Holtmann hci_debugfs_create_bredr(hdev); 9402bfa3531SMarcel Holtmann 941162a3bacSMarcel Holtmann if (lmp_le_capable(hdev)) 94260c5f5fbSMarcel Holtmann hci_debugfs_create_le(hdev); 943e7b8fc92SMarcel Holtmann 944baf27f6eSMarcel Holtmann return 0; 9452177bab5SJohan Hedberg } 9462177bab5SJohan Hedberg 947a1d01db1SJohan Hedberg static int hci_init0_req(struct hci_request *req, unsigned long opt) 9480ebca7d6SMarcel Holtmann { 9490ebca7d6SMarcel Holtmann struct hci_dev *hdev = req->hdev; 9500ebca7d6SMarcel Holtmann 9510ebca7d6SMarcel Holtmann BT_DBG("%s %ld", hdev->name, opt); 9520ebca7d6SMarcel Holtmann 9530ebca7d6SMarcel Holtmann /* Reset */ 9540ebca7d6SMarcel Holtmann if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 9550ebca7d6SMarcel Holtmann hci_reset_req(req, 0); 9560ebca7d6SMarcel Holtmann 9570ebca7d6SMarcel Holtmann /* Read Local Version */ 9580ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 9590ebca7d6SMarcel Holtmann 9600ebca7d6SMarcel Holtmann /* Read BD Address */ 9610ebca7d6SMarcel Holtmann if (hdev->set_bdaddr) 9620ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 963a1d01db1SJohan Hedberg 964a1d01db1SJohan Hedberg return 0; 9650ebca7d6SMarcel Holtmann } 9660ebca7d6SMarcel Holtmann 9670ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev) 9680ebca7d6SMarcel Holtmann { 9690ebca7d6SMarcel Holtmann int err; 9700ebca7d6SMarcel Holtmann 971cc78b44bSMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 972cc78b44bSMarcel Holtmann return 0; 973cc78b44bSMarcel Holtmann 9744ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT, NULL); 9750ebca7d6SMarcel Holtmann if (err < 0) 9760ebca7d6SMarcel Holtmann return err; 9770ebca7d6SMarcel Holtmann 978f640ee98SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 979f640ee98SMarcel Holtmann hci_debugfs_create_basic(hdev); 980f640ee98SMarcel Holtmann 9810ebca7d6SMarcel Holtmann return 0; 9820ebca7d6SMarcel Holtmann } 9830ebca7d6SMarcel Holtmann 984a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt) 9851da177e4SLinus Torvalds { 9861da177e4SLinus Torvalds __u8 scan = opt; 9871da177e4SLinus Torvalds 98842c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 9891da177e4SLinus Torvalds 9901da177e4SLinus Torvalds /* Inquiry and Page scans */ 99142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 992a1d01db1SJohan Hedberg return 0; 9931da177e4SLinus Torvalds } 9941da177e4SLinus Torvalds 995a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt) 9961da177e4SLinus Torvalds { 9971da177e4SLinus Torvalds __u8 auth = opt; 9981da177e4SLinus Torvalds 99942c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 10001da177e4SLinus Torvalds 10011da177e4SLinus Torvalds /* Authentication */ 100242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 1003a1d01db1SJohan Hedberg return 0; 10041da177e4SLinus Torvalds } 10051da177e4SLinus Torvalds 1006a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt) 10071da177e4SLinus Torvalds { 10081da177e4SLinus Torvalds __u8 encrypt = opt; 10091da177e4SLinus Torvalds 101042c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 10111da177e4SLinus Torvalds 1012e4e8e37cSMarcel Holtmann /* Encryption */ 101342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 1014a1d01db1SJohan Hedberg return 0; 10151da177e4SLinus Torvalds } 10161da177e4SLinus Torvalds 1017a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt) 1018e4e8e37cSMarcel Holtmann { 1019e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1020e4e8e37cSMarcel Holtmann 102142c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1022e4e8e37cSMarcel Holtmann 1023e4e8e37cSMarcel Holtmann /* Default link policy */ 102442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1025a1d01db1SJohan Hedberg return 0; 1026e4e8e37cSMarcel Holtmann } 1027e4e8e37cSMarcel Holtmann 10281da177e4SLinus Torvalds /* Get HCI device by index. 10291da177e4SLinus Torvalds * Device is held on return. */ 10301da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 10311da177e4SLinus Torvalds { 10328035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 10331da177e4SLinus Torvalds 10341da177e4SLinus Torvalds BT_DBG("%d", index); 10351da177e4SLinus Torvalds 10361da177e4SLinus Torvalds if (index < 0) 10371da177e4SLinus Torvalds return NULL; 10381da177e4SLinus Torvalds 10391da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 10408035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 10411da177e4SLinus Torvalds if (d->id == index) { 10421da177e4SLinus Torvalds hdev = hci_dev_hold(d); 10431da177e4SLinus Torvalds break; 10441da177e4SLinus Torvalds } 10451da177e4SLinus Torvalds } 10461da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 10471da177e4SLinus Torvalds return hdev; 10481da177e4SLinus Torvalds } 10491da177e4SLinus Torvalds 10501da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1051ff9ef578SJohan Hedberg 105230dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 105330dc78e1SJohan Hedberg { 105430dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 105530dc78e1SJohan Hedberg 10566fbe195dSAndre Guedes switch (discov->state) { 1057343f935bSAndre Guedes case DISCOVERY_FINDING: 10586fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 105930dc78e1SJohan Hedberg return true; 106030dc78e1SJohan Hedberg 10616fbe195dSAndre Guedes default: 106230dc78e1SJohan Hedberg return false; 106330dc78e1SJohan Hedberg } 10646fbe195dSAndre Guedes } 106530dc78e1SJohan Hedberg 1066ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1067ff9ef578SJohan Hedberg { 1068bb3e0a33SJohan Hedberg int old_state = hdev->discovery.state; 1069bb3e0a33SJohan Hedberg 1070ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1071ff9ef578SJohan Hedberg 1072bb3e0a33SJohan Hedberg if (old_state == state) 1073ff9ef578SJohan Hedberg return; 1074ff9ef578SJohan Hedberg 1075bb3e0a33SJohan Hedberg hdev->discovery.state = state; 1076bb3e0a33SJohan Hedberg 1077ff9ef578SJohan Hedberg switch (state) { 1078ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 1079c54c3860SAndre Guedes hci_update_background_scan(hdev); 1080c54c3860SAndre Guedes 1081bb3e0a33SJohan Hedberg if (old_state != DISCOVERY_STARTING) 1082ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1083ff9ef578SJohan Hedberg break; 1084ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1085ff9ef578SJohan Hedberg break; 1086343f935bSAndre Guedes case DISCOVERY_FINDING: 1087ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1088ff9ef578SJohan Hedberg break; 108930dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 109030dc78e1SJohan Hedberg break; 1091ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1092ff9ef578SJohan Hedberg break; 1093ff9ef578SJohan Hedberg } 1094ff9ef578SJohan Hedberg } 1095ff9ef578SJohan Hedberg 10961f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 10971da177e4SLinus Torvalds { 109830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1099b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 11001da177e4SLinus Torvalds 1101561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1102561aafbcSJohan Hedberg list_del(&p->all); 1103b57c1a56SJohan Hedberg kfree(p); 11041da177e4SLinus Torvalds } 1105561aafbcSJohan Hedberg 1106561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1107561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 11081da177e4SLinus Torvalds } 11091da177e4SLinus Torvalds 1110a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1111a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 11121da177e4SLinus Torvalds { 111330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 11141da177e4SLinus Torvalds struct inquiry_entry *e; 11151da177e4SLinus Torvalds 11166ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 11171da177e4SLinus Torvalds 1118561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 11191da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 11201da177e4SLinus Torvalds return e; 11211da177e4SLinus Torvalds } 11221da177e4SLinus Torvalds 1123b57c1a56SJohan Hedberg return NULL; 1124b57c1a56SJohan Hedberg } 1125b57c1a56SJohan Hedberg 1126561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1127561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1128561aafbcSJohan Hedberg { 112930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1130561aafbcSJohan Hedberg struct inquiry_entry *e; 1131561aafbcSJohan Hedberg 11326ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1133561aafbcSJohan Hedberg 1134561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1135561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1136561aafbcSJohan Hedberg return e; 1137561aafbcSJohan Hedberg } 1138561aafbcSJohan Hedberg 1139561aafbcSJohan Hedberg return NULL; 1140561aafbcSJohan Hedberg } 1141561aafbcSJohan Hedberg 114230dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 114330dc78e1SJohan Hedberg bdaddr_t *bdaddr, 114430dc78e1SJohan Hedberg int state) 114530dc78e1SJohan Hedberg { 114630dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 114730dc78e1SJohan Hedberg struct inquiry_entry *e; 114830dc78e1SJohan Hedberg 11496ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 115030dc78e1SJohan Hedberg 115130dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 115230dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 115330dc78e1SJohan Hedberg return e; 115430dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 115530dc78e1SJohan Hedberg return e; 115630dc78e1SJohan Hedberg } 115730dc78e1SJohan Hedberg 115830dc78e1SJohan Hedberg return NULL; 115930dc78e1SJohan Hedberg } 116030dc78e1SJohan Hedberg 1161a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1162a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1163a3d4e20aSJohan Hedberg { 1164a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1165a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1166a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1167a3d4e20aSJohan Hedberg 1168a3d4e20aSJohan Hedberg list_del(&ie->list); 1169a3d4e20aSJohan Hedberg 1170a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1171a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1172a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1173a3d4e20aSJohan Hedberg break; 1174a3d4e20aSJohan Hedberg pos = &p->list; 1175a3d4e20aSJohan Hedberg } 1176a3d4e20aSJohan Hedberg 1177a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1178a3d4e20aSJohan Hedberg } 1179a3d4e20aSJohan Hedberg 1180af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1181af58925cSMarcel Holtmann bool name_known) 11821da177e4SLinus Torvalds { 118330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 118470f23020SAndrei Emeltchenko struct inquiry_entry *ie; 1185af58925cSMarcel Holtmann u32 flags = 0; 11861da177e4SLinus Torvalds 11876ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 11881da177e4SLinus Torvalds 11896928a924SJohan Hedberg hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR); 11902b2fec4dSSzymon Janc 1191af58925cSMarcel Holtmann if (!data->ssp_mode) 1192af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1193388fc8faSJohan Hedberg 119470f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1195a3d4e20aSJohan Hedberg if (ie) { 1196af58925cSMarcel Holtmann if (!ie->data.ssp_mode) 1197af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1198388fc8faSJohan Hedberg 1199a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1200a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1201a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1202a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1203a3d4e20aSJohan Hedberg } 1204a3d4e20aSJohan Hedberg 1205561aafbcSJohan Hedberg goto update; 1206a3d4e20aSJohan Hedberg } 1207561aafbcSJohan Hedberg 12081da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 120927f70f3eSJohan Hedberg ie = kzalloc(sizeof(*ie), GFP_KERNEL); 1210af58925cSMarcel Holtmann if (!ie) { 1211af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 1212af58925cSMarcel Holtmann goto done; 1213af58925cSMarcel Holtmann } 121470f23020SAndrei Emeltchenko 1215561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1216561aafbcSJohan Hedberg 1217561aafbcSJohan Hedberg if (name_known) { 1218561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1219561aafbcSJohan Hedberg } else { 1220561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1221561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1222561aafbcSJohan Hedberg } 1223561aafbcSJohan Hedberg 1224561aafbcSJohan Hedberg update: 1225561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1226561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1227561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1228561aafbcSJohan Hedberg list_del(&ie->list); 12291da177e4SLinus Torvalds } 12301da177e4SLinus Torvalds 123170f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 123270f23020SAndrei Emeltchenko ie->timestamp = jiffies; 12331da177e4SLinus Torvalds cache->timestamp = jiffies; 12343175405bSJohan Hedberg 12353175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 1236af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 12373175405bSJohan Hedberg 1238af58925cSMarcel Holtmann done: 1239af58925cSMarcel Holtmann return flags; 12401da177e4SLinus Torvalds } 12411da177e4SLinus Torvalds 12421da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 12431da177e4SLinus Torvalds { 124430883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 12451da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 12461da177e4SLinus Torvalds struct inquiry_entry *e; 12471da177e4SLinus Torvalds int copied = 0; 12481da177e4SLinus Torvalds 1249561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 12501da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1251b57c1a56SJohan Hedberg 1252b57c1a56SJohan Hedberg if (copied >= num) 1253b57c1a56SJohan Hedberg break; 1254b57c1a56SJohan Hedberg 12551da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 12561da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 12571da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 12581da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 12591da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 12601da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1261b57c1a56SJohan Hedberg 12621da177e4SLinus Torvalds info++; 1263b57c1a56SJohan Hedberg copied++; 12641da177e4SLinus Torvalds } 12651da177e4SLinus Torvalds 12661da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 12671da177e4SLinus Torvalds return copied; 12681da177e4SLinus Torvalds } 12691da177e4SLinus Torvalds 1270a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt) 12711da177e4SLinus Torvalds { 12721da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 127342c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 12741da177e4SLinus Torvalds struct hci_cp_inquiry cp; 12751da177e4SLinus Torvalds 12761da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 12771da177e4SLinus Torvalds 12781da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 1279a1d01db1SJohan Hedberg return 0; 12801da177e4SLinus Torvalds 12811da177e4SLinus Torvalds /* Start Inquiry */ 12821da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 12831da177e4SLinus Torvalds cp.length = ir->length; 12841da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 128542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 1286a1d01db1SJohan Hedberg 1287a1d01db1SJohan Hedberg return 0; 12881da177e4SLinus Torvalds } 12891da177e4SLinus Torvalds 12901da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 12911da177e4SLinus Torvalds { 12921da177e4SLinus Torvalds __u8 __user *ptr = arg; 12931da177e4SLinus Torvalds struct hci_inquiry_req ir; 12941da177e4SLinus Torvalds struct hci_dev *hdev; 12951da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 12961da177e4SLinus Torvalds long timeo; 12971da177e4SLinus Torvalds __u8 *buf; 12981da177e4SLinus Torvalds 12991da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 13001da177e4SLinus Torvalds return -EFAULT; 13011da177e4SLinus Torvalds 13025a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 13035a08ecceSAndrei Emeltchenko if (!hdev) 13041da177e4SLinus Torvalds return -ENODEV; 13051da177e4SLinus Torvalds 1306d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 13070736cfa8SMarcel Holtmann err = -EBUSY; 13080736cfa8SMarcel Holtmann goto done; 13090736cfa8SMarcel Holtmann } 13100736cfa8SMarcel Holtmann 1311d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1312fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1313fee746b0SMarcel Holtmann goto done; 1314fee746b0SMarcel Holtmann } 1315fee746b0SMarcel Holtmann 1316ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 13175b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 13185b69bef5SMarcel Holtmann goto done; 13195b69bef5SMarcel Holtmann } 13205b69bef5SMarcel Holtmann 1321d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 132256f87901SJohan Hedberg err = -EOPNOTSUPP; 132356f87901SJohan Hedberg goto done; 132456f87901SJohan Hedberg } 132556f87901SJohan Hedberg 132609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 13271da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1328a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 13291f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 13301da177e4SLinus Torvalds do_inquiry = 1; 13311da177e4SLinus Torvalds } 133209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13331da177e4SLinus Torvalds 133404837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 133570f23020SAndrei Emeltchenko 133670f23020SAndrei Emeltchenko if (do_inquiry) { 133701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 13384ebeee2dSJohan Hedberg timeo, NULL); 133970f23020SAndrei Emeltchenko if (err < 0) 13401da177e4SLinus Torvalds goto done; 13413e13fa1eSAndre Guedes 13423e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 13433e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 13443e13fa1eSAndre Guedes */ 134574316201SNeilBrown if (wait_on_bit(&hdev->flags, HCI_INQUIRY, 13463e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 13473e13fa1eSAndre Guedes return -EINTR; 134870f23020SAndrei Emeltchenko } 13491da177e4SLinus Torvalds 13508fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 13518fc9ced3SGustavo Padovan * 255 entries 13528fc9ced3SGustavo Padovan */ 13531da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 13541da177e4SLinus Torvalds 13551da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 13561da177e4SLinus Torvalds * copy it to the user space. 13571da177e4SLinus Torvalds */ 13586da2ec56SKees Cook buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL); 135970f23020SAndrei Emeltchenko if (!buf) { 13601da177e4SLinus Torvalds err = -ENOMEM; 13611da177e4SLinus Torvalds goto done; 13621da177e4SLinus Torvalds } 13631da177e4SLinus Torvalds 136409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 13651da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 136609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13671da177e4SLinus Torvalds 13681da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 13691da177e4SLinus Torvalds 13701da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 13711da177e4SLinus Torvalds ptr += sizeof(ir); 13721da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 13731da177e4SLinus Torvalds ir.num_rsp)) 13741da177e4SLinus Torvalds err = -EFAULT; 13751da177e4SLinus Torvalds } else 13761da177e4SLinus Torvalds err = -EFAULT; 13771da177e4SLinus Torvalds 13781da177e4SLinus Torvalds kfree(buf); 13791da177e4SLinus Torvalds 13801da177e4SLinus Torvalds done: 13811da177e4SLinus Torvalds hci_dev_put(hdev); 13821da177e4SLinus Torvalds return err; 13831da177e4SLinus Torvalds } 13841da177e4SLinus Torvalds 13857a0e5b15SMatthias Kaehlcke /** 13867a0e5b15SMatthias Kaehlcke * hci_dev_get_bd_addr_from_property - Get the Bluetooth Device Address 13877a0e5b15SMatthias Kaehlcke * (BD_ADDR) for a HCI device from 13887a0e5b15SMatthias Kaehlcke * a firmware node property. 13897a0e5b15SMatthias Kaehlcke * @hdev: The HCI device 13907a0e5b15SMatthias Kaehlcke * 13917a0e5b15SMatthias Kaehlcke * Search the firmware node for 'local-bd-address'. 13927a0e5b15SMatthias Kaehlcke * 13937a0e5b15SMatthias Kaehlcke * All-zero BD addresses are rejected, because those could be properties 13947a0e5b15SMatthias Kaehlcke * that exist in the firmware tables, but were not updated by the firmware. For 13957a0e5b15SMatthias Kaehlcke * example, the DTS could define 'local-bd-address', with zero BD addresses. 13967a0e5b15SMatthias Kaehlcke */ 13977a0e5b15SMatthias Kaehlcke static void hci_dev_get_bd_addr_from_property(struct hci_dev *hdev) 13987a0e5b15SMatthias Kaehlcke { 13997a0e5b15SMatthias Kaehlcke struct fwnode_handle *fwnode = dev_fwnode(hdev->dev.parent); 14007a0e5b15SMatthias Kaehlcke bdaddr_t ba; 14017a0e5b15SMatthias Kaehlcke int ret; 14027a0e5b15SMatthias Kaehlcke 14037a0e5b15SMatthias Kaehlcke ret = fwnode_property_read_u8_array(fwnode, "local-bd-address", 14047a0e5b15SMatthias Kaehlcke (u8 *)&ba, sizeof(ba)); 14057a0e5b15SMatthias Kaehlcke if (ret < 0 || !bacmp(&ba, BDADDR_ANY)) 14067a0e5b15SMatthias Kaehlcke return; 14077a0e5b15SMatthias Kaehlcke 14087a0e5b15SMatthias Kaehlcke bacpy(&hdev->public_addr, &ba); 14097a0e5b15SMatthias Kaehlcke } 14107a0e5b15SMatthias Kaehlcke 1411cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 14121da177e4SLinus Torvalds { 14131da177e4SLinus Torvalds int ret = 0; 14141da177e4SLinus Torvalds 14151da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 14161da177e4SLinus Torvalds 1417b504430cSJohan Hedberg hci_req_sync_lock(hdev); 14181da177e4SLinus Torvalds 1419d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) { 142094324962SJohan Hovold ret = -ENODEV; 142194324962SJohan Hovold goto done; 142294324962SJohan Hovold } 142394324962SJohan Hovold 1424d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 1425d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 1426a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1427a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1428bf543036SJohan Hedberg */ 1429d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED)) { 1430611b30f7SMarcel Holtmann ret = -ERFKILL; 1431611b30f7SMarcel Holtmann goto done; 1432611b30f7SMarcel Holtmann } 1433611b30f7SMarcel Holtmann 1434a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 1435a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 1436a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1437a5c8f270SMarcel Holtmann * or not. 1438a5c8f270SMarcel Holtmann * 1439c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 1440c6beca0eSMarcel Holtmann * if a public address or static random address is 1441c6beca0eSMarcel Holtmann * available. 1442c6beca0eSMarcel Holtmann * 1443a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1444a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1445a5c8f270SMarcel Holtmann */ 1446d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1447ca8bee5dSMarcel Holtmann hdev->dev_type == HCI_PRIMARY && 1448a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1449a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1450a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1451a5c8f270SMarcel Holtmann goto done; 1452a5c8f270SMarcel Holtmann } 1453a5c8f270SMarcel Holtmann } 1454a5c8f270SMarcel Holtmann 14551da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 14561da177e4SLinus Torvalds ret = -EALREADY; 14571da177e4SLinus Torvalds goto done; 14581da177e4SLinus Torvalds } 14591da177e4SLinus Torvalds 14601da177e4SLinus Torvalds if (hdev->open(hdev)) { 14611da177e4SLinus Torvalds ret = -EIO; 14621da177e4SLinus Torvalds goto done; 14631da177e4SLinus Torvalds } 14641da177e4SLinus Torvalds 1465e9ca8bf1SMarcel Holtmann set_bit(HCI_RUNNING, &hdev->flags); 146605fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_OPEN); 14674a3f95b7SMarcel Holtmann 14681da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 14691da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1470f41c70c4SMarcel Holtmann 1471740011cfSSean Wang if (hci_dev_test_flag(hdev, HCI_SETUP) || 1472740011cfSSean Wang test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) { 14737fdf6c6aSMarcel Holtmann bool invalid_bdaddr; 14747fdf6c6aSMarcel Holtmann 1475e131d74aSMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_SETUP); 1476e131d74aSMarcel Holtmann 1477af202f84SMarcel Holtmann if (hdev->setup) 1478f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1479f41c70c4SMarcel Holtmann 14807fdf6c6aSMarcel Holtmann /* The transport driver can set the quirk to mark the 14817fdf6c6aSMarcel Holtmann * BD_ADDR invalid before creating the HCI device or in 14827fdf6c6aSMarcel Holtmann * its setup callback. 14837fdf6c6aSMarcel Holtmann */ 14847fdf6c6aSMarcel Holtmann invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR, 14857fdf6c6aSMarcel Holtmann &hdev->quirks); 14867fdf6c6aSMarcel Holtmann 14877a0e5b15SMatthias Kaehlcke if (ret) 14887a0e5b15SMatthias Kaehlcke goto setup_failed; 14897a0e5b15SMatthias Kaehlcke 14907a0e5b15SMatthias Kaehlcke if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) { 14917a0e5b15SMatthias Kaehlcke if (!bacmp(&hdev->public_addr, BDADDR_ANY)) 14927a0e5b15SMatthias Kaehlcke hci_dev_get_bd_addr_from_property(hdev); 14937a0e5b15SMatthias Kaehlcke 14947a0e5b15SMatthias Kaehlcke if (bacmp(&hdev->public_addr, BDADDR_ANY) && 14957fdf6c6aSMarcel Holtmann hdev->set_bdaddr) { 14967a0e5b15SMatthias Kaehlcke ret = hdev->set_bdaddr(hdev, 14977a0e5b15SMatthias Kaehlcke &hdev->public_addr); 14987fdf6c6aSMarcel Holtmann 14997fdf6c6aSMarcel Holtmann /* If setting of the BD_ADDR from the device 15007fdf6c6aSMarcel Holtmann * property succeeds, then treat the address 15017fdf6c6aSMarcel Holtmann * as valid even if the invalid BD_ADDR 15027fdf6c6aSMarcel Holtmann * quirk indicates otherwise. 15037fdf6c6aSMarcel Holtmann */ 15047fdf6c6aSMarcel Holtmann if (!ret) 15057fdf6c6aSMarcel Holtmann invalid_bdaddr = false; 15067fdf6c6aSMarcel Holtmann } 15077a0e5b15SMatthias Kaehlcke } 15087a0e5b15SMatthias Kaehlcke 15097a0e5b15SMatthias Kaehlcke setup_failed: 1510af202f84SMarcel Holtmann /* The transport driver can set these quirks before 1511af202f84SMarcel Holtmann * creating the HCI device or in its setup callback. 1512af202f84SMarcel Holtmann * 15137fdf6c6aSMarcel Holtmann * For the invalid BD_ADDR quirk it is possible that 15147fdf6c6aSMarcel Holtmann * it becomes a valid address if the bootloader does 15157fdf6c6aSMarcel Holtmann * provide it (see above). 15167fdf6c6aSMarcel Holtmann * 1517af202f84SMarcel Holtmann * In case any of them is set, the controller has to 1518af202f84SMarcel Holtmann * start up as unconfigured. 1519af202f84SMarcel Holtmann */ 1520eb1904f4SMarcel Holtmann if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) || 15217fdf6c6aSMarcel Holtmann invalid_bdaddr) 1522a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 1523f41c70c4SMarcel Holtmann 15240ebca7d6SMarcel Holtmann /* For an unconfigured controller it is required to 15250ebca7d6SMarcel Holtmann * read at least the version information provided by 15260ebca7d6SMarcel Holtmann * the Read Local Version Information command. 15270ebca7d6SMarcel Holtmann * 15280ebca7d6SMarcel Holtmann * If the set_bdaddr driver callback is provided, then 15290ebca7d6SMarcel Holtmann * also the original Bluetooth public device address 15300ebca7d6SMarcel Holtmann * will be read using the Read BD Address command. 15310ebca7d6SMarcel Holtmann */ 1532d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 15330ebca7d6SMarcel Holtmann ret = __hci_unconf_init(hdev); 153489bc22d2SMarcel Holtmann } 153589bc22d2SMarcel Holtmann 1536d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_CONFIG)) { 15379713c17bSMarcel Holtmann /* If public address change is configured, ensure that 15389713c17bSMarcel Holtmann * the address gets programmed. If the driver does not 15399713c17bSMarcel Holtmann * support changing the public address, fail the power 15409713c17bSMarcel Holtmann * on procedure. 154124c457e2SMarcel Holtmann */ 15429713c17bSMarcel Holtmann if (bacmp(&hdev->public_addr, BDADDR_ANY) && 15439713c17bSMarcel Holtmann hdev->set_bdaddr) 154424c457e2SMarcel Holtmann ret = hdev->set_bdaddr(hdev, &hdev->public_addr); 154524c457e2SMarcel Holtmann else 154624c457e2SMarcel Holtmann ret = -EADDRNOTAVAIL; 154724c457e2SMarcel Holtmann } 154824c457e2SMarcel Holtmann 1549f41c70c4SMarcel Holtmann if (!ret) { 1550d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 155198a63aafSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 15522177bab5SJohan Hedberg ret = __hci_init(hdev); 155398a63aafSMarcel Holtmann if (!ret && hdev->post_init) 155498a63aafSMarcel Holtmann ret = hdev->post_init(hdev); 155598a63aafSMarcel Holtmann } 15561da177e4SLinus Torvalds } 15571da177e4SLinus Torvalds 15587e995b9eSMarcel Holtmann /* If the HCI Reset command is clearing all diagnostic settings, 15597e995b9eSMarcel Holtmann * then they need to be reprogrammed after the init procedure 15607e995b9eSMarcel Holtmann * completed. 15617e995b9eSMarcel Holtmann */ 15627e995b9eSMarcel Holtmann if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) && 1563b56c7b25SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 15647e995b9eSMarcel Holtmann hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag) 15657e995b9eSMarcel Holtmann ret = hdev->set_diag(hdev, true); 15667e995b9eSMarcel Holtmann 1567145373cbSMiao-chen Chou msft_do_open(hdev); 1568145373cbSMiao-chen Chou 1569f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1570f41c70c4SMarcel Holtmann 15711da177e4SLinus Torvalds if (!ret) { 15721da177e4SLinus Torvalds hci_dev_hold(hdev); 1573a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); 1574a73c046aSJaganath Kanakkassery hci_adv_instances_set_rpa_expired(hdev, true); 15751da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 157605fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UP); 15776d5d2ee6SHeiner Kallweit hci_leds_update_powered(hdev, true); 1578d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 1579d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG) && 1580d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 1581d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 15822ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 1583ca8bee5dSMarcel Holtmann hdev->dev_type == HCI_PRIMARY) { 15842ff13894SJohan Hedberg ret = __hci_req_hci_power_on(hdev); 15852ff13894SJohan Hedberg mgmt_power_on(hdev, ret); 158656e5cb86SJohan Hedberg } 15871da177e4SLinus Torvalds } else { 15881da177e4SLinus Torvalds /* Init failed, cleanup */ 15893eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1590c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 1591b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 15921da177e4SLinus Torvalds 15931da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 15941da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 15951da177e4SLinus Torvalds 15961da177e4SLinus Torvalds if (hdev->flush) 15971da177e4SLinus Torvalds hdev->flush(hdev); 15981da177e4SLinus Torvalds 15991da177e4SLinus Torvalds if (hdev->sent_cmd) { 16001da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 16011da177e4SLinus Torvalds hdev->sent_cmd = NULL; 16021da177e4SLinus Torvalds } 16031da177e4SLinus Torvalds 1604e9ca8bf1SMarcel Holtmann clear_bit(HCI_RUNNING, &hdev->flags); 160505fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_CLOSE); 16064a3f95b7SMarcel Holtmann 16071da177e4SLinus Torvalds hdev->close(hdev); 1608fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 16091da177e4SLinus Torvalds } 16101da177e4SLinus Torvalds 16111da177e4SLinus Torvalds done: 1612b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 16131da177e4SLinus Torvalds return ret; 16141da177e4SLinus Torvalds } 16151da177e4SLinus Torvalds 1616cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 1617cbed0ca1SJohan Hedberg 1618cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 1619cbed0ca1SJohan Hedberg { 1620cbed0ca1SJohan Hedberg struct hci_dev *hdev; 1621cbed0ca1SJohan Hedberg int err; 1622cbed0ca1SJohan Hedberg 1623cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 1624cbed0ca1SJohan Hedberg if (!hdev) 1625cbed0ca1SJohan Hedberg return -ENODEV; 1626cbed0ca1SJohan Hedberg 16274a964404SMarcel Holtmann /* Devices that are marked as unconfigured can only be powered 1628fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices 1629fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is 1630fee746b0SMarcel Holtmann * possible. 1631fee746b0SMarcel Holtmann * 1632fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag 1633fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to 1634fee746b0SMarcel Holtmann * open the device. 1635fee746b0SMarcel Holtmann */ 1636d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 1637d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 1638fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1639fee746b0SMarcel Holtmann goto done; 1640fee746b0SMarcel Holtmann } 1641fee746b0SMarcel Holtmann 1642e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 1643e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 1644e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 1645e1d08f40SJohan Hedberg * completed. 1646e1d08f40SJohan Hedberg */ 1647a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 1648e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 1649e1d08f40SJohan Hedberg 1650a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 1651a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 1652a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 1653a5c8f270SMarcel Holtmann */ 1654e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 1655e1d08f40SJohan Hedberg 165612aa4f0aSMarcel Holtmann /* For controllers not using the management interface and that 1657b6ae8457SJohan Hedberg * are brought up using legacy ioctl, set the HCI_BONDABLE bit 165812aa4f0aSMarcel Holtmann * so that pairing works for them. Once the management interface 165912aa4f0aSMarcel Holtmann * is in use this bit will be cleared again and userspace has 166012aa4f0aSMarcel Holtmann * to explicitly enable it. 166112aa4f0aSMarcel Holtmann */ 1662d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1663d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_MGMT)) 1664a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BONDABLE); 166512aa4f0aSMarcel Holtmann 1666cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 1667cbed0ca1SJohan Hedberg 1668fee746b0SMarcel Holtmann done: 1669cbed0ca1SJohan Hedberg hci_dev_put(hdev); 1670cbed0ca1SJohan Hedberg return err; 1671cbed0ca1SJohan Hedberg } 1672cbed0ca1SJohan Hedberg 1673d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */ 1674d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev) 1675d7347f3cSJohan Hedberg { 1676d7347f3cSJohan Hedberg struct hci_conn_params *p; 1677d7347f3cSJohan Hedberg 1678f161dd41SJohan Hedberg list_for_each_entry(p, &hdev->le_conn_params, list) { 1679f161dd41SJohan Hedberg if (p->conn) { 1680f161dd41SJohan Hedberg hci_conn_drop(p->conn); 1681f8aaf9b6SJohan Hedberg hci_conn_put(p->conn); 1682f161dd41SJohan Hedberg p->conn = NULL; 1683f161dd41SJohan Hedberg } 1684d7347f3cSJohan Hedberg list_del_init(&p->action); 1685f161dd41SJohan Hedberg } 1686d7347f3cSJohan Hedberg 1687d7347f3cSJohan Hedberg BT_DBG("All LE pending actions cleared"); 1688d7347f3cSJohan Hedberg } 1689d7347f3cSJohan Hedberg 16906b3cc1dbSSimon Fels int hci_dev_do_close(struct hci_dev *hdev) 16911da177e4SLinus Torvalds { 1692acc649c6SMarcel Holtmann bool auto_off; 1693acc649c6SMarcel Holtmann 16941da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 16951da177e4SLinus Torvalds 1696d24d8144SGabriele Mazzotta if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && 1697867146a0SLoic Poulain !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1698d24d8144SGabriele Mazzotta test_bit(HCI_UP, &hdev->flags)) { 1699a44fecbdSTedd Ho-Jeong An /* Execute vendor specific shutdown routine */ 1700a44fecbdSTedd Ho-Jeong An if (hdev->shutdown) 1701a44fecbdSTedd Ho-Jeong An hdev->shutdown(hdev); 1702a44fecbdSTedd Ho-Jeong An } 1703a44fecbdSTedd Ho-Jeong An 170478c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 170578c04c0bSVinicius Costa Gomes 17067df0f73eSJohan Hedberg hci_request_cancel_all(hdev); 1707b504430cSJohan Hedberg hci_req_sync_lock(hdev); 17081da177e4SLinus Torvalds 17091da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 171065cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 1711b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 17121da177e4SLinus Torvalds return 0; 17131da177e4SLinus Torvalds } 17141da177e4SLinus Torvalds 17156d5d2ee6SHeiner Kallweit hci_leds_update_powered(hdev, false); 17166d5d2ee6SHeiner Kallweit 17173eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 17183eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1719b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 17201da177e4SLinus Torvalds 172116ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 172216ab91abSJohan Hedberg hdev->discov_timeout = 0; 1723a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_DISCOVERABLE); 1724a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 172516ab91abSJohan Hedberg } 172616ab91abSJohan Hedberg 1727a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE)) 17287d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 17297d78525dSJohan Hedberg 1730a73c046aSJaganath Kanakkassery if (hci_dev_test_flag(hdev, HCI_MGMT)) { 1731a73c046aSJaganath Kanakkassery struct adv_info *adv_instance; 1732a73c046aSJaganath Kanakkassery 1733d6bfd59cSJohan Hedberg cancel_delayed_work_sync(&hdev->rpa_expired); 17347ba8b4beSAndre Guedes 1735a73c046aSJaganath Kanakkassery list_for_each_entry(adv_instance, &hdev->adv_instances, list) 1736a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 1737a73c046aSJaganath Kanakkassery } 1738a73c046aSJaganath Kanakkassery 173976727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 174076727c02SJohan Hedberg * ensuring the workqueue is empty up front. 174176727c02SJohan Hedberg */ 174276727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 174376727c02SJohan Hedberg 174409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 17451aeb9c65SJohan Hedberg 17468f502f84SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 17478f502f84SJohan Hedberg 1748acc649c6SMarcel Holtmann auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF); 1749acc649c6SMarcel Holtmann 1750ca8bee5dSMarcel Holtmann if (!auto_off && hdev->dev_type == HCI_PRIMARY && 1751baab7932SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 17522ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT)) 17532ff13894SJohan Hedberg __mgmt_power_off(hdev); 17541aeb9c65SJohan Hedberg 17551f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 1756d7347f3cSJohan Hedberg hci_pend_le_actions_clear(hdev); 1757f161dd41SJohan Hedberg hci_conn_hash_flush(hdev); 175809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 17591da177e4SLinus Torvalds 176064dae967SMarcel Holtmann smp_unregister(hdev); 176164dae967SMarcel Holtmann 176205fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_DOWN); 17631da177e4SLinus Torvalds 1764145373cbSMiao-chen Chou msft_do_close(hdev); 1765145373cbSMiao-chen Chou 17661da177e4SLinus Torvalds if (hdev->flush) 17671da177e4SLinus Torvalds hdev->flush(hdev); 17681da177e4SLinus Torvalds 17691da177e4SLinus Torvalds /* Reset device */ 17701da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 17711da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 1772acc649c6SMarcel Holtmann if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) && 1773acc649c6SMarcel Holtmann !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 17741da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 17754ebeee2dSJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL); 17761da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 17771da177e4SLinus Torvalds } 17781da177e4SLinus Torvalds 1779c347b765SGustavo F. Padovan /* flush cmd work */ 1780c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 17811da177e4SLinus Torvalds 17821da177e4SLinus Torvalds /* Drop queues */ 17831da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 17841da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 17851da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 17861da177e4SLinus Torvalds 17871da177e4SLinus Torvalds /* Drop last sent command */ 17881da177e4SLinus Torvalds if (hdev->sent_cmd) { 178965cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 17901da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 17911da177e4SLinus Torvalds hdev->sent_cmd = NULL; 17921da177e4SLinus Torvalds } 17931da177e4SLinus Torvalds 1794e9ca8bf1SMarcel Holtmann clear_bit(HCI_RUNNING, &hdev->flags); 179505fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_CLOSE); 17964a3f95b7SMarcel Holtmann 17979952d90eSAbhishek Pandit-Subedi if (test_and_clear_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks)) 17989952d90eSAbhishek Pandit-Subedi wake_up(&hdev->suspend_wait_q); 17999952d90eSAbhishek Pandit-Subedi 18001da177e4SLinus Torvalds /* After this point our queues are empty 18011da177e4SLinus Torvalds * and no tasks are scheduled. */ 18021da177e4SLinus Torvalds hdev->close(hdev); 18031da177e4SLinus Torvalds 180435b973c9SJohan Hedberg /* Clear flags */ 1805fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 1806eacb44dfSMarcel Holtmann hci_dev_clear_volatile_flags(hdev); 180735b973c9SJohan Hedberg 1808ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 1809536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 1810ced5c338SAndrei Emeltchenko 1811e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 181209b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 18137a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, BDADDR_ANY); 1814e59fda8dSJohan Hedberg 1815b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 18161da177e4SLinus Torvalds 18171da177e4SLinus Torvalds hci_dev_put(hdev); 18181da177e4SLinus Torvalds return 0; 18191da177e4SLinus Torvalds } 18201da177e4SLinus Torvalds 18211da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 18221da177e4SLinus Torvalds { 18231da177e4SLinus Torvalds struct hci_dev *hdev; 18241da177e4SLinus Torvalds int err; 18251da177e4SLinus Torvalds 182670f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 182770f23020SAndrei Emeltchenko if (!hdev) 18281da177e4SLinus Torvalds return -ENODEV; 18298ee56540SMarcel Holtmann 1830d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 18310736cfa8SMarcel Holtmann err = -EBUSY; 18320736cfa8SMarcel Holtmann goto done; 18330736cfa8SMarcel Holtmann } 18340736cfa8SMarcel Holtmann 1835a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 18368ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 18378ee56540SMarcel Holtmann 18381da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 18398ee56540SMarcel Holtmann 18400736cfa8SMarcel Holtmann done: 18411da177e4SLinus Torvalds hci_dev_put(hdev); 18421da177e4SLinus Torvalds return err; 18431da177e4SLinus Torvalds } 18441da177e4SLinus Torvalds 18455c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev) 18461da177e4SLinus Torvalds { 18475c912495SMarcel Holtmann int ret; 18481da177e4SLinus Torvalds 18495c912495SMarcel Holtmann BT_DBG("%s %p", hdev->name, hdev); 18501da177e4SLinus Torvalds 1851b504430cSJohan Hedberg hci_req_sync_lock(hdev); 18521da177e4SLinus Torvalds 18531da177e4SLinus Torvalds /* Drop queues */ 18541da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 18551da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 18561da177e4SLinus Torvalds 185776727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 185876727c02SJohan Hedberg * ensuring the workqueue is empty up front. 185976727c02SJohan Hedberg */ 186076727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 186176727c02SJohan Hedberg 186209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 18631f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 18641da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 186509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18661da177e4SLinus Torvalds 18671da177e4SLinus Torvalds if (hdev->flush) 18681da177e4SLinus Torvalds hdev->flush(hdev); 18691da177e4SLinus Torvalds 18701da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 18716ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 18721da177e4SLinus Torvalds 18734ebeee2dSJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT, NULL); 18741da177e4SLinus Torvalds 1875b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 18761da177e4SLinus Torvalds return ret; 18771da177e4SLinus Torvalds } 18781da177e4SLinus Torvalds 18795c912495SMarcel Holtmann int hci_dev_reset(__u16 dev) 18805c912495SMarcel Holtmann { 18815c912495SMarcel Holtmann struct hci_dev *hdev; 18825c912495SMarcel Holtmann int err; 18835c912495SMarcel Holtmann 18845c912495SMarcel Holtmann hdev = hci_dev_get(dev); 18855c912495SMarcel Holtmann if (!hdev) 18865c912495SMarcel Holtmann return -ENODEV; 18875c912495SMarcel Holtmann 18885c912495SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 18895c912495SMarcel Holtmann err = -ENETDOWN; 18905c912495SMarcel Holtmann goto done; 18915c912495SMarcel Holtmann } 18925c912495SMarcel Holtmann 1893d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 18945c912495SMarcel Holtmann err = -EBUSY; 18955c912495SMarcel Holtmann goto done; 18965c912495SMarcel Holtmann } 18975c912495SMarcel Holtmann 1898d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 18995c912495SMarcel Holtmann err = -EOPNOTSUPP; 19005c912495SMarcel Holtmann goto done; 19015c912495SMarcel Holtmann } 19025c912495SMarcel Holtmann 19035c912495SMarcel Holtmann err = hci_dev_do_reset(hdev); 19045c912495SMarcel Holtmann 19055c912495SMarcel Holtmann done: 19065c912495SMarcel Holtmann hci_dev_put(hdev); 19075c912495SMarcel Holtmann return err; 19085c912495SMarcel Holtmann } 19095c912495SMarcel Holtmann 19101da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 19111da177e4SLinus Torvalds { 19121da177e4SLinus Torvalds struct hci_dev *hdev; 19131da177e4SLinus Torvalds int ret = 0; 19141da177e4SLinus Torvalds 191570f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 191670f23020SAndrei Emeltchenko if (!hdev) 19171da177e4SLinus Torvalds return -ENODEV; 19181da177e4SLinus Torvalds 1919d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 19200736cfa8SMarcel Holtmann ret = -EBUSY; 19210736cfa8SMarcel Holtmann goto done; 19220736cfa8SMarcel Holtmann } 19230736cfa8SMarcel Holtmann 1924d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1925fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 1926fee746b0SMarcel Holtmann goto done; 1927fee746b0SMarcel Holtmann } 1928fee746b0SMarcel Holtmann 19291da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 19301da177e4SLinus Torvalds 19310736cfa8SMarcel Holtmann done: 19321da177e4SLinus Torvalds hci_dev_put(hdev); 19331da177e4SLinus Torvalds return ret; 19341da177e4SLinus Torvalds } 19351da177e4SLinus Torvalds 1936123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan) 1937123abc08SJohan Hedberg { 1938bc6d2d04SJohan Hedberg bool conn_changed, discov_changed; 1939123abc08SJohan Hedberg 1940123abc08SJohan Hedberg BT_DBG("%s scan 0x%02x", hdev->name, scan); 1941123abc08SJohan Hedberg 1942123abc08SJohan Hedberg if ((scan & SCAN_PAGE)) 1943238be788SMarcel Holtmann conn_changed = !hci_dev_test_and_set_flag(hdev, 1944238be788SMarcel Holtmann HCI_CONNECTABLE); 1945123abc08SJohan Hedberg else 1946a69d8927SMarcel Holtmann conn_changed = hci_dev_test_and_clear_flag(hdev, 1947a69d8927SMarcel Holtmann HCI_CONNECTABLE); 1948123abc08SJohan Hedberg 1949bc6d2d04SJohan Hedberg if ((scan & SCAN_INQUIRY)) { 1950238be788SMarcel Holtmann discov_changed = !hci_dev_test_and_set_flag(hdev, 1951238be788SMarcel Holtmann HCI_DISCOVERABLE); 1952bc6d2d04SJohan Hedberg } else { 1953a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 1954a69d8927SMarcel Holtmann discov_changed = hci_dev_test_and_clear_flag(hdev, 1955a69d8927SMarcel Holtmann HCI_DISCOVERABLE); 1956bc6d2d04SJohan Hedberg } 1957bc6d2d04SJohan Hedberg 1958d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 1959123abc08SJohan Hedberg return; 1960123abc08SJohan Hedberg 1961bc6d2d04SJohan Hedberg if (conn_changed || discov_changed) { 1962bc6d2d04SJohan Hedberg /* In case this was disabled through mgmt */ 1963a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 1964bc6d2d04SJohan Hedberg 1965d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 1966cab054abSJohan Hedberg hci_req_update_adv_data(hdev, hdev->cur_adv_instance); 1967bc6d2d04SJohan Hedberg 1968123abc08SJohan Hedberg mgmt_new_settings(hdev); 1969123abc08SJohan Hedberg } 1970bc6d2d04SJohan Hedberg } 1971123abc08SJohan Hedberg 19721da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 19731da177e4SLinus Torvalds { 19741da177e4SLinus Torvalds struct hci_dev *hdev; 19751da177e4SLinus Torvalds struct hci_dev_req dr; 19761da177e4SLinus Torvalds int err = 0; 19771da177e4SLinus Torvalds 19781da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 19791da177e4SLinus Torvalds return -EFAULT; 19801da177e4SLinus Torvalds 198170f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 198270f23020SAndrei Emeltchenko if (!hdev) 19831da177e4SLinus Torvalds return -ENODEV; 19841da177e4SLinus Torvalds 1985d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 19860736cfa8SMarcel Holtmann err = -EBUSY; 19870736cfa8SMarcel Holtmann goto done; 19880736cfa8SMarcel Holtmann } 19890736cfa8SMarcel Holtmann 1990d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1991fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1992fee746b0SMarcel Holtmann goto done; 1993fee746b0SMarcel Holtmann } 1994fee746b0SMarcel Holtmann 1995ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 19965b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 19975b69bef5SMarcel Holtmann goto done; 19985b69bef5SMarcel Holtmann } 19995b69bef5SMarcel Holtmann 2000d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 200156f87901SJohan Hedberg err = -EOPNOTSUPP; 200256f87901SJohan Hedberg goto done; 200356f87901SJohan Hedberg } 200456f87901SJohan Hedberg 20051da177e4SLinus Torvalds switch (cmd) { 20061da177e4SLinus Torvalds case HCISETAUTH: 200701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 20084ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20091da177e4SLinus Torvalds break; 20101da177e4SLinus Torvalds 20111da177e4SLinus Torvalds case HCISETENCRYPT: 20121da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 20131da177e4SLinus Torvalds err = -EOPNOTSUPP; 20141da177e4SLinus Torvalds break; 20151da177e4SLinus Torvalds } 20161da177e4SLinus Torvalds 20171da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 20181da177e4SLinus Torvalds /* Auth must be enabled first */ 201901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 20204ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20211da177e4SLinus Torvalds if (err) 20221da177e4SLinus Torvalds break; 20231da177e4SLinus Torvalds } 20241da177e4SLinus Torvalds 202501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 20264ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20271da177e4SLinus Torvalds break; 20281da177e4SLinus Torvalds 20291da177e4SLinus Torvalds case HCISETSCAN: 203001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 20314ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 203291a668b0SJohan Hedberg 2033bc6d2d04SJohan Hedberg /* Ensure that the connectable and discoverable states 2034bc6d2d04SJohan Hedberg * get correctly modified as this was a non-mgmt change. 203591a668b0SJohan Hedberg */ 2036123abc08SJohan Hedberg if (!err) 2037123abc08SJohan Hedberg hci_update_scan_state(hdev, dr.dev_opt); 20381da177e4SLinus Torvalds break; 20391da177e4SLinus Torvalds 20401da177e4SLinus Torvalds case HCISETLINKPOL: 204101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 20424ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 20431da177e4SLinus Torvalds break; 20441da177e4SLinus Torvalds 20451da177e4SLinus Torvalds case HCISETLINKMODE: 2046e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2047e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2048e4e8e37cSMarcel Holtmann break; 2049e4e8e37cSMarcel Holtmann 2050e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2051b7c23df8SJaganath Kanakkassery if (hdev->pkt_type == (__u16) dr.dev_opt) 2052b7c23df8SJaganath Kanakkassery break; 2053b7c23df8SJaganath Kanakkassery 2054e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 2055b7c23df8SJaganath Kanakkassery mgmt_phy_configuration_changed(hdev, NULL); 20561da177e4SLinus Torvalds break; 20571da177e4SLinus Torvalds 20581da177e4SLinus Torvalds case HCISETACLMTU: 20591da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 20601da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 20611da177e4SLinus Torvalds break; 20621da177e4SLinus Torvalds 20631da177e4SLinus Torvalds case HCISETSCOMTU: 20641da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 20651da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 20661da177e4SLinus Torvalds break; 20671da177e4SLinus Torvalds 20681da177e4SLinus Torvalds default: 20691da177e4SLinus Torvalds err = -EINVAL; 20701da177e4SLinus Torvalds break; 20711da177e4SLinus Torvalds } 2072e4e8e37cSMarcel Holtmann 20730736cfa8SMarcel Holtmann done: 20741da177e4SLinus Torvalds hci_dev_put(hdev); 20751da177e4SLinus Torvalds return err; 20761da177e4SLinus Torvalds } 20771da177e4SLinus Torvalds 20781da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 20791da177e4SLinus Torvalds { 20808035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 20811da177e4SLinus Torvalds struct hci_dev_list_req *dl; 20821da177e4SLinus Torvalds struct hci_dev_req *dr; 20831da177e4SLinus Torvalds int n = 0, size, err; 20841da177e4SLinus Torvalds __u16 dev_num; 20851da177e4SLinus Torvalds 20861da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 20871da177e4SLinus Torvalds return -EFAULT; 20881da177e4SLinus Torvalds 20891da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 20901da177e4SLinus Torvalds return -EINVAL; 20911da177e4SLinus Torvalds 20921da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 20931da177e4SLinus Torvalds 209470f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 209570f23020SAndrei Emeltchenko if (!dl) 20961da177e4SLinus Torvalds return -ENOMEM; 20971da177e4SLinus Torvalds 20981da177e4SLinus Torvalds dr = dl->dev_req; 20991da177e4SLinus Torvalds 2100f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 21018035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 21022e84d8dbSMarcel Holtmann unsigned long flags = hdev->flags; 2103c542a06cSJohan Hedberg 21042e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 21052e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 21062e84d8dbSMarcel Holtmann * device is actually down. 21072e84d8dbSMarcel Holtmann */ 2108d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 21092e84d8dbSMarcel Holtmann flags &= ~BIT(HCI_UP); 2110c542a06cSJohan Hedberg 21111da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 21122e84d8dbSMarcel Holtmann (dr + n)->dev_opt = flags; 2113c542a06cSJohan Hedberg 21141da177e4SLinus Torvalds if (++n >= dev_num) 21151da177e4SLinus Torvalds break; 21161da177e4SLinus Torvalds } 2117f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 21181da177e4SLinus Torvalds 21191da177e4SLinus Torvalds dl->dev_num = n; 21201da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 21211da177e4SLinus Torvalds 21221da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 21231da177e4SLinus Torvalds kfree(dl); 21241da177e4SLinus Torvalds 21251da177e4SLinus Torvalds return err ? -EFAULT : 0; 21261da177e4SLinus Torvalds } 21271da177e4SLinus Torvalds 21281da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 21291da177e4SLinus Torvalds { 21301da177e4SLinus Torvalds struct hci_dev *hdev; 21311da177e4SLinus Torvalds struct hci_dev_info di; 21322e84d8dbSMarcel Holtmann unsigned long flags; 21331da177e4SLinus Torvalds int err = 0; 21341da177e4SLinus Torvalds 21351da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 21361da177e4SLinus Torvalds return -EFAULT; 21371da177e4SLinus Torvalds 213870f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 213970f23020SAndrei Emeltchenko if (!hdev) 21401da177e4SLinus Torvalds return -ENODEV; 21411da177e4SLinus Torvalds 21422e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 21432e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 21442e84d8dbSMarcel Holtmann * device is actually down. 21452e84d8dbSMarcel Holtmann */ 2146d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 21472e84d8dbSMarcel Holtmann flags = hdev->flags & ~BIT(HCI_UP); 21482e84d8dbSMarcel Holtmann else 21492e84d8dbSMarcel Holtmann flags = hdev->flags; 2150c542a06cSJohan Hedberg 21511da177e4SLinus Torvalds strcpy(di.name, hdev->name); 21521da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 215360f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 21542e84d8dbSMarcel Holtmann di.flags = flags; 21551da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2156572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 21571da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 21581da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 21591da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 21601da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2161572c7f84SJohan Hedberg } else { 2162572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2163572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2164572c7f84SJohan Hedberg di.sco_mtu = 0; 2165572c7f84SJohan Hedberg di.sco_pkts = 0; 2166572c7f84SJohan Hedberg } 21671da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 21681da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 21691da177e4SLinus Torvalds 21701da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 21711da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 21721da177e4SLinus Torvalds 21731da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 21741da177e4SLinus Torvalds err = -EFAULT; 21751da177e4SLinus Torvalds 21761da177e4SLinus Torvalds hci_dev_put(hdev); 21771da177e4SLinus Torvalds 21781da177e4SLinus Torvalds return err; 21791da177e4SLinus Torvalds } 21801da177e4SLinus Torvalds 21811da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 21821da177e4SLinus Torvalds 2183611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2184611b30f7SMarcel Holtmann { 2185611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2186611b30f7SMarcel Holtmann 2187611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2188611b30f7SMarcel Holtmann 2189d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) 21900736cfa8SMarcel Holtmann return -EBUSY; 21910736cfa8SMarcel Holtmann 21925e130367SJohan Hedberg if (blocked) { 2193a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 2194d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 2195d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 2196611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 21975e130367SJohan Hedberg } else { 2198a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_RFKILLED); 21995e130367SJohan Hedberg } 2200611b30f7SMarcel Holtmann 2201611b30f7SMarcel Holtmann return 0; 2202611b30f7SMarcel Holtmann } 2203611b30f7SMarcel Holtmann 2204611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2205611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2206611b30f7SMarcel Holtmann }; 2207611b30f7SMarcel Holtmann 2208ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2209ab81cbf9SJohan Hedberg { 2210ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 221196570ffcSJohan Hedberg int err; 2212ab81cbf9SJohan Hedberg 2213ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2214ab81cbf9SJohan Hedberg 22152ff13894SJohan Hedberg if (test_bit(HCI_UP, &hdev->flags) && 22162ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 22172ff13894SJohan Hedberg hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) { 2218d82142a8SWei-Ning Huang cancel_delayed_work(&hdev->power_off); 22192ff13894SJohan Hedberg hci_req_sync_lock(hdev); 22202ff13894SJohan Hedberg err = __hci_req_hci_power_on(hdev); 22212ff13894SJohan Hedberg hci_req_sync_unlock(hdev); 22222ff13894SJohan Hedberg mgmt_power_on(hdev, err); 22232ff13894SJohan Hedberg return; 22242ff13894SJohan Hedberg } 22252ff13894SJohan Hedberg 2226cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 222796570ffcSJohan Hedberg if (err < 0) { 22283ad67582SJaganath Kanakkassery hci_dev_lock(hdev); 222996570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 22303ad67582SJaganath Kanakkassery hci_dev_unlock(hdev); 2231ab81cbf9SJohan Hedberg return; 223296570ffcSJohan Hedberg } 2233ab81cbf9SJohan Hedberg 2234a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2235a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2236a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2237a5c8f270SMarcel Holtmann */ 2238d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED) || 2239d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_UNCONFIGURED) || 2240ca8bee5dSMarcel Holtmann (hdev->dev_type == HCI_PRIMARY && 2241a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2242a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2243a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_AUTO_OFF); 2244bf543036SJohan Hedberg hci_dev_do_close(hdev); 2245d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) { 224619202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 224719202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2248bf543036SJohan Hedberg } 2249ab81cbf9SJohan Hedberg 2250a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) { 22514a964404SMarcel Holtmann /* For unconfigured devices, set the HCI_RAW flag 22524a964404SMarcel Holtmann * so that userspace can easily identify them. 22534a964404SMarcel Holtmann */ 2254d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 22554a964404SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 22560602a8adSMarcel Holtmann 22570602a8adSMarcel Holtmann /* For fully configured devices, this will send 22580602a8adSMarcel Holtmann * the Index Added event. For unconfigured devices, 22590602a8adSMarcel Holtmann * it will send Unconfigued Index Added event. 22600602a8adSMarcel Holtmann * 22610602a8adSMarcel Holtmann * Devices with HCI_QUIRK_RAW_DEVICE are ignored 22620602a8adSMarcel Holtmann * and no event will be send. 22630602a8adSMarcel Holtmann */ 2264744cf19eSJohan Hedberg mgmt_index_added(hdev); 2265a69d8927SMarcel Holtmann } else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) { 22665ea234d3SMarcel Holtmann /* When the controller is now configured, then it 22675ea234d3SMarcel Holtmann * is important to clear the HCI_RAW flag. 22685ea234d3SMarcel Holtmann */ 2269d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 22705ea234d3SMarcel Holtmann clear_bit(HCI_RAW, &hdev->flags); 22715ea234d3SMarcel Holtmann 2272d603b76bSMarcel Holtmann /* Powering on the controller with HCI_CONFIG set only 2273d603b76bSMarcel Holtmann * happens with the transition from unconfigured to 2274d603b76bSMarcel Holtmann * configured. This will send the Index Added event. 2275d603b76bSMarcel Holtmann */ 2276d603b76bSMarcel Holtmann mgmt_index_added(hdev); 2277ab81cbf9SJohan Hedberg } 2278ab81cbf9SJohan Hedberg } 2279ab81cbf9SJohan Hedberg 2280ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2281ab81cbf9SJohan Hedberg { 22823243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 22833243553fSJohan Hedberg power_off.work); 2284ab81cbf9SJohan Hedberg 2285ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2286ab81cbf9SJohan Hedberg 22878ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2288ab81cbf9SJohan Hedberg } 2289ab81cbf9SJohan Hedberg 2290c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work) 2291c7741d16SMarcel Holtmann { 2292c7741d16SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset); 2293c7741d16SMarcel Holtmann 2294c7741d16SMarcel Holtmann BT_DBG("%s", hdev->name); 2295c7741d16SMarcel Holtmann 2296c7741d16SMarcel Holtmann if (hdev->hw_error) 2297c7741d16SMarcel Holtmann hdev->hw_error(hdev, hdev->hw_error_code); 2298c7741d16SMarcel Holtmann else 22992064ee33SMarcel Holtmann bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code); 2300c7741d16SMarcel Holtmann 2301c7741d16SMarcel Holtmann if (hci_dev_do_close(hdev)) 2302c7741d16SMarcel Holtmann return; 2303c7741d16SMarcel Holtmann 2304c7741d16SMarcel Holtmann hci_dev_do_open(hdev); 2305c7741d16SMarcel Holtmann } 2306c7741d16SMarcel Holtmann 230735f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 23082aeb9a1aSJohan Hedberg { 23094821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 23102aeb9a1aSJohan Hedberg 23114821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 23124821002cSJohan Hedberg list_del(&uuid->list); 23132aeb9a1aSJohan Hedberg kfree(uuid); 23142aeb9a1aSJohan Hedberg } 23152aeb9a1aSJohan Hedberg } 23162aeb9a1aSJohan Hedberg 231735f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 231855ed8ca1SJohan Hedberg { 231955ed8ca1SJohan Hedberg struct link_key *key; 232055ed8ca1SJohan Hedberg 2321d7d41682SMadhuparna Bhowmik list_for_each_entry(key, &hdev->link_keys, list) { 23220378b597SJohan Hedberg list_del_rcu(&key->list); 23230378b597SJohan Hedberg kfree_rcu(key, rcu); 232455ed8ca1SJohan Hedberg } 232555ed8ca1SJohan Hedberg } 232655ed8ca1SJohan Hedberg 232735f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2328b899efafSVinicius Costa Gomes { 2329970d0f1bSJohan Hedberg struct smp_ltk *k; 2330b899efafSVinicius Costa Gomes 2331d7d41682SMadhuparna Bhowmik list_for_each_entry(k, &hdev->long_term_keys, list) { 2332970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2333970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2334b899efafSVinicius Costa Gomes } 2335b899efafSVinicius Costa Gomes } 2336b899efafSVinicius Costa Gomes 2337970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2338970c4e46SJohan Hedberg { 2339adae20cbSJohan Hedberg struct smp_irk *k; 2340970c4e46SJohan Hedberg 2341d7d41682SMadhuparna Bhowmik list_for_each_entry(k, &hdev->identity_resolving_keys, list) { 2342adae20cbSJohan Hedberg list_del_rcu(&k->list); 2343adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2344970c4e46SJohan Hedberg } 2345970c4e46SJohan Hedberg } 2346970c4e46SJohan Hedberg 2347600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev) 2348600a8749SAlain Michaud { 2349600a8749SAlain Michaud struct blocked_key *b; 2350600a8749SAlain Michaud 2351d7d41682SMadhuparna Bhowmik list_for_each_entry(b, &hdev->blocked_keys, list) { 2352600a8749SAlain Michaud list_del_rcu(&b->list); 2353600a8749SAlain Michaud kfree_rcu(b, rcu); 2354600a8749SAlain Michaud } 2355600a8749SAlain Michaud } 2356600a8749SAlain Michaud 2357600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16]) 2358600a8749SAlain Michaud { 2359600a8749SAlain Michaud bool blocked = false; 2360600a8749SAlain Michaud struct blocked_key *b; 2361600a8749SAlain Michaud 2362600a8749SAlain Michaud rcu_read_lock(); 23630c2ac7d4SMadhuparna Bhowmik list_for_each_entry_rcu(b, &hdev->blocked_keys, list) { 2364600a8749SAlain Michaud if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) { 2365600a8749SAlain Michaud blocked = true; 2366600a8749SAlain Michaud break; 2367600a8749SAlain Michaud } 2368600a8749SAlain Michaud } 2369600a8749SAlain Michaud 2370600a8749SAlain Michaud rcu_read_unlock(); 2371600a8749SAlain Michaud return blocked; 2372600a8749SAlain Michaud } 2373600a8749SAlain Michaud 237455ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 237555ed8ca1SJohan Hedberg { 237655ed8ca1SJohan Hedberg struct link_key *k; 237755ed8ca1SJohan Hedberg 23780378b597SJohan Hedberg rcu_read_lock(); 23790378b597SJohan Hedberg list_for_each_entry_rcu(k, &hdev->link_keys, list) { 23800378b597SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) { 23810378b597SJohan Hedberg rcu_read_unlock(); 2382600a8749SAlain Michaud 2383600a8749SAlain Michaud if (hci_is_blocked_key(hdev, 2384600a8749SAlain Michaud HCI_BLOCKED_KEY_TYPE_LINKKEY, 2385600a8749SAlain Michaud k->val)) { 2386600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, 2387600a8749SAlain Michaud "Link key blocked for %pMR", 2388600a8749SAlain Michaud &k->bdaddr); 2389600a8749SAlain Michaud return NULL; 2390600a8749SAlain Michaud } 2391600a8749SAlain Michaud 239255ed8ca1SJohan Hedberg return k; 23930378b597SJohan Hedberg } 23940378b597SJohan Hedberg } 23950378b597SJohan Hedberg rcu_read_unlock(); 239655ed8ca1SJohan Hedberg 239755ed8ca1SJohan Hedberg return NULL; 239855ed8ca1SJohan Hedberg } 239955ed8ca1SJohan Hedberg 2400745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2401d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2402d25e28abSJohan Hedberg { 2403d25e28abSJohan Hedberg /* Legacy key */ 2404d25e28abSJohan Hedberg if (key_type < 0x03) 2405745c0ce3SVishal Agarwal return true; 2406d25e28abSJohan Hedberg 2407d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2408d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2409745c0ce3SVishal Agarwal return false; 2410d25e28abSJohan Hedberg 2411d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2412d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2413745c0ce3SVishal Agarwal return false; 2414d25e28abSJohan Hedberg 2415d25e28abSJohan Hedberg /* Security mode 3 case */ 2416d25e28abSJohan Hedberg if (!conn) 2417745c0ce3SVishal Agarwal return true; 2418d25e28abSJohan Hedberg 2419e3befab9SJohan Hedberg /* BR/EDR key derived using SC from an LE link */ 2420e3befab9SJohan Hedberg if (conn->type == LE_LINK) 2421e3befab9SJohan Hedberg return true; 2422e3befab9SJohan Hedberg 2423d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2424d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2425745c0ce3SVishal Agarwal return true; 2426d25e28abSJohan Hedberg 2427d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2428d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2429745c0ce3SVishal Agarwal return true; 2430d25e28abSJohan Hedberg 2431d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2432d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2433745c0ce3SVishal Agarwal return true; 2434d25e28abSJohan Hedberg 2435d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2436d25e28abSJohan Hedberg * persistently */ 2437745c0ce3SVishal Agarwal return false; 2438d25e28abSJohan Hedberg } 2439d25e28abSJohan Hedberg 2440e804d25dSJohan Hedberg static u8 ltk_role(u8 type) 244198a0b845SJohan Hedberg { 2442e804d25dSJohan Hedberg if (type == SMP_LTK) 2443e804d25dSJohan Hedberg return HCI_ROLE_MASTER; 244498a0b845SJohan Hedberg 2445e804d25dSJohan Hedberg return HCI_ROLE_SLAVE; 244698a0b845SJohan Hedberg } 244798a0b845SJohan Hedberg 2448f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2449e804d25dSJohan Hedberg u8 addr_type, u8 role) 245075d262c2SVinicius Costa Gomes { 2451c9839a11SVinicius Costa Gomes struct smp_ltk *k; 245275d262c2SVinicius Costa Gomes 2453970d0f1bSJohan Hedberg rcu_read_lock(); 2454970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 24555378bc56SJohan Hedberg if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr)) 24565378bc56SJohan Hedberg continue; 24575378bc56SJohan Hedberg 2458923e2414SJohan Hedberg if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) { 2459970d0f1bSJohan Hedberg rcu_read_unlock(); 2460600a8749SAlain Michaud 2461600a8749SAlain Michaud if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK, 2462600a8749SAlain Michaud k->val)) { 2463600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, 2464600a8749SAlain Michaud "LTK blocked for %pMR", 2465600a8749SAlain Michaud &k->bdaddr); 2466600a8749SAlain Michaud return NULL; 2467600a8749SAlain Michaud } 2468600a8749SAlain Michaud 246975d262c2SVinicius Costa Gomes return k; 2470970d0f1bSJohan Hedberg } 2471970d0f1bSJohan Hedberg } 2472970d0f1bSJohan Hedberg rcu_read_unlock(); 247375d262c2SVinicius Costa Gomes 247475d262c2SVinicius Costa Gomes return NULL; 247575d262c2SVinicius Costa Gomes } 247675d262c2SVinicius Costa Gomes 2477970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 2478970c4e46SJohan Hedberg { 2479600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL; 2480970c4e46SJohan Hedberg struct smp_irk *irk; 2481970c4e46SJohan Hedberg 2482adae20cbSJohan Hedberg rcu_read_lock(); 2483adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2484adae20cbSJohan Hedberg if (!bacmp(&irk->rpa, rpa)) { 2485600a8749SAlain Michaud irk_to_return = irk; 2486600a8749SAlain Michaud goto done; 2487970c4e46SJohan Hedberg } 2488adae20cbSJohan Hedberg } 2489970c4e46SJohan Hedberg 2490adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2491defce9e8SJohan Hedberg if (smp_irk_matches(hdev, irk->val, rpa)) { 2492970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2493600a8749SAlain Michaud irk_to_return = irk; 2494600a8749SAlain Michaud goto done; 2495970c4e46SJohan Hedberg } 2496970c4e46SJohan Hedberg } 2497600a8749SAlain Michaud 2498600a8749SAlain Michaud done: 2499600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK, 2500600a8749SAlain Michaud irk_to_return->val)) { 2501600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR", 2502600a8749SAlain Michaud &irk_to_return->bdaddr); 2503600a8749SAlain Michaud irk_to_return = NULL; 2504600a8749SAlain Michaud } 2505600a8749SAlain Michaud 2506adae20cbSJohan Hedberg rcu_read_unlock(); 2507970c4e46SJohan Hedberg 2508600a8749SAlain Michaud return irk_to_return; 2509970c4e46SJohan Hedberg } 2510970c4e46SJohan Hedberg 2511970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2512970c4e46SJohan Hedberg u8 addr_type) 2513970c4e46SJohan Hedberg { 2514600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL; 2515970c4e46SJohan Hedberg struct smp_irk *irk; 2516970c4e46SJohan Hedberg 25176cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 25186cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 25196cfc9988SJohan Hedberg return NULL; 25206cfc9988SJohan Hedberg 2521adae20cbSJohan Hedberg rcu_read_lock(); 2522adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2523970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 2524adae20cbSJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) { 2525600a8749SAlain Michaud irk_to_return = irk; 2526600a8749SAlain Michaud goto done; 2527970c4e46SJohan Hedberg } 2528adae20cbSJohan Hedberg } 2529600a8749SAlain Michaud 2530600a8749SAlain Michaud done: 2531600a8749SAlain Michaud 2532600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK, 2533600a8749SAlain Michaud irk_to_return->val)) { 2534600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR", 2535600a8749SAlain Michaud &irk_to_return->bdaddr); 2536600a8749SAlain Michaud irk_to_return = NULL; 2537600a8749SAlain Michaud } 2538600a8749SAlain Michaud 2539adae20cbSJohan Hedberg rcu_read_unlock(); 2540970c4e46SJohan Hedberg 2541600a8749SAlain Michaud return irk_to_return; 2542970c4e46SJohan Hedberg } 2543970c4e46SJohan Hedberg 2544567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 25457652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 25467652ff6aSJohan Hedberg u8 pin_len, bool *persistent) 254755ed8ca1SJohan Hedberg { 254855ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2549745c0ce3SVishal Agarwal u8 old_key_type; 255055ed8ca1SJohan Hedberg 255155ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 255255ed8ca1SJohan Hedberg if (old_key) { 255355ed8ca1SJohan Hedberg old_key_type = old_key->type; 255455ed8ca1SJohan Hedberg key = old_key; 255555ed8ca1SJohan Hedberg } else { 255612adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 25570a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 255855ed8ca1SJohan Hedberg if (!key) 2559567fa2aaSJohan Hedberg return NULL; 25600378b597SJohan Hedberg list_add_rcu(&key->list, &hdev->link_keys); 256155ed8ca1SJohan Hedberg } 256255ed8ca1SJohan Hedberg 25636ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 256455ed8ca1SJohan Hedberg 2565d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2566d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2567d25e28abSJohan Hedberg * previous key */ 2568d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2569a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2570d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2571655fe6ecSJohan Hedberg if (conn) 2572655fe6ecSJohan Hedberg conn->key_type = type; 2573655fe6ecSJohan Hedberg } 2574d25e28abSJohan Hedberg 257555ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 25769b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 257755ed8ca1SJohan Hedberg key->pin_len = pin_len; 257855ed8ca1SJohan Hedberg 2579b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 258055ed8ca1SJohan Hedberg key->type = old_key_type; 25814748fed2SJohan Hedberg else 25824748fed2SJohan Hedberg key->type = type; 25834748fed2SJohan Hedberg 25847652ff6aSJohan Hedberg if (persistent) 25857652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type, 25867652ff6aSJohan Hedberg old_key_type); 25874df378a1SJohan Hedberg 2588567fa2aaSJohan Hedberg return key; 258955ed8ca1SJohan Hedberg } 259055ed8ca1SJohan Hedberg 2591ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 259235d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 2593fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand) 259475d262c2SVinicius Costa Gomes { 2595c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 2596e804d25dSJohan Hedberg u8 role = ltk_role(type); 259775d262c2SVinicius Costa Gomes 2598f3a73d97SJohan Hedberg old_key = hci_find_ltk(hdev, bdaddr, addr_type, role); 2599c9839a11SVinicius Costa Gomes if (old_key) 260075d262c2SVinicius Costa Gomes key = old_key; 2601c9839a11SVinicius Costa Gomes else { 26020a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 260375d262c2SVinicius Costa Gomes if (!key) 2604ca9142b8SJohan Hedberg return NULL; 2605970d0f1bSJohan Hedberg list_add_rcu(&key->list, &hdev->long_term_keys); 260675d262c2SVinicius Costa Gomes } 260775d262c2SVinicius Costa Gomes 260875d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2609c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2610c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2611c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2612c9839a11SVinicius Costa Gomes key->ediv = ediv; 2613fe39c7b2SMarcel Holtmann key->rand = rand; 2614c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2615c9839a11SVinicius Costa Gomes key->type = type; 261675d262c2SVinicius Costa Gomes 2617ca9142b8SJohan Hedberg return key; 261875d262c2SVinicius Costa Gomes } 261975d262c2SVinicius Costa Gomes 2620ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2621ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 2622970c4e46SJohan Hedberg { 2623970c4e46SJohan Hedberg struct smp_irk *irk; 2624970c4e46SJohan Hedberg 2625970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 2626970c4e46SJohan Hedberg if (!irk) { 2627970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 2628970c4e46SJohan Hedberg if (!irk) 2629ca9142b8SJohan Hedberg return NULL; 2630970c4e46SJohan Hedberg 2631970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 2632970c4e46SJohan Hedberg irk->addr_type = addr_type; 2633970c4e46SJohan Hedberg 2634adae20cbSJohan Hedberg list_add_rcu(&irk->list, &hdev->identity_resolving_keys); 2635970c4e46SJohan Hedberg } 2636970c4e46SJohan Hedberg 2637970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 2638970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2639970c4e46SJohan Hedberg 2640ca9142b8SJohan Hedberg return irk; 2641970c4e46SJohan Hedberg } 2642970c4e46SJohan Hedberg 264355ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 264455ed8ca1SJohan Hedberg { 264555ed8ca1SJohan Hedberg struct link_key *key; 264655ed8ca1SJohan Hedberg 264755ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 264855ed8ca1SJohan Hedberg if (!key) 264955ed8ca1SJohan Hedberg return -ENOENT; 265055ed8ca1SJohan Hedberg 26516ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 265255ed8ca1SJohan Hedberg 26530378b597SJohan Hedberg list_del_rcu(&key->list); 26540378b597SJohan Hedberg kfree_rcu(key, rcu); 265555ed8ca1SJohan Hedberg 265655ed8ca1SJohan Hedberg return 0; 265755ed8ca1SJohan Hedberg } 265855ed8ca1SJohan Hedberg 2659e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 2660b899efafSVinicius Costa Gomes { 2661970d0f1bSJohan Hedberg struct smp_ltk *k; 2662c51ffa0bSJohan Hedberg int removed = 0; 2663b899efafSVinicius Costa Gomes 2664970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 2665e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 2666b899efafSVinicius Costa Gomes continue; 2667b899efafSVinicius Costa Gomes 26686ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2669b899efafSVinicius Costa Gomes 2670970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2671970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2672c51ffa0bSJohan Hedberg removed++; 2673b899efafSVinicius Costa Gomes } 2674b899efafSVinicius Costa Gomes 2675c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 2676b899efafSVinicius Costa Gomes } 2677b899efafSVinicius Costa Gomes 2678a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 2679a7ec7338SJohan Hedberg { 2680adae20cbSJohan Hedberg struct smp_irk *k; 2681a7ec7338SJohan Hedberg 2682adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 2683a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 2684a7ec7338SJohan Hedberg continue; 2685a7ec7338SJohan Hedberg 2686a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2687a7ec7338SJohan Hedberg 2688adae20cbSJohan Hedberg list_del_rcu(&k->list); 2689adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2690a7ec7338SJohan Hedberg } 2691a7ec7338SJohan Hedberg } 2692a7ec7338SJohan Hedberg 269355e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 269455e76b38SJohan Hedberg { 269555e76b38SJohan Hedberg struct smp_ltk *k; 26964ba9faf3SJohan Hedberg struct smp_irk *irk; 269755e76b38SJohan Hedberg u8 addr_type; 269855e76b38SJohan Hedberg 269955e76b38SJohan Hedberg if (type == BDADDR_BREDR) { 270055e76b38SJohan Hedberg if (hci_find_link_key(hdev, bdaddr)) 270155e76b38SJohan Hedberg return true; 270255e76b38SJohan Hedberg return false; 270355e76b38SJohan Hedberg } 270455e76b38SJohan Hedberg 270555e76b38SJohan Hedberg /* Convert to HCI addr type which struct smp_ltk uses */ 270655e76b38SJohan Hedberg if (type == BDADDR_LE_PUBLIC) 270755e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_PUBLIC; 270855e76b38SJohan Hedberg else 270955e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_RANDOM; 271055e76b38SJohan Hedberg 27114ba9faf3SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, addr_type); 27124ba9faf3SJohan Hedberg if (irk) { 27134ba9faf3SJohan Hedberg bdaddr = &irk->bdaddr; 27144ba9faf3SJohan Hedberg addr_type = irk->addr_type; 27154ba9faf3SJohan Hedberg } 27164ba9faf3SJohan Hedberg 271755e76b38SJohan Hedberg rcu_read_lock(); 271855e76b38SJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 271987c8b28dSJohan Hedberg if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) { 272087c8b28dSJohan Hedberg rcu_read_unlock(); 272155e76b38SJohan Hedberg return true; 272255e76b38SJohan Hedberg } 272387c8b28dSJohan Hedberg } 272455e76b38SJohan Hedberg rcu_read_unlock(); 272555e76b38SJohan Hedberg 272655e76b38SJohan Hedberg return false; 272755e76b38SJohan Hedberg } 272855e76b38SJohan Hedberg 27296bd32326SVille Tervo /* HCI command timer function */ 273065cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work) 27316bd32326SVille Tervo { 273265cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, 273365cc2b49SMarcel Holtmann cmd_timer.work); 27346bd32326SVille Tervo 2735bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2736bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2737bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2738bda4f23aSAndrei Emeltchenko 27392064ee33SMarcel Holtmann bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); 2740bda4f23aSAndrei Emeltchenko } else { 27412064ee33SMarcel Holtmann bt_dev_err(hdev, "command tx timeout"); 2742bda4f23aSAndrei Emeltchenko } 2743bda4f23aSAndrei Emeltchenko 2744e2bef384SRajat Jain if (hdev->cmd_timeout) 2745e2bef384SRajat Jain hdev->cmd_timeout(hdev); 2746e2bef384SRajat Jain 27476bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2748c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 27496bd32326SVille Tervo } 27506bd32326SVille Tervo 27512763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 27526928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type) 27532763eda6SSzymon Janc { 27542763eda6SSzymon Janc struct oob_data *data; 27552763eda6SSzymon Janc 27566928a924SJohan Hedberg list_for_each_entry(data, &hdev->remote_oob_data, list) { 27576928a924SJohan Hedberg if (bacmp(bdaddr, &data->bdaddr) != 0) 27586928a924SJohan Hedberg continue; 27596928a924SJohan Hedberg if (data->bdaddr_type != bdaddr_type) 27606928a924SJohan Hedberg continue; 27612763eda6SSzymon Janc return data; 27626928a924SJohan Hedberg } 27632763eda6SSzymon Janc 27642763eda6SSzymon Janc return NULL; 27652763eda6SSzymon Janc } 27662763eda6SSzymon Janc 27676928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 27686928a924SJohan Hedberg u8 bdaddr_type) 27692763eda6SSzymon Janc { 27702763eda6SSzymon Janc struct oob_data *data; 27712763eda6SSzymon Janc 27726928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 27732763eda6SSzymon Janc if (!data) 27742763eda6SSzymon Janc return -ENOENT; 27752763eda6SSzymon Janc 27766928a924SJohan Hedberg BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type); 27772763eda6SSzymon Janc 27782763eda6SSzymon Janc list_del(&data->list); 27792763eda6SSzymon Janc kfree(data); 27802763eda6SSzymon Janc 27812763eda6SSzymon Janc return 0; 27822763eda6SSzymon Janc } 27832763eda6SSzymon Janc 278435f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 27852763eda6SSzymon Janc { 27862763eda6SSzymon Janc struct oob_data *data, *n; 27872763eda6SSzymon Janc 27882763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 27892763eda6SSzymon Janc list_del(&data->list); 27902763eda6SSzymon Janc kfree(data); 27912763eda6SSzymon Janc } 27922763eda6SSzymon Janc } 27932763eda6SSzymon Janc 27940798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 27956928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192, 279638da1703SJohan Hedberg u8 *hash256, u8 *rand256) 27970798872eSMarcel Holtmann { 27980798872eSMarcel Holtmann struct oob_data *data; 27990798872eSMarcel Holtmann 28006928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 28010798872eSMarcel Holtmann if (!data) { 28020a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 28030798872eSMarcel Holtmann if (!data) 28040798872eSMarcel Holtmann return -ENOMEM; 28050798872eSMarcel Holtmann 28060798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 28076928a924SJohan Hedberg data->bdaddr_type = bdaddr_type; 28080798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 28090798872eSMarcel Holtmann } 28100798872eSMarcel Holtmann 281181328d5cSJohan Hedberg if (hash192 && rand192) { 28120798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 281338da1703SJohan Hedberg memcpy(data->rand192, rand192, sizeof(data->rand192)); 2814f7697b16SMarcel Holtmann if (hash256 && rand256) 2815f7697b16SMarcel Holtmann data->present = 0x03; 281681328d5cSJohan Hedberg } else { 281781328d5cSJohan Hedberg memset(data->hash192, 0, sizeof(data->hash192)); 281881328d5cSJohan Hedberg memset(data->rand192, 0, sizeof(data->rand192)); 2819f7697b16SMarcel Holtmann if (hash256 && rand256) 2820f7697b16SMarcel Holtmann data->present = 0x02; 2821f7697b16SMarcel Holtmann else 2822f7697b16SMarcel Holtmann data->present = 0x00; 282381328d5cSJohan Hedberg } 28240798872eSMarcel Holtmann 282581328d5cSJohan Hedberg if (hash256 && rand256) { 28260798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 282738da1703SJohan Hedberg memcpy(data->rand256, rand256, sizeof(data->rand256)); 282881328d5cSJohan Hedberg } else { 282981328d5cSJohan Hedberg memset(data->hash256, 0, sizeof(data->hash256)); 283081328d5cSJohan Hedberg memset(data->rand256, 0, sizeof(data->rand256)); 2831f7697b16SMarcel Holtmann if (hash192 && rand192) 2832f7697b16SMarcel Holtmann data->present = 0x01; 283381328d5cSJohan Hedberg } 28340798872eSMarcel Holtmann 28356ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 28362763eda6SSzymon Janc 28372763eda6SSzymon Janc return 0; 28382763eda6SSzymon Janc } 28392763eda6SSzymon Janc 2840d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2841d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance) 2842d2609b34SFlorian Grandel { 2843d2609b34SFlorian Grandel struct adv_info *adv_instance; 2844d2609b34SFlorian Grandel 2845d2609b34SFlorian Grandel list_for_each_entry(adv_instance, &hdev->adv_instances, list) { 2846d2609b34SFlorian Grandel if (adv_instance->instance == instance) 2847d2609b34SFlorian Grandel return adv_instance; 2848d2609b34SFlorian Grandel } 2849d2609b34SFlorian Grandel 2850d2609b34SFlorian Grandel return NULL; 2851d2609b34SFlorian Grandel } 2852d2609b34SFlorian Grandel 2853d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 285474b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance) 285574b93e9fSPrasanna Karthik { 2856d2609b34SFlorian Grandel struct adv_info *cur_instance; 2857d2609b34SFlorian Grandel 2858d2609b34SFlorian Grandel cur_instance = hci_find_adv_instance(hdev, instance); 2859d2609b34SFlorian Grandel if (!cur_instance) 2860d2609b34SFlorian Grandel return NULL; 2861d2609b34SFlorian Grandel 2862d2609b34SFlorian Grandel if (cur_instance == list_last_entry(&hdev->adv_instances, 2863d2609b34SFlorian Grandel struct adv_info, list)) 2864d2609b34SFlorian Grandel return list_first_entry(&hdev->adv_instances, 2865d2609b34SFlorian Grandel struct adv_info, list); 2866d2609b34SFlorian Grandel else 2867d2609b34SFlorian Grandel return list_next_entry(cur_instance, list); 2868d2609b34SFlorian Grandel } 2869d2609b34SFlorian Grandel 2870d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2871d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance) 2872d2609b34SFlorian Grandel { 2873d2609b34SFlorian Grandel struct adv_info *adv_instance; 2874d2609b34SFlorian Grandel 2875d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 2876d2609b34SFlorian Grandel if (!adv_instance) 2877d2609b34SFlorian Grandel return -ENOENT; 2878d2609b34SFlorian Grandel 2879d2609b34SFlorian Grandel BT_DBG("%s removing %dMR", hdev->name, instance); 2880d2609b34SFlorian Grandel 2881cab054abSJohan Hedberg if (hdev->cur_adv_instance == instance) { 2882cab054abSJohan Hedberg if (hdev->adv_instance_timeout) { 28835d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 28845d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 28855d900e46SFlorian Grandel } 2886cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 2887cab054abSJohan Hedberg } 28885d900e46SFlorian Grandel 2889a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 2890a73c046aSJaganath Kanakkassery 2891d2609b34SFlorian Grandel list_del(&adv_instance->list); 2892d2609b34SFlorian Grandel kfree(adv_instance); 2893d2609b34SFlorian Grandel 2894d2609b34SFlorian Grandel hdev->adv_instance_cnt--; 2895d2609b34SFlorian Grandel 2896d2609b34SFlorian Grandel return 0; 2897d2609b34SFlorian Grandel } 2898d2609b34SFlorian Grandel 2899a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired) 2900a73c046aSJaganath Kanakkassery { 2901a73c046aSJaganath Kanakkassery struct adv_info *adv_instance, *n; 2902a73c046aSJaganath Kanakkassery 2903a73c046aSJaganath Kanakkassery list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) 2904a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = rpa_expired; 2905a73c046aSJaganath Kanakkassery } 2906a73c046aSJaganath Kanakkassery 2907d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2908d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev) 2909d2609b34SFlorian Grandel { 2910d2609b34SFlorian Grandel struct adv_info *adv_instance, *n; 2911d2609b34SFlorian Grandel 29125d900e46SFlorian Grandel if (hdev->adv_instance_timeout) { 29135d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 29145d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 29155d900e46SFlorian Grandel } 29165d900e46SFlorian Grandel 2917d2609b34SFlorian Grandel list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) { 2918a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 2919d2609b34SFlorian Grandel list_del(&adv_instance->list); 2920d2609b34SFlorian Grandel kfree(adv_instance); 2921d2609b34SFlorian Grandel } 2922d2609b34SFlorian Grandel 2923d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 2924cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 2925d2609b34SFlorian Grandel } 2926d2609b34SFlorian Grandel 2927a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work) 2928a73c046aSJaganath Kanakkassery { 2929a73c046aSJaganath Kanakkassery struct adv_info *adv_instance = container_of(work, struct adv_info, 2930a73c046aSJaganath Kanakkassery rpa_expired_cb.work); 2931a73c046aSJaganath Kanakkassery 2932a73c046aSJaganath Kanakkassery BT_DBG(""); 2933a73c046aSJaganath Kanakkassery 2934a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = true; 2935a73c046aSJaganath Kanakkassery } 2936a73c046aSJaganath Kanakkassery 2937d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2938d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags, 2939d2609b34SFlorian Grandel u16 adv_data_len, u8 *adv_data, 2940d2609b34SFlorian Grandel u16 scan_rsp_len, u8 *scan_rsp_data, 2941d2609b34SFlorian Grandel u16 timeout, u16 duration) 2942d2609b34SFlorian Grandel { 2943d2609b34SFlorian Grandel struct adv_info *adv_instance; 2944d2609b34SFlorian Grandel 2945d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 2946d2609b34SFlorian Grandel if (adv_instance) { 2947d2609b34SFlorian Grandel memset(adv_instance->adv_data, 0, 2948d2609b34SFlorian Grandel sizeof(adv_instance->adv_data)); 2949d2609b34SFlorian Grandel memset(adv_instance->scan_rsp_data, 0, 2950d2609b34SFlorian Grandel sizeof(adv_instance->scan_rsp_data)); 2951d2609b34SFlorian Grandel } else { 29521d0fac2cSLuiz Augusto von Dentz if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets || 2953d2609b34SFlorian Grandel instance < 1 || instance > HCI_MAX_ADV_INSTANCES) 2954d2609b34SFlorian Grandel return -EOVERFLOW; 2955d2609b34SFlorian Grandel 295639ecfad6SJohan Hedberg adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL); 2957d2609b34SFlorian Grandel if (!adv_instance) 2958d2609b34SFlorian Grandel return -ENOMEM; 2959d2609b34SFlorian Grandel 2960fffd38bcSFlorian Grandel adv_instance->pending = true; 2961d2609b34SFlorian Grandel adv_instance->instance = instance; 2962d2609b34SFlorian Grandel list_add(&adv_instance->list, &hdev->adv_instances); 2963d2609b34SFlorian Grandel hdev->adv_instance_cnt++; 2964d2609b34SFlorian Grandel } 2965d2609b34SFlorian Grandel 2966d2609b34SFlorian Grandel adv_instance->flags = flags; 2967d2609b34SFlorian Grandel adv_instance->adv_data_len = adv_data_len; 2968d2609b34SFlorian Grandel adv_instance->scan_rsp_len = scan_rsp_len; 2969d2609b34SFlorian Grandel 2970d2609b34SFlorian Grandel if (adv_data_len) 2971d2609b34SFlorian Grandel memcpy(adv_instance->adv_data, adv_data, adv_data_len); 2972d2609b34SFlorian Grandel 2973d2609b34SFlorian Grandel if (scan_rsp_len) 2974d2609b34SFlorian Grandel memcpy(adv_instance->scan_rsp_data, 2975d2609b34SFlorian Grandel scan_rsp_data, scan_rsp_len); 2976d2609b34SFlorian Grandel 2977d2609b34SFlorian Grandel adv_instance->timeout = timeout; 29785d900e46SFlorian Grandel adv_instance->remaining_time = timeout; 2979d2609b34SFlorian Grandel 2980d2609b34SFlorian Grandel if (duration == 0) 2981d2609b34SFlorian Grandel adv_instance->duration = HCI_DEFAULT_ADV_DURATION; 2982d2609b34SFlorian Grandel else 2983d2609b34SFlorian Grandel adv_instance->duration = duration; 2984d2609b34SFlorian Grandel 2985de181e88SJaganath Kanakkassery adv_instance->tx_power = HCI_TX_POWER_INVALID; 2986de181e88SJaganath Kanakkassery 2987a73c046aSJaganath Kanakkassery INIT_DELAYED_WORK(&adv_instance->rpa_expired_cb, 2988a73c046aSJaganath Kanakkassery adv_instance_rpa_expired); 2989a73c046aSJaganath Kanakkassery 2990d2609b34SFlorian Grandel BT_DBG("%s for %dMR", hdev->name, instance); 2991d2609b34SFlorian Grandel 2992d2609b34SFlorian Grandel return 0; 2993d2609b34SFlorian Grandel } 2994d2609b34SFlorian Grandel 2995dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list, 2996b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 2997b2a66aadSAntti Julku { 2998b2a66aadSAntti Julku struct bdaddr_list *b; 2999b2a66aadSAntti Julku 3000dcc36c16SJohan Hedberg list_for_each_entry(b, bdaddr_list, list) { 3001b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3002b2a66aadSAntti Julku return b; 3003b9ee0a78SMarcel Holtmann } 3004b2a66aadSAntti Julku 3005b2a66aadSAntti Julku return NULL; 3006b2a66aadSAntti Julku } 3007b2a66aadSAntti Julku 3008b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk( 3009b950aa88SAnkit Navik struct list_head *bdaddr_list, bdaddr_t *bdaddr, 3010b950aa88SAnkit Navik u8 type) 3011b950aa88SAnkit Navik { 3012b950aa88SAnkit Navik struct bdaddr_list_with_irk *b; 3013b950aa88SAnkit Navik 3014b950aa88SAnkit Navik list_for_each_entry(b, bdaddr_list, list) { 3015b950aa88SAnkit Navik if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3016b950aa88SAnkit Navik return b; 3017b950aa88SAnkit Navik } 3018b950aa88SAnkit Navik 3019b950aa88SAnkit Navik return NULL; 3020b950aa88SAnkit Navik } 3021b950aa88SAnkit Navik 3022dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list) 3023b2a66aadSAntti Julku { 30247eb7404fSGeliang Tang struct bdaddr_list *b, *n; 3025b2a66aadSAntti Julku 30267eb7404fSGeliang Tang list_for_each_entry_safe(b, n, bdaddr_list, list) { 30277eb7404fSGeliang Tang list_del(&b->list); 3028b2a66aadSAntti Julku kfree(b); 3029b2a66aadSAntti Julku } 3030b2a66aadSAntti Julku } 3031b2a66aadSAntti Julku 3032dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type) 3033b2a66aadSAntti Julku { 3034b2a66aadSAntti Julku struct bdaddr_list *entry; 3035b2a66aadSAntti Julku 3036b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3037b2a66aadSAntti Julku return -EBADF; 3038b2a66aadSAntti Julku 3039dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(list, bdaddr, type)) 30405e762444SAntti Julku return -EEXIST; 3041b2a66aadSAntti Julku 304227f70f3eSJohan Hedberg entry = kzalloc(sizeof(*entry), GFP_KERNEL); 30435e762444SAntti Julku if (!entry) 30445e762444SAntti Julku return -ENOMEM; 3045b2a66aadSAntti Julku 3046b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 3047b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 3048b2a66aadSAntti Julku 3049dcc36c16SJohan Hedberg list_add(&entry->list, list); 3050b2a66aadSAntti Julku 30512a8357f2SJohan Hedberg return 0; 3052b2a66aadSAntti Julku } 3053b2a66aadSAntti Julku 3054b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr, 3055b950aa88SAnkit Navik u8 type, u8 *peer_irk, u8 *local_irk) 3056b950aa88SAnkit Navik { 3057b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 3058b950aa88SAnkit Navik 3059b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) 3060b950aa88SAnkit Navik return -EBADF; 3061b950aa88SAnkit Navik 3062b950aa88SAnkit Navik if (hci_bdaddr_list_lookup(list, bdaddr, type)) 3063b950aa88SAnkit Navik return -EEXIST; 3064b950aa88SAnkit Navik 3065b950aa88SAnkit Navik entry = kzalloc(sizeof(*entry), GFP_KERNEL); 3066b950aa88SAnkit Navik if (!entry) 3067b950aa88SAnkit Navik return -ENOMEM; 3068b950aa88SAnkit Navik 3069b950aa88SAnkit Navik bacpy(&entry->bdaddr, bdaddr); 3070b950aa88SAnkit Navik entry->bdaddr_type = type; 3071b950aa88SAnkit Navik 3072b950aa88SAnkit Navik if (peer_irk) 3073b950aa88SAnkit Navik memcpy(entry->peer_irk, peer_irk, 16); 3074b950aa88SAnkit Navik 3075b950aa88SAnkit Navik if (local_irk) 3076b950aa88SAnkit Navik memcpy(entry->local_irk, local_irk, 16); 3077b950aa88SAnkit Navik 3078b950aa88SAnkit Navik list_add(&entry->list, list); 3079b950aa88SAnkit Navik 3080b950aa88SAnkit Navik return 0; 3081b950aa88SAnkit Navik } 3082b950aa88SAnkit Navik 3083dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type) 3084b2a66aadSAntti Julku { 3085b2a66aadSAntti Julku struct bdaddr_list *entry; 3086b2a66aadSAntti Julku 308735f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 3088dcc36c16SJohan Hedberg hci_bdaddr_list_clear(list); 308935f7498aSJohan Hedberg return 0; 309035f7498aSJohan Hedberg } 3091b2a66aadSAntti Julku 3092dcc36c16SJohan Hedberg entry = hci_bdaddr_list_lookup(list, bdaddr, type); 3093d2ab0ac1SMarcel Holtmann if (!entry) 3094d2ab0ac1SMarcel Holtmann return -ENOENT; 3095d2ab0ac1SMarcel Holtmann 3096d2ab0ac1SMarcel Holtmann list_del(&entry->list); 3097d2ab0ac1SMarcel Holtmann kfree(entry); 3098d2ab0ac1SMarcel Holtmann 3099d2ab0ac1SMarcel Holtmann return 0; 3100d2ab0ac1SMarcel Holtmann } 3101d2ab0ac1SMarcel Holtmann 3102b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr, 3103b950aa88SAnkit Navik u8 type) 3104b950aa88SAnkit Navik { 3105b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 3106b950aa88SAnkit Navik 3107b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) { 3108b950aa88SAnkit Navik hci_bdaddr_list_clear(list); 3109b950aa88SAnkit Navik return 0; 3110b950aa88SAnkit Navik } 3111b950aa88SAnkit Navik 3112b950aa88SAnkit Navik entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type); 3113b950aa88SAnkit Navik if (!entry) 3114b950aa88SAnkit Navik return -ENOENT; 3115b950aa88SAnkit Navik 3116b950aa88SAnkit Navik list_del(&entry->list); 3117b950aa88SAnkit Navik kfree(entry); 3118b950aa88SAnkit Navik 3119b950aa88SAnkit Navik return 0; 3120b950aa88SAnkit Navik } 3121b950aa88SAnkit Navik 312215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 312315819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 312415819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 312515819a70SAndre Guedes { 312615819a70SAndre Guedes struct hci_conn_params *params; 312715819a70SAndre Guedes 312815819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 312915819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 313015819a70SAndre Guedes params->addr_type == addr_type) { 313115819a70SAndre Guedes return params; 313215819a70SAndre Guedes } 313315819a70SAndre Guedes } 313415819a70SAndre Guedes 313515819a70SAndre Guedes return NULL; 313615819a70SAndre Guedes } 313715819a70SAndre Guedes 313815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 3139501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 31404b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type) 314115819a70SAndre Guedes { 3142912b42efSJohan Hedberg struct hci_conn_params *param; 314315819a70SAndre Guedes 3144501f8827SJohan Hedberg list_for_each_entry(param, list, action) { 3145912b42efSJohan Hedberg if (bacmp(¶m->addr, addr) == 0 && 3146912b42efSJohan Hedberg param->addr_type == addr_type) 3147912b42efSJohan Hedberg return param; 31484b10966fSMarcel Holtmann } 31494b10966fSMarcel Holtmann 31504b10966fSMarcel Holtmann return NULL; 315115819a70SAndre Guedes } 315215819a70SAndre Guedes 315315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 315451d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 315551d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type) 315615819a70SAndre Guedes { 315715819a70SAndre Guedes struct hci_conn_params *params; 315815819a70SAndre Guedes 315915819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 3160cef952ceSAndre Guedes if (params) 316151d167c0SMarcel Holtmann return params; 316215819a70SAndre Guedes 316315819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 316415819a70SAndre Guedes if (!params) { 31652064ee33SMarcel Holtmann bt_dev_err(hdev, "out of memory"); 316651d167c0SMarcel Holtmann return NULL; 316715819a70SAndre Guedes } 316815819a70SAndre Guedes 316915819a70SAndre Guedes bacpy(¶ms->addr, addr); 317015819a70SAndre Guedes params->addr_type = addr_type; 3171cef952ceSAndre Guedes 3172cef952ceSAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 317393450c75SJohan Hedberg INIT_LIST_HEAD(¶ms->action); 3174cef952ceSAndre Guedes 3175bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval; 3176bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval; 3177bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency; 3178bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout; 3179bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED; 3180bf5b3c8bSMarcel Holtmann 3181bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 3182bf5b3c8bSMarcel Holtmann 318351d167c0SMarcel Holtmann return params; 3184bf5b3c8bSMarcel Holtmann } 3185bf5b3c8bSMarcel Holtmann 3186f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params) 3187f6c63249SJohan Hedberg { 3188f6c63249SJohan Hedberg if (params->conn) { 3189f6c63249SJohan Hedberg hci_conn_drop(params->conn); 3190f6c63249SJohan Hedberg hci_conn_put(params->conn); 3191f6c63249SJohan Hedberg } 3192f6c63249SJohan Hedberg 3193f6c63249SJohan Hedberg list_del(¶ms->action); 3194f6c63249SJohan Hedberg list_del(¶ms->list); 3195f6c63249SJohan Hedberg kfree(params); 3196f6c63249SJohan Hedberg } 3197f6c63249SJohan Hedberg 319815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 319915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 320015819a70SAndre Guedes { 320115819a70SAndre Guedes struct hci_conn_params *params; 320215819a70SAndre Guedes 320315819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 320415819a70SAndre Guedes if (!params) 320515819a70SAndre Guedes return; 320615819a70SAndre Guedes 3207f6c63249SJohan Hedberg hci_conn_params_free(params); 320815819a70SAndre Guedes 320995305baaSJohan Hedberg hci_update_background_scan(hdev); 321095305baaSJohan Hedberg 321115819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 321215819a70SAndre Guedes } 321315819a70SAndre Guedes 321415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 321555af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev) 321615819a70SAndre Guedes { 321715819a70SAndre Guedes struct hci_conn_params *params, *tmp; 321815819a70SAndre Guedes 321915819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 322055af49a8SJohan Hedberg if (params->auto_connect != HCI_AUTO_CONN_DISABLED) 322155af49a8SJohan Hedberg continue; 3222f75113a2SJakub Pawlowski 3223f75113a2SJakub Pawlowski /* If trying to estabilish one time connection to disabled 3224f75113a2SJakub Pawlowski * device, leave the params, but mark them as just once. 3225f75113a2SJakub Pawlowski */ 3226f75113a2SJakub Pawlowski if (params->explicit_connect) { 3227f75113a2SJakub Pawlowski params->auto_connect = HCI_AUTO_CONN_EXPLICIT; 3228f75113a2SJakub Pawlowski continue; 3229f75113a2SJakub Pawlowski } 3230f75113a2SJakub Pawlowski 323115819a70SAndre Guedes list_del(¶ms->list); 323215819a70SAndre Guedes kfree(params); 323315819a70SAndre Guedes } 323415819a70SAndre Guedes 323555af49a8SJohan Hedberg BT_DBG("All LE disabled connection parameters were removed"); 323655af49a8SJohan Hedberg } 323755af49a8SJohan Hedberg 323855af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */ 3239030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev) 324015819a70SAndre Guedes { 324115819a70SAndre Guedes struct hci_conn_params *params, *tmp; 324215819a70SAndre Guedes 3243f6c63249SJohan Hedberg list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) 3244f6c63249SJohan Hedberg hci_conn_params_free(params); 324515819a70SAndre Guedes 324615819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 324715819a70SAndre Guedes } 324815819a70SAndre Guedes 3249a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 3250a1f4c318SJohan Hedberg * 3251a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 3252a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 3253a1f4c318SJohan Hedberg * the static random address. 3254a1f4c318SJohan Hedberg * 3255a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 3256a1f4c318SJohan Hedberg * public address to use the static random address instead. 325750b5b952SMarcel Holtmann * 325850b5b952SMarcel Holtmann * In case BR/EDR has been disabled on a dual-mode controller and 325950b5b952SMarcel Holtmann * userspace has configured a static address, then that address 326050b5b952SMarcel Holtmann * becomes the identity address instead of the public BR/EDR address. 3261a1f4c318SJohan Hedberg */ 3262a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 3263a1f4c318SJohan Hedberg u8 *bdaddr_type) 3264a1f4c318SJohan Hedberg { 3265b7cb93e5SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) || 326650b5b952SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) || 3267d7a5a11dSMarcel Holtmann (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) && 326850b5b952SMarcel Holtmann bacmp(&hdev->static_addr, BDADDR_ANY))) { 3269a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 3270a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 3271a1f4c318SJohan Hedberg } else { 3272a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 3273a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 3274a1f4c318SJohan Hedberg } 3275a1f4c318SJohan Hedberg } 3276a1f4c318SJohan Hedberg 32779952d90eSAbhishek Pandit-Subedi static int hci_suspend_wait_event(struct hci_dev *hdev) 32789952d90eSAbhishek Pandit-Subedi { 32799952d90eSAbhishek Pandit-Subedi #define WAKE_COND \ 32809952d90eSAbhishek Pandit-Subedi (find_first_bit(hdev->suspend_tasks, __SUSPEND_NUM_TASKS) == \ 32819952d90eSAbhishek Pandit-Subedi __SUSPEND_NUM_TASKS) 32829952d90eSAbhishek Pandit-Subedi 32839952d90eSAbhishek Pandit-Subedi int i; 32849952d90eSAbhishek Pandit-Subedi int ret = wait_event_timeout(hdev->suspend_wait_q, 32859952d90eSAbhishek Pandit-Subedi WAKE_COND, SUSPEND_NOTIFIER_TIMEOUT); 32869952d90eSAbhishek Pandit-Subedi 32879952d90eSAbhishek Pandit-Subedi if (ret == 0) { 32889952d90eSAbhishek Pandit-Subedi bt_dev_dbg(hdev, "Timed out waiting for suspend"); 32899952d90eSAbhishek Pandit-Subedi for (i = 0; i < __SUSPEND_NUM_TASKS; ++i) { 32909952d90eSAbhishek Pandit-Subedi if (test_bit(i, hdev->suspend_tasks)) 32919952d90eSAbhishek Pandit-Subedi bt_dev_dbg(hdev, "Bit %d is set", i); 32929952d90eSAbhishek Pandit-Subedi clear_bit(i, hdev->suspend_tasks); 32939952d90eSAbhishek Pandit-Subedi } 32949952d90eSAbhishek Pandit-Subedi 32959952d90eSAbhishek Pandit-Subedi ret = -ETIMEDOUT; 32969952d90eSAbhishek Pandit-Subedi } else { 32979952d90eSAbhishek Pandit-Subedi ret = 0; 32989952d90eSAbhishek Pandit-Subedi } 32999952d90eSAbhishek Pandit-Subedi 33009952d90eSAbhishek Pandit-Subedi return ret; 33019952d90eSAbhishek Pandit-Subedi } 33029952d90eSAbhishek Pandit-Subedi 33039952d90eSAbhishek Pandit-Subedi static void hci_prepare_suspend(struct work_struct *work) 33049952d90eSAbhishek Pandit-Subedi { 33059952d90eSAbhishek Pandit-Subedi struct hci_dev *hdev = 33069952d90eSAbhishek Pandit-Subedi container_of(work, struct hci_dev, suspend_prepare); 33079952d90eSAbhishek Pandit-Subedi 33089952d90eSAbhishek Pandit-Subedi hci_dev_lock(hdev); 33099952d90eSAbhishek Pandit-Subedi hci_req_prepare_suspend(hdev, hdev->suspend_state_next); 33109952d90eSAbhishek Pandit-Subedi hci_dev_unlock(hdev); 33119952d90eSAbhishek Pandit-Subedi } 33129952d90eSAbhishek Pandit-Subedi 33138731840aSAbhishek Pandit-Subedi static int hci_change_suspend_state(struct hci_dev *hdev, 33148731840aSAbhishek Pandit-Subedi enum suspended_state next) 33158731840aSAbhishek Pandit-Subedi { 33168731840aSAbhishek Pandit-Subedi hdev->suspend_state_next = next; 33178731840aSAbhishek Pandit-Subedi set_bit(SUSPEND_PREPARE_NOTIFIER, hdev->suspend_tasks); 33188731840aSAbhishek Pandit-Subedi queue_work(hdev->req_workqueue, &hdev->suspend_prepare); 33198731840aSAbhishek Pandit-Subedi return hci_suspend_wait_event(hdev); 33208731840aSAbhishek Pandit-Subedi } 33218731840aSAbhishek Pandit-Subedi 33229952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, 33239952d90eSAbhishek Pandit-Subedi void *data) 33249952d90eSAbhishek Pandit-Subedi { 33259952d90eSAbhishek Pandit-Subedi struct hci_dev *hdev = 33269952d90eSAbhishek Pandit-Subedi container_of(nb, struct hci_dev, suspend_notifier); 33279952d90eSAbhishek Pandit-Subedi int ret = 0; 33289952d90eSAbhishek Pandit-Subedi 33299952d90eSAbhishek Pandit-Subedi /* If powering down, wait for completion. */ 33309952d90eSAbhishek Pandit-Subedi if (mgmt_powering_down(hdev)) { 33319952d90eSAbhishek Pandit-Subedi set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks); 33329952d90eSAbhishek Pandit-Subedi ret = hci_suspend_wait_event(hdev); 33339952d90eSAbhishek Pandit-Subedi if (ret) 33349952d90eSAbhishek Pandit-Subedi goto done; 33359952d90eSAbhishek Pandit-Subedi } 33369952d90eSAbhishek Pandit-Subedi 33379952d90eSAbhishek Pandit-Subedi /* Suspend notifier should only act on events when powered. */ 33389952d90eSAbhishek Pandit-Subedi if (!hdev_is_powered(hdev)) 33399952d90eSAbhishek Pandit-Subedi goto done; 33409952d90eSAbhishek Pandit-Subedi 33419952d90eSAbhishek Pandit-Subedi if (action == PM_SUSPEND_PREPARE) { 33424f40afc6SAbhishek Pandit-Subedi /* Suspend consists of two actions: 33434f40afc6SAbhishek Pandit-Subedi * - First, disconnect everything and make the controller not 33444f40afc6SAbhishek Pandit-Subedi * connectable (disabling scanning) 33454f40afc6SAbhishek Pandit-Subedi * - Second, program event filter/whitelist and enable scan 33464f40afc6SAbhishek Pandit-Subedi */ 33478731840aSAbhishek Pandit-Subedi ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT); 33484f40afc6SAbhishek Pandit-Subedi 33498731840aSAbhishek Pandit-Subedi /* Only configure whitelist if disconnect succeeded */ 33508731840aSAbhishek Pandit-Subedi if (!ret) 33518731840aSAbhishek Pandit-Subedi ret = hci_change_suspend_state(hdev, 33528731840aSAbhishek Pandit-Subedi BT_SUSPEND_COMPLETE); 33539952d90eSAbhishek Pandit-Subedi } else if (action == PM_POST_SUSPEND) { 33548731840aSAbhishek Pandit-Subedi ret = hci_change_suspend_state(hdev, BT_RUNNING); 33559952d90eSAbhishek Pandit-Subedi } 33569952d90eSAbhishek Pandit-Subedi 33578731840aSAbhishek Pandit-Subedi /* If suspend failed, restore it to running */ 33588731840aSAbhishek Pandit-Subedi if (ret && action == PM_SUSPEND_PREPARE) 33598731840aSAbhishek Pandit-Subedi hci_change_suspend_state(hdev, BT_RUNNING); 33608731840aSAbhishek Pandit-Subedi 33619952d90eSAbhishek Pandit-Subedi done: 33629952d90eSAbhishek Pandit-Subedi return ret ? notifier_from_errno(-EBUSY) : NOTIFY_STOP; 33639952d90eSAbhishek Pandit-Subedi } 33648731840aSAbhishek Pandit-Subedi 33659be0dab7SDavid Herrmann /* Alloc HCI device */ 33669be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 33679be0dab7SDavid Herrmann { 33689be0dab7SDavid Herrmann struct hci_dev *hdev; 33699be0dab7SDavid Herrmann 337027f70f3eSJohan Hedberg hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); 33719be0dab7SDavid Herrmann if (!hdev) 33729be0dab7SDavid Herrmann return NULL; 33739be0dab7SDavid Herrmann 3374b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3375b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3376b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3377b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3378b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 337996c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */ 3380bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3381bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3382d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 3383d2609b34SFlorian Grandel hdev->cur_adv_instance = 0x00; 33845d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 3385b1b813d4SDavid Herrmann 3386b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3387b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3388b1b813d4SDavid Herrmann 33893f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 3390628531c9SGeorg Lukas hdev->le_adv_min_interval = 0x0800; 3391628531c9SGeorg Lukas hdev->le_adv_max_interval = 0x0800; 3392bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3393bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 3394b48c3b59SJonas Holmberg hdev->le_conn_min_interval = 0x0018; 3395b48c3b59SJonas Holmberg hdev->le_conn_max_interval = 0x0028; 339604fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000; 339704fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a; 3398a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = 0x001b; 3399a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = 0x0148; 3400a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = 0x001b; 3401a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = 0x0148; 3402a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = 0x001b; 3403a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = 0x0148; 340430d65e08SMatias Karhumaa hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE; 340530d65e08SMatias Karhumaa hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE; 34066decb5b4SJaganath Kanakkassery hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M; 34076decb5b4SJaganath Kanakkassery hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M; 34081d0fac2cSLuiz Augusto von Dentz hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES; 3409bef64738SMarcel Holtmann 3410d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 3411b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 341231ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 341331ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 3414302975cbSSpoorthi Ravishankar Koppad hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT; 341558a96fc3SMarcel Holtmann hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE; 3416d6bfd59cSJohan Hedberg 3417b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3418b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3419b1b813d4SDavid Herrmann 3420b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3421b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 34226659358eSJohan Hedberg INIT_LIST_HEAD(&hdev->whitelist); 34234f40afc6SAbhishek Pandit-Subedi INIT_LIST_HEAD(&hdev->wakeable); 3424b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3425b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3426b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3427970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3428b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 3429d2ab0ac1SMarcel Holtmann INIT_LIST_HEAD(&hdev->le_white_list); 3430cfdb0c2dSAnkit Navik INIT_LIST_HEAD(&hdev->le_resolv_list); 343115819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 343277a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 343366f8455aSJohan Hedberg INIT_LIST_HEAD(&hdev->pend_le_reports); 34346b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3435d2609b34SFlorian Grandel INIT_LIST_HEAD(&hdev->adv_instances); 3436600a8749SAlain Michaud INIT_LIST_HEAD(&hdev->blocked_keys); 3437b1b813d4SDavid Herrmann 3438b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3439b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3440b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3441b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3442c7741d16SMarcel Holtmann INIT_WORK(&hdev->error_reset, hci_error_reset); 34439952d90eSAbhishek Pandit-Subedi INIT_WORK(&hdev->suspend_prepare, hci_prepare_suspend); 3444b1b813d4SDavid Herrmann 3445b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3446b1b813d4SDavid Herrmann 3447b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3448b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3449b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3450b1b813d4SDavid Herrmann 3451b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 34529952d90eSAbhishek Pandit-Subedi init_waitqueue_head(&hdev->suspend_wait_q); 3453b1b813d4SDavid Herrmann 345465cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout); 3455b1b813d4SDavid Herrmann 34565fc16cc4SJohan Hedberg hci_request_setup(hdev); 34575fc16cc4SJohan Hedberg 3458b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3459b1b813d4SDavid Herrmann discovery_init(hdev); 34609be0dab7SDavid Herrmann 34619be0dab7SDavid Herrmann return hdev; 34629be0dab7SDavid Herrmann } 34639be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 34649be0dab7SDavid Herrmann 34659be0dab7SDavid Herrmann /* Free HCI device */ 34669be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 34679be0dab7SDavid Herrmann { 34689be0dab7SDavid Herrmann /* will free via device release */ 34699be0dab7SDavid Herrmann put_device(&hdev->dev); 34709be0dab7SDavid Herrmann } 34719be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 34729be0dab7SDavid Herrmann 34731da177e4SLinus Torvalds /* Register HCI device */ 34741da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 34751da177e4SLinus Torvalds { 3476b1b813d4SDavid Herrmann int id, error; 34771da177e4SLinus Torvalds 347874292d5aSMarcel Holtmann if (!hdev->open || !hdev->close || !hdev->send) 34791da177e4SLinus Torvalds return -EINVAL; 34801da177e4SLinus Torvalds 348108add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 348208add513SMat Martineau * so the index can be used as the AMP controller ID. 348308add513SMat Martineau */ 34843df92b31SSasha Levin switch (hdev->dev_type) { 3485ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 34863df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 34871da177e4SLinus Torvalds break; 34883df92b31SSasha Levin case HCI_AMP: 34893df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 34903df92b31SSasha Levin break; 34913df92b31SSasha Levin default: 34923df92b31SSasha Levin return -EINVAL; 34931da177e4SLinus Torvalds } 34941da177e4SLinus Torvalds 34953df92b31SSasha Levin if (id < 0) 34963df92b31SSasha Levin return id; 34973df92b31SSasha Levin 34981da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 34991da177e4SLinus Torvalds hdev->id = id; 35002d8b3a11SAndrei Emeltchenko 35012d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 35022d8b3a11SAndrei Emeltchenko 350329e2dd0dSTejun Heo hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name); 350433ca954dSDavid Herrmann if (!hdev->workqueue) { 350533ca954dSDavid Herrmann error = -ENOMEM; 350633ca954dSDavid Herrmann goto err; 350733ca954dSDavid Herrmann } 3508f48fd9c8SMarcel Holtmann 350929e2dd0dSTejun Heo hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, 351029e2dd0dSTejun Heo hdev->name); 35116ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 35126ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 35136ead1bbcSJohan Hedberg error = -ENOMEM; 35146ead1bbcSJohan Hedberg goto err; 35156ead1bbcSJohan Hedberg } 35166ead1bbcSJohan Hedberg 35170153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 35180153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 35190153e2ecSMarcel Holtmann 3520bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3521bdc3e0f1SMarcel Holtmann 3522bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 352333ca954dSDavid Herrmann if (error < 0) 352454506918SJohan Hedberg goto err_wqueue; 35251da177e4SLinus Torvalds 35266d5d2ee6SHeiner Kallweit hci_leds_init(hdev); 35276d5d2ee6SHeiner Kallweit 3528611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3529a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3530a8c5fb1aSGustavo Padovan hdev); 3531611b30f7SMarcel Holtmann if (hdev->rfkill) { 3532611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3533611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3534611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3535611b30f7SMarcel Holtmann } 3536611b30f7SMarcel Holtmann } 3537611b30f7SMarcel Holtmann 35385e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 3539a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 35405e130367SJohan Hedberg 3541a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SETUP); 3542a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_AUTO_OFF); 3543ce2be9acSAndrei Emeltchenko 3544ca8bee5dSMarcel Holtmann if (hdev->dev_type == HCI_PRIMARY) { 354556f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 354656f87901SJohan Hedberg * through reading supported features during init. 354756f87901SJohan Hedberg */ 3548a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 354956f87901SJohan Hedberg } 3550ce2be9acSAndrei Emeltchenko 3551fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3552fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3553fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3554fcee3377SGustavo Padovan 35554a964404SMarcel Holtmann /* Devices that are marked for raw-only usage are unconfigured 35564a964404SMarcel Holtmann * and should not be included in normal operation. 3557fee746b0SMarcel Holtmann */ 3558fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 3559a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 3560fee746b0SMarcel Holtmann 356105fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_REG); 3562dc946bd8SDavid Herrmann hci_dev_hold(hdev); 35631da177e4SLinus Torvalds 35649952d90eSAbhishek Pandit-Subedi hdev->suspend_notifier.notifier_call = hci_suspend_notifier; 35659952d90eSAbhishek Pandit-Subedi error = register_pm_notifier(&hdev->suspend_notifier); 35669952d90eSAbhishek Pandit-Subedi if (error) 35679952d90eSAbhishek Pandit-Subedi goto err_wqueue; 35689952d90eSAbhishek Pandit-Subedi 356919202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3570fbe96d6fSMarcel Holtmann 35711da177e4SLinus Torvalds return id; 3572f48fd9c8SMarcel Holtmann 357333ca954dSDavid Herrmann err_wqueue: 357433ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 35756ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 357633ca954dSDavid Herrmann err: 35773df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3578f48fd9c8SMarcel Holtmann 357933ca954dSDavid Herrmann return error; 35801da177e4SLinus Torvalds } 35811da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 35821da177e4SLinus Torvalds 35831da177e4SLinus Torvalds /* Unregister HCI device */ 358459735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 35851da177e4SLinus Torvalds { 35862d7cc19eSMarcel Holtmann int id; 3587ef222013SMarcel Holtmann 3588c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 35891da177e4SLinus Torvalds 3590a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNREGISTER); 359194324962SJohan Hovold 35923df92b31SSasha Levin id = hdev->id; 35933df92b31SSasha Levin 3594f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 35951da177e4SLinus Torvalds list_del(&hdev->list); 3596f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 35971da177e4SLinus Torvalds 3598b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 3599b9b5ef18SGustavo Padovan 3600bf389cabSJiri Slaby hci_dev_do_close(hdev); 3601bf389cabSJiri Slaby 36029952d90eSAbhishek Pandit-Subedi unregister_pm_notifier(&hdev->suspend_notifier); 36039952d90eSAbhishek Pandit-Subedi 3604ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 3605d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_SETUP) && 3606d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 360709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3608744cf19eSJohan Hedberg mgmt_index_removed(hdev); 360909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 361056e5cb86SJohan Hedberg } 3611ab81cbf9SJohan Hedberg 36122e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 36132e58ef3eSJohan Hedberg * pending list */ 36142e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 36152e58ef3eSJohan Hedberg 361605fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UNREG); 36171da177e4SLinus Torvalds 3618611b30f7SMarcel Holtmann if (hdev->rfkill) { 3619611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 3620611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3621611b30f7SMarcel Holtmann } 3622611b30f7SMarcel Holtmann 3623bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 3624147e2d59SDave Young 36250153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 36265177a838SMarcel Holtmann kfree_const(hdev->hw_info); 36275177a838SMarcel Holtmann kfree_const(hdev->fw_info); 36280153e2ecSMarcel Holtmann 3629f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 36306ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 3631f48fd9c8SMarcel Holtmann 363209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3633dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->blacklist); 36346659358eSJohan Hedberg hci_bdaddr_list_clear(&hdev->whitelist); 36352aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 363655ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 3637b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 3638970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 36392763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 3640d2609b34SFlorian Grandel hci_adv_instances_clear(hdev); 3641dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->le_white_list); 3642cfdb0c2dSAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 3643373110c5SJohan Hedberg hci_conn_params_clear_all(hdev); 364422078800SMarcel Holtmann hci_discovery_filter_clear(hdev); 3645600a8749SAlain Michaud hci_blocked_keys_clear(hdev); 364609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 3647e2e0cacbSJohan Hedberg 3648dc946bd8SDavid Herrmann hci_dev_put(hdev); 36493df92b31SSasha Levin 36503df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 36511da177e4SLinus Torvalds } 36521da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 36531da177e4SLinus Torvalds 36541da177e4SLinus Torvalds /* Suspend HCI device */ 36551da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 36561da177e4SLinus Torvalds { 365705fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_SUSPEND); 36581da177e4SLinus Torvalds return 0; 36591da177e4SLinus Torvalds } 36601da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 36611da177e4SLinus Torvalds 36621da177e4SLinus Torvalds /* Resume HCI device */ 36631da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 36641da177e4SLinus Torvalds { 366505fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_RESUME); 36661da177e4SLinus Torvalds return 0; 36671da177e4SLinus Torvalds } 36681da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 36691da177e4SLinus Torvalds 367075e0569fSMarcel Holtmann /* Reset HCI device */ 367175e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev) 367275e0569fSMarcel Holtmann { 36731e4b6e91SColin Ian King static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; 367475e0569fSMarcel Holtmann struct sk_buff *skb; 367575e0569fSMarcel Holtmann 367675e0569fSMarcel Holtmann skb = bt_skb_alloc(3, GFP_ATOMIC); 367775e0569fSMarcel Holtmann if (!skb) 367875e0569fSMarcel Holtmann return -ENOMEM; 367975e0569fSMarcel Holtmann 3680d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_EVENT_PKT; 368159ae1d12SJohannes Berg skb_put_data(skb, hw_err, 3); 368275e0569fSMarcel Holtmann 368375e0569fSMarcel Holtmann /* Send Hardware Error to upper stack */ 368475e0569fSMarcel Holtmann return hci_recv_frame(hdev, skb); 368575e0569fSMarcel Holtmann } 368675e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev); 368775e0569fSMarcel Holtmann 368876bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 3689e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 369076bca880SMarcel Holtmann { 369176bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 369276bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 369376bca880SMarcel Holtmann kfree_skb(skb); 369476bca880SMarcel Holtmann return -ENXIO; 369576bca880SMarcel Holtmann } 369676bca880SMarcel Holtmann 3697d79f34e3SMarcel Holtmann if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT && 3698d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && 3699cc974003SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_SCODATA_PKT && 3700cc974003SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) { 3701fe806dceSMarcel Holtmann kfree_skb(skb); 3702fe806dceSMarcel Holtmann return -EINVAL; 3703fe806dceSMarcel Holtmann } 3704fe806dceSMarcel Holtmann 3705d82603c6SJorrit Schippers /* Incoming skb */ 370676bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 370776bca880SMarcel Holtmann 370876bca880SMarcel Holtmann /* Time stamp */ 370976bca880SMarcel Holtmann __net_timestamp(skb); 371076bca880SMarcel Holtmann 371176bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3712b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3713c78ae283SMarcel Holtmann 371476bca880SMarcel Holtmann return 0; 371576bca880SMarcel Holtmann } 371676bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 371776bca880SMarcel Holtmann 3718e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */ 3719e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb) 3720e875ff84SMarcel Holtmann { 3721581d6fd6SMarcel Holtmann /* Mark as diagnostic packet */ 3722d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_DIAG_PKT; 3723581d6fd6SMarcel Holtmann 3724e875ff84SMarcel Holtmann /* Time stamp */ 3725e875ff84SMarcel Holtmann __net_timestamp(skb); 3726e875ff84SMarcel Holtmann 3727581d6fd6SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3728581d6fd6SMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3729e875ff84SMarcel Holtmann 3730e875ff84SMarcel Holtmann return 0; 3731e875ff84SMarcel Holtmann } 3732e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag); 3733e875ff84SMarcel Holtmann 37345177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...) 37355177a838SMarcel Holtmann { 37365177a838SMarcel Holtmann va_list vargs; 37375177a838SMarcel Holtmann 37385177a838SMarcel Holtmann va_start(vargs, fmt); 37395177a838SMarcel Holtmann kfree_const(hdev->hw_info); 37405177a838SMarcel Holtmann hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 37415177a838SMarcel Holtmann va_end(vargs); 37425177a838SMarcel Holtmann } 37435177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info); 37445177a838SMarcel Holtmann 37455177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...) 37465177a838SMarcel Holtmann { 37475177a838SMarcel Holtmann va_list vargs; 37485177a838SMarcel Holtmann 37495177a838SMarcel Holtmann va_start(vargs, fmt); 37505177a838SMarcel Holtmann kfree_const(hdev->fw_info); 37515177a838SMarcel Holtmann hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 37525177a838SMarcel Holtmann va_end(vargs); 37535177a838SMarcel Holtmann } 37545177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info); 37555177a838SMarcel Holtmann 37561da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 37571da177e4SLinus Torvalds 37581da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 37591da177e4SLinus Torvalds { 37601da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 37611da177e4SLinus Torvalds 3762fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 376300629e0fSJohan Hedberg list_add_tail(&cb->list, &hci_cb_list); 3764fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 37651da177e4SLinus Torvalds 37661da177e4SLinus Torvalds return 0; 37671da177e4SLinus Torvalds } 37681da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 37691da177e4SLinus Torvalds 37701da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 37711da177e4SLinus Torvalds { 37721da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 37731da177e4SLinus Torvalds 3774fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 37751da177e4SLinus Torvalds list_del(&cb->list); 3776fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 37771da177e4SLinus Torvalds 37781da177e4SLinus Torvalds return 0; 37791da177e4SLinus Torvalds } 37801da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 37811da177e4SLinus Torvalds 378251086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 37831da177e4SLinus Torvalds { 3784cdc52faaSMarcel Holtmann int err; 3785cdc52faaSMarcel Holtmann 3786d79f34e3SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb), 3787d79f34e3SMarcel Holtmann skb->len); 37881da177e4SLinus Torvalds 37891da177e4SLinus Torvalds /* Time stamp */ 3790a61bbcf2SPatrick McHardy __net_timestamp(skb); 37911da177e4SLinus Torvalds 3792cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3793cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3794cd82e61cSMarcel Holtmann 3795cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3796cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3797470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 37981da177e4SLinus Torvalds } 37991da177e4SLinus Torvalds 38001da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 38011da177e4SLinus Torvalds skb_orphan(skb); 38021da177e4SLinus Torvalds 380373d0d3c8SMarcel Holtmann if (!test_bit(HCI_RUNNING, &hdev->flags)) { 380473d0d3c8SMarcel Holtmann kfree_skb(skb); 380573d0d3c8SMarcel Holtmann return; 380673d0d3c8SMarcel Holtmann } 380773d0d3c8SMarcel Holtmann 3808cdc52faaSMarcel Holtmann err = hdev->send(hdev, skb); 3809cdc52faaSMarcel Holtmann if (err < 0) { 38102064ee33SMarcel Holtmann bt_dev_err(hdev, "sending frame failed (%d)", err); 3811cdc52faaSMarcel Holtmann kfree_skb(skb); 3812cdc52faaSMarcel Holtmann } 38131da177e4SLinus Torvalds } 38141da177e4SLinus Torvalds 38151ca3a9d0SJohan Hedberg /* Send HCI command */ 381607dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 381707dc93ddSJohan Hedberg const void *param) 38181ca3a9d0SJohan Hedberg { 38191ca3a9d0SJohan Hedberg struct sk_buff *skb; 38201ca3a9d0SJohan Hedberg 38211ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 38221ca3a9d0SJohan Hedberg 38231ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 38241ca3a9d0SJohan Hedberg if (!skb) { 38252064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for command"); 38261ca3a9d0SJohan Hedberg return -ENOMEM; 38271ca3a9d0SJohan Hedberg } 38281ca3a9d0SJohan Hedberg 382949c922bbSStephen Hemminger /* Stand-alone HCI commands must be flagged as 383011714b3dSJohan Hedberg * single-command requests. 383111714b3dSJohan Hedberg */ 383244d27137SJohan Hedberg bt_cb(skb)->hci.req_flags |= HCI_REQ_START; 383311714b3dSJohan Hedberg 38341da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3835c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 38361da177e4SLinus Torvalds 38371da177e4SLinus Torvalds return 0; 38381da177e4SLinus Torvalds } 38391da177e4SLinus Torvalds 3840d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen, 3841d6ee6ad7SLoic Poulain const void *param) 3842d6ee6ad7SLoic Poulain { 3843d6ee6ad7SLoic Poulain struct sk_buff *skb; 3844d6ee6ad7SLoic Poulain 3845d6ee6ad7SLoic Poulain if (hci_opcode_ogf(opcode) != 0x3f) { 3846d6ee6ad7SLoic Poulain /* A controller receiving a command shall respond with either 3847d6ee6ad7SLoic Poulain * a Command Status Event or a Command Complete Event. 3848d6ee6ad7SLoic Poulain * Therefore, all standard HCI commands must be sent via the 3849d6ee6ad7SLoic Poulain * standard API, using hci_send_cmd or hci_cmd_sync helpers. 3850d6ee6ad7SLoic Poulain * Some vendors do not comply with this rule for vendor-specific 3851d6ee6ad7SLoic Poulain * commands and do not return any event. We want to support 3852d6ee6ad7SLoic Poulain * unresponded commands for such cases only. 3853d6ee6ad7SLoic Poulain */ 3854d6ee6ad7SLoic Poulain bt_dev_err(hdev, "unresponded command not supported"); 3855d6ee6ad7SLoic Poulain return -EINVAL; 3856d6ee6ad7SLoic Poulain } 3857d6ee6ad7SLoic Poulain 3858d6ee6ad7SLoic Poulain skb = hci_prepare_cmd(hdev, opcode, plen, param); 3859d6ee6ad7SLoic Poulain if (!skb) { 3860d6ee6ad7SLoic Poulain bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)", 3861d6ee6ad7SLoic Poulain opcode); 3862d6ee6ad7SLoic Poulain return -ENOMEM; 3863d6ee6ad7SLoic Poulain } 3864d6ee6ad7SLoic Poulain 3865d6ee6ad7SLoic Poulain hci_send_frame(hdev, skb); 3866d6ee6ad7SLoic Poulain 3867d6ee6ad7SLoic Poulain return 0; 3868d6ee6ad7SLoic Poulain } 3869d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send); 3870d6ee6ad7SLoic Poulain 38711da177e4SLinus Torvalds /* Get data from the previously sent command */ 3872a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 38731da177e4SLinus Torvalds { 38741da177e4SLinus Torvalds struct hci_command_hdr *hdr; 38751da177e4SLinus Torvalds 38761da177e4SLinus Torvalds if (!hdev->sent_cmd) 38771da177e4SLinus Torvalds return NULL; 38781da177e4SLinus Torvalds 38791da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 38801da177e4SLinus Torvalds 3881a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 38821da177e4SLinus Torvalds return NULL; 38831da177e4SLinus Torvalds 3884f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 38851da177e4SLinus Torvalds 38861da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 38871da177e4SLinus Torvalds } 38881da177e4SLinus Torvalds 3889fbef168fSLoic Poulain /* Send HCI command and wait for command commplete event */ 3890fbef168fSLoic Poulain struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 3891fbef168fSLoic Poulain const void *param, u32 timeout) 3892fbef168fSLoic Poulain { 3893fbef168fSLoic Poulain struct sk_buff *skb; 3894fbef168fSLoic Poulain 3895fbef168fSLoic Poulain if (!test_bit(HCI_UP, &hdev->flags)) 3896fbef168fSLoic Poulain return ERR_PTR(-ENETDOWN); 3897fbef168fSLoic Poulain 3898fbef168fSLoic Poulain bt_dev_dbg(hdev, "opcode 0x%4.4x plen %d", opcode, plen); 3899fbef168fSLoic Poulain 3900b504430cSJohan Hedberg hci_req_sync_lock(hdev); 3901fbef168fSLoic Poulain skb = __hci_cmd_sync(hdev, opcode, plen, param, timeout); 3902b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 3903fbef168fSLoic Poulain 3904fbef168fSLoic Poulain return skb; 3905fbef168fSLoic Poulain } 3906fbef168fSLoic Poulain EXPORT_SYMBOL(hci_cmd_sync); 3907fbef168fSLoic Poulain 39081da177e4SLinus Torvalds /* Send ACL data */ 39091da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 39101da177e4SLinus Torvalds { 39111da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 39121da177e4SLinus Torvalds int len = skb->len; 39131da177e4SLinus Torvalds 3914badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3915badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 39169c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3917aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3918aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 39191da177e4SLinus Torvalds } 39201da177e4SLinus Torvalds 3921ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 392273d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 39231da177e4SLinus Torvalds { 3924ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 39251da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 39261da177e4SLinus Torvalds struct sk_buff *list; 39271da177e4SLinus Torvalds 3928087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3929087bfd99SGustavo Padovan skb->data_len = 0; 3930087bfd99SGustavo Padovan 3931d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 3932204a6e54SAndrei Emeltchenko 3933204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3934ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 3935087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3936204a6e54SAndrei Emeltchenko break; 3937204a6e54SAndrei Emeltchenko case HCI_AMP: 3938204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3939204a6e54SAndrei Emeltchenko break; 3940204a6e54SAndrei Emeltchenko default: 39412064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type); 3942204a6e54SAndrei Emeltchenko return; 3943204a6e54SAndrei Emeltchenko } 3944087bfd99SGustavo Padovan 394570f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 394670f23020SAndrei Emeltchenko if (!list) { 39471da177e4SLinus Torvalds /* Non fragmented */ 39481da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 39491da177e4SLinus Torvalds 395073d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 39511da177e4SLinus Torvalds } else { 39521da177e4SLinus Torvalds /* Fragmented */ 39531da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 39541da177e4SLinus Torvalds 39551da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 39561da177e4SLinus Torvalds 39579cfd5a23SJukka Rissanen /* Queue all fragments atomically. We need to use spin_lock_bh 39589cfd5a23SJukka Rissanen * here because of 6LoWPAN links, as there this function is 39599cfd5a23SJukka Rissanen * called from softirq and using normal spin lock could cause 39609cfd5a23SJukka Rissanen * deadlocks. 39619cfd5a23SJukka Rissanen */ 39629cfd5a23SJukka Rissanen spin_lock_bh(&queue->lock); 39631da177e4SLinus Torvalds 396473d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3965e702112fSAndrei Emeltchenko 3966e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3967e702112fSAndrei Emeltchenko flags |= ACL_CONT; 39681da177e4SLinus Torvalds do { 39691da177e4SLinus Torvalds skb = list; list = list->next; 39701da177e4SLinus Torvalds 3971d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 3972e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 39731da177e4SLinus Torvalds 39741da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 39751da177e4SLinus Torvalds 397673d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 39771da177e4SLinus Torvalds } while (list); 39781da177e4SLinus Torvalds 39799cfd5a23SJukka Rissanen spin_unlock_bh(&queue->lock); 39801da177e4SLinus Torvalds } 398173d80debSLuiz Augusto von Dentz } 398273d80debSLuiz Augusto von Dentz 398373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 398473d80debSLuiz Augusto von Dentz { 3985ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 398673d80debSLuiz Augusto von Dentz 3987f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 398873d80debSLuiz Augusto von Dentz 3989ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 39901da177e4SLinus Torvalds 39913eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 39921da177e4SLinus Torvalds } 39931da177e4SLinus Torvalds 39941da177e4SLinus Torvalds /* Send SCO data */ 39950d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 39961da177e4SLinus Torvalds { 39971da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 39981da177e4SLinus Torvalds struct hci_sco_hdr hdr; 39991da177e4SLinus Torvalds 40001da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 40011da177e4SLinus Torvalds 4002aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 40031da177e4SLinus Torvalds hdr.dlen = skb->len; 40041da177e4SLinus Torvalds 4005badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 4006badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 40079c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 40081da177e4SLinus Torvalds 4009d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_SCODATA_PKT; 4010c78ae283SMarcel Holtmann 40111da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 40123eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 40131da177e4SLinus Torvalds } 40141da177e4SLinus Torvalds 40151da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 40161da177e4SLinus Torvalds 40171da177e4SLinus Torvalds /* HCI Connection scheduler */ 40186039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 4019a8c5fb1aSGustavo Padovan int *quote) 40201da177e4SLinus Torvalds { 40211da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 40228035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 4023abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 40241da177e4SLinus Torvalds 40251da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 40261da177e4SLinus Torvalds * added and removed with TX task disabled. */ 4027bf4c6325SGustavo F. Padovan 4028bf4c6325SGustavo F. Padovan rcu_read_lock(); 4029bf4c6325SGustavo F. Padovan 4030bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4031769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 40321da177e4SLinus Torvalds continue; 4033769be974SMarcel Holtmann 4034769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 4035769be974SMarcel Holtmann continue; 4036769be974SMarcel Holtmann 40371da177e4SLinus Torvalds num++; 40381da177e4SLinus Torvalds 40391da177e4SLinus Torvalds if (c->sent < min) { 40401da177e4SLinus Torvalds min = c->sent; 40411da177e4SLinus Torvalds conn = c; 40421da177e4SLinus Torvalds } 404352087a79SLuiz Augusto von Dentz 404452087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 404552087a79SLuiz Augusto von Dentz break; 40461da177e4SLinus Torvalds } 40471da177e4SLinus Torvalds 4048bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4049bf4c6325SGustavo F. Padovan 40501da177e4SLinus Torvalds if (conn) { 40516ed58ec5SVille Tervo int cnt, q; 40526ed58ec5SVille Tervo 40536ed58ec5SVille Tervo switch (conn->type) { 40546ed58ec5SVille Tervo case ACL_LINK: 40556ed58ec5SVille Tervo cnt = hdev->acl_cnt; 40566ed58ec5SVille Tervo break; 40576ed58ec5SVille Tervo case SCO_LINK: 40586ed58ec5SVille Tervo case ESCO_LINK: 40596ed58ec5SVille Tervo cnt = hdev->sco_cnt; 40606ed58ec5SVille Tervo break; 40616ed58ec5SVille Tervo case LE_LINK: 40626ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 40636ed58ec5SVille Tervo break; 40646ed58ec5SVille Tervo default: 40656ed58ec5SVille Tervo cnt = 0; 40662064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown link type %d", conn->type); 40676ed58ec5SVille Tervo } 40686ed58ec5SVille Tervo 40696ed58ec5SVille Tervo q = cnt / num; 40701da177e4SLinus Torvalds *quote = q ? q : 1; 40711da177e4SLinus Torvalds } else 40721da177e4SLinus Torvalds *quote = 0; 40731da177e4SLinus Torvalds 40741da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 40751da177e4SLinus Torvalds return conn; 40761da177e4SLinus Torvalds } 40771da177e4SLinus Torvalds 40786039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 40791da177e4SLinus Torvalds { 40801da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 40811da177e4SLinus Torvalds struct hci_conn *c; 40821da177e4SLinus Torvalds 40832064ee33SMarcel Holtmann bt_dev_err(hdev, "link tx timeout"); 40841da177e4SLinus Torvalds 4085bf4c6325SGustavo F. Padovan rcu_read_lock(); 4086bf4c6325SGustavo F. Padovan 40871da177e4SLinus Torvalds /* Kill stalled connections */ 4088bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4089bae1f5d9SVille Tervo if (c->type == type && c->sent) { 40902064ee33SMarcel Holtmann bt_dev_err(hdev, "killing stalled connection %pMR", 40912064ee33SMarcel Holtmann &c->dst); 4092bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 40931da177e4SLinus Torvalds } 40941da177e4SLinus Torvalds } 4095bf4c6325SGustavo F. Padovan 4096bf4c6325SGustavo F. Padovan rcu_read_unlock(); 40971da177e4SLinus Torvalds } 40981da177e4SLinus Torvalds 40996039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 410073d80debSLuiz Augusto von Dentz int *quote) 410173d80debSLuiz Augusto von Dentz { 410273d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 410373d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 4104abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 410573d80debSLuiz Augusto von Dentz struct hci_conn *conn; 410673d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 410773d80debSLuiz Augusto von Dentz 410873d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 410973d80debSLuiz Augusto von Dentz 4110bf4c6325SGustavo F. Padovan rcu_read_lock(); 4111bf4c6325SGustavo F. Padovan 4112bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 411373d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 411473d80debSLuiz Augusto von Dentz 411573d80debSLuiz Augusto von Dentz if (conn->type != type) 411673d80debSLuiz Augusto von Dentz continue; 411773d80debSLuiz Augusto von Dentz 411873d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 411973d80debSLuiz Augusto von Dentz continue; 412073d80debSLuiz Augusto von Dentz 412173d80debSLuiz Augusto von Dentz conn_num++; 412273d80debSLuiz Augusto von Dentz 41238192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 412473d80debSLuiz Augusto von Dentz struct sk_buff *skb; 412573d80debSLuiz Augusto von Dentz 412673d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 412773d80debSLuiz Augusto von Dentz continue; 412873d80debSLuiz Augusto von Dentz 412973d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 413073d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 413173d80debSLuiz Augusto von Dentz continue; 413273d80debSLuiz Augusto von Dentz 413373d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 413473d80debSLuiz Augusto von Dentz num = 0; 413573d80debSLuiz Augusto von Dentz min = ~0; 413673d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 413773d80debSLuiz Augusto von Dentz } 413873d80debSLuiz Augusto von Dentz 413973d80debSLuiz Augusto von Dentz num++; 414073d80debSLuiz Augusto von Dentz 414173d80debSLuiz Augusto von Dentz if (conn->sent < min) { 414273d80debSLuiz Augusto von Dentz min = conn->sent; 414373d80debSLuiz Augusto von Dentz chan = tmp; 414473d80debSLuiz Augusto von Dentz } 414573d80debSLuiz Augusto von Dentz } 414673d80debSLuiz Augusto von Dentz 414773d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 414873d80debSLuiz Augusto von Dentz break; 414973d80debSLuiz Augusto von Dentz } 415073d80debSLuiz Augusto von Dentz 4151bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4152bf4c6325SGustavo F. Padovan 415373d80debSLuiz Augusto von Dentz if (!chan) 415473d80debSLuiz Augusto von Dentz return NULL; 415573d80debSLuiz Augusto von Dentz 415673d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 415773d80debSLuiz Augusto von Dentz case ACL_LINK: 415873d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 415973d80debSLuiz Augusto von Dentz break; 4160bd1eb66bSAndrei Emeltchenko case AMP_LINK: 4161bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 4162bd1eb66bSAndrei Emeltchenko break; 416373d80debSLuiz Augusto von Dentz case SCO_LINK: 416473d80debSLuiz Augusto von Dentz case ESCO_LINK: 416573d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 416673d80debSLuiz Augusto von Dentz break; 416773d80debSLuiz Augusto von Dentz case LE_LINK: 416873d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 416973d80debSLuiz Augusto von Dentz break; 417073d80debSLuiz Augusto von Dentz default: 417173d80debSLuiz Augusto von Dentz cnt = 0; 41722064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown link type %d", chan->conn->type); 417373d80debSLuiz Augusto von Dentz } 417473d80debSLuiz Augusto von Dentz 417573d80debSLuiz Augusto von Dentz q = cnt / num; 417673d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 417773d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 417873d80debSLuiz Augusto von Dentz return chan; 417973d80debSLuiz Augusto von Dentz } 418073d80debSLuiz Augusto von Dentz 418102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 418202b20f0bSLuiz Augusto von Dentz { 418302b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 418402b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 418502b20f0bSLuiz Augusto von Dentz int num = 0; 418602b20f0bSLuiz Augusto von Dentz 418702b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 418802b20f0bSLuiz Augusto von Dentz 4189bf4c6325SGustavo F. Padovan rcu_read_lock(); 4190bf4c6325SGustavo F. Padovan 4191bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 419202b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 419302b20f0bSLuiz Augusto von Dentz 419402b20f0bSLuiz Augusto von Dentz if (conn->type != type) 419502b20f0bSLuiz Augusto von Dentz continue; 419602b20f0bSLuiz Augusto von Dentz 419702b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 419802b20f0bSLuiz Augusto von Dentz continue; 419902b20f0bSLuiz Augusto von Dentz 420002b20f0bSLuiz Augusto von Dentz num++; 420102b20f0bSLuiz Augusto von Dentz 42028192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 420302b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 420402b20f0bSLuiz Augusto von Dentz 420502b20f0bSLuiz Augusto von Dentz if (chan->sent) { 420602b20f0bSLuiz Augusto von Dentz chan->sent = 0; 420702b20f0bSLuiz Augusto von Dentz continue; 420802b20f0bSLuiz Augusto von Dentz } 420902b20f0bSLuiz Augusto von Dentz 421002b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 421102b20f0bSLuiz Augusto von Dentz continue; 421202b20f0bSLuiz Augusto von Dentz 421302b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 421402b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 421502b20f0bSLuiz Augusto von Dentz continue; 421602b20f0bSLuiz Augusto von Dentz 421702b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 421802b20f0bSLuiz Augusto von Dentz 421902b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 422002b20f0bSLuiz Augusto von Dentz skb->priority); 422102b20f0bSLuiz Augusto von Dentz } 422202b20f0bSLuiz Augusto von Dentz 422302b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 422402b20f0bSLuiz Augusto von Dentz break; 422502b20f0bSLuiz Augusto von Dentz } 4226bf4c6325SGustavo F. Padovan 4227bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4228bf4c6325SGustavo F. Padovan 422902b20f0bSLuiz Augusto von Dentz } 423002b20f0bSLuiz Augusto von Dentz 4231b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4232b71d385aSAndrei Emeltchenko { 4233b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4234b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4235b71d385aSAndrei Emeltchenko } 4236b71d385aSAndrei Emeltchenko 42376039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 42381da177e4SLinus Torvalds { 4239d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 42401da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 42411da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 424263d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 42435f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 4244bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 42451da177e4SLinus Torvalds } 424663d2bc1bSAndrei Emeltchenko } 42471da177e4SLinus Torvalds 42487fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */ 42497fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev) 42507fedd3bbSAbhishek Pandit-Subedi { 42517fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn; 42527fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb; 42537fedd3bbSAbhishek Pandit-Subedi int quote; 42547fedd3bbSAbhishek Pandit-Subedi 42557fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name); 42567fedd3bbSAbhishek Pandit-Subedi 42577fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, SCO_LINK)) 42587fedd3bbSAbhishek Pandit-Subedi return; 42597fedd3bbSAbhishek Pandit-Subedi 42607fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 42617fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 42627fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len); 42637fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb); 42647fedd3bbSAbhishek Pandit-Subedi 42657fedd3bbSAbhishek Pandit-Subedi conn->sent++; 42667fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0) 42677fedd3bbSAbhishek Pandit-Subedi conn->sent = 0; 42687fedd3bbSAbhishek Pandit-Subedi } 42697fedd3bbSAbhishek Pandit-Subedi } 42707fedd3bbSAbhishek Pandit-Subedi } 42717fedd3bbSAbhishek Pandit-Subedi 42727fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev) 42737fedd3bbSAbhishek Pandit-Subedi { 42747fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn; 42757fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb; 42767fedd3bbSAbhishek Pandit-Subedi int quote; 42777fedd3bbSAbhishek Pandit-Subedi 42787fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name); 42797fedd3bbSAbhishek Pandit-Subedi 42807fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, ESCO_LINK)) 42817fedd3bbSAbhishek Pandit-Subedi return; 42827fedd3bbSAbhishek Pandit-Subedi 42837fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 42847fedd3bbSAbhishek Pandit-Subedi "e))) { 42857fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 42867fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len); 42877fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb); 42887fedd3bbSAbhishek Pandit-Subedi 42897fedd3bbSAbhishek Pandit-Subedi conn->sent++; 42907fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0) 42917fedd3bbSAbhishek Pandit-Subedi conn->sent = 0; 42927fedd3bbSAbhishek Pandit-Subedi } 42937fedd3bbSAbhishek Pandit-Subedi } 42947fedd3bbSAbhishek Pandit-Subedi } 42957fedd3bbSAbhishek Pandit-Subedi 42966039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 429763d2bc1bSAndrei Emeltchenko { 429863d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 429963d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 430063d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 430163d2bc1bSAndrei Emeltchenko int quote; 430263d2bc1bSAndrei Emeltchenko 430363d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 430404837f64SMarcel Holtmann 430573d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 430673d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 4307ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4308ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 430973d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 431073d80debSLuiz Augusto von Dentz skb->len, skb->priority); 431173d80debSLuiz Augusto von Dentz 4312ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4313ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4314ec1cce24SLuiz Augusto von Dentz break; 4315ec1cce24SLuiz Augusto von Dentz 4316ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4317ec1cce24SLuiz Augusto von Dentz 431873d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 431973d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 432004837f64SMarcel Holtmann 432157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 43221da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 43231da177e4SLinus Torvalds 43241da177e4SLinus Torvalds hdev->acl_cnt--; 432573d80debSLuiz Augusto von Dentz chan->sent++; 432673d80debSLuiz Augusto von Dentz chan->conn->sent++; 43277fedd3bbSAbhishek Pandit-Subedi 43287fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */ 43297fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev); 43307fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev); 43311da177e4SLinus Torvalds } 43321da177e4SLinus Torvalds } 433302b20f0bSLuiz Augusto von Dentz 433402b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 433502b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 43361da177e4SLinus Torvalds } 43371da177e4SLinus Torvalds 43386039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4339b71d385aSAndrei Emeltchenko { 434063d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4341b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4342b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4343b71d385aSAndrei Emeltchenko int quote; 4344bd1eb66bSAndrei Emeltchenko u8 type; 4345b71d385aSAndrei Emeltchenko 434663d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4347b71d385aSAndrei Emeltchenko 4348bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4349bd1eb66bSAndrei Emeltchenko 4350bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4351bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4352bd1eb66bSAndrei Emeltchenko else 4353bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4354bd1eb66bSAndrei Emeltchenko 4355b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4356bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4357b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4358b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4359b71d385aSAndrei Emeltchenko int blocks; 4360b71d385aSAndrei Emeltchenko 4361b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4362b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4363b71d385aSAndrei Emeltchenko 4364b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4365b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4366b71d385aSAndrei Emeltchenko break; 4367b71d385aSAndrei Emeltchenko 4368b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4369b71d385aSAndrei Emeltchenko 4370b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4371b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4372b71d385aSAndrei Emeltchenko return; 4373b71d385aSAndrei Emeltchenko 4374b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4375b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4376b71d385aSAndrei Emeltchenko 437757d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4378b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4379b71d385aSAndrei Emeltchenko 4380b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4381b71d385aSAndrei Emeltchenko quote -= blocks; 4382b71d385aSAndrei Emeltchenko 4383b71d385aSAndrei Emeltchenko chan->sent += blocks; 4384b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4385b71d385aSAndrei Emeltchenko } 4386b71d385aSAndrei Emeltchenko } 4387b71d385aSAndrei Emeltchenko 4388b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4389bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4390b71d385aSAndrei Emeltchenko } 4391b71d385aSAndrei Emeltchenko 43926039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4393b71d385aSAndrei Emeltchenko { 4394b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4395b71d385aSAndrei Emeltchenko 4396bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4397ca8bee5dSMarcel Holtmann if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY) 4398bd1eb66bSAndrei Emeltchenko return; 4399bd1eb66bSAndrei Emeltchenko 4400bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4401bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4402b71d385aSAndrei Emeltchenko return; 4403b71d385aSAndrei Emeltchenko 4404b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4405b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4406b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4407b71d385aSAndrei Emeltchenko break; 4408b71d385aSAndrei Emeltchenko 4409b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4410b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4411b71d385aSAndrei Emeltchenko break; 4412b71d385aSAndrei Emeltchenko } 4413b71d385aSAndrei Emeltchenko } 4414b71d385aSAndrei Emeltchenko 44156039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 44166ed58ec5SVille Tervo { 441773d80debSLuiz Augusto von Dentz struct hci_chan *chan; 44186ed58ec5SVille Tervo struct sk_buff *skb; 441902b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 44206ed58ec5SVille Tervo 44216ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 44226ed58ec5SVille Tervo 442352087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 442452087a79SLuiz Augusto von Dentz return; 442552087a79SLuiz Augusto von Dentz 44266ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 44271b1d29e5SLuiz Augusto von Dentz 44281b1d29e5SLuiz Augusto von Dentz __check_timeout(hdev, cnt); 44291b1d29e5SLuiz Augusto von Dentz 443002b20f0bSLuiz Augusto von Dentz tmp = cnt; 443173d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 4432ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4433ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 443473d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 443573d80debSLuiz Augusto von Dentz skb->len, skb->priority); 44366ed58ec5SVille Tervo 4437ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4438ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4439ec1cce24SLuiz Augusto von Dentz break; 4440ec1cce24SLuiz Augusto von Dentz 4441ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4442ec1cce24SLuiz Augusto von Dentz 444357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 44446ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 44456ed58ec5SVille Tervo 44466ed58ec5SVille Tervo cnt--; 444773d80debSLuiz Augusto von Dentz chan->sent++; 444873d80debSLuiz Augusto von Dentz chan->conn->sent++; 44497fedd3bbSAbhishek Pandit-Subedi 44507fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */ 44517fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev); 44527fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev); 44536ed58ec5SVille Tervo } 44546ed58ec5SVille Tervo } 445573d80debSLuiz Augusto von Dentz 44566ed58ec5SVille Tervo if (hdev->le_pkts) 44576ed58ec5SVille Tervo hdev->le_cnt = cnt; 44586ed58ec5SVille Tervo else 44596ed58ec5SVille Tervo hdev->acl_cnt = cnt; 446002b20f0bSLuiz Augusto von Dentz 446102b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 446202b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 44636ed58ec5SVille Tervo } 44646ed58ec5SVille Tervo 44653eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 44661da177e4SLinus Torvalds { 44673eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 44681da177e4SLinus Torvalds struct sk_buff *skb; 44691da177e4SLinus Torvalds 44706ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 44716ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 44721da177e4SLinus Torvalds 4473d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 44741da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 44751da177e4SLinus Torvalds hci_sched_sco(hdev); 4476b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 44777fedd3bbSAbhishek Pandit-Subedi hci_sched_acl(hdev); 44786ed58ec5SVille Tervo hci_sched_le(hdev); 447952de599eSMarcel Holtmann } 44806ed58ec5SVille Tervo 44811da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 44821da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 448357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 44841da177e4SLinus Torvalds } 44851da177e4SLinus Torvalds 448625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 44871da177e4SLinus Torvalds 44881da177e4SLinus Torvalds /* ACL data packet */ 44896039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 44901da177e4SLinus Torvalds { 44911da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 44921da177e4SLinus Torvalds struct hci_conn *conn; 44931da177e4SLinus Torvalds __u16 handle, flags; 44941da177e4SLinus Torvalds 44951da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 44961da177e4SLinus Torvalds 44971da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 44981da177e4SLinus Torvalds flags = hci_flags(handle); 44991da177e4SLinus Torvalds handle = hci_handle(handle); 45001da177e4SLinus Torvalds 4501f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4502a8c5fb1aSGustavo Padovan handle, flags); 45031da177e4SLinus Torvalds 45041da177e4SLinus Torvalds hdev->stat.acl_rx++; 45051da177e4SLinus Torvalds 45061da177e4SLinus Torvalds hci_dev_lock(hdev); 45071da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 45081da177e4SLinus Torvalds hci_dev_unlock(hdev); 45091da177e4SLinus Torvalds 45101da177e4SLinus Torvalds if (conn) { 451165983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 451204837f64SMarcel Holtmann 45131da177e4SLinus Torvalds /* Send to upper protocol */ 4514686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 45151da177e4SLinus Torvalds return; 45161da177e4SLinus Torvalds } else { 45172064ee33SMarcel Holtmann bt_dev_err(hdev, "ACL packet for unknown connection handle %d", 45182064ee33SMarcel Holtmann handle); 45191da177e4SLinus Torvalds } 45201da177e4SLinus Torvalds 45211da177e4SLinus Torvalds kfree_skb(skb); 45221da177e4SLinus Torvalds } 45231da177e4SLinus Torvalds 45241da177e4SLinus Torvalds /* SCO data packet */ 45256039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 45261da177e4SLinus Torvalds { 45271da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 45281da177e4SLinus Torvalds struct hci_conn *conn; 4529debdedf2SMarcel Holtmann __u16 handle, flags; 45301da177e4SLinus Torvalds 45311da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 45321da177e4SLinus Torvalds 45331da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 4534debdedf2SMarcel Holtmann flags = hci_flags(handle); 4535debdedf2SMarcel Holtmann handle = hci_handle(handle); 45361da177e4SLinus Torvalds 4537debdedf2SMarcel Holtmann BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4538debdedf2SMarcel Holtmann handle, flags); 45391da177e4SLinus Torvalds 45401da177e4SLinus Torvalds hdev->stat.sco_rx++; 45411da177e4SLinus Torvalds 45421da177e4SLinus Torvalds hci_dev_lock(hdev); 45431da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 45441da177e4SLinus Torvalds hci_dev_unlock(hdev); 45451da177e4SLinus Torvalds 45461da177e4SLinus Torvalds if (conn) { 45471da177e4SLinus Torvalds /* Send to upper protocol */ 4548686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 45491da177e4SLinus Torvalds return; 45501da177e4SLinus Torvalds } else { 45512064ee33SMarcel Holtmann bt_dev_err(hdev, "SCO packet for unknown connection handle %d", 45522064ee33SMarcel Holtmann handle); 45531da177e4SLinus Torvalds } 45541da177e4SLinus Torvalds 45551da177e4SLinus Torvalds kfree_skb(skb); 45561da177e4SLinus Torvalds } 45571da177e4SLinus Torvalds 45589238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 45599238f36aSJohan Hedberg { 45609238f36aSJohan Hedberg struct sk_buff *skb; 45619238f36aSJohan Hedberg 45629238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 45639238f36aSJohan Hedberg if (!skb) 45649238f36aSJohan Hedberg return true; 45659238f36aSJohan Hedberg 456644d27137SJohan Hedberg return (bt_cb(skb)->hci.req_flags & HCI_REQ_START); 45679238f36aSJohan Hedberg } 45689238f36aSJohan Hedberg 456942c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 457042c6b129SJohan Hedberg { 457142c6b129SJohan Hedberg struct hci_command_hdr *sent; 457242c6b129SJohan Hedberg struct sk_buff *skb; 457342c6b129SJohan Hedberg u16 opcode; 457442c6b129SJohan Hedberg 457542c6b129SJohan Hedberg if (!hdev->sent_cmd) 457642c6b129SJohan Hedberg return; 457742c6b129SJohan Hedberg 457842c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 457942c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 458042c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 458142c6b129SJohan Hedberg return; 458242c6b129SJohan Hedberg 458342c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 458442c6b129SJohan Hedberg if (!skb) 458542c6b129SJohan Hedberg return; 458642c6b129SJohan Hedberg 458742c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 458842c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 458942c6b129SJohan Hedberg } 459042c6b129SJohan Hedberg 4591e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, 4592e6214487SJohan Hedberg hci_req_complete_t *req_complete, 4593e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 45949238f36aSJohan Hedberg { 45959238f36aSJohan Hedberg struct sk_buff *skb; 45969238f36aSJohan Hedberg unsigned long flags; 45979238f36aSJohan Hedberg 45989238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 45999238f36aSJohan Hedberg 460042c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 460142c6b129SJohan Hedberg * sent we need to do special handling of it. 46029238f36aSJohan Hedberg */ 460342c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 460442c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 460542c6b129SJohan Hedberg * reset complete event during init and any pending 460642c6b129SJohan Hedberg * command will never be completed. In such a case we 460742c6b129SJohan Hedberg * need to resend whatever was the last sent 460842c6b129SJohan Hedberg * command. 460942c6b129SJohan Hedberg */ 461042c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 461142c6b129SJohan Hedberg hci_resend_last(hdev); 461242c6b129SJohan Hedberg 46139238f36aSJohan Hedberg return; 461442c6b129SJohan Hedberg } 46159238f36aSJohan Hedberg 4616f80c5dadSJoão Paulo Rechi Vita /* If we reach this point this event matches the last command sent */ 4617f80c5dadSJoão Paulo Rechi Vita hci_dev_clear_flag(hdev, HCI_CMD_PENDING); 4618f80c5dadSJoão Paulo Rechi Vita 46199238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 46209238f36aSJohan Hedberg * this request the request is not yet complete. 46219238f36aSJohan Hedberg */ 46229238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 46239238f36aSJohan Hedberg return; 46249238f36aSJohan Hedberg 46259238f36aSJohan Hedberg /* If this was the last command in a request the complete 46269238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 46279238f36aSJohan Hedberg * command queue (hdev->cmd_q). 46289238f36aSJohan Hedberg */ 462944d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) { 463044d27137SJohan Hedberg *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb; 4631e6214487SJohan Hedberg return; 46329238f36aSJohan Hedberg } 4633e6214487SJohan Hedberg 463444d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_complete) { 463544d27137SJohan Hedberg *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete; 4636e6214487SJohan Hedberg return; 463753e21fbcSJohan Hedberg } 46389238f36aSJohan Hedberg 46399238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 46409238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 46419238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 464244d27137SJohan Hedberg if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) { 46439238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 46449238f36aSJohan Hedberg break; 46459238f36aSJohan Hedberg } 46469238f36aSJohan Hedberg 46473bd7594eSDouglas Anderson if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) 4648242c0ebdSMarcel Holtmann *req_complete_skb = bt_cb(skb)->hci.req_complete_skb; 46493bd7594eSDouglas Anderson else 46503bd7594eSDouglas Anderson *req_complete = bt_cb(skb)->hci.req_complete; 46519238f36aSJohan Hedberg kfree_skb(skb); 46529238f36aSJohan Hedberg } 46539238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 46549238f36aSJohan Hedberg } 46559238f36aSJohan Hedberg 4656b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 46571da177e4SLinus Torvalds { 4658b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 46591da177e4SLinus Torvalds struct sk_buff *skb; 46601da177e4SLinus Torvalds 46611da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 46621da177e4SLinus Torvalds 46631da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 4664cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4665cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4666cd82e61cSMarcel Holtmann 46671da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 46681da177e4SLinus Torvalds /* Send copy to the sockets */ 4669470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 46701da177e4SLinus Torvalds } 46711da177e4SLinus Torvalds 4672eb8c101eSMattijs Korpershoek /* If the device has been opened in HCI_USER_CHANNEL, 4673eb8c101eSMattijs Korpershoek * the userspace has exclusive access to device. 4674eb8c101eSMattijs Korpershoek * When device is HCI_INIT, we still need to process 4675eb8c101eSMattijs Korpershoek * the data packets to the driver in order 4676eb8c101eSMattijs Korpershoek * to complete its setup(). 4677eb8c101eSMattijs Korpershoek */ 4678eb8c101eSMattijs Korpershoek if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 4679eb8c101eSMattijs Korpershoek !test_bit(HCI_INIT, &hdev->flags)) { 46801da177e4SLinus Torvalds kfree_skb(skb); 46811da177e4SLinus Torvalds continue; 46821da177e4SLinus Torvalds } 46831da177e4SLinus Torvalds 46841da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 46851da177e4SLinus Torvalds /* Don't process data packets in this states. */ 4686d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 46871da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 46881da177e4SLinus Torvalds case HCI_SCODATA_PKT: 4689cc974003SMarcel Holtmann case HCI_ISODATA_PKT: 46901da177e4SLinus Torvalds kfree_skb(skb); 46911da177e4SLinus Torvalds continue; 46923ff50b79SStephen Hemminger } 46931da177e4SLinus Torvalds } 46941da177e4SLinus Torvalds 46951da177e4SLinus Torvalds /* Process frame */ 4696d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 46971da177e4SLinus Torvalds case HCI_EVENT_PKT: 4698b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 46991da177e4SLinus Torvalds hci_event_packet(hdev, skb); 47001da177e4SLinus Torvalds break; 47011da177e4SLinus Torvalds 47021da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 47031da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 47041da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 47051da177e4SLinus Torvalds break; 47061da177e4SLinus Torvalds 47071da177e4SLinus Torvalds case HCI_SCODATA_PKT: 47081da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 47091da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 47101da177e4SLinus Torvalds break; 47111da177e4SLinus Torvalds 47121da177e4SLinus Torvalds default: 47131da177e4SLinus Torvalds kfree_skb(skb); 47141da177e4SLinus Torvalds break; 47151da177e4SLinus Torvalds } 47161da177e4SLinus Torvalds } 47171da177e4SLinus Torvalds } 47181da177e4SLinus Torvalds 4719c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 47201da177e4SLinus Torvalds { 4721c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 47221da177e4SLinus Torvalds struct sk_buff *skb; 47231da177e4SLinus Torvalds 47242104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 47252104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 47261da177e4SLinus Torvalds 47271da177e4SLinus Torvalds /* Send queued commands */ 47285a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 47295a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 47305a08ecceSAndrei Emeltchenko if (!skb) 47315a08ecceSAndrei Emeltchenko return; 47325a08ecceSAndrei Emeltchenko 47331da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 47341da177e4SLinus Torvalds 4735a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 473670f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 4737f80c5dadSJoão Paulo Rechi Vita if (hci_req_status_pend(hdev)) 4738f80c5dadSJoão Paulo Rechi Vita hci_dev_set_flag(hdev, HCI_CMD_PENDING); 47391da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 474057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 47417bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 474265cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 47437bdb8a5cSSzymon Janc else 474465cc2b49SMarcel Holtmann schedule_delayed_work(&hdev->cmd_timer, 474565cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT); 47461da177e4SLinus Torvalds } else { 47471da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4748c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 47491da177e4SLinus Torvalds } 47501da177e4SLinus Torvalds } 47511da177e4SLinus Torvalds } 4752