11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 31da177e4SLinus Torvalds Copyright (C) 2000-2001 Qualcomm Incorporated 4590051deSGustavo F. Padovan Copyright (C) 2011 ProFUSION Embedded Systems 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 91da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 101da177e4SLinus Torvalds published by the Free Software Foundation; 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 131da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 141da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 151da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 161da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 171da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 181da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 191da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 221da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 231da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 241da177e4SLinus Torvalds */ 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds /* Bluetooth HCI core. */ 271da177e4SLinus Torvalds 288c520a59SGustavo Padovan #include <linux/export.h> 293df92b31SSasha Levin #include <linux/idr.h> 30611b30f7SMarcel Holtmann #include <linux/rfkill.h> 31baf27f6eSMarcel Holtmann #include <linux/debugfs.h> 3299780a7bSJohan Hedberg #include <linux/crypto.h> 3347219839SMarcel Holtmann #include <asm/unaligned.h> 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 361da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 374bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h> 38af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h> 391da177e4SLinus Torvalds 400857dd3bSJohan Hedberg #include "hci_request.h" 4160c5f5fbSMarcel Holtmann #include "hci_debugfs.h" 42970c4e46SJohan Hedberg #include "smp.h" 436d5d2ee6SHeiner Kallweit #include "leds.h" 44970c4e46SJohan Hedberg 45b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 46c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 473eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds /* HCI device list */ 501da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 511da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 521da177e4SLinus Torvalds 531da177e4SLinus Torvalds /* HCI callback list */ 541da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 55fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock); 561da177e4SLinus Torvalds 573df92b31SSasha Levin /* HCI ID Numbering */ 583df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 593df92b31SSasha Levin 60baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */ 61baf27f6eSMarcel Holtmann 624b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf, 634b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 644b4148e9SMarcel Holtmann { 654b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 664b4148e9SMarcel Holtmann char buf[3]; 674b4148e9SMarcel Holtmann 68b7cb93e5SMarcel Holtmann buf[0] = hci_dev_test_flag(hdev, HCI_DUT_MODE) ? 'Y' : 'N'; 694b4148e9SMarcel Holtmann buf[1] = '\n'; 704b4148e9SMarcel Holtmann buf[2] = '\0'; 714b4148e9SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 724b4148e9SMarcel Holtmann } 734b4148e9SMarcel Holtmann 744b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf, 754b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 764b4148e9SMarcel Holtmann { 774b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 784b4148e9SMarcel Holtmann struct sk_buff *skb; 794b4148e9SMarcel Holtmann char buf[32]; 804b4148e9SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 814b4148e9SMarcel Holtmann bool enable; 824b4148e9SMarcel Holtmann 834b4148e9SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 844b4148e9SMarcel Holtmann return -ENETDOWN; 854b4148e9SMarcel Holtmann 864b4148e9SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 874b4148e9SMarcel Holtmann return -EFAULT; 884b4148e9SMarcel Holtmann 894b4148e9SMarcel Holtmann buf[buf_size] = '\0'; 904b4148e9SMarcel Holtmann if (strtobool(buf, &enable)) 914b4148e9SMarcel Holtmann return -EINVAL; 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 char buf[32]; 1394b4113d6SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 1404b4113d6SMarcel Holtmann bool enable; 1414b4113d6SMarcel Holtmann int err; 1424b4113d6SMarcel Holtmann 1434b4113d6SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 1444b4113d6SMarcel Holtmann return -EFAULT; 1454b4113d6SMarcel Holtmann 1464b4113d6SMarcel Holtmann buf[buf_size] = '\0'; 1474b4113d6SMarcel Holtmann if (strtobool(buf, &enable)) 1484b4113d6SMarcel Holtmann return -EINVAL; 1494b4113d6SMarcel Holtmann 1507e995b9eSMarcel Holtmann /* When the diagnostic flags are not persistent and the transport 151b56c7b25SMarcel Holtmann * is not active or in user channel operation, then there is no need 152b56c7b25SMarcel Holtmann * for the vendor callback. Instead just store the desired value and 153b56c7b25SMarcel Holtmann * the setting will be programmed when the controller gets powered on. 1547e995b9eSMarcel Holtmann */ 1557e995b9eSMarcel Holtmann if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) && 156b56c7b25SMarcel Holtmann (!test_bit(HCI_RUNNING, &hdev->flags) || 157b56c7b25SMarcel Holtmann hci_dev_test_flag(hdev, HCI_USER_CHANNEL))) 1587e995b9eSMarcel Holtmann goto done; 1597e995b9eSMarcel Holtmann 160b504430cSJohan Hedberg hci_req_sync_lock(hdev); 1614b4113d6SMarcel Holtmann err = hdev->set_diag(hdev, enable); 162b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 1634b4113d6SMarcel Holtmann 1644b4113d6SMarcel Holtmann if (err < 0) 1654b4113d6SMarcel Holtmann return err; 1664b4113d6SMarcel Holtmann 1677e995b9eSMarcel Holtmann done: 1684b4113d6SMarcel Holtmann if (enable) 1694b4113d6SMarcel Holtmann hci_dev_set_flag(hdev, HCI_VENDOR_DIAG); 1704b4113d6SMarcel Holtmann else 1714b4113d6SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_VENDOR_DIAG); 1724b4113d6SMarcel Holtmann 1734b4113d6SMarcel Holtmann return count; 1744b4113d6SMarcel Holtmann } 1754b4113d6SMarcel Holtmann 1764b4113d6SMarcel Holtmann static const struct file_operations vendor_diag_fops = { 1774b4113d6SMarcel Holtmann .open = simple_open, 1784b4113d6SMarcel Holtmann .read = vendor_diag_read, 1794b4113d6SMarcel Holtmann .write = vendor_diag_write, 1804b4113d6SMarcel Holtmann .llseek = default_llseek, 1814b4113d6SMarcel Holtmann }; 1824b4113d6SMarcel Holtmann 183f640ee98SMarcel Holtmann static void hci_debugfs_create_basic(struct hci_dev *hdev) 184f640ee98SMarcel Holtmann { 185f640ee98SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 186f640ee98SMarcel Holtmann &dut_mode_fops); 187f640ee98SMarcel Holtmann 188f640ee98SMarcel Holtmann if (hdev->set_diag) 189f640ee98SMarcel Holtmann debugfs_create_file("vendor_diag", 0644, hdev->debugfs, hdev, 190f640ee98SMarcel Holtmann &vendor_diag_fops); 191f640ee98SMarcel Holtmann } 192f640ee98SMarcel Holtmann 193a1d01db1SJohan Hedberg static int hci_reset_req(struct hci_request *req, unsigned long opt) 1941da177e4SLinus Torvalds { 19542c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 1961da177e4SLinus Torvalds 1971da177e4SLinus Torvalds /* Reset device */ 19842c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 19942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 200a1d01db1SJohan Hedberg return 0; 2011da177e4SLinus Torvalds } 2021da177e4SLinus Torvalds 20342c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 2041da177e4SLinus Torvalds { 20542c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 2062455a3eaSAndrei Emeltchenko 2071da177e4SLinus Torvalds /* Read Local Supported Features */ 20842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 2091da177e4SLinus Torvalds 2101143e5a6SMarcel Holtmann /* Read Local Version */ 21142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2122177bab5SJohan Hedberg 2132177bab5SJohan Hedberg /* Read BD Address */ 21442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 2151da177e4SLinus Torvalds } 2161da177e4SLinus Torvalds 2170af801b9SJohan Hedberg static void amp_init1(struct hci_request *req) 218e61ef499SAndrei Emeltchenko { 21942c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 2202455a3eaSAndrei Emeltchenko 221e61ef499SAndrei Emeltchenko /* Read Local Version */ 22242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2236bcbc489SAndrei Emeltchenko 224f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 225f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 226f6996cfeSMarcel Holtmann 2276bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 22842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 229e71dfabaSAndrei Emeltchenko 230e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 23142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 2327528ca1cSMarcel Holtmann 233f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 234f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 235f38ba941SMarcel Holtmann 2367528ca1cSMarcel Holtmann /* Read Location Data */ 2377528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 238e61ef499SAndrei Emeltchenko } 239e61ef499SAndrei Emeltchenko 240a1d01db1SJohan Hedberg static int amp_init2(struct hci_request *req) 2410af801b9SJohan Hedberg { 2420af801b9SJohan Hedberg /* Read Local Supported Features. Not all AMP controllers 2430af801b9SJohan Hedberg * support this so it's placed conditionally in the second 2440af801b9SJohan Hedberg * stage init. 2450af801b9SJohan Hedberg */ 2460af801b9SJohan Hedberg if (req->hdev->commands[14] & 0x20) 2470af801b9SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 248a1d01db1SJohan Hedberg 249a1d01db1SJohan Hedberg return 0; 2500af801b9SJohan Hedberg } 2510af801b9SJohan Hedberg 252a1d01db1SJohan Hedberg static int hci_init1_req(struct hci_request *req, unsigned long opt) 253e61ef499SAndrei Emeltchenko { 25442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 255e61ef499SAndrei Emeltchenko 256e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 257e61ef499SAndrei Emeltchenko 25811778716SAndrei Emeltchenko /* Reset */ 25911778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 26042c6b129SJohan Hedberg hci_reset_req(req, 0); 26111778716SAndrei Emeltchenko 262e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 263ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 26442c6b129SJohan Hedberg bredr_init(req); 265e61ef499SAndrei Emeltchenko break; 266e61ef499SAndrei Emeltchenko case HCI_AMP: 2670af801b9SJohan Hedberg amp_init1(req); 268e61ef499SAndrei Emeltchenko break; 269e61ef499SAndrei Emeltchenko default: 270e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 271e61ef499SAndrei Emeltchenko break; 272e61ef499SAndrei Emeltchenko } 273a1d01db1SJohan Hedberg 274a1d01db1SJohan Hedberg return 0; 275e61ef499SAndrei Emeltchenko } 276e61ef499SAndrei Emeltchenko 27742c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 2782177bab5SJohan Hedberg { 2792177bab5SJohan Hedberg __le16 param; 2802177bab5SJohan Hedberg __u8 flt_type; 2812177bab5SJohan Hedberg 2822177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 28342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 2842177bab5SJohan Hedberg 2852177bab5SJohan Hedberg /* Read Class of Device */ 28642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 2872177bab5SJohan Hedberg 2882177bab5SJohan Hedberg /* Read Local Name */ 28942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 2902177bab5SJohan Hedberg 2912177bab5SJohan Hedberg /* Read Voice Setting */ 29242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 2932177bab5SJohan Hedberg 294b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 295b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 296b4cb9fb2SMarcel Holtmann 2974b836f39SMarcel Holtmann /* Read Current IAC LAP */ 2984b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 2994b836f39SMarcel Holtmann 3002177bab5SJohan Hedberg /* Clear Event Filters */ 3012177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 30242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 3032177bab5SJohan Hedberg 3042177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 305dcf4adbfSJoe Perches param = cpu_to_le16(0x7d00); 30642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 3072177bab5SJohan Hedberg } 3082177bab5SJohan Hedberg 30942c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 3102177bab5SJohan Hedberg { 311c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 312c73eee91SJohan Hedberg 3132177bab5SJohan Hedberg /* Read LE Buffer Size */ 31442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 3152177bab5SJohan Hedberg 3162177bab5SJohan Hedberg /* Read LE Local Supported Features */ 31742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 3182177bab5SJohan Hedberg 319747d3f03SMarcel Holtmann /* Read LE Supported States */ 320747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 321747d3f03SMarcel Holtmann 322c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 323c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 324a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ENABLED); 3252177bab5SJohan Hedberg } 3262177bab5SJohan Hedberg 32742c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 3282177bab5SJohan Hedberg { 32942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 33042c6b129SJohan Hedberg 3312177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 3322177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 3332177bab5SJohan Hedberg * command otherwise. 3342177bab5SJohan Hedberg */ 3352177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 3362177bab5SJohan Hedberg 3372177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 3382177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 3392177bab5SJohan Hedberg */ 3402177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 3412177bab5SJohan Hedberg return; 3422177bab5SJohan Hedberg 3432177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 3442177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 345c7882cbdSMarcel Holtmann } else { 346c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 347c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 348c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 349c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 350c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 3515c3d3b4cSMarcel Holtmann 3525c3d3b4cSMarcel Holtmann /* If the controller supports the Disconnect command, enable 3535c3d3b4cSMarcel Holtmann * the corresponding event. In addition enable packet flow 3545c3d3b4cSMarcel Holtmann * control related events. 3555c3d3b4cSMarcel Holtmann */ 3565c3d3b4cSMarcel Holtmann if (hdev->commands[0] & 0x20) { 3575c3d3b4cSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 358c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 359c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 3605c3d3b4cSMarcel Holtmann } 3615c3d3b4cSMarcel Holtmann 3625c3d3b4cSMarcel Holtmann /* If the controller supports the Read Remote Version 3635c3d3b4cSMarcel Holtmann * Information command, enable the corresponding event. 3645c3d3b4cSMarcel Holtmann */ 3655c3d3b4cSMarcel Holtmann if (hdev->commands[2] & 0x80) 3665c3d3b4cSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information 3675c3d3b4cSMarcel Holtmann * Complete 3685c3d3b4cSMarcel Holtmann */ 3690da71f1bSMarcel Holtmann 3700da71f1bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) { 3710da71f1bSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 372c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 3732177bab5SJohan Hedberg } 3740da71f1bSMarcel Holtmann } 3752177bab5SJohan Hedberg 3769fe759ceSMarcel Holtmann if (lmp_inq_rssi_capable(hdev) || 3779fe759ceSMarcel Holtmann test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) 3782177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 3792177bab5SJohan Hedberg 38070f56aa2SMarcel Holtmann if (lmp_ext_feat_capable(hdev)) 38170f56aa2SMarcel Holtmann events[4] |= 0x04; /* Read Remote Extended Features Complete */ 38270f56aa2SMarcel Holtmann 38370f56aa2SMarcel Holtmann if (lmp_esco_capable(hdev)) { 38470f56aa2SMarcel Holtmann events[5] |= 0x08; /* Synchronous Connection Complete */ 38570f56aa2SMarcel Holtmann events[5] |= 0x10; /* Synchronous Connection Changed */ 38670f56aa2SMarcel Holtmann } 38770f56aa2SMarcel Holtmann 3882177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 3892177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 3902177bab5SJohan Hedberg 3912177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 3922177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 3932177bab5SJohan Hedberg 3942177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 3952177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 3962177bab5SJohan Hedberg 3972177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 3982177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 3992177bab5SJohan Hedberg 4002177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 4012177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 4022177bab5SJohan Hedberg 4032177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 4042177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 4052177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 4062177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 4072177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 4082177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 4092177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 4102177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 4112177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 4122177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 4132177bab5SJohan Hedberg * Features Notification 4142177bab5SJohan Hedberg */ 4152177bab5SJohan Hedberg } 4162177bab5SJohan Hedberg 4172177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 4182177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 4192177bab5SJohan Hedberg 42042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 4212177bab5SJohan Hedberg } 4222177bab5SJohan Hedberg 423a1d01db1SJohan Hedberg static int hci_init2_req(struct hci_request *req, unsigned long opt) 4242177bab5SJohan Hedberg { 42542c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 42642c6b129SJohan Hedberg 4270af801b9SJohan Hedberg if (hdev->dev_type == HCI_AMP) 4280af801b9SJohan Hedberg return amp_init2(req); 4290af801b9SJohan Hedberg 4302177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 43142c6b129SJohan Hedberg bredr_setup(req); 43256f87901SJohan Hedberg else 433a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED); 4342177bab5SJohan Hedberg 4352177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 43642c6b129SJohan Hedberg le_setup(req); 4372177bab5SJohan Hedberg 4380f3adeaeSMarcel Holtmann /* All Bluetooth 1.2 and later controllers should support the 4390f3adeaeSMarcel Holtmann * HCI command for reading the local supported commands. 4400f3adeaeSMarcel Holtmann * 4410f3adeaeSMarcel Holtmann * Unfortunately some controllers indicate Bluetooth 1.2 support, 4420f3adeaeSMarcel Holtmann * but do not have support for this command. If that is the case, 4430f3adeaeSMarcel Holtmann * the driver can quirk the behavior and skip reading the local 4440f3adeaeSMarcel Holtmann * supported commands. 4453f8e2d75SJohan Hedberg */ 4460f3adeaeSMarcel Holtmann if (hdev->hci_ver > BLUETOOTH_VER_1_1 && 4470f3adeaeSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks)) 44842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 4492177bab5SJohan Hedberg 4502177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 45157af75a8SMarcel Holtmann /* When SSP is available, then the host features page 45257af75a8SMarcel Holtmann * should also be available as well. However some 45357af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 45457af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 45557af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 45657af75a8SMarcel Holtmann */ 45757af75a8SMarcel Holtmann hdev->max_page = 0x01; 45857af75a8SMarcel Holtmann 459d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) { 4602177bab5SJohan Hedberg u8 mode = 0x01; 461574ea3c7SMarcel Holtmann 46242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 4632177bab5SJohan Hedberg sizeof(mode), &mode); 4642177bab5SJohan Hedberg } else { 4652177bab5SJohan Hedberg struct hci_cp_write_eir cp; 4662177bab5SJohan Hedberg 4672177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 4682177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 4692177bab5SJohan Hedberg 47042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 4712177bab5SJohan Hedberg } 4722177bab5SJohan Hedberg } 4732177bab5SJohan Hedberg 474043ec9bfSMarcel Holtmann if (lmp_inq_rssi_capable(hdev) || 475043ec9bfSMarcel Holtmann test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) { 47604422da9SMarcel Holtmann u8 mode; 47704422da9SMarcel Holtmann 47804422da9SMarcel Holtmann /* If Extended Inquiry Result events are supported, then 47904422da9SMarcel Holtmann * they are clearly preferred over Inquiry Result with RSSI 48004422da9SMarcel Holtmann * events. 48104422da9SMarcel Holtmann */ 48204422da9SMarcel Holtmann mode = lmp_ext_inq_capable(hdev) ? 0x02 : 0x01; 48304422da9SMarcel Holtmann 48404422da9SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 48504422da9SMarcel Holtmann } 4862177bab5SJohan Hedberg 4872177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 48842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 4892177bab5SJohan Hedberg 4902177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 4912177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 4922177bab5SJohan Hedberg 4932177bab5SJohan Hedberg cp.page = 0x01; 49442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 49542c6b129SJohan Hedberg sizeof(cp), &cp); 4962177bab5SJohan Hedberg } 4972177bab5SJohan Hedberg 498d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LINK_SECURITY)) { 4992177bab5SJohan Hedberg u8 enable = 1; 50042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 5012177bab5SJohan Hedberg &enable); 5022177bab5SJohan Hedberg } 503a1d01db1SJohan Hedberg 504a1d01db1SJohan Hedberg return 0; 5052177bab5SJohan Hedberg } 5062177bab5SJohan Hedberg 50742c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 5082177bab5SJohan Hedberg { 50942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 5102177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 5112177bab5SJohan Hedberg u16 link_policy = 0; 5122177bab5SJohan Hedberg 5132177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 5142177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 5152177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 5162177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 5172177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 5182177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 5192177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 5202177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 5212177bab5SJohan Hedberg 5222177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 52342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 5242177bab5SJohan Hedberg } 5252177bab5SJohan Hedberg 52642c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 5272177bab5SJohan Hedberg { 52842c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 5292177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 5302177bab5SJohan Hedberg 531c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 532c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 533c73eee91SJohan Hedberg return; 534c73eee91SJohan Hedberg 5352177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 5362177bab5SJohan Hedberg 537d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) { 5382177bab5SJohan Hedberg cp.le = 0x01; 53932226e4fSMarcel Holtmann cp.simul = 0x00; 5402177bab5SJohan Hedberg } 5412177bab5SJohan Hedberg 5422177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 54342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 5442177bab5SJohan Hedberg &cp); 5452177bab5SJohan Hedberg } 5462177bab5SJohan Hedberg 547d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 548d62e6d67SJohan Hedberg { 549d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 550d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 551313f6888SMarcel Holtmann bool changed = false; 552d62e6d67SJohan Hedberg 553d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 554d62e6d67SJohan Hedberg * enable all necessary events for it. 555d62e6d67SJohan Hedberg */ 55653b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 557d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 558d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 559d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 560d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 561313f6888SMarcel Holtmann changed = true; 562d62e6d67SJohan Hedberg } 563d62e6d67SJohan Hedberg 564d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 565d62e6d67SJohan Hedberg * enable all necessary events for it. 566d62e6d67SJohan Hedberg */ 56753b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 568d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 569d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 570d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 571d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 572313f6888SMarcel Holtmann changed = true; 573d62e6d67SJohan Hedberg } 574d62e6d67SJohan Hedberg 57540c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 576313f6888SMarcel Holtmann if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) { 57740c59fcbSMarcel Holtmann events[2] |= 0x80; 578313f6888SMarcel Holtmann changed = true; 579313f6888SMarcel Holtmann } 58040c59fcbSMarcel Holtmann 581313f6888SMarcel Holtmann /* Some Broadcom based controllers indicate support for Set Event 582313f6888SMarcel Holtmann * Mask Page 2 command, but then actually do not support it. Since 583313f6888SMarcel Holtmann * the default value is all bits set to zero, the command is only 584313f6888SMarcel Holtmann * required if the event mask has to be changed. In case no change 585313f6888SMarcel Holtmann * to the event mask is needed, skip this command. 586313f6888SMarcel Holtmann */ 587313f6888SMarcel Holtmann if (changed) 588313f6888SMarcel Holtmann hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, 589313f6888SMarcel Holtmann sizeof(events), events); 590d62e6d67SJohan Hedberg } 591d62e6d67SJohan Hedberg 592a1d01db1SJohan Hedberg static int hci_init3_req(struct hci_request *req, unsigned long opt) 5932177bab5SJohan Hedberg { 59442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 595d2c5d77fSJohan Hedberg u8 p; 59642c6b129SJohan Hedberg 5970da71f1bSMarcel Holtmann hci_setup_event_mask(req); 5980da71f1bSMarcel Holtmann 599e81be90bSJohan Hedberg if (hdev->commands[6] & 0x20 && 600e81be90bSJohan Hedberg !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 60148ce62c4SMarcel Holtmann struct hci_cp_read_stored_link_key cp; 60248ce62c4SMarcel Holtmann 60348ce62c4SMarcel Holtmann bacpy(&cp.bdaddr, BDADDR_ANY); 60448ce62c4SMarcel Holtmann cp.read_all = 0x01; 60548ce62c4SMarcel Holtmann hci_req_add(req, HCI_OP_READ_STORED_LINK_KEY, sizeof(cp), &cp); 60648ce62c4SMarcel Holtmann } 60748ce62c4SMarcel Holtmann 6082177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 60942c6b129SJohan Hedberg hci_setup_link_policy(req); 6102177bab5SJohan Hedberg 611417287deSMarcel Holtmann if (hdev->commands[8] & 0x01) 612417287deSMarcel Holtmann hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 613417287deSMarcel Holtmann 614417287deSMarcel Holtmann /* Some older Broadcom based Bluetooth 1.2 controllers do not 615417287deSMarcel Holtmann * support the Read Page Scan Type command. Check support for 616417287deSMarcel Holtmann * this command in the bit mask of supported commands. 617417287deSMarcel Holtmann */ 618417287deSMarcel Holtmann if (hdev->commands[13] & 0x01) 619417287deSMarcel Holtmann hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 620417287deSMarcel Holtmann 6219193c6e8SAndre Guedes if (lmp_le_capable(hdev)) { 6229193c6e8SAndre Guedes u8 events[8]; 6239193c6e8SAndre Guedes 6249193c6e8SAndre Guedes memset(events, 0, sizeof(events)); 6254d6c705bSMarcel Holtmann 6264d6c705bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) 6274d6c705bSMarcel Holtmann events[0] |= 0x10; /* LE Long Term Key Request */ 628662bc2e6SAndre Guedes 629662bc2e6SAndre Guedes /* If controller supports the Connection Parameters Request 630662bc2e6SAndre Guedes * Link Layer Procedure, enable the corresponding event. 631662bc2e6SAndre Guedes */ 632662bc2e6SAndre Guedes if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC) 633662bc2e6SAndre Guedes events[0] |= 0x20; /* LE Remote Connection 634662bc2e6SAndre Guedes * Parameter Request 635662bc2e6SAndre Guedes */ 636662bc2e6SAndre Guedes 637a9f6068eSMarcel Holtmann /* If the controller supports the Data Length Extension 638a9f6068eSMarcel Holtmann * feature, enable the corresponding event. 639a9f6068eSMarcel Holtmann */ 640a9f6068eSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) 641a9f6068eSMarcel Holtmann events[0] |= 0x40; /* LE Data Length Change */ 642a9f6068eSMarcel Holtmann 6434b71bba4SMarcel Holtmann /* If the controller supports Extended Scanner Filter 6444b71bba4SMarcel Holtmann * Policies, enable the correspondig event. 6454b71bba4SMarcel Holtmann */ 6464b71bba4SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY) 6474b71bba4SMarcel Holtmann events[1] |= 0x04; /* LE Direct Advertising 6484b71bba4SMarcel Holtmann * Report 6494b71bba4SMarcel Holtmann */ 6504b71bba4SMarcel Holtmann 6519756d33bSMarcel Holtmann /* If the controller supports Channel Selection Algorithm #2 6529756d33bSMarcel Holtmann * feature, enable the corresponding event. 6539756d33bSMarcel Holtmann */ 6549756d33bSMarcel Holtmann if (hdev->le_features[1] & HCI_LE_CHAN_SEL_ALG2) 6559756d33bSMarcel Holtmann events[2] |= 0x08; /* LE Channel Selection 6569756d33bSMarcel Holtmann * Algorithm 6579756d33bSMarcel Holtmann */ 6589756d33bSMarcel Holtmann 6597d26f5c4SMarcel Holtmann /* If the controller supports the LE Set Scan Enable command, 6607d26f5c4SMarcel Holtmann * enable the corresponding advertising report event. 6617d26f5c4SMarcel Holtmann */ 6627d26f5c4SMarcel Holtmann if (hdev->commands[26] & 0x08) 6637d26f5c4SMarcel Holtmann events[0] |= 0x02; /* LE Advertising Report */ 6647d26f5c4SMarcel Holtmann 6657d26f5c4SMarcel Holtmann /* If the controller supports the LE Create Connection 6667d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6677d26f5c4SMarcel Holtmann */ 6687d26f5c4SMarcel Holtmann if (hdev->commands[26] & 0x10) 6697d26f5c4SMarcel Holtmann events[0] |= 0x01; /* LE Connection Complete */ 6707d26f5c4SMarcel Holtmann 6717d26f5c4SMarcel Holtmann /* If the controller supports the LE Connection Update 6727d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6737d26f5c4SMarcel Holtmann */ 6747d26f5c4SMarcel Holtmann if (hdev->commands[27] & 0x04) 6757d26f5c4SMarcel Holtmann events[0] |= 0x04; /* LE Connection Update 6767d26f5c4SMarcel Holtmann * Complete 6777d26f5c4SMarcel Holtmann */ 6787d26f5c4SMarcel Holtmann 6797d26f5c4SMarcel Holtmann /* If the controller supports the LE Read Remote Used Features 6807d26f5c4SMarcel Holtmann * command, enable the corresponding event. 6817d26f5c4SMarcel Holtmann */ 6827d26f5c4SMarcel Holtmann if (hdev->commands[27] & 0x20) 6837d26f5c4SMarcel Holtmann events[0] |= 0x08; /* LE Read Remote Used 6847d26f5c4SMarcel Holtmann * Features Complete 6857d26f5c4SMarcel Holtmann */ 6867d26f5c4SMarcel Holtmann 6875a34bd5fSMarcel Holtmann /* If the controller supports the LE Read Local P-256 6885a34bd5fSMarcel Holtmann * Public Key command, enable the corresponding event. 6895a34bd5fSMarcel Holtmann */ 6905a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x02) 6915a34bd5fSMarcel Holtmann events[0] |= 0x80; /* LE Read Local P-256 6925a34bd5fSMarcel Holtmann * Public Key Complete 6935a34bd5fSMarcel Holtmann */ 6945a34bd5fSMarcel Holtmann 6955a34bd5fSMarcel Holtmann /* If the controller supports the LE Generate DHKey 6965a34bd5fSMarcel Holtmann * command, enable the corresponding event. 6975a34bd5fSMarcel Holtmann */ 6985a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x04) 6995a34bd5fSMarcel Holtmann events[1] |= 0x01; /* LE Generate DHKey Complete */ 7005a34bd5fSMarcel Holtmann 70127bbca44SMarcel Holtmann /* If the controller supports the LE Set Default PHY or 70227bbca44SMarcel Holtmann * LE Set PHY commands, enable the corresponding event. 70327bbca44SMarcel Holtmann */ 70427bbca44SMarcel Holtmann if (hdev->commands[35] & (0x20 | 0x40)) 70527bbca44SMarcel Holtmann events[1] |= 0x08; /* LE PHY Update Complete */ 70627bbca44SMarcel Holtmann 7079193c6e8SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), 7089193c6e8SAndre Guedes events); 7099193c6e8SAndre Guedes 71015a49ccaSMarcel Holtmann if (hdev->commands[25] & 0x40) { 71115a49ccaSMarcel Holtmann /* Read LE Advertising Channel TX Power */ 71215a49ccaSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 71315a49ccaSMarcel Holtmann } 71415a49ccaSMarcel Holtmann 7152ab216a7SMarcel Holtmann if (hdev->commands[26] & 0x40) { 7162ab216a7SMarcel Holtmann /* Read LE White List Size */ 7172ab216a7SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 7182ab216a7SMarcel Holtmann 0, NULL); 7192ab216a7SMarcel Holtmann } 7202ab216a7SMarcel Holtmann 7212ab216a7SMarcel Holtmann if (hdev->commands[26] & 0x80) { 7222ab216a7SMarcel Holtmann /* Clear LE White List */ 7232ab216a7SMarcel Holtmann hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL); 7242ab216a7SMarcel Holtmann } 7252ab216a7SMarcel Holtmann 726a9f6068eSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { 727a9f6068eSMarcel Holtmann /* Read LE Maximum Data Length */ 728a9f6068eSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL); 729a9f6068eSMarcel Holtmann 730a9f6068eSMarcel Holtmann /* Read LE Suggested Default Data Length */ 731a9f6068eSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL); 732a9f6068eSMarcel Holtmann } 733a9f6068eSMarcel Holtmann 73442c6b129SJohan Hedberg hci_set_le_support(req); 7359193c6e8SAndre Guedes } 736d2c5d77fSJohan Hedberg 737d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 738d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 739d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 740d2c5d77fSJohan Hedberg 741d2c5d77fSJohan Hedberg cp.page = p; 742d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 743d2c5d77fSJohan Hedberg sizeof(cp), &cp); 744d2c5d77fSJohan Hedberg } 745a1d01db1SJohan Hedberg 746a1d01db1SJohan Hedberg return 0; 7472177bab5SJohan Hedberg } 7482177bab5SJohan Hedberg 749a1d01db1SJohan Hedberg static int hci_init4_req(struct hci_request *req, unsigned long opt) 7505d4e7e8dSJohan Hedberg { 7515d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 7525d4e7e8dSJohan Hedberg 75336f260ceSMarcel Holtmann /* Some Broadcom based Bluetooth controllers do not support the 75436f260ceSMarcel Holtmann * Delete Stored Link Key command. They are clearly indicating its 75536f260ceSMarcel Holtmann * absence in the bit mask of supported commands. 75636f260ceSMarcel Holtmann * 75736f260ceSMarcel Holtmann * Check the supported commands and only if the the command is marked 75836f260ceSMarcel Holtmann * as supported send it. If not supported assume that the controller 75936f260ceSMarcel Holtmann * does not have actual support for stored link keys which makes this 76036f260ceSMarcel Holtmann * command redundant anyway. 76136f260ceSMarcel Holtmann * 76236f260ceSMarcel Holtmann * Some controllers indicate that they support handling deleting 76336f260ceSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 76436f260ceSMarcel Holtmann * just disable this command. 76536f260ceSMarcel Holtmann */ 76636f260ceSMarcel Holtmann if (hdev->commands[6] & 0x80 && 76736f260ceSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 76836f260ceSMarcel Holtmann struct hci_cp_delete_stored_link_key cp; 76936f260ceSMarcel Holtmann 77036f260ceSMarcel Holtmann bacpy(&cp.bdaddr, BDADDR_ANY); 77136f260ceSMarcel Holtmann cp.delete_all = 0x01; 77236f260ceSMarcel Holtmann hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 77336f260ceSMarcel Holtmann sizeof(cp), &cp); 77436f260ceSMarcel Holtmann } 77536f260ceSMarcel Holtmann 776d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 777d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 778d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 779d62e6d67SJohan Hedberg 780109e3191SMarcel Holtmann /* Read local codec list if the HCI command is supported */ 781109e3191SMarcel Holtmann if (hdev->commands[29] & 0x20) 782109e3191SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL); 783109e3191SMarcel Holtmann 784f4fe73edSMarcel Holtmann /* Get MWS transport configuration if the HCI command is supported */ 785f4fe73edSMarcel Holtmann if (hdev->commands[30] & 0x08) 786f4fe73edSMarcel Holtmann hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL); 787f4fe73edSMarcel Holtmann 7885d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 78953b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 7905d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 791a6d0d690SMarcel Holtmann 792a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 793d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) && 794574ea3c7SMarcel Holtmann bredr_sc_enabled(hdev)) { 795a6d0d690SMarcel Holtmann u8 support = 0x01; 796574ea3c7SMarcel Holtmann 797a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 798a6d0d690SMarcel Holtmann sizeof(support), &support); 799a6d0d690SMarcel Holtmann } 800a1d01db1SJohan Hedberg 80112204875SMarcel Holtmann /* Set Suggested Default Data Length to maximum if supported */ 80212204875SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { 80312204875SMarcel Holtmann struct hci_cp_le_write_def_data_len cp; 80412204875SMarcel Holtmann 80512204875SMarcel Holtmann cp.tx_len = hdev->le_max_tx_len; 80612204875SMarcel Holtmann cp.tx_time = hdev->le_max_tx_time; 80712204875SMarcel Holtmann hci_req_add(req, HCI_OP_LE_WRITE_DEF_DATA_LEN, sizeof(cp), &cp); 80812204875SMarcel Holtmann } 80912204875SMarcel Holtmann 810de2ba303SMarcel Holtmann /* Set Default PHY parameters if command is supported */ 811de2ba303SMarcel Holtmann if (hdev->commands[35] & 0x20) { 812de2ba303SMarcel Holtmann struct hci_cp_le_set_default_phy cp; 813de2ba303SMarcel Holtmann 814de2ba303SMarcel Holtmann /* No transmitter PHY or receiver PHY preferences */ 815de2ba303SMarcel Holtmann cp.all_phys = 0x03; 816de2ba303SMarcel Holtmann cp.tx_phys = 0; 817de2ba303SMarcel Holtmann cp.rx_phys = 0; 818de2ba303SMarcel Holtmann 819de2ba303SMarcel Holtmann hci_req_add(req, HCI_OP_LE_SET_DEFAULT_PHY, sizeof(cp), &cp); 820de2ba303SMarcel Holtmann } 821de2ba303SMarcel Holtmann 822a1d01db1SJohan Hedberg return 0; 8235d4e7e8dSJohan Hedberg } 8245d4e7e8dSJohan Hedberg 8252177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 8262177bab5SJohan Hedberg { 8272177bab5SJohan Hedberg int err; 8282177bab5SJohan Hedberg 8294ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT, NULL); 8302177bab5SJohan Hedberg if (err < 0) 8312177bab5SJohan Hedberg return err; 8322177bab5SJohan Hedberg 833f640ee98SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 834f640ee98SMarcel Holtmann hci_debugfs_create_basic(hdev); 8354b4148e9SMarcel Holtmann 8364ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT, NULL); 8372177bab5SJohan Hedberg if (err < 0) 8382177bab5SJohan Hedberg return err; 8392177bab5SJohan Hedberg 840ca8bee5dSMarcel Holtmann /* HCI_PRIMARY covers both single-mode LE, BR/EDR and dual-mode 8410af801b9SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 8420af801b9SJohan Hedberg * first two stages of init. 8430af801b9SJohan Hedberg */ 844ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) 8450af801b9SJohan Hedberg return 0; 8460af801b9SJohan Hedberg 8474ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT, NULL); 8485d4e7e8dSJohan Hedberg if (err < 0) 8495d4e7e8dSJohan Hedberg return err; 8505d4e7e8dSJohan Hedberg 8514ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT, NULL); 852baf27f6eSMarcel Holtmann if (err < 0) 853baf27f6eSMarcel Holtmann return err; 854baf27f6eSMarcel Holtmann 855ec6cef9cSMarcel Holtmann /* This function is only called when the controller is actually in 856ec6cef9cSMarcel Holtmann * configured state. When the controller is marked as unconfigured, 857ec6cef9cSMarcel Holtmann * this initialization procedure is not run. 858ec6cef9cSMarcel Holtmann * 859ec6cef9cSMarcel Holtmann * It means that it is possible that a controller runs through its 860ec6cef9cSMarcel Holtmann * setup phase and then discovers missing settings. If that is the 861ec6cef9cSMarcel Holtmann * case, then this function will not be called. It then will only 862ec6cef9cSMarcel Holtmann * be called during the config phase. 863ec6cef9cSMarcel Holtmann * 864ec6cef9cSMarcel Holtmann * So only when in setup phase or config phase, create the debugfs 865ec6cef9cSMarcel Holtmann * entries and register the SMP channels. 866baf27f6eSMarcel Holtmann */ 867d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 868d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 869baf27f6eSMarcel Holtmann return 0; 870baf27f6eSMarcel Holtmann 87160c5f5fbSMarcel Holtmann hci_debugfs_create_common(hdev); 87260c5f5fbSMarcel Holtmann 87371c3b60eSMarcel Holtmann if (lmp_bredr_capable(hdev)) 87460c5f5fbSMarcel Holtmann hci_debugfs_create_bredr(hdev); 8752bfa3531SMarcel Holtmann 876162a3bacSMarcel Holtmann if (lmp_le_capable(hdev)) 87760c5f5fbSMarcel Holtmann hci_debugfs_create_le(hdev); 878e7b8fc92SMarcel Holtmann 879baf27f6eSMarcel Holtmann return 0; 8802177bab5SJohan Hedberg } 8812177bab5SJohan Hedberg 882a1d01db1SJohan Hedberg static int hci_init0_req(struct hci_request *req, unsigned long opt) 8830ebca7d6SMarcel Holtmann { 8840ebca7d6SMarcel Holtmann struct hci_dev *hdev = req->hdev; 8850ebca7d6SMarcel Holtmann 8860ebca7d6SMarcel Holtmann BT_DBG("%s %ld", hdev->name, opt); 8870ebca7d6SMarcel Holtmann 8880ebca7d6SMarcel Holtmann /* Reset */ 8890ebca7d6SMarcel Holtmann if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 8900ebca7d6SMarcel Holtmann hci_reset_req(req, 0); 8910ebca7d6SMarcel Holtmann 8920ebca7d6SMarcel Holtmann /* Read Local Version */ 8930ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 8940ebca7d6SMarcel Holtmann 8950ebca7d6SMarcel Holtmann /* Read BD Address */ 8960ebca7d6SMarcel Holtmann if (hdev->set_bdaddr) 8970ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 898a1d01db1SJohan Hedberg 899a1d01db1SJohan Hedberg return 0; 9000ebca7d6SMarcel Holtmann } 9010ebca7d6SMarcel Holtmann 9020ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev) 9030ebca7d6SMarcel Holtmann { 9040ebca7d6SMarcel Holtmann int err; 9050ebca7d6SMarcel Holtmann 906cc78b44bSMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 907cc78b44bSMarcel Holtmann return 0; 908cc78b44bSMarcel Holtmann 9094ebeee2dSJohan Hedberg err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT, NULL); 9100ebca7d6SMarcel Holtmann if (err < 0) 9110ebca7d6SMarcel Holtmann return err; 9120ebca7d6SMarcel Holtmann 913f640ee98SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 914f640ee98SMarcel Holtmann hci_debugfs_create_basic(hdev); 915f640ee98SMarcel Holtmann 9160ebca7d6SMarcel Holtmann return 0; 9170ebca7d6SMarcel Holtmann } 9180ebca7d6SMarcel Holtmann 919a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt) 9201da177e4SLinus Torvalds { 9211da177e4SLinus Torvalds __u8 scan = opt; 9221da177e4SLinus Torvalds 92342c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 9241da177e4SLinus Torvalds 9251da177e4SLinus Torvalds /* Inquiry and Page scans */ 92642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 927a1d01db1SJohan Hedberg return 0; 9281da177e4SLinus Torvalds } 9291da177e4SLinus Torvalds 930a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt) 9311da177e4SLinus Torvalds { 9321da177e4SLinus Torvalds __u8 auth = opt; 9331da177e4SLinus Torvalds 93442c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 9351da177e4SLinus Torvalds 9361da177e4SLinus Torvalds /* Authentication */ 93742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 938a1d01db1SJohan Hedberg return 0; 9391da177e4SLinus Torvalds } 9401da177e4SLinus Torvalds 941a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt) 9421da177e4SLinus Torvalds { 9431da177e4SLinus Torvalds __u8 encrypt = opt; 9441da177e4SLinus Torvalds 94542c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 9461da177e4SLinus Torvalds 947e4e8e37cSMarcel Holtmann /* Encryption */ 94842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 949a1d01db1SJohan Hedberg return 0; 9501da177e4SLinus Torvalds } 9511da177e4SLinus Torvalds 952a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt) 953e4e8e37cSMarcel Holtmann { 954e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 955e4e8e37cSMarcel Holtmann 95642c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 957e4e8e37cSMarcel Holtmann 958e4e8e37cSMarcel Holtmann /* Default link policy */ 95942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 960a1d01db1SJohan Hedberg return 0; 961e4e8e37cSMarcel Holtmann } 962e4e8e37cSMarcel Holtmann 9631da177e4SLinus Torvalds /* Get HCI device by index. 9641da177e4SLinus Torvalds * Device is held on return. */ 9651da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 9661da177e4SLinus Torvalds { 9678035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 9681da177e4SLinus Torvalds 9691da177e4SLinus Torvalds BT_DBG("%d", index); 9701da177e4SLinus Torvalds 9711da177e4SLinus Torvalds if (index < 0) 9721da177e4SLinus Torvalds return NULL; 9731da177e4SLinus Torvalds 9741da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 9758035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 9761da177e4SLinus Torvalds if (d->id == index) { 9771da177e4SLinus Torvalds hdev = hci_dev_hold(d); 9781da177e4SLinus Torvalds break; 9791da177e4SLinus Torvalds } 9801da177e4SLinus Torvalds } 9811da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 9821da177e4SLinus Torvalds return hdev; 9831da177e4SLinus Torvalds } 9841da177e4SLinus Torvalds 9851da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 986ff9ef578SJohan Hedberg 98730dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 98830dc78e1SJohan Hedberg { 98930dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 99030dc78e1SJohan Hedberg 9916fbe195dSAndre Guedes switch (discov->state) { 992343f935bSAndre Guedes case DISCOVERY_FINDING: 9936fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 99430dc78e1SJohan Hedberg return true; 99530dc78e1SJohan Hedberg 9966fbe195dSAndre Guedes default: 99730dc78e1SJohan Hedberg return false; 99830dc78e1SJohan Hedberg } 9996fbe195dSAndre Guedes } 100030dc78e1SJohan Hedberg 1001ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1002ff9ef578SJohan Hedberg { 1003bb3e0a33SJohan Hedberg int old_state = hdev->discovery.state; 1004bb3e0a33SJohan Hedberg 1005ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1006ff9ef578SJohan Hedberg 1007bb3e0a33SJohan Hedberg if (old_state == state) 1008ff9ef578SJohan Hedberg return; 1009ff9ef578SJohan Hedberg 1010bb3e0a33SJohan Hedberg hdev->discovery.state = state; 1011bb3e0a33SJohan Hedberg 1012ff9ef578SJohan Hedberg switch (state) { 1013ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 1014c54c3860SAndre Guedes hci_update_background_scan(hdev); 1015c54c3860SAndre Guedes 1016bb3e0a33SJohan Hedberg if (old_state != DISCOVERY_STARTING) 1017ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1018ff9ef578SJohan Hedberg break; 1019ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1020ff9ef578SJohan Hedberg break; 1021343f935bSAndre Guedes case DISCOVERY_FINDING: 1022ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1023ff9ef578SJohan Hedberg break; 102430dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 102530dc78e1SJohan Hedberg break; 1026ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1027ff9ef578SJohan Hedberg break; 1028ff9ef578SJohan Hedberg } 1029ff9ef578SJohan Hedberg } 1030ff9ef578SJohan Hedberg 10311f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 10321da177e4SLinus Torvalds { 103330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1034b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 10351da177e4SLinus Torvalds 1036561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1037561aafbcSJohan Hedberg list_del(&p->all); 1038b57c1a56SJohan Hedberg kfree(p); 10391da177e4SLinus Torvalds } 1040561aafbcSJohan Hedberg 1041561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1042561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 10431da177e4SLinus Torvalds } 10441da177e4SLinus Torvalds 1045a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1046a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 10471da177e4SLinus Torvalds { 104830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 10491da177e4SLinus Torvalds struct inquiry_entry *e; 10501da177e4SLinus Torvalds 10516ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 10521da177e4SLinus Torvalds 1053561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 10541da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 10551da177e4SLinus Torvalds return e; 10561da177e4SLinus Torvalds } 10571da177e4SLinus Torvalds 1058b57c1a56SJohan Hedberg return NULL; 1059b57c1a56SJohan Hedberg } 1060b57c1a56SJohan Hedberg 1061561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1062561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1063561aafbcSJohan Hedberg { 106430883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1065561aafbcSJohan Hedberg struct inquiry_entry *e; 1066561aafbcSJohan Hedberg 10676ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1068561aafbcSJohan Hedberg 1069561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1070561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1071561aafbcSJohan Hedberg return e; 1072561aafbcSJohan Hedberg } 1073561aafbcSJohan Hedberg 1074561aafbcSJohan Hedberg return NULL; 1075561aafbcSJohan Hedberg } 1076561aafbcSJohan Hedberg 107730dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 107830dc78e1SJohan Hedberg bdaddr_t *bdaddr, 107930dc78e1SJohan Hedberg int state) 108030dc78e1SJohan Hedberg { 108130dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 108230dc78e1SJohan Hedberg struct inquiry_entry *e; 108330dc78e1SJohan Hedberg 10846ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 108530dc78e1SJohan Hedberg 108630dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 108730dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 108830dc78e1SJohan Hedberg return e; 108930dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 109030dc78e1SJohan Hedberg return e; 109130dc78e1SJohan Hedberg } 109230dc78e1SJohan Hedberg 109330dc78e1SJohan Hedberg return NULL; 109430dc78e1SJohan Hedberg } 109530dc78e1SJohan Hedberg 1096a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1097a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1098a3d4e20aSJohan Hedberg { 1099a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1100a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1101a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1102a3d4e20aSJohan Hedberg 1103a3d4e20aSJohan Hedberg list_del(&ie->list); 1104a3d4e20aSJohan Hedberg 1105a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1106a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1107a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1108a3d4e20aSJohan Hedberg break; 1109a3d4e20aSJohan Hedberg pos = &p->list; 1110a3d4e20aSJohan Hedberg } 1111a3d4e20aSJohan Hedberg 1112a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1113a3d4e20aSJohan Hedberg } 1114a3d4e20aSJohan Hedberg 1115af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1116af58925cSMarcel Holtmann bool name_known) 11171da177e4SLinus Torvalds { 111830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 111970f23020SAndrei Emeltchenko struct inquiry_entry *ie; 1120af58925cSMarcel Holtmann u32 flags = 0; 11211da177e4SLinus Torvalds 11226ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 11231da177e4SLinus Torvalds 11246928a924SJohan Hedberg hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR); 11252b2fec4dSSzymon Janc 1126af58925cSMarcel Holtmann if (!data->ssp_mode) 1127af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1128388fc8faSJohan Hedberg 112970f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1130a3d4e20aSJohan Hedberg if (ie) { 1131af58925cSMarcel Holtmann if (!ie->data.ssp_mode) 1132af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1133388fc8faSJohan Hedberg 1134a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1135a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1136a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1137a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1138a3d4e20aSJohan Hedberg } 1139a3d4e20aSJohan Hedberg 1140561aafbcSJohan Hedberg goto update; 1141a3d4e20aSJohan Hedberg } 1142561aafbcSJohan Hedberg 11431da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 114427f70f3eSJohan Hedberg ie = kzalloc(sizeof(*ie), GFP_KERNEL); 1145af58925cSMarcel Holtmann if (!ie) { 1146af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 1147af58925cSMarcel Holtmann goto done; 1148af58925cSMarcel Holtmann } 114970f23020SAndrei Emeltchenko 1150561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1151561aafbcSJohan Hedberg 1152561aafbcSJohan Hedberg if (name_known) { 1153561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1154561aafbcSJohan Hedberg } else { 1155561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1156561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1157561aafbcSJohan Hedberg } 1158561aafbcSJohan Hedberg 1159561aafbcSJohan Hedberg update: 1160561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1161561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1162561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1163561aafbcSJohan Hedberg list_del(&ie->list); 11641da177e4SLinus Torvalds } 11651da177e4SLinus Torvalds 116670f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 116770f23020SAndrei Emeltchenko ie->timestamp = jiffies; 11681da177e4SLinus Torvalds cache->timestamp = jiffies; 11693175405bSJohan Hedberg 11703175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 1171af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 11723175405bSJohan Hedberg 1173af58925cSMarcel Holtmann done: 1174af58925cSMarcel Holtmann return flags; 11751da177e4SLinus Torvalds } 11761da177e4SLinus Torvalds 11771da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 11781da177e4SLinus Torvalds { 117930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 11801da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 11811da177e4SLinus Torvalds struct inquiry_entry *e; 11821da177e4SLinus Torvalds int copied = 0; 11831da177e4SLinus Torvalds 1184561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 11851da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1186b57c1a56SJohan Hedberg 1187b57c1a56SJohan Hedberg if (copied >= num) 1188b57c1a56SJohan Hedberg break; 1189b57c1a56SJohan Hedberg 11901da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 11911da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 11921da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 11931da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 11941da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 11951da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1196b57c1a56SJohan Hedberg 11971da177e4SLinus Torvalds info++; 1198b57c1a56SJohan Hedberg copied++; 11991da177e4SLinus Torvalds } 12001da177e4SLinus Torvalds 12011da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 12021da177e4SLinus Torvalds return copied; 12031da177e4SLinus Torvalds } 12041da177e4SLinus Torvalds 1205a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt) 12061da177e4SLinus Torvalds { 12071da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 120842c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 12091da177e4SLinus Torvalds struct hci_cp_inquiry cp; 12101da177e4SLinus Torvalds 12111da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 12121da177e4SLinus Torvalds 12131da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 1214a1d01db1SJohan Hedberg return 0; 12151da177e4SLinus Torvalds 12161da177e4SLinus Torvalds /* Start Inquiry */ 12171da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 12181da177e4SLinus Torvalds cp.length = ir->length; 12191da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 122042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 1221a1d01db1SJohan Hedberg 1222a1d01db1SJohan Hedberg return 0; 12231da177e4SLinus Torvalds } 12241da177e4SLinus Torvalds 12251da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 12261da177e4SLinus Torvalds { 12271da177e4SLinus Torvalds __u8 __user *ptr = arg; 12281da177e4SLinus Torvalds struct hci_inquiry_req ir; 12291da177e4SLinus Torvalds struct hci_dev *hdev; 12301da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 12311da177e4SLinus Torvalds long timeo; 12321da177e4SLinus Torvalds __u8 *buf; 12331da177e4SLinus Torvalds 12341da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 12351da177e4SLinus Torvalds return -EFAULT; 12361da177e4SLinus Torvalds 12375a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 12385a08ecceSAndrei Emeltchenko if (!hdev) 12391da177e4SLinus Torvalds return -ENODEV; 12401da177e4SLinus Torvalds 1241d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 12420736cfa8SMarcel Holtmann err = -EBUSY; 12430736cfa8SMarcel Holtmann goto done; 12440736cfa8SMarcel Holtmann } 12450736cfa8SMarcel Holtmann 1246d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1247fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1248fee746b0SMarcel Holtmann goto done; 1249fee746b0SMarcel Holtmann } 1250fee746b0SMarcel Holtmann 1251ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 12525b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 12535b69bef5SMarcel Holtmann goto done; 12545b69bef5SMarcel Holtmann } 12555b69bef5SMarcel Holtmann 1256d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 125756f87901SJohan Hedberg err = -EOPNOTSUPP; 125856f87901SJohan Hedberg goto done; 125956f87901SJohan Hedberg } 126056f87901SJohan Hedberg 126109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 12621da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1263a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 12641f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 12651da177e4SLinus Torvalds do_inquiry = 1; 12661da177e4SLinus Torvalds } 126709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 12681da177e4SLinus Torvalds 126904837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 127070f23020SAndrei Emeltchenko 127170f23020SAndrei Emeltchenko if (do_inquiry) { 127201178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 12734ebeee2dSJohan Hedberg timeo, NULL); 127470f23020SAndrei Emeltchenko if (err < 0) 12751da177e4SLinus Torvalds goto done; 12763e13fa1eSAndre Guedes 12773e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 12783e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 12793e13fa1eSAndre Guedes */ 128074316201SNeilBrown if (wait_on_bit(&hdev->flags, HCI_INQUIRY, 12813e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 12823e13fa1eSAndre Guedes return -EINTR; 128370f23020SAndrei Emeltchenko } 12841da177e4SLinus Torvalds 12858fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 12868fc9ced3SGustavo Padovan * 255 entries 12878fc9ced3SGustavo Padovan */ 12881da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 12891da177e4SLinus Torvalds 12901da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 12911da177e4SLinus Torvalds * copy it to the user space. 12921da177e4SLinus Torvalds */ 129370f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 129470f23020SAndrei Emeltchenko if (!buf) { 12951da177e4SLinus Torvalds err = -ENOMEM; 12961da177e4SLinus Torvalds goto done; 12971da177e4SLinus Torvalds } 12981da177e4SLinus Torvalds 129909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 13001da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 130109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13021da177e4SLinus Torvalds 13031da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 13041da177e4SLinus Torvalds 13051da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 13061da177e4SLinus Torvalds ptr += sizeof(ir); 13071da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 13081da177e4SLinus Torvalds ir.num_rsp)) 13091da177e4SLinus Torvalds err = -EFAULT; 13101da177e4SLinus Torvalds } else 13111da177e4SLinus Torvalds err = -EFAULT; 13121da177e4SLinus Torvalds 13131da177e4SLinus Torvalds kfree(buf); 13141da177e4SLinus Torvalds 13151da177e4SLinus Torvalds done: 13161da177e4SLinus Torvalds hci_dev_put(hdev); 13171da177e4SLinus Torvalds return err; 13181da177e4SLinus Torvalds } 13191da177e4SLinus Torvalds 1320cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 13211da177e4SLinus Torvalds { 13221da177e4SLinus Torvalds int ret = 0; 13231da177e4SLinus Torvalds 13241da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 13251da177e4SLinus Torvalds 1326b504430cSJohan Hedberg hci_req_sync_lock(hdev); 13271da177e4SLinus Torvalds 1328d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) { 132994324962SJohan Hovold ret = -ENODEV; 133094324962SJohan Hovold goto done; 133194324962SJohan Hovold } 133294324962SJohan Hovold 1333d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 1334d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 1335a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1336a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1337bf543036SJohan Hedberg */ 1338d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED)) { 1339611b30f7SMarcel Holtmann ret = -ERFKILL; 1340611b30f7SMarcel Holtmann goto done; 1341611b30f7SMarcel Holtmann } 1342611b30f7SMarcel Holtmann 1343a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 1344a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 1345a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1346a5c8f270SMarcel Holtmann * or not. 1347a5c8f270SMarcel Holtmann * 1348c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 1349c6beca0eSMarcel Holtmann * if a public address or static random address is 1350c6beca0eSMarcel Holtmann * available. 1351c6beca0eSMarcel Holtmann * 1352a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1353a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1354a5c8f270SMarcel Holtmann */ 1355d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1356ca8bee5dSMarcel Holtmann hdev->dev_type == HCI_PRIMARY && 1357a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1358a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1359a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1360a5c8f270SMarcel Holtmann goto done; 1361a5c8f270SMarcel Holtmann } 1362a5c8f270SMarcel Holtmann } 1363a5c8f270SMarcel Holtmann 13641da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 13651da177e4SLinus Torvalds ret = -EALREADY; 13661da177e4SLinus Torvalds goto done; 13671da177e4SLinus Torvalds } 13681da177e4SLinus Torvalds 13691da177e4SLinus Torvalds if (hdev->open(hdev)) { 13701da177e4SLinus Torvalds ret = -EIO; 13711da177e4SLinus Torvalds goto done; 13721da177e4SLinus Torvalds } 13731da177e4SLinus Torvalds 1374e9ca8bf1SMarcel Holtmann set_bit(HCI_RUNNING, &hdev->flags); 137505fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_OPEN); 13764a3f95b7SMarcel Holtmann 13771da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 13781da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1379f41c70c4SMarcel Holtmann 1380d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) { 1381e131d74aSMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_SETUP); 1382e131d74aSMarcel Holtmann 1383af202f84SMarcel Holtmann if (hdev->setup) 1384f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1385f41c70c4SMarcel Holtmann 1386af202f84SMarcel Holtmann /* The transport driver can set these quirks before 1387af202f84SMarcel Holtmann * creating the HCI device or in its setup callback. 1388af202f84SMarcel Holtmann * 1389af202f84SMarcel Holtmann * In case any of them is set, the controller has to 1390af202f84SMarcel Holtmann * start up as unconfigured. 1391af202f84SMarcel Holtmann */ 1392eb1904f4SMarcel Holtmann if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) || 1393eb1904f4SMarcel Holtmann test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks)) 1394a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 1395f41c70c4SMarcel Holtmann 13960ebca7d6SMarcel Holtmann /* For an unconfigured controller it is required to 13970ebca7d6SMarcel Holtmann * read at least the version information provided by 13980ebca7d6SMarcel Holtmann * the Read Local Version Information command. 13990ebca7d6SMarcel Holtmann * 14000ebca7d6SMarcel Holtmann * If the set_bdaddr driver callback is provided, then 14010ebca7d6SMarcel Holtmann * also the original Bluetooth public device address 14020ebca7d6SMarcel Holtmann * will be read using the Read BD Address command. 14030ebca7d6SMarcel Holtmann */ 1404d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 14050ebca7d6SMarcel Holtmann ret = __hci_unconf_init(hdev); 140689bc22d2SMarcel Holtmann } 140789bc22d2SMarcel Holtmann 1408d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_CONFIG)) { 14099713c17bSMarcel Holtmann /* If public address change is configured, ensure that 14109713c17bSMarcel Holtmann * the address gets programmed. If the driver does not 14119713c17bSMarcel Holtmann * support changing the public address, fail the power 14129713c17bSMarcel Holtmann * on procedure. 141324c457e2SMarcel Holtmann */ 14149713c17bSMarcel Holtmann if (bacmp(&hdev->public_addr, BDADDR_ANY) && 14159713c17bSMarcel Holtmann hdev->set_bdaddr) 141624c457e2SMarcel Holtmann ret = hdev->set_bdaddr(hdev, &hdev->public_addr); 141724c457e2SMarcel Holtmann else 141824c457e2SMarcel Holtmann ret = -EADDRNOTAVAIL; 141924c457e2SMarcel Holtmann } 142024c457e2SMarcel Holtmann 1421f41c70c4SMarcel Holtmann if (!ret) { 1422d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 142398a63aafSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 14242177bab5SJohan Hedberg ret = __hci_init(hdev); 142598a63aafSMarcel Holtmann if (!ret && hdev->post_init) 142698a63aafSMarcel Holtmann ret = hdev->post_init(hdev); 142798a63aafSMarcel Holtmann } 14281da177e4SLinus Torvalds } 14291da177e4SLinus Torvalds 14307e995b9eSMarcel Holtmann /* If the HCI Reset command is clearing all diagnostic settings, 14317e995b9eSMarcel Holtmann * then they need to be reprogrammed after the init procedure 14327e995b9eSMarcel Holtmann * completed. 14337e995b9eSMarcel Holtmann */ 14347e995b9eSMarcel Holtmann if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) && 1435b56c7b25SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 14367e995b9eSMarcel Holtmann hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag) 14377e995b9eSMarcel Holtmann ret = hdev->set_diag(hdev, true); 14387e995b9eSMarcel Holtmann 1439f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1440f41c70c4SMarcel Holtmann 14411da177e4SLinus Torvalds if (!ret) { 14421da177e4SLinus Torvalds hci_dev_hold(hdev); 1443a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); 14441da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 144505fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UP); 14466d5d2ee6SHeiner Kallweit hci_leds_update_powered(hdev, true); 1447d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 1448d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG) && 1449d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 1450d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 14512ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 1452ca8bee5dSMarcel Holtmann hdev->dev_type == HCI_PRIMARY) { 14532ff13894SJohan Hedberg ret = __hci_req_hci_power_on(hdev); 14542ff13894SJohan Hedberg mgmt_power_on(hdev, ret); 145556e5cb86SJohan Hedberg } 14561da177e4SLinus Torvalds } else { 14571da177e4SLinus Torvalds /* Init failed, cleanup */ 14583eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1459c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 1460b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 14611da177e4SLinus Torvalds 14621da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 14631da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 14641da177e4SLinus Torvalds 14651da177e4SLinus Torvalds if (hdev->flush) 14661da177e4SLinus Torvalds hdev->flush(hdev); 14671da177e4SLinus Torvalds 14681da177e4SLinus Torvalds if (hdev->sent_cmd) { 14691da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 14701da177e4SLinus Torvalds hdev->sent_cmd = NULL; 14711da177e4SLinus Torvalds } 14721da177e4SLinus Torvalds 1473e9ca8bf1SMarcel Holtmann clear_bit(HCI_RUNNING, &hdev->flags); 147405fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_CLOSE); 14754a3f95b7SMarcel Holtmann 14761da177e4SLinus Torvalds hdev->close(hdev); 1477fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 14781da177e4SLinus Torvalds } 14791da177e4SLinus Torvalds 14801da177e4SLinus Torvalds done: 1481b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 14821da177e4SLinus Torvalds return ret; 14831da177e4SLinus Torvalds } 14841da177e4SLinus Torvalds 1485cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 1486cbed0ca1SJohan Hedberg 1487cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 1488cbed0ca1SJohan Hedberg { 1489cbed0ca1SJohan Hedberg struct hci_dev *hdev; 1490cbed0ca1SJohan Hedberg int err; 1491cbed0ca1SJohan Hedberg 1492cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 1493cbed0ca1SJohan Hedberg if (!hdev) 1494cbed0ca1SJohan Hedberg return -ENODEV; 1495cbed0ca1SJohan Hedberg 14964a964404SMarcel Holtmann /* Devices that are marked as unconfigured can only be powered 1497fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices 1498fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is 1499fee746b0SMarcel Holtmann * possible. 1500fee746b0SMarcel Holtmann * 1501fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag 1502fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to 1503fee746b0SMarcel Holtmann * open the device. 1504fee746b0SMarcel Holtmann */ 1505d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 1506d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 1507fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1508fee746b0SMarcel Holtmann goto done; 1509fee746b0SMarcel Holtmann } 1510fee746b0SMarcel Holtmann 1511e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 1512e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 1513e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 1514e1d08f40SJohan Hedberg * completed. 1515e1d08f40SJohan Hedberg */ 1516a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 1517e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 1518e1d08f40SJohan Hedberg 1519a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 1520a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 1521a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 1522a5c8f270SMarcel Holtmann */ 1523e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 1524e1d08f40SJohan Hedberg 152512aa4f0aSMarcel Holtmann /* For controllers not using the management interface and that 1526b6ae8457SJohan Hedberg * are brought up using legacy ioctl, set the HCI_BONDABLE bit 152712aa4f0aSMarcel Holtmann * so that pairing works for them. Once the management interface 152812aa4f0aSMarcel Holtmann * is in use this bit will be cleared again and userspace has 152912aa4f0aSMarcel Holtmann * to explicitly enable it. 153012aa4f0aSMarcel Holtmann */ 1531d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1532d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_MGMT)) 1533a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BONDABLE); 153412aa4f0aSMarcel Holtmann 1535cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 1536cbed0ca1SJohan Hedberg 1537fee746b0SMarcel Holtmann done: 1538cbed0ca1SJohan Hedberg hci_dev_put(hdev); 1539cbed0ca1SJohan Hedberg return err; 1540cbed0ca1SJohan Hedberg } 1541cbed0ca1SJohan Hedberg 1542d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */ 1543d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev) 1544d7347f3cSJohan Hedberg { 1545d7347f3cSJohan Hedberg struct hci_conn_params *p; 1546d7347f3cSJohan Hedberg 1547f161dd41SJohan Hedberg list_for_each_entry(p, &hdev->le_conn_params, list) { 1548f161dd41SJohan Hedberg if (p->conn) { 1549f161dd41SJohan Hedberg hci_conn_drop(p->conn); 1550f8aaf9b6SJohan Hedberg hci_conn_put(p->conn); 1551f161dd41SJohan Hedberg p->conn = NULL; 1552f161dd41SJohan Hedberg } 1553d7347f3cSJohan Hedberg list_del_init(&p->action); 1554f161dd41SJohan Hedberg } 1555d7347f3cSJohan Hedberg 1556d7347f3cSJohan Hedberg BT_DBG("All LE pending actions cleared"); 1557d7347f3cSJohan Hedberg } 1558d7347f3cSJohan Hedberg 15596b3cc1dbSSimon Fels int hci_dev_do_close(struct hci_dev *hdev) 15601da177e4SLinus Torvalds { 1561acc649c6SMarcel Holtmann bool auto_off; 1562acc649c6SMarcel Holtmann 15631da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 15641da177e4SLinus Torvalds 1565d24d8144SGabriele Mazzotta if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && 1566867146a0SLoic Poulain !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 1567d24d8144SGabriele Mazzotta test_bit(HCI_UP, &hdev->flags)) { 1568a44fecbdSTedd Ho-Jeong An /* Execute vendor specific shutdown routine */ 1569a44fecbdSTedd Ho-Jeong An if (hdev->shutdown) 1570a44fecbdSTedd Ho-Jeong An hdev->shutdown(hdev); 1571a44fecbdSTedd Ho-Jeong An } 1572a44fecbdSTedd Ho-Jeong An 157378c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 157478c04c0bSVinicius Costa Gomes 15757df0f73eSJohan Hedberg hci_request_cancel_all(hdev); 1576b504430cSJohan Hedberg hci_req_sync_lock(hdev); 15771da177e4SLinus Torvalds 15781da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 157965cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 1580b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 15811da177e4SLinus Torvalds return 0; 15821da177e4SLinus Torvalds } 15831da177e4SLinus Torvalds 15846d5d2ee6SHeiner Kallweit hci_leds_update_powered(hdev, false); 15856d5d2ee6SHeiner Kallweit 15863eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 15873eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1588b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 15891da177e4SLinus Torvalds 159016ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 159116ab91abSJohan Hedberg hdev->discov_timeout = 0; 1592a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_DISCOVERABLE); 1593a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 159416ab91abSJohan Hedberg } 159516ab91abSJohan Hedberg 1596a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE)) 15977d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 15987d78525dSJohan Hedberg 1599d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1600d6bfd59cSJohan Hedberg cancel_delayed_work_sync(&hdev->rpa_expired); 16017ba8b4beSAndre Guedes 160276727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 160376727c02SJohan Hedberg * ensuring the workqueue is empty up front. 160476727c02SJohan Hedberg */ 160576727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 160676727c02SJohan Hedberg 160709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 16081aeb9c65SJohan Hedberg 16098f502f84SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 16108f502f84SJohan Hedberg 1611acc649c6SMarcel Holtmann auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF); 1612acc649c6SMarcel Holtmann 1613ca8bee5dSMarcel Holtmann if (!auto_off && hdev->dev_type == HCI_PRIMARY && 1614baab7932SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 16152ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT)) 16162ff13894SJohan Hedberg __mgmt_power_off(hdev); 16171aeb9c65SJohan Hedberg 16181f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 1619d7347f3cSJohan Hedberg hci_pend_le_actions_clear(hdev); 1620f161dd41SJohan Hedberg hci_conn_hash_flush(hdev); 162109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 16221da177e4SLinus Torvalds 162364dae967SMarcel Holtmann smp_unregister(hdev); 162464dae967SMarcel Holtmann 162505fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_DOWN); 16261da177e4SLinus Torvalds 16271da177e4SLinus Torvalds if (hdev->flush) 16281da177e4SLinus Torvalds hdev->flush(hdev); 16291da177e4SLinus Torvalds 16301da177e4SLinus Torvalds /* Reset device */ 16311da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 16321da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 1633acc649c6SMarcel Holtmann if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) && 1634acc649c6SMarcel Holtmann !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 16351da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 16364ebeee2dSJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL); 16371da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 16381da177e4SLinus Torvalds } 16391da177e4SLinus Torvalds 1640c347b765SGustavo F. Padovan /* flush cmd work */ 1641c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 16421da177e4SLinus Torvalds 16431da177e4SLinus Torvalds /* Drop queues */ 16441da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 16451da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 16461da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 16471da177e4SLinus Torvalds 16481da177e4SLinus Torvalds /* Drop last sent command */ 16491da177e4SLinus Torvalds if (hdev->sent_cmd) { 165065cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 16511da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 16521da177e4SLinus Torvalds hdev->sent_cmd = NULL; 16531da177e4SLinus Torvalds } 16541da177e4SLinus Torvalds 1655e9ca8bf1SMarcel Holtmann clear_bit(HCI_RUNNING, &hdev->flags); 165605fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_CLOSE); 16574a3f95b7SMarcel Holtmann 16581da177e4SLinus Torvalds /* After this point our queues are empty 16591da177e4SLinus Torvalds * and no tasks are scheduled. */ 16601da177e4SLinus Torvalds hdev->close(hdev); 16611da177e4SLinus Torvalds 166235b973c9SJohan Hedberg /* Clear flags */ 1663fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 1664eacb44dfSMarcel Holtmann hci_dev_clear_volatile_flags(hdev); 166535b973c9SJohan Hedberg 1666ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 1667536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 1668ced5c338SAndrei Emeltchenko 1669e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 167009b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 16717a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, BDADDR_ANY); 1672e59fda8dSJohan Hedberg 1673b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 16741da177e4SLinus Torvalds 16751da177e4SLinus Torvalds hci_dev_put(hdev); 16761da177e4SLinus Torvalds return 0; 16771da177e4SLinus Torvalds } 16781da177e4SLinus Torvalds 16791da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 16801da177e4SLinus Torvalds { 16811da177e4SLinus Torvalds struct hci_dev *hdev; 16821da177e4SLinus Torvalds int err; 16831da177e4SLinus Torvalds 168470f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 168570f23020SAndrei Emeltchenko if (!hdev) 16861da177e4SLinus Torvalds return -ENODEV; 16878ee56540SMarcel Holtmann 1688d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 16890736cfa8SMarcel Holtmann err = -EBUSY; 16900736cfa8SMarcel Holtmann goto done; 16910736cfa8SMarcel Holtmann } 16920736cfa8SMarcel Holtmann 1693a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 16948ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 16958ee56540SMarcel Holtmann 16961da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 16978ee56540SMarcel Holtmann 16980736cfa8SMarcel Holtmann done: 16991da177e4SLinus Torvalds hci_dev_put(hdev); 17001da177e4SLinus Torvalds return err; 17011da177e4SLinus Torvalds } 17021da177e4SLinus Torvalds 17035c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev) 17041da177e4SLinus Torvalds { 17055c912495SMarcel Holtmann int ret; 17061da177e4SLinus Torvalds 17075c912495SMarcel Holtmann BT_DBG("%s %p", hdev->name, hdev); 17081da177e4SLinus Torvalds 1709b504430cSJohan Hedberg hci_req_sync_lock(hdev); 17101da177e4SLinus Torvalds 17111da177e4SLinus Torvalds /* Drop queues */ 17121da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 17131da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 17141da177e4SLinus Torvalds 171576727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 171676727c02SJohan Hedberg * ensuring the workqueue is empty up front. 171776727c02SJohan Hedberg */ 171876727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 171976727c02SJohan Hedberg 172009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 17211f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 17221da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 172309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 17241da177e4SLinus Torvalds 17251da177e4SLinus Torvalds if (hdev->flush) 17261da177e4SLinus Torvalds hdev->flush(hdev); 17271da177e4SLinus Torvalds 17281da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 17296ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 17301da177e4SLinus Torvalds 17314ebeee2dSJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT, NULL); 17321da177e4SLinus Torvalds 1733b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 17341da177e4SLinus Torvalds return ret; 17351da177e4SLinus Torvalds } 17361da177e4SLinus Torvalds 17375c912495SMarcel Holtmann int hci_dev_reset(__u16 dev) 17385c912495SMarcel Holtmann { 17395c912495SMarcel Holtmann struct hci_dev *hdev; 17405c912495SMarcel Holtmann int err; 17415c912495SMarcel Holtmann 17425c912495SMarcel Holtmann hdev = hci_dev_get(dev); 17435c912495SMarcel Holtmann if (!hdev) 17445c912495SMarcel Holtmann return -ENODEV; 17455c912495SMarcel Holtmann 17465c912495SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 17475c912495SMarcel Holtmann err = -ENETDOWN; 17485c912495SMarcel Holtmann goto done; 17495c912495SMarcel Holtmann } 17505c912495SMarcel Holtmann 1751d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 17525c912495SMarcel Holtmann err = -EBUSY; 17535c912495SMarcel Holtmann goto done; 17545c912495SMarcel Holtmann } 17555c912495SMarcel Holtmann 1756d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 17575c912495SMarcel Holtmann err = -EOPNOTSUPP; 17585c912495SMarcel Holtmann goto done; 17595c912495SMarcel Holtmann } 17605c912495SMarcel Holtmann 17615c912495SMarcel Holtmann err = hci_dev_do_reset(hdev); 17625c912495SMarcel Holtmann 17635c912495SMarcel Holtmann done: 17645c912495SMarcel Holtmann hci_dev_put(hdev); 17655c912495SMarcel Holtmann return err; 17665c912495SMarcel Holtmann } 17675c912495SMarcel Holtmann 17681da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 17691da177e4SLinus Torvalds { 17701da177e4SLinus Torvalds struct hci_dev *hdev; 17711da177e4SLinus Torvalds int ret = 0; 17721da177e4SLinus Torvalds 177370f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 177470f23020SAndrei Emeltchenko if (!hdev) 17751da177e4SLinus Torvalds return -ENODEV; 17761da177e4SLinus Torvalds 1777d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 17780736cfa8SMarcel Holtmann ret = -EBUSY; 17790736cfa8SMarcel Holtmann goto done; 17800736cfa8SMarcel Holtmann } 17810736cfa8SMarcel Holtmann 1782d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1783fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 1784fee746b0SMarcel Holtmann goto done; 1785fee746b0SMarcel Holtmann } 1786fee746b0SMarcel Holtmann 17871da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 17881da177e4SLinus Torvalds 17890736cfa8SMarcel Holtmann done: 17901da177e4SLinus Torvalds hci_dev_put(hdev); 17911da177e4SLinus Torvalds return ret; 17921da177e4SLinus Torvalds } 17931da177e4SLinus Torvalds 1794123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan) 1795123abc08SJohan Hedberg { 1796bc6d2d04SJohan Hedberg bool conn_changed, discov_changed; 1797123abc08SJohan Hedberg 1798123abc08SJohan Hedberg BT_DBG("%s scan 0x%02x", hdev->name, scan); 1799123abc08SJohan Hedberg 1800123abc08SJohan Hedberg if ((scan & SCAN_PAGE)) 1801238be788SMarcel Holtmann conn_changed = !hci_dev_test_and_set_flag(hdev, 1802238be788SMarcel Holtmann HCI_CONNECTABLE); 1803123abc08SJohan Hedberg else 1804a69d8927SMarcel Holtmann conn_changed = hci_dev_test_and_clear_flag(hdev, 1805a69d8927SMarcel Holtmann HCI_CONNECTABLE); 1806123abc08SJohan Hedberg 1807bc6d2d04SJohan Hedberg if ((scan & SCAN_INQUIRY)) { 1808238be788SMarcel Holtmann discov_changed = !hci_dev_test_and_set_flag(hdev, 1809238be788SMarcel Holtmann HCI_DISCOVERABLE); 1810bc6d2d04SJohan Hedberg } else { 1811a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 1812a69d8927SMarcel Holtmann discov_changed = hci_dev_test_and_clear_flag(hdev, 1813a69d8927SMarcel Holtmann HCI_DISCOVERABLE); 1814bc6d2d04SJohan Hedberg } 1815bc6d2d04SJohan Hedberg 1816d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 1817123abc08SJohan Hedberg return; 1818123abc08SJohan Hedberg 1819bc6d2d04SJohan Hedberg if (conn_changed || discov_changed) { 1820bc6d2d04SJohan Hedberg /* In case this was disabled through mgmt */ 1821a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 1822bc6d2d04SJohan Hedberg 1823d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 1824cab054abSJohan Hedberg hci_req_update_adv_data(hdev, hdev->cur_adv_instance); 1825bc6d2d04SJohan Hedberg 1826123abc08SJohan Hedberg mgmt_new_settings(hdev); 1827123abc08SJohan Hedberg } 1828bc6d2d04SJohan Hedberg } 1829123abc08SJohan Hedberg 18301da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 18311da177e4SLinus Torvalds { 18321da177e4SLinus Torvalds struct hci_dev *hdev; 18331da177e4SLinus Torvalds struct hci_dev_req dr; 18341da177e4SLinus Torvalds int err = 0; 18351da177e4SLinus Torvalds 18361da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 18371da177e4SLinus Torvalds return -EFAULT; 18381da177e4SLinus Torvalds 183970f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 184070f23020SAndrei Emeltchenko if (!hdev) 18411da177e4SLinus Torvalds return -ENODEV; 18421da177e4SLinus Torvalds 1843d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 18440736cfa8SMarcel Holtmann err = -EBUSY; 18450736cfa8SMarcel Holtmann goto done; 18460736cfa8SMarcel Holtmann } 18470736cfa8SMarcel Holtmann 1848d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 1849fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1850fee746b0SMarcel Holtmann goto done; 1851fee746b0SMarcel Holtmann } 1852fee746b0SMarcel Holtmann 1853ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 18545b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 18555b69bef5SMarcel Holtmann goto done; 18565b69bef5SMarcel Holtmann } 18575b69bef5SMarcel Holtmann 1858d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 185956f87901SJohan Hedberg err = -EOPNOTSUPP; 186056f87901SJohan Hedberg goto done; 186156f87901SJohan Hedberg } 186256f87901SJohan Hedberg 18631da177e4SLinus Torvalds switch (cmd) { 18641da177e4SLinus Torvalds case HCISETAUTH: 186501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 18664ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 18671da177e4SLinus Torvalds break; 18681da177e4SLinus Torvalds 18691da177e4SLinus Torvalds case HCISETENCRYPT: 18701da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 18711da177e4SLinus Torvalds err = -EOPNOTSUPP; 18721da177e4SLinus Torvalds break; 18731da177e4SLinus Torvalds } 18741da177e4SLinus Torvalds 18751da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 18761da177e4SLinus Torvalds /* Auth must be enabled first */ 187701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 18784ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 18791da177e4SLinus Torvalds if (err) 18801da177e4SLinus Torvalds break; 18811da177e4SLinus Torvalds } 18821da177e4SLinus Torvalds 188301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 18844ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 18851da177e4SLinus Torvalds break; 18861da177e4SLinus Torvalds 18871da177e4SLinus Torvalds case HCISETSCAN: 188801178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 18894ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 189091a668b0SJohan Hedberg 1891bc6d2d04SJohan Hedberg /* Ensure that the connectable and discoverable states 1892bc6d2d04SJohan Hedberg * get correctly modified as this was a non-mgmt change. 189391a668b0SJohan Hedberg */ 1894123abc08SJohan Hedberg if (!err) 1895123abc08SJohan Hedberg hci_update_scan_state(hdev, dr.dev_opt); 18961da177e4SLinus Torvalds break; 18971da177e4SLinus Torvalds 18981da177e4SLinus Torvalds case HCISETLINKPOL: 189901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 19004ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 19011da177e4SLinus Torvalds break; 19021da177e4SLinus Torvalds 19031da177e4SLinus Torvalds case HCISETLINKMODE: 1904e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 1905e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 1906e4e8e37cSMarcel Holtmann break; 1907e4e8e37cSMarcel Holtmann 1908e4e8e37cSMarcel Holtmann case HCISETPTYPE: 1909e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 19101da177e4SLinus Torvalds break; 19111da177e4SLinus Torvalds 19121da177e4SLinus Torvalds case HCISETACLMTU: 19131da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 19141da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 19151da177e4SLinus Torvalds break; 19161da177e4SLinus Torvalds 19171da177e4SLinus Torvalds case HCISETSCOMTU: 19181da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 19191da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 19201da177e4SLinus Torvalds break; 19211da177e4SLinus Torvalds 19221da177e4SLinus Torvalds default: 19231da177e4SLinus Torvalds err = -EINVAL; 19241da177e4SLinus Torvalds break; 19251da177e4SLinus Torvalds } 1926e4e8e37cSMarcel Holtmann 19270736cfa8SMarcel Holtmann done: 19281da177e4SLinus Torvalds hci_dev_put(hdev); 19291da177e4SLinus Torvalds return err; 19301da177e4SLinus Torvalds } 19311da177e4SLinus Torvalds 19321da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 19331da177e4SLinus Torvalds { 19348035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 19351da177e4SLinus Torvalds struct hci_dev_list_req *dl; 19361da177e4SLinus Torvalds struct hci_dev_req *dr; 19371da177e4SLinus Torvalds int n = 0, size, err; 19381da177e4SLinus Torvalds __u16 dev_num; 19391da177e4SLinus Torvalds 19401da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 19411da177e4SLinus Torvalds return -EFAULT; 19421da177e4SLinus Torvalds 19431da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 19441da177e4SLinus Torvalds return -EINVAL; 19451da177e4SLinus Torvalds 19461da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 19471da177e4SLinus Torvalds 194870f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 194970f23020SAndrei Emeltchenko if (!dl) 19501da177e4SLinus Torvalds return -ENOMEM; 19511da177e4SLinus Torvalds 19521da177e4SLinus Torvalds dr = dl->dev_req; 19531da177e4SLinus Torvalds 1954f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 19558035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 19562e84d8dbSMarcel Holtmann unsigned long flags = hdev->flags; 1957c542a06cSJohan Hedberg 19582e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 19592e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 19602e84d8dbSMarcel Holtmann * device is actually down. 19612e84d8dbSMarcel Holtmann */ 1962d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 19632e84d8dbSMarcel Holtmann flags &= ~BIT(HCI_UP); 1964c542a06cSJohan Hedberg 19651da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 19662e84d8dbSMarcel Holtmann (dr + n)->dev_opt = flags; 1967c542a06cSJohan Hedberg 19681da177e4SLinus Torvalds if (++n >= dev_num) 19691da177e4SLinus Torvalds break; 19701da177e4SLinus Torvalds } 1971f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 19721da177e4SLinus Torvalds 19731da177e4SLinus Torvalds dl->dev_num = n; 19741da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 19751da177e4SLinus Torvalds 19761da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 19771da177e4SLinus Torvalds kfree(dl); 19781da177e4SLinus Torvalds 19791da177e4SLinus Torvalds return err ? -EFAULT : 0; 19801da177e4SLinus Torvalds } 19811da177e4SLinus Torvalds 19821da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 19831da177e4SLinus Torvalds { 19841da177e4SLinus Torvalds struct hci_dev *hdev; 19851da177e4SLinus Torvalds struct hci_dev_info di; 19862e84d8dbSMarcel Holtmann unsigned long flags; 19871da177e4SLinus Torvalds int err = 0; 19881da177e4SLinus Torvalds 19891da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 19901da177e4SLinus Torvalds return -EFAULT; 19911da177e4SLinus Torvalds 199270f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 199370f23020SAndrei Emeltchenko if (!hdev) 19941da177e4SLinus Torvalds return -ENODEV; 19951da177e4SLinus Torvalds 19962e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 19972e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 19982e84d8dbSMarcel Holtmann * device is actually down. 19992e84d8dbSMarcel Holtmann */ 2000d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 20012e84d8dbSMarcel Holtmann flags = hdev->flags & ~BIT(HCI_UP); 20022e84d8dbSMarcel Holtmann else 20032e84d8dbSMarcel Holtmann flags = hdev->flags; 2004c542a06cSJohan Hedberg 20051da177e4SLinus Torvalds strcpy(di.name, hdev->name); 20061da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 200760f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 20082e84d8dbSMarcel Holtmann di.flags = flags; 20091da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2010572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 20111da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 20121da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 20131da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 20141da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2015572c7f84SJohan Hedberg } else { 2016572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2017572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2018572c7f84SJohan Hedberg di.sco_mtu = 0; 2019572c7f84SJohan Hedberg di.sco_pkts = 0; 2020572c7f84SJohan Hedberg } 20211da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 20221da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 20231da177e4SLinus Torvalds 20241da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 20251da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 20261da177e4SLinus Torvalds 20271da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 20281da177e4SLinus Torvalds err = -EFAULT; 20291da177e4SLinus Torvalds 20301da177e4SLinus Torvalds hci_dev_put(hdev); 20311da177e4SLinus Torvalds 20321da177e4SLinus Torvalds return err; 20331da177e4SLinus Torvalds } 20341da177e4SLinus Torvalds 20351da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 20361da177e4SLinus Torvalds 2037611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2038611b30f7SMarcel Holtmann { 2039611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2040611b30f7SMarcel Holtmann 2041611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2042611b30f7SMarcel Holtmann 2043d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) 20440736cfa8SMarcel Holtmann return -EBUSY; 20450736cfa8SMarcel Holtmann 20465e130367SJohan Hedberg if (blocked) { 2047a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 2048d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 2049d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 2050611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 20515e130367SJohan Hedberg } else { 2052a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_RFKILLED); 20535e130367SJohan Hedberg } 2054611b30f7SMarcel Holtmann 2055611b30f7SMarcel Holtmann return 0; 2056611b30f7SMarcel Holtmann } 2057611b30f7SMarcel Holtmann 2058611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2059611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2060611b30f7SMarcel Holtmann }; 2061611b30f7SMarcel Holtmann 2062ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2063ab81cbf9SJohan Hedberg { 2064ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 206596570ffcSJohan Hedberg int err; 2066ab81cbf9SJohan Hedberg 2067ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2068ab81cbf9SJohan Hedberg 20692ff13894SJohan Hedberg if (test_bit(HCI_UP, &hdev->flags) && 20702ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 20712ff13894SJohan Hedberg hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) { 2072d82142a8SWei-Ning Huang cancel_delayed_work(&hdev->power_off); 20732ff13894SJohan Hedberg hci_req_sync_lock(hdev); 20742ff13894SJohan Hedberg err = __hci_req_hci_power_on(hdev); 20752ff13894SJohan Hedberg hci_req_sync_unlock(hdev); 20762ff13894SJohan Hedberg mgmt_power_on(hdev, err); 20772ff13894SJohan Hedberg return; 20782ff13894SJohan Hedberg } 20792ff13894SJohan Hedberg 2080cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 208196570ffcSJohan Hedberg if (err < 0) { 20823ad67582SJaganath Kanakkassery hci_dev_lock(hdev); 208396570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 20843ad67582SJaganath Kanakkassery hci_dev_unlock(hdev); 2085ab81cbf9SJohan Hedberg return; 208696570ffcSJohan Hedberg } 2087ab81cbf9SJohan Hedberg 2088a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2089a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2090a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2091a5c8f270SMarcel Holtmann */ 2092d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED) || 2093d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_UNCONFIGURED) || 2094ca8bee5dSMarcel Holtmann (hdev->dev_type == HCI_PRIMARY && 2095a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2096a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2097a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_AUTO_OFF); 2098bf543036SJohan Hedberg hci_dev_do_close(hdev); 2099d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) { 210019202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 210119202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2102bf543036SJohan Hedberg } 2103ab81cbf9SJohan Hedberg 2104a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) { 21054a964404SMarcel Holtmann /* For unconfigured devices, set the HCI_RAW flag 21064a964404SMarcel Holtmann * so that userspace can easily identify them. 21074a964404SMarcel Holtmann */ 2108d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 21094a964404SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 21100602a8adSMarcel Holtmann 21110602a8adSMarcel Holtmann /* For fully configured devices, this will send 21120602a8adSMarcel Holtmann * the Index Added event. For unconfigured devices, 21130602a8adSMarcel Holtmann * it will send Unconfigued Index Added event. 21140602a8adSMarcel Holtmann * 21150602a8adSMarcel Holtmann * Devices with HCI_QUIRK_RAW_DEVICE are ignored 21160602a8adSMarcel Holtmann * and no event will be send. 21170602a8adSMarcel Holtmann */ 2118744cf19eSJohan Hedberg mgmt_index_added(hdev); 2119a69d8927SMarcel Holtmann } else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) { 21205ea234d3SMarcel Holtmann /* When the controller is now configured, then it 21215ea234d3SMarcel Holtmann * is important to clear the HCI_RAW flag. 21225ea234d3SMarcel Holtmann */ 2123d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 21245ea234d3SMarcel Holtmann clear_bit(HCI_RAW, &hdev->flags); 21255ea234d3SMarcel Holtmann 2126d603b76bSMarcel Holtmann /* Powering on the controller with HCI_CONFIG set only 2127d603b76bSMarcel Holtmann * happens with the transition from unconfigured to 2128d603b76bSMarcel Holtmann * configured. This will send the Index Added event. 2129d603b76bSMarcel Holtmann */ 2130d603b76bSMarcel Holtmann mgmt_index_added(hdev); 2131ab81cbf9SJohan Hedberg } 2132ab81cbf9SJohan Hedberg } 2133ab81cbf9SJohan Hedberg 2134ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2135ab81cbf9SJohan Hedberg { 21363243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 21373243553fSJohan Hedberg power_off.work); 2138ab81cbf9SJohan Hedberg 2139ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2140ab81cbf9SJohan Hedberg 21418ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2142ab81cbf9SJohan Hedberg } 2143ab81cbf9SJohan Hedberg 2144c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work) 2145c7741d16SMarcel Holtmann { 2146c7741d16SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset); 2147c7741d16SMarcel Holtmann 2148c7741d16SMarcel Holtmann BT_DBG("%s", hdev->name); 2149c7741d16SMarcel Holtmann 2150c7741d16SMarcel Holtmann if (hdev->hw_error) 2151c7741d16SMarcel Holtmann hdev->hw_error(hdev, hdev->hw_error_code); 2152c7741d16SMarcel Holtmann else 2153c7741d16SMarcel Holtmann BT_ERR("%s hardware error 0x%2.2x", hdev->name, 2154c7741d16SMarcel Holtmann hdev->hw_error_code); 2155c7741d16SMarcel Holtmann 2156c7741d16SMarcel Holtmann if (hci_dev_do_close(hdev)) 2157c7741d16SMarcel Holtmann return; 2158c7741d16SMarcel Holtmann 2159c7741d16SMarcel Holtmann hci_dev_do_open(hdev); 2160c7741d16SMarcel Holtmann } 2161c7741d16SMarcel Holtmann 216235f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 21632aeb9a1aSJohan Hedberg { 21644821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 21652aeb9a1aSJohan Hedberg 21664821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 21674821002cSJohan Hedberg list_del(&uuid->list); 21682aeb9a1aSJohan Hedberg kfree(uuid); 21692aeb9a1aSJohan Hedberg } 21702aeb9a1aSJohan Hedberg } 21712aeb9a1aSJohan Hedberg 217235f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 217355ed8ca1SJohan Hedberg { 217455ed8ca1SJohan Hedberg struct link_key *key; 217555ed8ca1SJohan Hedberg 21760378b597SJohan Hedberg list_for_each_entry_rcu(key, &hdev->link_keys, list) { 21770378b597SJohan Hedberg list_del_rcu(&key->list); 21780378b597SJohan Hedberg kfree_rcu(key, rcu); 217955ed8ca1SJohan Hedberg } 218055ed8ca1SJohan Hedberg } 218155ed8ca1SJohan Hedberg 218235f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2183b899efafSVinicius Costa Gomes { 2184970d0f1bSJohan Hedberg struct smp_ltk *k; 2185b899efafSVinicius Costa Gomes 2186970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 2187970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2188970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2189b899efafSVinicius Costa Gomes } 2190b899efafSVinicius Costa Gomes } 2191b899efafSVinicius Costa Gomes 2192970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2193970c4e46SJohan Hedberg { 2194adae20cbSJohan Hedberg struct smp_irk *k; 2195970c4e46SJohan Hedberg 2196adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 2197adae20cbSJohan Hedberg list_del_rcu(&k->list); 2198adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2199970c4e46SJohan Hedberg } 2200970c4e46SJohan Hedberg } 2201970c4e46SJohan Hedberg 220255ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 220355ed8ca1SJohan Hedberg { 220455ed8ca1SJohan Hedberg struct link_key *k; 220555ed8ca1SJohan Hedberg 22060378b597SJohan Hedberg rcu_read_lock(); 22070378b597SJohan Hedberg list_for_each_entry_rcu(k, &hdev->link_keys, list) { 22080378b597SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) { 22090378b597SJohan Hedberg rcu_read_unlock(); 221055ed8ca1SJohan Hedberg return k; 22110378b597SJohan Hedberg } 22120378b597SJohan Hedberg } 22130378b597SJohan Hedberg rcu_read_unlock(); 221455ed8ca1SJohan Hedberg 221555ed8ca1SJohan Hedberg return NULL; 221655ed8ca1SJohan Hedberg } 221755ed8ca1SJohan Hedberg 2218745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2219d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2220d25e28abSJohan Hedberg { 2221d25e28abSJohan Hedberg /* Legacy key */ 2222d25e28abSJohan Hedberg if (key_type < 0x03) 2223745c0ce3SVishal Agarwal return true; 2224d25e28abSJohan Hedberg 2225d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2226d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2227745c0ce3SVishal Agarwal return false; 2228d25e28abSJohan Hedberg 2229d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2230d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2231745c0ce3SVishal Agarwal return false; 2232d25e28abSJohan Hedberg 2233d25e28abSJohan Hedberg /* Security mode 3 case */ 2234d25e28abSJohan Hedberg if (!conn) 2235745c0ce3SVishal Agarwal return true; 2236d25e28abSJohan Hedberg 2237e3befab9SJohan Hedberg /* BR/EDR key derived using SC from an LE link */ 2238e3befab9SJohan Hedberg if (conn->type == LE_LINK) 2239e3befab9SJohan Hedberg return true; 2240e3befab9SJohan Hedberg 2241d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2242d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2243745c0ce3SVishal Agarwal return true; 2244d25e28abSJohan Hedberg 2245d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2246d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2247745c0ce3SVishal Agarwal return true; 2248d25e28abSJohan Hedberg 2249d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2250d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2251745c0ce3SVishal Agarwal return true; 2252d25e28abSJohan Hedberg 2253d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2254d25e28abSJohan Hedberg * persistently */ 2255745c0ce3SVishal Agarwal return false; 2256d25e28abSJohan Hedberg } 2257d25e28abSJohan Hedberg 2258e804d25dSJohan Hedberg static u8 ltk_role(u8 type) 225998a0b845SJohan Hedberg { 2260e804d25dSJohan Hedberg if (type == SMP_LTK) 2261e804d25dSJohan Hedberg return HCI_ROLE_MASTER; 226298a0b845SJohan Hedberg 2263e804d25dSJohan Hedberg return HCI_ROLE_SLAVE; 226498a0b845SJohan Hedberg } 226598a0b845SJohan Hedberg 2266f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2267e804d25dSJohan Hedberg u8 addr_type, u8 role) 226875d262c2SVinicius Costa Gomes { 2269c9839a11SVinicius Costa Gomes struct smp_ltk *k; 227075d262c2SVinicius Costa Gomes 2271970d0f1bSJohan Hedberg rcu_read_lock(); 2272970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 22735378bc56SJohan Hedberg if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr)) 22745378bc56SJohan Hedberg continue; 22755378bc56SJohan Hedberg 2276923e2414SJohan Hedberg if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) { 2277970d0f1bSJohan Hedberg rcu_read_unlock(); 227875d262c2SVinicius Costa Gomes return k; 2279970d0f1bSJohan Hedberg } 2280970d0f1bSJohan Hedberg } 2281970d0f1bSJohan Hedberg rcu_read_unlock(); 228275d262c2SVinicius Costa Gomes 228375d262c2SVinicius Costa Gomes return NULL; 228475d262c2SVinicius Costa Gomes } 228575d262c2SVinicius Costa Gomes 2286970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 2287970c4e46SJohan Hedberg { 2288970c4e46SJohan Hedberg struct smp_irk *irk; 2289970c4e46SJohan Hedberg 2290adae20cbSJohan Hedberg rcu_read_lock(); 2291adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2292adae20cbSJohan Hedberg if (!bacmp(&irk->rpa, rpa)) { 2293adae20cbSJohan Hedberg rcu_read_unlock(); 2294970c4e46SJohan Hedberg return irk; 2295970c4e46SJohan Hedberg } 2296adae20cbSJohan Hedberg } 2297970c4e46SJohan Hedberg 2298adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2299defce9e8SJohan Hedberg if (smp_irk_matches(hdev, irk->val, rpa)) { 2300970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2301adae20cbSJohan Hedberg rcu_read_unlock(); 2302970c4e46SJohan Hedberg return irk; 2303970c4e46SJohan Hedberg } 2304970c4e46SJohan Hedberg } 2305adae20cbSJohan Hedberg rcu_read_unlock(); 2306970c4e46SJohan Hedberg 2307970c4e46SJohan Hedberg return NULL; 2308970c4e46SJohan Hedberg } 2309970c4e46SJohan Hedberg 2310970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2311970c4e46SJohan Hedberg u8 addr_type) 2312970c4e46SJohan Hedberg { 2313970c4e46SJohan Hedberg struct smp_irk *irk; 2314970c4e46SJohan Hedberg 23156cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 23166cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 23176cfc9988SJohan Hedberg return NULL; 23186cfc9988SJohan Hedberg 2319adae20cbSJohan Hedberg rcu_read_lock(); 2320adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2321970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 2322adae20cbSJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) { 2323adae20cbSJohan Hedberg rcu_read_unlock(); 2324970c4e46SJohan Hedberg return irk; 2325970c4e46SJohan Hedberg } 2326adae20cbSJohan Hedberg } 2327adae20cbSJohan Hedberg rcu_read_unlock(); 2328970c4e46SJohan Hedberg 2329970c4e46SJohan Hedberg return NULL; 2330970c4e46SJohan Hedberg } 2331970c4e46SJohan Hedberg 2332567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 23337652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 23347652ff6aSJohan Hedberg u8 pin_len, bool *persistent) 233555ed8ca1SJohan Hedberg { 233655ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2337745c0ce3SVishal Agarwal u8 old_key_type; 233855ed8ca1SJohan Hedberg 233955ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 234055ed8ca1SJohan Hedberg if (old_key) { 234155ed8ca1SJohan Hedberg old_key_type = old_key->type; 234255ed8ca1SJohan Hedberg key = old_key; 234355ed8ca1SJohan Hedberg } else { 234412adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 23450a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 234655ed8ca1SJohan Hedberg if (!key) 2347567fa2aaSJohan Hedberg return NULL; 23480378b597SJohan Hedberg list_add_rcu(&key->list, &hdev->link_keys); 234955ed8ca1SJohan Hedberg } 235055ed8ca1SJohan Hedberg 23516ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 235255ed8ca1SJohan Hedberg 2353d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2354d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2355d25e28abSJohan Hedberg * previous key */ 2356d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2357a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2358d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2359655fe6ecSJohan Hedberg if (conn) 2360655fe6ecSJohan Hedberg conn->key_type = type; 2361655fe6ecSJohan Hedberg } 2362d25e28abSJohan Hedberg 236355ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 23649b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 236555ed8ca1SJohan Hedberg key->pin_len = pin_len; 236655ed8ca1SJohan Hedberg 2367b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 236855ed8ca1SJohan Hedberg key->type = old_key_type; 23694748fed2SJohan Hedberg else 23704748fed2SJohan Hedberg key->type = type; 23714748fed2SJohan Hedberg 23727652ff6aSJohan Hedberg if (persistent) 23737652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type, 23747652ff6aSJohan Hedberg old_key_type); 23754df378a1SJohan Hedberg 2376567fa2aaSJohan Hedberg return key; 237755ed8ca1SJohan Hedberg } 237855ed8ca1SJohan Hedberg 2379ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 238035d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 2381fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand) 238275d262c2SVinicius Costa Gomes { 2383c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 2384e804d25dSJohan Hedberg u8 role = ltk_role(type); 238575d262c2SVinicius Costa Gomes 2386f3a73d97SJohan Hedberg old_key = hci_find_ltk(hdev, bdaddr, addr_type, role); 2387c9839a11SVinicius Costa Gomes if (old_key) 238875d262c2SVinicius Costa Gomes key = old_key; 2389c9839a11SVinicius Costa Gomes else { 23900a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 239175d262c2SVinicius Costa Gomes if (!key) 2392ca9142b8SJohan Hedberg return NULL; 2393970d0f1bSJohan Hedberg list_add_rcu(&key->list, &hdev->long_term_keys); 239475d262c2SVinicius Costa Gomes } 239575d262c2SVinicius Costa Gomes 239675d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2397c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2398c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2399c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2400c9839a11SVinicius Costa Gomes key->ediv = ediv; 2401fe39c7b2SMarcel Holtmann key->rand = rand; 2402c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2403c9839a11SVinicius Costa Gomes key->type = type; 240475d262c2SVinicius Costa Gomes 2405ca9142b8SJohan Hedberg return key; 240675d262c2SVinicius Costa Gomes } 240775d262c2SVinicius Costa Gomes 2408ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2409ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 2410970c4e46SJohan Hedberg { 2411970c4e46SJohan Hedberg struct smp_irk *irk; 2412970c4e46SJohan Hedberg 2413970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 2414970c4e46SJohan Hedberg if (!irk) { 2415970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 2416970c4e46SJohan Hedberg if (!irk) 2417ca9142b8SJohan Hedberg return NULL; 2418970c4e46SJohan Hedberg 2419970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 2420970c4e46SJohan Hedberg irk->addr_type = addr_type; 2421970c4e46SJohan Hedberg 2422adae20cbSJohan Hedberg list_add_rcu(&irk->list, &hdev->identity_resolving_keys); 2423970c4e46SJohan Hedberg } 2424970c4e46SJohan Hedberg 2425970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 2426970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2427970c4e46SJohan Hedberg 2428ca9142b8SJohan Hedberg return irk; 2429970c4e46SJohan Hedberg } 2430970c4e46SJohan Hedberg 243155ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 243255ed8ca1SJohan Hedberg { 243355ed8ca1SJohan Hedberg struct link_key *key; 243455ed8ca1SJohan Hedberg 243555ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 243655ed8ca1SJohan Hedberg if (!key) 243755ed8ca1SJohan Hedberg return -ENOENT; 243855ed8ca1SJohan Hedberg 24396ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 244055ed8ca1SJohan Hedberg 24410378b597SJohan Hedberg list_del_rcu(&key->list); 24420378b597SJohan Hedberg kfree_rcu(key, rcu); 244355ed8ca1SJohan Hedberg 244455ed8ca1SJohan Hedberg return 0; 244555ed8ca1SJohan Hedberg } 244655ed8ca1SJohan Hedberg 2447e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 2448b899efafSVinicius Costa Gomes { 2449970d0f1bSJohan Hedberg struct smp_ltk *k; 2450c51ffa0bSJohan Hedberg int removed = 0; 2451b899efafSVinicius Costa Gomes 2452970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 2453e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 2454b899efafSVinicius Costa Gomes continue; 2455b899efafSVinicius Costa Gomes 24566ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2457b899efafSVinicius Costa Gomes 2458970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2459970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2460c51ffa0bSJohan Hedberg removed++; 2461b899efafSVinicius Costa Gomes } 2462b899efafSVinicius Costa Gomes 2463c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 2464b899efafSVinicius Costa Gomes } 2465b899efafSVinicius Costa Gomes 2466a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 2467a7ec7338SJohan Hedberg { 2468adae20cbSJohan Hedberg struct smp_irk *k; 2469a7ec7338SJohan Hedberg 2470adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 2471a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 2472a7ec7338SJohan Hedberg continue; 2473a7ec7338SJohan Hedberg 2474a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2475a7ec7338SJohan Hedberg 2476adae20cbSJohan Hedberg list_del_rcu(&k->list); 2477adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2478a7ec7338SJohan Hedberg } 2479a7ec7338SJohan Hedberg } 2480a7ec7338SJohan Hedberg 248155e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 248255e76b38SJohan Hedberg { 248355e76b38SJohan Hedberg struct smp_ltk *k; 24844ba9faf3SJohan Hedberg struct smp_irk *irk; 248555e76b38SJohan Hedberg u8 addr_type; 248655e76b38SJohan Hedberg 248755e76b38SJohan Hedberg if (type == BDADDR_BREDR) { 248855e76b38SJohan Hedberg if (hci_find_link_key(hdev, bdaddr)) 248955e76b38SJohan Hedberg return true; 249055e76b38SJohan Hedberg return false; 249155e76b38SJohan Hedberg } 249255e76b38SJohan Hedberg 249355e76b38SJohan Hedberg /* Convert to HCI addr type which struct smp_ltk uses */ 249455e76b38SJohan Hedberg if (type == BDADDR_LE_PUBLIC) 249555e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_PUBLIC; 249655e76b38SJohan Hedberg else 249755e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_RANDOM; 249855e76b38SJohan Hedberg 24994ba9faf3SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, addr_type); 25004ba9faf3SJohan Hedberg if (irk) { 25014ba9faf3SJohan Hedberg bdaddr = &irk->bdaddr; 25024ba9faf3SJohan Hedberg addr_type = irk->addr_type; 25034ba9faf3SJohan Hedberg } 25044ba9faf3SJohan Hedberg 250555e76b38SJohan Hedberg rcu_read_lock(); 250655e76b38SJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 250787c8b28dSJohan Hedberg if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) { 250887c8b28dSJohan Hedberg rcu_read_unlock(); 250955e76b38SJohan Hedberg return true; 251055e76b38SJohan Hedberg } 251187c8b28dSJohan Hedberg } 251255e76b38SJohan Hedberg rcu_read_unlock(); 251355e76b38SJohan Hedberg 251455e76b38SJohan Hedberg return false; 251555e76b38SJohan Hedberg } 251655e76b38SJohan Hedberg 25176bd32326SVille Tervo /* HCI command timer function */ 251865cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work) 25196bd32326SVille Tervo { 252065cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, 252165cc2b49SMarcel Holtmann cmd_timer.work); 25226bd32326SVille Tervo 2523bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2524bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2525bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2526bda4f23aSAndrei Emeltchenko 2527bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 2528bda4f23aSAndrei Emeltchenko } else { 25296bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 2530bda4f23aSAndrei Emeltchenko } 2531bda4f23aSAndrei Emeltchenko 25326bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2533c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 25346bd32326SVille Tervo } 25356bd32326SVille Tervo 25362763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 25376928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type) 25382763eda6SSzymon Janc { 25392763eda6SSzymon Janc struct oob_data *data; 25402763eda6SSzymon Janc 25416928a924SJohan Hedberg list_for_each_entry(data, &hdev->remote_oob_data, list) { 25426928a924SJohan Hedberg if (bacmp(bdaddr, &data->bdaddr) != 0) 25436928a924SJohan Hedberg continue; 25446928a924SJohan Hedberg if (data->bdaddr_type != bdaddr_type) 25456928a924SJohan Hedberg continue; 25462763eda6SSzymon Janc return data; 25476928a924SJohan Hedberg } 25482763eda6SSzymon Janc 25492763eda6SSzymon Janc return NULL; 25502763eda6SSzymon Janc } 25512763eda6SSzymon Janc 25526928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 25536928a924SJohan Hedberg u8 bdaddr_type) 25542763eda6SSzymon Janc { 25552763eda6SSzymon Janc struct oob_data *data; 25562763eda6SSzymon Janc 25576928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 25582763eda6SSzymon Janc if (!data) 25592763eda6SSzymon Janc return -ENOENT; 25602763eda6SSzymon Janc 25616928a924SJohan Hedberg BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type); 25622763eda6SSzymon Janc 25632763eda6SSzymon Janc list_del(&data->list); 25642763eda6SSzymon Janc kfree(data); 25652763eda6SSzymon Janc 25662763eda6SSzymon Janc return 0; 25672763eda6SSzymon Janc } 25682763eda6SSzymon Janc 256935f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 25702763eda6SSzymon Janc { 25712763eda6SSzymon Janc struct oob_data *data, *n; 25722763eda6SSzymon Janc 25732763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 25742763eda6SSzymon Janc list_del(&data->list); 25752763eda6SSzymon Janc kfree(data); 25762763eda6SSzymon Janc } 25772763eda6SSzymon Janc } 25782763eda6SSzymon Janc 25790798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 25806928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192, 258138da1703SJohan Hedberg u8 *hash256, u8 *rand256) 25820798872eSMarcel Holtmann { 25830798872eSMarcel Holtmann struct oob_data *data; 25840798872eSMarcel Holtmann 25856928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 25860798872eSMarcel Holtmann if (!data) { 25870a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 25880798872eSMarcel Holtmann if (!data) 25890798872eSMarcel Holtmann return -ENOMEM; 25900798872eSMarcel Holtmann 25910798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 25926928a924SJohan Hedberg data->bdaddr_type = bdaddr_type; 25930798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 25940798872eSMarcel Holtmann } 25950798872eSMarcel Holtmann 259681328d5cSJohan Hedberg if (hash192 && rand192) { 25970798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 259838da1703SJohan Hedberg memcpy(data->rand192, rand192, sizeof(data->rand192)); 2599f7697b16SMarcel Holtmann if (hash256 && rand256) 2600f7697b16SMarcel Holtmann data->present = 0x03; 260181328d5cSJohan Hedberg } else { 260281328d5cSJohan Hedberg memset(data->hash192, 0, sizeof(data->hash192)); 260381328d5cSJohan Hedberg memset(data->rand192, 0, sizeof(data->rand192)); 2604f7697b16SMarcel Holtmann if (hash256 && rand256) 2605f7697b16SMarcel Holtmann data->present = 0x02; 2606f7697b16SMarcel Holtmann else 2607f7697b16SMarcel Holtmann data->present = 0x00; 260881328d5cSJohan Hedberg } 26090798872eSMarcel Holtmann 261081328d5cSJohan Hedberg if (hash256 && rand256) { 26110798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 261238da1703SJohan Hedberg memcpy(data->rand256, rand256, sizeof(data->rand256)); 261381328d5cSJohan Hedberg } else { 261481328d5cSJohan Hedberg memset(data->hash256, 0, sizeof(data->hash256)); 261581328d5cSJohan Hedberg memset(data->rand256, 0, sizeof(data->rand256)); 2616f7697b16SMarcel Holtmann if (hash192 && rand192) 2617f7697b16SMarcel Holtmann data->present = 0x01; 261881328d5cSJohan Hedberg } 26190798872eSMarcel Holtmann 26206ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 26212763eda6SSzymon Janc 26222763eda6SSzymon Janc return 0; 26232763eda6SSzymon Janc } 26242763eda6SSzymon Janc 2625d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2626d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance) 2627d2609b34SFlorian Grandel { 2628d2609b34SFlorian Grandel struct adv_info *adv_instance; 2629d2609b34SFlorian Grandel 2630d2609b34SFlorian Grandel list_for_each_entry(adv_instance, &hdev->adv_instances, list) { 2631d2609b34SFlorian Grandel if (adv_instance->instance == instance) 2632d2609b34SFlorian Grandel return adv_instance; 2633d2609b34SFlorian Grandel } 2634d2609b34SFlorian Grandel 2635d2609b34SFlorian Grandel return NULL; 2636d2609b34SFlorian Grandel } 2637d2609b34SFlorian Grandel 2638d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 263974b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance) 264074b93e9fSPrasanna Karthik { 2641d2609b34SFlorian Grandel struct adv_info *cur_instance; 2642d2609b34SFlorian Grandel 2643d2609b34SFlorian Grandel cur_instance = hci_find_adv_instance(hdev, instance); 2644d2609b34SFlorian Grandel if (!cur_instance) 2645d2609b34SFlorian Grandel return NULL; 2646d2609b34SFlorian Grandel 2647d2609b34SFlorian Grandel if (cur_instance == list_last_entry(&hdev->adv_instances, 2648d2609b34SFlorian Grandel struct adv_info, list)) 2649d2609b34SFlorian Grandel return list_first_entry(&hdev->adv_instances, 2650d2609b34SFlorian Grandel struct adv_info, list); 2651d2609b34SFlorian Grandel else 2652d2609b34SFlorian Grandel return list_next_entry(cur_instance, list); 2653d2609b34SFlorian Grandel } 2654d2609b34SFlorian Grandel 2655d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2656d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance) 2657d2609b34SFlorian Grandel { 2658d2609b34SFlorian Grandel struct adv_info *adv_instance; 2659d2609b34SFlorian Grandel 2660d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 2661d2609b34SFlorian Grandel if (!adv_instance) 2662d2609b34SFlorian Grandel return -ENOENT; 2663d2609b34SFlorian Grandel 2664d2609b34SFlorian Grandel BT_DBG("%s removing %dMR", hdev->name, instance); 2665d2609b34SFlorian Grandel 2666cab054abSJohan Hedberg if (hdev->cur_adv_instance == instance) { 2667cab054abSJohan Hedberg if (hdev->adv_instance_timeout) { 26685d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 26695d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 26705d900e46SFlorian Grandel } 2671cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 2672cab054abSJohan Hedberg } 26735d900e46SFlorian Grandel 2674d2609b34SFlorian Grandel list_del(&adv_instance->list); 2675d2609b34SFlorian Grandel kfree(adv_instance); 2676d2609b34SFlorian Grandel 2677d2609b34SFlorian Grandel hdev->adv_instance_cnt--; 2678d2609b34SFlorian Grandel 2679d2609b34SFlorian Grandel return 0; 2680d2609b34SFlorian Grandel } 2681d2609b34SFlorian Grandel 2682d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2683d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev) 2684d2609b34SFlorian Grandel { 2685d2609b34SFlorian Grandel struct adv_info *adv_instance, *n; 2686d2609b34SFlorian Grandel 26875d900e46SFlorian Grandel if (hdev->adv_instance_timeout) { 26885d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 26895d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 26905d900e46SFlorian Grandel } 26915d900e46SFlorian Grandel 2692d2609b34SFlorian Grandel list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) { 2693d2609b34SFlorian Grandel list_del(&adv_instance->list); 2694d2609b34SFlorian Grandel kfree(adv_instance); 2695d2609b34SFlorian Grandel } 2696d2609b34SFlorian Grandel 2697d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 2698cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 2699d2609b34SFlorian Grandel } 2700d2609b34SFlorian Grandel 2701d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 2702d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags, 2703d2609b34SFlorian Grandel u16 adv_data_len, u8 *adv_data, 2704d2609b34SFlorian Grandel u16 scan_rsp_len, u8 *scan_rsp_data, 2705d2609b34SFlorian Grandel u16 timeout, u16 duration) 2706d2609b34SFlorian Grandel { 2707d2609b34SFlorian Grandel struct adv_info *adv_instance; 2708d2609b34SFlorian Grandel 2709d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 2710d2609b34SFlorian Grandel if (adv_instance) { 2711d2609b34SFlorian Grandel memset(adv_instance->adv_data, 0, 2712d2609b34SFlorian Grandel sizeof(adv_instance->adv_data)); 2713d2609b34SFlorian Grandel memset(adv_instance->scan_rsp_data, 0, 2714d2609b34SFlorian Grandel sizeof(adv_instance->scan_rsp_data)); 2715d2609b34SFlorian Grandel } else { 2716d2609b34SFlorian Grandel if (hdev->adv_instance_cnt >= HCI_MAX_ADV_INSTANCES || 2717d2609b34SFlorian Grandel instance < 1 || instance > HCI_MAX_ADV_INSTANCES) 2718d2609b34SFlorian Grandel return -EOVERFLOW; 2719d2609b34SFlorian Grandel 272039ecfad6SJohan Hedberg adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL); 2721d2609b34SFlorian Grandel if (!adv_instance) 2722d2609b34SFlorian Grandel return -ENOMEM; 2723d2609b34SFlorian Grandel 2724fffd38bcSFlorian Grandel adv_instance->pending = true; 2725d2609b34SFlorian Grandel adv_instance->instance = instance; 2726d2609b34SFlorian Grandel list_add(&adv_instance->list, &hdev->adv_instances); 2727d2609b34SFlorian Grandel hdev->adv_instance_cnt++; 2728d2609b34SFlorian Grandel } 2729d2609b34SFlorian Grandel 2730d2609b34SFlorian Grandel adv_instance->flags = flags; 2731d2609b34SFlorian Grandel adv_instance->adv_data_len = adv_data_len; 2732d2609b34SFlorian Grandel adv_instance->scan_rsp_len = scan_rsp_len; 2733d2609b34SFlorian Grandel 2734d2609b34SFlorian Grandel if (adv_data_len) 2735d2609b34SFlorian Grandel memcpy(adv_instance->adv_data, adv_data, adv_data_len); 2736d2609b34SFlorian Grandel 2737d2609b34SFlorian Grandel if (scan_rsp_len) 2738d2609b34SFlorian Grandel memcpy(adv_instance->scan_rsp_data, 2739d2609b34SFlorian Grandel scan_rsp_data, scan_rsp_len); 2740d2609b34SFlorian Grandel 2741d2609b34SFlorian Grandel adv_instance->timeout = timeout; 27425d900e46SFlorian Grandel adv_instance->remaining_time = timeout; 2743d2609b34SFlorian Grandel 2744d2609b34SFlorian Grandel if (duration == 0) 2745d2609b34SFlorian Grandel adv_instance->duration = HCI_DEFAULT_ADV_DURATION; 2746d2609b34SFlorian Grandel else 2747d2609b34SFlorian Grandel adv_instance->duration = duration; 2748d2609b34SFlorian Grandel 2749d2609b34SFlorian Grandel BT_DBG("%s for %dMR", hdev->name, instance); 2750d2609b34SFlorian Grandel 2751d2609b34SFlorian Grandel return 0; 2752d2609b34SFlorian Grandel } 2753d2609b34SFlorian Grandel 2754dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list, 2755b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 2756b2a66aadSAntti Julku { 2757b2a66aadSAntti Julku struct bdaddr_list *b; 2758b2a66aadSAntti Julku 2759dcc36c16SJohan Hedberg list_for_each_entry(b, bdaddr_list, list) { 2760b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2761b2a66aadSAntti Julku return b; 2762b9ee0a78SMarcel Holtmann } 2763b2a66aadSAntti Julku 2764b2a66aadSAntti Julku return NULL; 2765b2a66aadSAntti Julku } 2766b2a66aadSAntti Julku 2767dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list) 2768b2a66aadSAntti Julku { 27697eb7404fSGeliang Tang struct bdaddr_list *b, *n; 2770b2a66aadSAntti Julku 27717eb7404fSGeliang Tang list_for_each_entry_safe(b, n, bdaddr_list, list) { 27727eb7404fSGeliang Tang list_del(&b->list); 2773b2a66aadSAntti Julku kfree(b); 2774b2a66aadSAntti Julku } 2775b2a66aadSAntti Julku } 2776b2a66aadSAntti Julku 2777dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type) 2778b2a66aadSAntti Julku { 2779b2a66aadSAntti Julku struct bdaddr_list *entry; 2780b2a66aadSAntti Julku 2781b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 2782b2a66aadSAntti Julku return -EBADF; 2783b2a66aadSAntti Julku 2784dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(list, bdaddr, type)) 27855e762444SAntti Julku return -EEXIST; 2786b2a66aadSAntti Julku 278727f70f3eSJohan Hedberg entry = kzalloc(sizeof(*entry), GFP_KERNEL); 27885e762444SAntti Julku if (!entry) 27895e762444SAntti Julku return -ENOMEM; 2790b2a66aadSAntti Julku 2791b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 2792b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 2793b2a66aadSAntti Julku 2794dcc36c16SJohan Hedberg list_add(&entry->list, list); 2795b2a66aadSAntti Julku 27962a8357f2SJohan Hedberg return 0; 2797b2a66aadSAntti Julku } 2798b2a66aadSAntti Julku 2799dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type) 2800b2a66aadSAntti Julku { 2801b2a66aadSAntti Julku struct bdaddr_list *entry; 2802b2a66aadSAntti Julku 280335f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 2804dcc36c16SJohan Hedberg hci_bdaddr_list_clear(list); 280535f7498aSJohan Hedberg return 0; 280635f7498aSJohan Hedberg } 2807b2a66aadSAntti Julku 2808dcc36c16SJohan Hedberg entry = hci_bdaddr_list_lookup(list, bdaddr, type); 2809d2ab0ac1SMarcel Holtmann if (!entry) 2810d2ab0ac1SMarcel Holtmann return -ENOENT; 2811d2ab0ac1SMarcel Holtmann 2812d2ab0ac1SMarcel Holtmann list_del(&entry->list); 2813d2ab0ac1SMarcel Holtmann kfree(entry); 2814d2ab0ac1SMarcel Holtmann 2815d2ab0ac1SMarcel Holtmann return 0; 2816d2ab0ac1SMarcel Holtmann } 2817d2ab0ac1SMarcel Holtmann 281815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 281915819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 282015819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 282115819a70SAndre Guedes { 282215819a70SAndre Guedes struct hci_conn_params *params; 282315819a70SAndre Guedes 282415819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 282515819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 282615819a70SAndre Guedes params->addr_type == addr_type) { 282715819a70SAndre Guedes return params; 282815819a70SAndre Guedes } 282915819a70SAndre Guedes } 283015819a70SAndre Guedes 283115819a70SAndre Guedes return NULL; 283215819a70SAndre Guedes } 283315819a70SAndre Guedes 283415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 2835501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 28364b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type) 283715819a70SAndre Guedes { 2838912b42efSJohan Hedberg struct hci_conn_params *param; 283915819a70SAndre Guedes 2840501f8827SJohan Hedberg list_for_each_entry(param, list, action) { 2841912b42efSJohan Hedberg if (bacmp(¶m->addr, addr) == 0 && 2842912b42efSJohan Hedberg param->addr_type == addr_type) 2843912b42efSJohan Hedberg return param; 28444b10966fSMarcel Holtmann } 28454b10966fSMarcel Holtmann 28464b10966fSMarcel Holtmann return NULL; 284715819a70SAndre Guedes } 284815819a70SAndre Guedes 284915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 285051d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 285151d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type) 285215819a70SAndre Guedes { 285315819a70SAndre Guedes struct hci_conn_params *params; 285415819a70SAndre Guedes 285515819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 2856cef952ceSAndre Guedes if (params) 285751d167c0SMarcel Holtmann return params; 285815819a70SAndre Guedes 285915819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 286015819a70SAndre Guedes if (!params) { 286115819a70SAndre Guedes BT_ERR("Out of memory"); 286251d167c0SMarcel Holtmann return NULL; 286315819a70SAndre Guedes } 286415819a70SAndre Guedes 286515819a70SAndre Guedes bacpy(¶ms->addr, addr); 286615819a70SAndre Guedes params->addr_type = addr_type; 2867cef952ceSAndre Guedes 2868cef952ceSAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 286993450c75SJohan Hedberg INIT_LIST_HEAD(¶ms->action); 2870cef952ceSAndre Guedes 2871bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval; 2872bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval; 2873bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency; 2874bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout; 2875bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED; 2876bf5b3c8bSMarcel Holtmann 2877bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 2878bf5b3c8bSMarcel Holtmann 287951d167c0SMarcel Holtmann return params; 2880bf5b3c8bSMarcel Holtmann } 2881bf5b3c8bSMarcel Holtmann 2882f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params) 2883f6c63249SJohan Hedberg { 2884f6c63249SJohan Hedberg if (params->conn) { 2885f6c63249SJohan Hedberg hci_conn_drop(params->conn); 2886f6c63249SJohan Hedberg hci_conn_put(params->conn); 2887f6c63249SJohan Hedberg } 2888f6c63249SJohan Hedberg 2889f6c63249SJohan Hedberg list_del(¶ms->action); 2890f6c63249SJohan Hedberg list_del(¶ms->list); 2891f6c63249SJohan Hedberg kfree(params); 2892f6c63249SJohan Hedberg } 2893f6c63249SJohan Hedberg 289415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 289515819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 289615819a70SAndre Guedes { 289715819a70SAndre Guedes struct hci_conn_params *params; 289815819a70SAndre Guedes 289915819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 290015819a70SAndre Guedes if (!params) 290115819a70SAndre Guedes return; 290215819a70SAndre Guedes 2903f6c63249SJohan Hedberg hci_conn_params_free(params); 290415819a70SAndre Guedes 290595305baaSJohan Hedberg hci_update_background_scan(hdev); 290695305baaSJohan Hedberg 290715819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 290815819a70SAndre Guedes } 290915819a70SAndre Guedes 291015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 291155af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev) 291215819a70SAndre Guedes { 291315819a70SAndre Guedes struct hci_conn_params *params, *tmp; 291415819a70SAndre Guedes 291515819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 291655af49a8SJohan Hedberg if (params->auto_connect != HCI_AUTO_CONN_DISABLED) 291755af49a8SJohan Hedberg continue; 2918f75113a2SJakub Pawlowski 2919f75113a2SJakub Pawlowski /* If trying to estabilish one time connection to disabled 2920f75113a2SJakub Pawlowski * device, leave the params, but mark them as just once. 2921f75113a2SJakub Pawlowski */ 2922f75113a2SJakub Pawlowski if (params->explicit_connect) { 2923f75113a2SJakub Pawlowski params->auto_connect = HCI_AUTO_CONN_EXPLICIT; 2924f75113a2SJakub Pawlowski continue; 2925f75113a2SJakub Pawlowski } 2926f75113a2SJakub Pawlowski 292715819a70SAndre Guedes list_del(¶ms->list); 292815819a70SAndre Guedes kfree(params); 292915819a70SAndre Guedes } 293015819a70SAndre Guedes 293155af49a8SJohan Hedberg BT_DBG("All LE disabled connection parameters were removed"); 293255af49a8SJohan Hedberg } 293355af49a8SJohan Hedberg 293455af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */ 2935030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev) 293615819a70SAndre Guedes { 293715819a70SAndre Guedes struct hci_conn_params *params, *tmp; 293815819a70SAndre Guedes 2939f6c63249SJohan Hedberg list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) 2940f6c63249SJohan Hedberg hci_conn_params_free(params); 294115819a70SAndre Guedes 294215819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 294315819a70SAndre Guedes } 294415819a70SAndre Guedes 2945a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 2946a1f4c318SJohan Hedberg * 2947a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 2948a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 2949a1f4c318SJohan Hedberg * the static random address. 2950a1f4c318SJohan Hedberg * 2951a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 2952a1f4c318SJohan Hedberg * public address to use the static random address instead. 295350b5b952SMarcel Holtmann * 295450b5b952SMarcel Holtmann * In case BR/EDR has been disabled on a dual-mode controller and 295550b5b952SMarcel Holtmann * userspace has configured a static address, then that address 295650b5b952SMarcel Holtmann * becomes the identity address instead of the public BR/EDR address. 2957a1f4c318SJohan Hedberg */ 2958a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 2959a1f4c318SJohan Hedberg u8 *bdaddr_type) 2960a1f4c318SJohan Hedberg { 2961b7cb93e5SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) || 296250b5b952SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) || 2963d7a5a11dSMarcel Holtmann (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) && 296450b5b952SMarcel Holtmann bacmp(&hdev->static_addr, BDADDR_ANY))) { 2965a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 2966a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 2967a1f4c318SJohan Hedberg } else { 2968a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 2969a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 2970a1f4c318SJohan Hedberg } 2971a1f4c318SJohan Hedberg } 2972a1f4c318SJohan Hedberg 29739be0dab7SDavid Herrmann /* Alloc HCI device */ 29749be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 29759be0dab7SDavid Herrmann { 29769be0dab7SDavid Herrmann struct hci_dev *hdev; 29779be0dab7SDavid Herrmann 297827f70f3eSJohan Hedberg hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); 29799be0dab7SDavid Herrmann if (!hdev) 29809be0dab7SDavid Herrmann return NULL; 29819be0dab7SDavid Herrmann 2982b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 2983b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 2984b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 2985b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 2986b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 298796c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */ 2988bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 2989bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2990d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 2991d2609b34SFlorian Grandel hdev->cur_adv_instance = 0x00; 29925d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 2993b1b813d4SDavid Herrmann 2994b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 2995b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 2996b1b813d4SDavid Herrmann 29973f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 2998628531c9SGeorg Lukas hdev->le_adv_min_interval = 0x0800; 2999628531c9SGeorg Lukas hdev->le_adv_max_interval = 0x0800; 3000bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3001bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 3002b48c3b59SJonas Holmberg hdev->le_conn_min_interval = 0x0018; 3003b48c3b59SJonas Holmberg hdev->le_conn_max_interval = 0x0028; 300404fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000; 300504fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a; 3006a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = 0x001b; 3007a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = 0x0148; 3008a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = 0x001b; 3009a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = 0x0148; 3010a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = 0x001b; 3011a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = 0x0148; 3012bef64738SMarcel Holtmann 3013d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 3014b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 301531ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 301631ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 3017d6bfd59cSJohan Hedberg 3018b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3019b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3020b1b813d4SDavid Herrmann 3021b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3022b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 30236659358eSJohan Hedberg INIT_LIST_HEAD(&hdev->whitelist); 3024b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3025b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3026b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3027970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3028b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 3029d2ab0ac1SMarcel Holtmann INIT_LIST_HEAD(&hdev->le_white_list); 303015819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 303177a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 303266f8455aSJohan Hedberg INIT_LIST_HEAD(&hdev->pend_le_reports); 30336b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3034d2609b34SFlorian Grandel INIT_LIST_HEAD(&hdev->adv_instances); 3035b1b813d4SDavid Herrmann 3036b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3037b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3038b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3039b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3040c7741d16SMarcel Holtmann INIT_WORK(&hdev->error_reset, hci_error_reset); 3041b1b813d4SDavid Herrmann 3042b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3043b1b813d4SDavid Herrmann 3044b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3045b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3046b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3047b1b813d4SDavid Herrmann 3048b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 3049b1b813d4SDavid Herrmann 305065cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout); 3051b1b813d4SDavid Herrmann 30525fc16cc4SJohan Hedberg hci_request_setup(hdev); 30535fc16cc4SJohan Hedberg 3054b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3055b1b813d4SDavid Herrmann discovery_init(hdev); 30569be0dab7SDavid Herrmann 30579be0dab7SDavid Herrmann return hdev; 30589be0dab7SDavid Herrmann } 30599be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 30609be0dab7SDavid Herrmann 30619be0dab7SDavid Herrmann /* Free HCI device */ 30629be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 30639be0dab7SDavid Herrmann { 30649be0dab7SDavid Herrmann /* will free via device release */ 30659be0dab7SDavid Herrmann put_device(&hdev->dev); 30669be0dab7SDavid Herrmann } 30679be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 30689be0dab7SDavid Herrmann 30691da177e4SLinus Torvalds /* Register HCI device */ 30701da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 30711da177e4SLinus Torvalds { 3072b1b813d4SDavid Herrmann int id, error; 30731da177e4SLinus Torvalds 307474292d5aSMarcel Holtmann if (!hdev->open || !hdev->close || !hdev->send) 30751da177e4SLinus Torvalds return -EINVAL; 30761da177e4SLinus Torvalds 307708add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 307808add513SMat Martineau * so the index can be used as the AMP controller ID. 307908add513SMat Martineau */ 30803df92b31SSasha Levin switch (hdev->dev_type) { 3081ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 30823df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 30831da177e4SLinus Torvalds break; 30843df92b31SSasha Levin case HCI_AMP: 30853df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 30863df92b31SSasha Levin break; 30873df92b31SSasha Levin default: 30883df92b31SSasha Levin return -EINVAL; 30891da177e4SLinus Torvalds } 30901da177e4SLinus Torvalds 30913df92b31SSasha Levin if (id < 0) 30923df92b31SSasha Levin return id; 30933df92b31SSasha Levin 30941da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 30951da177e4SLinus Torvalds hdev->id = id; 30962d8b3a11SAndrei Emeltchenko 30972d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 30982d8b3a11SAndrei Emeltchenko 3099d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3100d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 310133ca954dSDavid Herrmann if (!hdev->workqueue) { 310233ca954dSDavid Herrmann error = -ENOMEM; 310333ca954dSDavid Herrmann goto err; 310433ca954dSDavid Herrmann } 3105f48fd9c8SMarcel Holtmann 3106d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3107d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 31086ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 31096ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 31106ead1bbcSJohan Hedberg error = -ENOMEM; 31116ead1bbcSJohan Hedberg goto err; 31126ead1bbcSJohan Hedberg } 31136ead1bbcSJohan Hedberg 31140153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 31150153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 31160153e2ecSMarcel Holtmann 3117bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3118bdc3e0f1SMarcel Holtmann 3119bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 312033ca954dSDavid Herrmann if (error < 0) 312154506918SJohan Hedberg goto err_wqueue; 31221da177e4SLinus Torvalds 31236d5d2ee6SHeiner Kallweit hci_leds_init(hdev); 31246d5d2ee6SHeiner Kallweit 3125611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3126a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3127a8c5fb1aSGustavo Padovan hdev); 3128611b30f7SMarcel Holtmann if (hdev->rfkill) { 3129611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3130611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3131611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3132611b30f7SMarcel Holtmann } 3133611b30f7SMarcel Holtmann } 3134611b30f7SMarcel Holtmann 31355e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 3136a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 31375e130367SJohan Hedberg 3138a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SETUP); 3139a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_AUTO_OFF); 3140ce2be9acSAndrei Emeltchenko 3141ca8bee5dSMarcel Holtmann if (hdev->dev_type == HCI_PRIMARY) { 314256f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 314356f87901SJohan Hedberg * through reading supported features during init. 314456f87901SJohan Hedberg */ 3145a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 314656f87901SJohan Hedberg } 3147ce2be9acSAndrei Emeltchenko 3148fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3149fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3150fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3151fcee3377SGustavo Padovan 31524a964404SMarcel Holtmann /* Devices that are marked for raw-only usage are unconfigured 31534a964404SMarcel Holtmann * and should not be included in normal operation. 3154fee746b0SMarcel Holtmann */ 3155fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 3156a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 3157fee746b0SMarcel Holtmann 315805fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_REG); 3159dc946bd8SDavid Herrmann hci_dev_hold(hdev); 31601da177e4SLinus Torvalds 316119202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3162fbe96d6fSMarcel Holtmann 31631da177e4SLinus Torvalds return id; 3164f48fd9c8SMarcel Holtmann 316533ca954dSDavid Herrmann err_wqueue: 316633ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 31676ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 316833ca954dSDavid Herrmann err: 31693df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3170f48fd9c8SMarcel Holtmann 317133ca954dSDavid Herrmann return error; 31721da177e4SLinus Torvalds } 31731da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 31741da177e4SLinus Torvalds 31751da177e4SLinus Torvalds /* Unregister HCI device */ 317659735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 31771da177e4SLinus Torvalds { 31782d7cc19eSMarcel Holtmann int id; 3179ef222013SMarcel Holtmann 3180c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 31811da177e4SLinus Torvalds 3182a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNREGISTER); 318394324962SJohan Hovold 31843df92b31SSasha Levin id = hdev->id; 31853df92b31SSasha Levin 3186f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 31871da177e4SLinus Torvalds list_del(&hdev->list); 3188f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 31891da177e4SLinus Torvalds 3190b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 3191b9b5ef18SGustavo Padovan 3192bf389cabSJiri Slaby hci_dev_do_close(hdev); 3193bf389cabSJiri Slaby 3194ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 3195d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_SETUP) && 3196d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 319709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3198744cf19eSJohan Hedberg mgmt_index_removed(hdev); 319909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 320056e5cb86SJohan Hedberg } 3201ab81cbf9SJohan Hedberg 32022e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 32032e58ef3eSJohan Hedberg * pending list */ 32042e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 32052e58ef3eSJohan Hedberg 320605fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UNREG); 32071da177e4SLinus Torvalds 3208611b30f7SMarcel Holtmann if (hdev->rfkill) { 3209611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 3210611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3211611b30f7SMarcel Holtmann } 3212611b30f7SMarcel Holtmann 3213bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 3214147e2d59SDave Young 32150153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 32165177a838SMarcel Holtmann kfree_const(hdev->hw_info); 32175177a838SMarcel Holtmann kfree_const(hdev->fw_info); 32180153e2ecSMarcel Holtmann 3219f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 32206ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 3221f48fd9c8SMarcel Holtmann 322209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3223dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->blacklist); 32246659358eSJohan Hedberg hci_bdaddr_list_clear(&hdev->whitelist); 32252aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 322655ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 3227b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 3228970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 32292763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 3230d2609b34SFlorian Grandel hci_adv_instances_clear(hdev); 3231dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->le_white_list); 3232373110c5SJohan Hedberg hci_conn_params_clear_all(hdev); 323322078800SMarcel Holtmann hci_discovery_filter_clear(hdev); 323409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 3235e2e0cacbSJohan Hedberg 3236dc946bd8SDavid Herrmann hci_dev_put(hdev); 32373df92b31SSasha Levin 32383df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 32391da177e4SLinus Torvalds } 32401da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 32411da177e4SLinus Torvalds 32421da177e4SLinus Torvalds /* Suspend HCI device */ 32431da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 32441da177e4SLinus Torvalds { 324505fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_SUSPEND); 32461da177e4SLinus Torvalds return 0; 32471da177e4SLinus Torvalds } 32481da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 32491da177e4SLinus Torvalds 32501da177e4SLinus Torvalds /* Resume HCI device */ 32511da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 32521da177e4SLinus Torvalds { 325305fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_RESUME); 32541da177e4SLinus Torvalds return 0; 32551da177e4SLinus Torvalds } 32561da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 32571da177e4SLinus Torvalds 325875e0569fSMarcel Holtmann /* Reset HCI device */ 325975e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev) 326075e0569fSMarcel Holtmann { 326175e0569fSMarcel Holtmann const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; 326275e0569fSMarcel Holtmann struct sk_buff *skb; 326375e0569fSMarcel Holtmann 326475e0569fSMarcel Holtmann skb = bt_skb_alloc(3, GFP_ATOMIC); 326575e0569fSMarcel Holtmann if (!skb) 326675e0569fSMarcel Holtmann return -ENOMEM; 326775e0569fSMarcel Holtmann 3268d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_EVENT_PKT; 326959ae1d12SJohannes Berg skb_put_data(skb, hw_err, 3); 327075e0569fSMarcel Holtmann 327175e0569fSMarcel Holtmann /* Send Hardware Error to upper stack */ 327275e0569fSMarcel Holtmann return hci_recv_frame(hdev, skb); 327375e0569fSMarcel Holtmann } 327475e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev); 327575e0569fSMarcel Holtmann 327676bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 3277e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 327876bca880SMarcel Holtmann { 327976bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 328076bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 328176bca880SMarcel Holtmann kfree_skb(skb); 328276bca880SMarcel Holtmann return -ENXIO; 328376bca880SMarcel Holtmann } 328476bca880SMarcel Holtmann 3285d79f34e3SMarcel Holtmann if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT && 3286d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && 3287d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) { 3288fe806dceSMarcel Holtmann kfree_skb(skb); 3289fe806dceSMarcel Holtmann return -EINVAL; 3290fe806dceSMarcel Holtmann } 3291fe806dceSMarcel Holtmann 3292d82603c6SJorrit Schippers /* Incoming skb */ 329376bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 329476bca880SMarcel Holtmann 329576bca880SMarcel Holtmann /* Time stamp */ 329676bca880SMarcel Holtmann __net_timestamp(skb); 329776bca880SMarcel Holtmann 329876bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3299b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3300c78ae283SMarcel Holtmann 330176bca880SMarcel Holtmann return 0; 330276bca880SMarcel Holtmann } 330376bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 330476bca880SMarcel Holtmann 3305e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */ 3306e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb) 3307e875ff84SMarcel Holtmann { 3308581d6fd6SMarcel Holtmann /* Mark as diagnostic packet */ 3309d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_DIAG_PKT; 3310581d6fd6SMarcel Holtmann 3311e875ff84SMarcel Holtmann /* Time stamp */ 3312e875ff84SMarcel Holtmann __net_timestamp(skb); 3313e875ff84SMarcel Holtmann 3314581d6fd6SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3315581d6fd6SMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3316e875ff84SMarcel Holtmann 3317e875ff84SMarcel Holtmann return 0; 3318e875ff84SMarcel Holtmann } 3319e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag); 3320e875ff84SMarcel Holtmann 33215177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...) 33225177a838SMarcel Holtmann { 33235177a838SMarcel Holtmann va_list vargs; 33245177a838SMarcel Holtmann 33255177a838SMarcel Holtmann va_start(vargs, fmt); 33265177a838SMarcel Holtmann kfree_const(hdev->hw_info); 33275177a838SMarcel Holtmann hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 33285177a838SMarcel Holtmann va_end(vargs); 33295177a838SMarcel Holtmann } 33305177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info); 33315177a838SMarcel Holtmann 33325177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...) 33335177a838SMarcel Holtmann { 33345177a838SMarcel Holtmann va_list vargs; 33355177a838SMarcel Holtmann 33365177a838SMarcel Holtmann va_start(vargs, fmt); 33375177a838SMarcel Holtmann kfree_const(hdev->fw_info); 33385177a838SMarcel Holtmann hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 33395177a838SMarcel Holtmann va_end(vargs); 33405177a838SMarcel Holtmann } 33415177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info); 33425177a838SMarcel Holtmann 33431da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 33441da177e4SLinus Torvalds 33451da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 33461da177e4SLinus Torvalds { 33471da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 33481da177e4SLinus Torvalds 3349fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 335000629e0fSJohan Hedberg list_add_tail(&cb->list, &hci_cb_list); 3351fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 33521da177e4SLinus Torvalds 33531da177e4SLinus Torvalds return 0; 33541da177e4SLinus Torvalds } 33551da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 33561da177e4SLinus Torvalds 33571da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 33581da177e4SLinus Torvalds { 33591da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 33601da177e4SLinus Torvalds 3361fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 33621da177e4SLinus Torvalds list_del(&cb->list); 3363fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 33641da177e4SLinus Torvalds 33651da177e4SLinus Torvalds return 0; 33661da177e4SLinus Torvalds } 33671da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 33681da177e4SLinus Torvalds 336951086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 33701da177e4SLinus Torvalds { 3371cdc52faaSMarcel Holtmann int err; 3372cdc52faaSMarcel Holtmann 3373d79f34e3SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb), 3374d79f34e3SMarcel Holtmann skb->len); 33751da177e4SLinus Torvalds 33761da177e4SLinus Torvalds /* Time stamp */ 3377a61bbcf2SPatrick McHardy __net_timestamp(skb); 33781da177e4SLinus Torvalds 3379cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3380cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3381cd82e61cSMarcel Holtmann 3382cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3383cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3384470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 33851da177e4SLinus Torvalds } 33861da177e4SLinus Torvalds 33871da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 33881da177e4SLinus Torvalds skb_orphan(skb); 33891da177e4SLinus Torvalds 339073d0d3c8SMarcel Holtmann if (!test_bit(HCI_RUNNING, &hdev->flags)) { 339173d0d3c8SMarcel Holtmann kfree_skb(skb); 339273d0d3c8SMarcel Holtmann return; 339373d0d3c8SMarcel Holtmann } 339473d0d3c8SMarcel Holtmann 3395cdc52faaSMarcel Holtmann err = hdev->send(hdev, skb); 3396cdc52faaSMarcel Holtmann if (err < 0) { 3397cdc52faaSMarcel Holtmann BT_ERR("%s sending frame failed (%d)", hdev->name, err); 3398cdc52faaSMarcel Holtmann kfree_skb(skb); 3399cdc52faaSMarcel Holtmann } 34001da177e4SLinus Torvalds } 34011da177e4SLinus Torvalds 34021ca3a9d0SJohan Hedberg /* Send HCI command */ 340307dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 340407dc93ddSJohan Hedberg const void *param) 34051ca3a9d0SJohan Hedberg { 34061ca3a9d0SJohan Hedberg struct sk_buff *skb; 34071ca3a9d0SJohan Hedberg 34081ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 34091ca3a9d0SJohan Hedberg 34101ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 34111ca3a9d0SJohan Hedberg if (!skb) { 34121ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 34131ca3a9d0SJohan Hedberg return -ENOMEM; 34141ca3a9d0SJohan Hedberg } 34151ca3a9d0SJohan Hedberg 341649c922bbSStephen Hemminger /* Stand-alone HCI commands must be flagged as 341711714b3dSJohan Hedberg * single-command requests. 341811714b3dSJohan Hedberg */ 341944d27137SJohan Hedberg bt_cb(skb)->hci.req_flags |= HCI_REQ_START; 342011714b3dSJohan Hedberg 34211da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3422c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 34231da177e4SLinus Torvalds 34241da177e4SLinus Torvalds return 0; 34251da177e4SLinus Torvalds } 34261da177e4SLinus Torvalds 34271da177e4SLinus Torvalds /* Get data from the previously sent command */ 3428a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 34291da177e4SLinus Torvalds { 34301da177e4SLinus Torvalds struct hci_command_hdr *hdr; 34311da177e4SLinus Torvalds 34321da177e4SLinus Torvalds if (!hdev->sent_cmd) 34331da177e4SLinus Torvalds return NULL; 34341da177e4SLinus Torvalds 34351da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 34361da177e4SLinus Torvalds 3437a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 34381da177e4SLinus Torvalds return NULL; 34391da177e4SLinus Torvalds 3440f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 34411da177e4SLinus Torvalds 34421da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 34431da177e4SLinus Torvalds } 34441da177e4SLinus Torvalds 3445fbef168fSLoic Poulain /* Send HCI command and wait for command commplete event */ 3446fbef168fSLoic Poulain struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 3447fbef168fSLoic Poulain const void *param, u32 timeout) 3448fbef168fSLoic Poulain { 3449fbef168fSLoic Poulain struct sk_buff *skb; 3450fbef168fSLoic Poulain 3451fbef168fSLoic Poulain if (!test_bit(HCI_UP, &hdev->flags)) 3452fbef168fSLoic Poulain return ERR_PTR(-ENETDOWN); 3453fbef168fSLoic Poulain 3454fbef168fSLoic Poulain bt_dev_dbg(hdev, "opcode 0x%4.4x plen %d", opcode, plen); 3455fbef168fSLoic Poulain 3456b504430cSJohan Hedberg hci_req_sync_lock(hdev); 3457fbef168fSLoic Poulain skb = __hci_cmd_sync(hdev, opcode, plen, param, timeout); 3458b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 3459fbef168fSLoic Poulain 3460fbef168fSLoic Poulain return skb; 3461fbef168fSLoic Poulain } 3462fbef168fSLoic Poulain EXPORT_SYMBOL(hci_cmd_sync); 3463fbef168fSLoic Poulain 34641da177e4SLinus Torvalds /* Send ACL data */ 34651da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 34661da177e4SLinus Torvalds { 34671da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 34681da177e4SLinus Torvalds int len = skb->len; 34691da177e4SLinus Torvalds 3470badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3471badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 34729c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3473aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3474aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 34751da177e4SLinus Torvalds } 34761da177e4SLinus Torvalds 3477ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 347873d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 34791da177e4SLinus Torvalds { 3480ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 34811da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 34821da177e4SLinus Torvalds struct sk_buff *list; 34831da177e4SLinus Torvalds 3484087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3485087bfd99SGustavo Padovan skb->data_len = 0; 3486087bfd99SGustavo Padovan 3487d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 3488204a6e54SAndrei Emeltchenko 3489204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3490ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 3491087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3492204a6e54SAndrei Emeltchenko break; 3493204a6e54SAndrei Emeltchenko case HCI_AMP: 3494204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3495204a6e54SAndrei Emeltchenko break; 3496204a6e54SAndrei Emeltchenko default: 3497204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 3498204a6e54SAndrei Emeltchenko return; 3499204a6e54SAndrei Emeltchenko } 3500087bfd99SGustavo Padovan 350170f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 350270f23020SAndrei Emeltchenko if (!list) { 35031da177e4SLinus Torvalds /* Non fragmented */ 35041da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 35051da177e4SLinus Torvalds 350673d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 35071da177e4SLinus Torvalds } else { 35081da177e4SLinus Torvalds /* Fragmented */ 35091da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 35101da177e4SLinus Torvalds 35111da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 35121da177e4SLinus Torvalds 35139cfd5a23SJukka Rissanen /* Queue all fragments atomically. We need to use spin_lock_bh 35149cfd5a23SJukka Rissanen * here because of 6LoWPAN links, as there this function is 35159cfd5a23SJukka Rissanen * called from softirq and using normal spin lock could cause 35169cfd5a23SJukka Rissanen * deadlocks. 35179cfd5a23SJukka Rissanen */ 35189cfd5a23SJukka Rissanen spin_lock_bh(&queue->lock); 35191da177e4SLinus Torvalds 352073d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3521e702112fSAndrei Emeltchenko 3522e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3523e702112fSAndrei Emeltchenko flags |= ACL_CONT; 35241da177e4SLinus Torvalds do { 35251da177e4SLinus Torvalds skb = list; list = list->next; 35261da177e4SLinus Torvalds 3527d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 3528e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 35291da177e4SLinus Torvalds 35301da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 35311da177e4SLinus Torvalds 353273d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 35331da177e4SLinus Torvalds } while (list); 35341da177e4SLinus Torvalds 35359cfd5a23SJukka Rissanen spin_unlock_bh(&queue->lock); 35361da177e4SLinus Torvalds } 353773d80debSLuiz Augusto von Dentz } 353873d80debSLuiz Augusto von Dentz 353973d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 354073d80debSLuiz Augusto von Dentz { 3541ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 354273d80debSLuiz Augusto von Dentz 3543f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 354473d80debSLuiz Augusto von Dentz 3545ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 35461da177e4SLinus Torvalds 35473eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 35481da177e4SLinus Torvalds } 35491da177e4SLinus Torvalds 35501da177e4SLinus Torvalds /* Send SCO data */ 35510d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 35521da177e4SLinus Torvalds { 35531da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 35541da177e4SLinus Torvalds struct hci_sco_hdr hdr; 35551da177e4SLinus Torvalds 35561da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 35571da177e4SLinus Torvalds 3558aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 35591da177e4SLinus Torvalds hdr.dlen = skb->len; 35601da177e4SLinus Torvalds 3561badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 3562badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 35639c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 35641da177e4SLinus Torvalds 3565d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_SCODATA_PKT; 3566c78ae283SMarcel Holtmann 35671da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 35683eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 35691da177e4SLinus Torvalds } 35701da177e4SLinus Torvalds 35711da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 35721da177e4SLinus Torvalds 35731da177e4SLinus Torvalds /* HCI Connection scheduler */ 35746039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 3575a8c5fb1aSGustavo Padovan int *quote) 35761da177e4SLinus Torvalds { 35771da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 35788035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 3579abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 35801da177e4SLinus Torvalds 35811da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 35821da177e4SLinus Torvalds * added and removed with TX task disabled. */ 3583bf4c6325SGustavo F. Padovan 3584bf4c6325SGustavo F. Padovan rcu_read_lock(); 3585bf4c6325SGustavo F. Padovan 3586bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3587769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 35881da177e4SLinus Torvalds continue; 3589769be974SMarcel Holtmann 3590769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 3591769be974SMarcel Holtmann continue; 3592769be974SMarcel Holtmann 35931da177e4SLinus Torvalds num++; 35941da177e4SLinus Torvalds 35951da177e4SLinus Torvalds if (c->sent < min) { 35961da177e4SLinus Torvalds min = c->sent; 35971da177e4SLinus Torvalds conn = c; 35981da177e4SLinus Torvalds } 359952087a79SLuiz Augusto von Dentz 360052087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 360152087a79SLuiz Augusto von Dentz break; 36021da177e4SLinus Torvalds } 36031da177e4SLinus Torvalds 3604bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3605bf4c6325SGustavo F. Padovan 36061da177e4SLinus Torvalds if (conn) { 36076ed58ec5SVille Tervo int cnt, q; 36086ed58ec5SVille Tervo 36096ed58ec5SVille Tervo switch (conn->type) { 36106ed58ec5SVille Tervo case ACL_LINK: 36116ed58ec5SVille Tervo cnt = hdev->acl_cnt; 36126ed58ec5SVille Tervo break; 36136ed58ec5SVille Tervo case SCO_LINK: 36146ed58ec5SVille Tervo case ESCO_LINK: 36156ed58ec5SVille Tervo cnt = hdev->sco_cnt; 36166ed58ec5SVille Tervo break; 36176ed58ec5SVille Tervo case LE_LINK: 36186ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 36196ed58ec5SVille Tervo break; 36206ed58ec5SVille Tervo default: 36216ed58ec5SVille Tervo cnt = 0; 36226ed58ec5SVille Tervo BT_ERR("Unknown link type"); 36236ed58ec5SVille Tervo } 36246ed58ec5SVille Tervo 36256ed58ec5SVille Tervo q = cnt / num; 36261da177e4SLinus Torvalds *quote = q ? q : 1; 36271da177e4SLinus Torvalds } else 36281da177e4SLinus Torvalds *quote = 0; 36291da177e4SLinus Torvalds 36301da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 36311da177e4SLinus Torvalds return conn; 36321da177e4SLinus Torvalds } 36331da177e4SLinus Torvalds 36346039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 36351da177e4SLinus Torvalds { 36361da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 36371da177e4SLinus Torvalds struct hci_conn *c; 36381da177e4SLinus Torvalds 3639bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 36401da177e4SLinus Torvalds 3641bf4c6325SGustavo F. Padovan rcu_read_lock(); 3642bf4c6325SGustavo F. Padovan 36431da177e4SLinus Torvalds /* Kill stalled connections */ 3644bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3645bae1f5d9SVille Tervo if (c->type == type && c->sent) { 36466ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 36476ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 3648bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 36491da177e4SLinus Torvalds } 36501da177e4SLinus Torvalds } 3651bf4c6325SGustavo F. Padovan 3652bf4c6325SGustavo F. Padovan rcu_read_unlock(); 36531da177e4SLinus Torvalds } 36541da177e4SLinus Torvalds 36556039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 365673d80debSLuiz Augusto von Dentz int *quote) 365773d80debSLuiz Augusto von Dentz { 365873d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 365973d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 3660abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 366173d80debSLuiz Augusto von Dentz struct hci_conn *conn; 366273d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 366373d80debSLuiz Augusto von Dentz 366473d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 366573d80debSLuiz Augusto von Dentz 3666bf4c6325SGustavo F. Padovan rcu_read_lock(); 3667bf4c6325SGustavo F. Padovan 3668bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 366973d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 367073d80debSLuiz Augusto von Dentz 367173d80debSLuiz Augusto von Dentz if (conn->type != type) 367273d80debSLuiz Augusto von Dentz continue; 367373d80debSLuiz Augusto von Dentz 367473d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 367573d80debSLuiz Augusto von Dentz continue; 367673d80debSLuiz Augusto von Dentz 367773d80debSLuiz Augusto von Dentz conn_num++; 367873d80debSLuiz Augusto von Dentz 36798192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 368073d80debSLuiz Augusto von Dentz struct sk_buff *skb; 368173d80debSLuiz Augusto von Dentz 368273d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 368373d80debSLuiz Augusto von Dentz continue; 368473d80debSLuiz Augusto von Dentz 368573d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 368673d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 368773d80debSLuiz Augusto von Dentz continue; 368873d80debSLuiz Augusto von Dentz 368973d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 369073d80debSLuiz Augusto von Dentz num = 0; 369173d80debSLuiz Augusto von Dentz min = ~0; 369273d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 369373d80debSLuiz Augusto von Dentz } 369473d80debSLuiz Augusto von Dentz 369573d80debSLuiz Augusto von Dentz num++; 369673d80debSLuiz Augusto von Dentz 369773d80debSLuiz Augusto von Dentz if (conn->sent < min) { 369873d80debSLuiz Augusto von Dentz min = conn->sent; 369973d80debSLuiz Augusto von Dentz chan = tmp; 370073d80debSLuiz Augusto von Dentz } 370173d80debSLuiz Augusto von Dentz } 370273d80debSLuiz Augusto von Dentz 370373d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 370473d80debSLuiz Augusto von Dentz break; 370573d80debSLuiz Augusto von Dentz } 370673d80debSLuiz Augusto von Dentz 3707bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3708bf4c6325SGustavo F. Padovan 370973d80debSLuiz Augusto von Dentz if (!chan) 371073d80debSLuiz Augusto von Dentz return NULL; 371173d80debSLuiz Augusto von Dentz 371273d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 371373d80debSLuiz Augusto von Dentz case ACL_LINK: 371473d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 371573d80debSLuiz Augusto von Dentz break; 3716bd1eb66bSAndrei Emeltchenko case AMP_LINK: 3717bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 3718bd1eb66bSAndrei Emeltchenko break; 371973d80debSLuiz Augusto von Dentz case SCO_LINK: 372073d80debSLuiz Augusto von Dentz case ESCO_LINK: 372173d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 372273d80debSLuiz Augusto von Dentz break; 372373d80debSLuiz Augusto von Dentz case LE_LINK: 372473d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 372573d80debSLuiz Augusto von Dentz break; 372673d80debSLuiz Augusto von Dentz default: 372773d80debSLuiz Augusto von Dentz cnt = 0; 372873d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 372973d80debSLuiz Augusto von Dentz } 373073d80debSLuiz Augusto von Dentz 373173d80debSLuiz Augusto von Dentz q = cnt / num; 373273d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 373373d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 373473d80debSLuiz Augusto von Dentz return chan; 373573d80debSLuiz Augusto von Dentz } 373673d80debSLuiz Augusto von Dentz 373702b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 373802b20f0bSLuiz Augusto von Dentz { 373902b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 374002b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 374102b20f0bSLuiz Augusto von Dentz int num = 0; 374202b20f0bSLuiz Augusto von Dentz 374302b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 374402b20f0bSLuiz Augusto von Dentz 3745bf4c6325SGustavo F. Padovan rcu_read_lock(); 3746bf4c6325SGustavo F. Padovan 3747bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 374802b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 374902b20f0bSLuiz Augusto von Dentz 375002b20f0bSLuiz Augusto von Dentz if (conn->type != type) 375102b20f0bSLuiz Augusto von Dentz continue; 375202b20f0bSLuiz Augusto von Dentz 375302b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 375402b20f0bSLuiz Augusto von Dentz continue; 375502b20f0bSLuiz Augusto von Dentz 375602b20f0bSLuiz Augusto von Dentz num++; 375702b20f0bSLuiz Augusto von Dentz 37588192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 375902b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 376002b20f0bSLuiz Augusto von Dentz 376102b20f0bSLuiz Augusto von Dentz if (chan->sent) { 376202b20f0bSLuiz Augusto von Dentz chan->sent = 0; 376302b20f0bSLuiz Augusto von Dentz continue; 376402b20f0bSLuiz Augusto von Dentz } 376502b20f0bSLuiz Augusto von Dentz 376602b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 376702b20f0bSLuiz Augusto von Dentz continue; 376802b20f0bSLuiz Augusto von Dentz 376902b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 377002b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 377102b20f0bSLuiz Augusto von Dentz continue; 377202b20f0bSLuiz Augusto von Dentz 377302b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 377402b20f0bSLuiz Augusto von Dentz 377502b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 377602b20f0bSLuiz Augusto von Dentz skb->priority); 377702b20f0bSLuiz Augusto von Dentz } 377802b20f0bSLuiz Augusto von Dentz 377902b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 378002b20f0bSLuiz Augusto von Dentz break; 378102b20f0bSLuiz Augusto von Dentz } 3782bf4c6325SGustavo F. Padovan 3783bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3784bf4c6325SGustavo F. Padovan 378502b20f0bSLuiz Augusto von Dentz } 378602b20f0bSLuiz Augusto von Dentz 3787b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 3788b71d385aSAndrei Emeltchenko { 3789b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 3790b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 3791b71d385aSAndrei Emeltchenko } 3792b71d385aSAndrei Emeltchenko 37936039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 37941da177e4SLinus Torvalds { 3795d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 37961da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 37971da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 379863d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 37995f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 3800bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 38011da177e4SLinus Torvalds } 380263d2bc1bSAndrei Emeltchenko } 38031da177e4SLinus Torvalds 38046039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 380563d2bc1bSAndrei Emeltchenko { 380663d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 380763d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 380863d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 380963d2bc1bSAndrei Emeltchenko int quote; 381063d2bc1bSAndrei Emeltchenko 381163d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 381204837f64SMarcel Holtmann 381373d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 381473d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 3815ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3816ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 381773d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 381873d80debSLuiz Augusto von Dentz skb->len, skb->priority); 381973d80debSLuiz Augusto von Dentz 3820ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3821ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3822ec1cce24SLuiz Augusto von Dentz break; 3823ec1cce24SLuiz Augusto von Dentz 3824ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3825ec1cce24SLuiz Augusto von Dentz 382673d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 382773d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 382804837f64SMarcel Holtmann 382957d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 38301da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 38311da177e4SLinus Torvalds 38321da177e4SLinus Torvalds hdev->acl_cnt--; 383373d80debSLuiz Augusto von Dentz chan->sent++; 383473d80debSLuiz Augusto von Dentz chan->conn->sent++; 38351da177e4SLinus Torvalds } 38361da177e4SLinus Torvalds } 383702b20f0bSLuiz Augusto von Dentz 383802b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 383902b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 38401da177e4SLinus Torvalds } 38411da177e4SLinus Torvalds 38426039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 3843b71d385aSAndrei Emeltchenko { 384463d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 3845b71d385aSAndrei Emeltchenko struct hci_chan *chan; 3846b71d385aSAndrei Emeltchenko struct sk_buff *skb; 3847b71d385aSAndrei Emeltchenko int quote; 3848bd1eb66bSAndrei Emeltchenko u8 type; 3849b71d385aSAndrei Emeltchenko 385063d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 3851b71d385aSAndrei Emeltchenko 3852bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3853bd1eb66bSAndrei Emeltchenko 3854bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 3855bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 3856bd1eb66bSAndrei Emeltchenko else 3857bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 3858bd1eb66bSAndrei Emeltchenko 3859b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 3860bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 3861b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 3862b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 3863b71d385aSAndrei Emeltchenko int blocks; 3864b71d385aSAndrei Emeltchenko 3865b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 3866b71d385aSAndrei Emeltchenko skb->len, skb->priority); 3867b71d385aSAndrei Emeltchenko 3868b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 3869b71d385aSAndrei Emeltchenko if (skb->priority < priority) 3870b71d385aSAndrei Emeltchenko break; 3871b71d385aSAndrei Emeltchenko 3872b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 3873b71d385aSAndrei Emeltchenko 3874b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 3875b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 3876b71d385aSAndrei Emeltchenko return; 3877b71d385aSAndrei Emeltchenko 3878b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 3879b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 3880b71d385aSAndrei Emeltchenko 388157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 3882b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 3883b71d385aSAndrei Emeltchenko 3884b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 3885b71d385aSAndrei Emeltchenko quote -= blocks; 3886b71d385aSAndrei Emeltchenko 3887b71d385aSAndrei Emeltchenko chan->sent += blocks; 3888b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 3889b71d385aSAndrei Emeltchenko } 3890b71d385aSAndrei Emeltchenko } 3891b71d385aSAndrei Emeltchenko 3892b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 3893bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 3894b71d385aSAndrei Emeltchenko } 3895b71d385aSAndrei Emeltchenko 38966039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 3897b71d385aSAndrei Emeltchenko { 3898b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3899b71d385aSAndrei Emeltchenko 3900bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 3901ca8bee5dSMarcel Holtmann if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY) 3902bd1eb66bSAndrei Emeltchenko return; 3903bd1eb66bSAndrei Emeltchenko 3904bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 3905bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 3906b71d385aSAndrei Emeltchenko return; 3907b71d385aSAndrei Emeltchenko 3908b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 3909b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 3910b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 3911b71d385aSAndrei Emeltchenko break; 3912b71d385aSAndrei Emeltchenko 3913b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 3914b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 3915b71d385aSAndrei Emeltchenko break; 3916b71d385aSAndrei Emeltchenko } 3917b71d385aSAndrei Emeltchenko } 3918b71d385aSAndrei Emeltchenko 39191da177e4SLinus Torvalds /* Schedule SCO */ 39206039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 39211da177e4SLinus Torvalds { 39221da177e4SLinus Torvalds struct hci_conn *conn; 39231da177e4SLinus Torvalds struct sk_buff *skb; 39241da177e4SLinus Torvalds int quote; 39251da177e4SLinus Torvalds 39261da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 39271da177e4SLinus Torvalds 392852087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 392952087a79SLuiz Augusto von Dentz return; 393052087a79SLuiz Augusto von Dentz 39311da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 39321da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 39331da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 393457d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 39351da177e4SLinus Torvalds 39361da177e4SLinus Torvalds conn->sent++; 39371da177e4SLinus Torvalds if (conn->sent == ~0) 39381da177e4SLinus Torvalds conn->sent = 0; 39391da177e4SLinus Torvalds } 39401da177e4SLinus Torvalds } 39411da177e4SLinus Torvalds } 39421da177e4SLinus Torvalds 39436039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 3944b6a0dc82SMarcel Holtmann { 3945b6a0dc82SMarcel Holtmann struct hci_conn *conn; 3946b6a0dc82SMarcel Holtmann struct sk_buff *skb; 3947b6a0dc82SMarcel Holtmann int quote; 3948b6a0dc82SMarcel Holtmann 3949b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 3950b6a0dc82SMarcel Holtmann 395152087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 395252087a79SLuiz Augusto von Dentz return; 395352087a79SLuiz Augusto von Dentz 39548fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 39558fc9ced3SGustavo Padovan "e))) { 3956b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 3957b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 395857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 3959b6a0dc82SMarcel Holtmann 3960b6a0dc82SMarcel Holtmann conn->sent++; 3961b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 3962b6a0dc82SMarcel Holtmann conn->sent = 0; 3963b6a0dc82SMarcel Holtmann } 3964b6a0dc82SMarcel Holtmann } 3965b6a0dc82SMarcel Holtmann } 3966b6a0dc82SMarcel Holtmann 39676039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 39686ed58ec5SVille Tervo { 396973d80debSLuiz Augusto von Dentz struct hci_chan *chan; 39706ed58ec5SVille Tervo struct sk_buff *skb; 397102b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 39726ed58ec5SVille Tervo 39736ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 39746ed58ec5SVille Tervo 397552087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 397652087a79SLuiz Augusto von Dentz return; 397752087a79SLuiz Augusto von Dentz 3978d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 39796ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 39806ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 3981bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 39826ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 3983bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 39846ed58ec5SVille Tervo } 39856ed58ec5SVille Tervo 39866ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 398702b20f0bSLuiz Augusto von Dentz tmp = cnt; 398873d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 3989ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3990ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 399173d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 399273d80debSLuiz Augusto von Dentz skb->len, skb->priority); 39936ed58ec5SVille Tervo 3994ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3995ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3996ec1cce24SLuiz Augusto von Dentz break; 3997ec1cce24SLuiz Augusto von Dentz 3998ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3999ec1cce24SLuiz Augusto von Dentz 400057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 40016ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 40026ed58ec5SVille Tervo 40036ed58ec5SVille Tervo cnt--; 400473d80debSLuiz Augusto von Dentz chan->sent++; 400573d80debSLuiz Augusto von Dentz chan->conn->sent++; 40066ed58ec5SVille Tervo } 40076ed58ec5SVille Tervo } 400873d80debSLuiz Augusto von Dentz 40096ed58ec5SVille Tervo if (hdev->le_pkts) 40106ed58ec5SVille Tervo hdev->le_cnt = cnt; 40116ed58ec5SVille Tervo else 40126ed58ec5SVille Tervo hdev->acl_cnt = cnt; 401302b20f0bSLuiz Augusto von Dentz 401402b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 401502b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 40166ed58ec5SVille Tervo } 40176ed58ec5SVille Tervo 40183eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 40191da177e4SLinus Torvalds { 40203eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 40211da177e4SLinus Torvalds struct sk_buff *skb; 40221da177e4SLinus Torvalds 40236ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 40246ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 40251da177e4SLinus Torvalds 4026d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 40271da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 40281da177e4SLinus Torvalds hci_sched_acl(hdev); 40291da177e4SLinus Torvalds hci_sched_sco(hdev); 4030b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 40316ed58ec5SVille Tervo hci_sched_le(hdev); 403252de599eSMarcel Holtmann } 40336ed58ec5SVille Tervo 40341da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 40351da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 403657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 40371da177e4SLinus Torvalds } 40381da177e4SLinus Torvalds 403925985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 40401da177e4SLinus Torvalds 40411da177e4SLinus Torvalds /* ACL data packet */ 40426039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 40431da177e4SLinus Torvalds { 40441da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 40451da177e4SLinus Torvalds struct hci_conn *conn; 40461da177e4SLinus Torvalds __u16 handle, flags; 40471da177e4SLinus Torvalds 40481da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 40491da177e4SLinus Torvalds 40501da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 40511da177e4SLinus Torvalds flags = hci_flags(handle); 40521da177e4SLinus Torvalds handle = hci_handle(handle); 40531da177e4SLinus Torvalds 4054f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4055a8c5fb1aSGustavo Padovan handle, flags); 40561da177e4SLinus Torvalds 40571da177e4SLinus Torvalds hdev->stat.acl_rx++; 40581da177e4SLinus Torvalds 40591da177e4SLinus Torvalds hci_dev_lock(hdev); 40601da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 40611da177e4SLinus Torvalds hci_dev_unlock(hdev); 40621da177e4SLinus Torvalds 40631da177e4SLinus Torvalds if (conn) { 406465983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 406504837f64SMarcel Holtmann 40661da177e4SLinus Torvalds /* Send to upper protocol */ 4067686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 40681da177e4SLinus Torvalds return; 40691da177e4SLinus Torvalds } else { 40701da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 40711da177e4SLinus Torvalds hdev->name, handle); 40721da177e4SLinus Torvalds } 40731da177e4SLinus Torvalds 40741da177e4SLinus Torvalds kfree_skb(skb); 40751da177e4SLinus Torvalds } 40761da177e4SLinus Torvalds 40771da177e4SLinus Torvalds /* SCO data packet */ 40786039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 40791da177e4SLinus Torvalds { 40801da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 40811da177e4SLinus Torvalds struct hci_conn *conn; 40821da177e4SLinus Torvalds __u16 handle; 40831da177e4SLinus Torvalds 40841da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 40851da177e4SLinus Torvalds 40861da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 40871da177e4SLinus Torvalds 4088f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 40891da177e4SLinus Torvalds 40901da177e4SLinus Torvalds hdev->stat.sco_rx++; 40911da177e4SLinus Torvalds 40921da177e4SLinus Torvalds hci_dev_lock(hdev); 40931da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 40941da177e4SLinus Torvalds hci_dev_unlock(hdev); 40951da177e4SLinus Torvalds 40961da177e4SLinus Torvalds if (conn) { 40971da177e4SLinus Torvalds /* Send to upper protocol */ 4098686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 40991da177e4SLinus Torvalds return; 41001da177e4SLinus Torvalds } else { 41011da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 41021da177e4SLinus Torvalds hdev->name, handle); 41031da177e4SLinus Torvalds } 41041da177e4SLinus Torvalds 41051da177e4SLinus Torvalds kfree_skb(skb); 41061da177e4SLinus Torvalds } 41071da177e4SLinus Torvalds 41089238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 41099238f36aSJohan Hedberg { 41109238f36aSJohan Hedberg struct sk_buff *skb; 41119238f36aSJohan Hedberg 41129238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 41139238f36aSJohan Hedberg if (!skb) 41149238f36aSJohan Hedberg return true; 41159238f36aSJohan Hedberg 411644d27137SJohan Hedberg return (bt_cb(skb)->hci.req_flags & HCI_REQ_START); 41179238f36aSJohan Hedberg } 41189238f36aSJohan Hedberg 411942c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 412042c6b129SJohan Hedberg { 412142c6b129SJohan Hedberg struct hci_command_hdr *sent; 412242c6b129SJohan Hedberg struct sk_buff *skb; 412342c6b129SJohan Hedberg u16 opcode; 412442c6b129SJohan Hedberg 412542c6b129SJohan Hedberg if (!hdev->sent_cmd) 412642c6b129SJohan Hedberg return; 412742c6b129SJohan Hedberg 412842c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 412942c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 413042c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 413142c6b129SJohan Hedberg return; 413242c6b129SJohan Hedberg 413342c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 413442c6b129SJohan Hedberg if (!skb) 413542c6b129SJohan Hedberg return; 413642c6b129SJohan Hedberg 413742c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 413842c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 413942c6b129SJohan Hedberg } 414042c6b129SJohan Hedberg 4141e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, 4142e6214487SJohan Hedberg hci_req_complete_t *req_complete, 4143e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 41449238f36aSJohan Hedberg { 41459238f36aSJohan Hedberg struct sk_buff *skb; 41469238f36aSJohan Hedberg unsigned long flags; 41479238f36aSJohan Hedberg 41489238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 41499238f36aSJohan Hedberg 415042c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 415142c6b129SJohan Hedberg * sent we need to do special handling of it. 41529238f36aSJohan Hedberg */ 415342c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 415442c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 415542c6b129SJohan Hedberg * reset complete event during init and any pending 415642c6b129SJohan Hedberg * command will never be completed. In such a case we 415742c6b129SJohan Hedberg * need to resend whatever was the last sent 415842c6b129SJohan Hedberg * command. 415942c6b129SJohan Hedberg */ 416042c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 416142c6b129SJohan Hedberg hci_resend_last(hdev); 416242c6b129SJohan Hedberg 41639238f36aSJohan Hedberg return; 416442c6b129SJohan Hedberg } 41659238f36aSJohan Hedberg 41669238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 41679238f36aSJohan Hedberg * this request the request is not yet complete. 41689238f36aSJohan Hedberg */ 41699238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 41709238f36aSJohan Hedberg return; 41719238f36aSJohan Hedberg 41729238f36aSJohan Hedberg /* If this was the last command in a request the complete 41739238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 41749238f36aSJohan Hedberg * command queue (hdev->cmd_q). 41759238f36aSJohan Hedberg */ 417644d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) { 417744d27137SJohan Hedberg *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb; 4178e6214487SJohan Hedberg return; 41799238f36aSJohan Hedberg } 4180e6214487SJohan Hedberg 418144d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_complete) { 418244d27137SJohan Hedberg *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete; 4183e6214487SJohan Hedberg return; 418453e21fbcSJohan Hedberg } 41859238f36aSJohan Hedberg 41869238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 41879238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 41889238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 418944d27137SJohan Hedberg if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) { 41909238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 41919238f36aSJohan Hedberg break; 41929238f36aSJohan Hedberg } 41939238f36aSJohan Hedberg 41943bd7594eSDouglas Anderson if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) 4195242c0ebdSMarcel Holtmann *req_complete_skb = bt_cb(skb)->hci.req_complete_skb; 41963bd7594eSDouglas Anderson else 41973bd7594eSDouglas Anderson *req_complete = bt_cb(skb)->hci.req_complete; 41989238f36aSJohan Hedberg kfree_skb(skb); 41999238f36aSJohan Hedberg } 42009238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 42019238f36aSJohan Hedberg } 42029238f36aSJohan Hedberg 4203b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 42041da177e4SLinus Torvalds { 4205b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 42061da177e4SLinus Torvalds struct sk_buff *skb; 42071da177e4SLinus Torvalds 42081da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 42091da177e4SLinus Torvalds 42101da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 4211cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4212cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4213cd82e61cSMarcel Holtmann 42141da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 42151da177e4SLinus Torvalds /* Send copy to the sockets */ 4216470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 42171da177e4SLinus Torvalds } 42181da177e4SLinus Torvalds 4219d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 42201da177e4SLinus Torvalds kfree_skb(skb); 42211da177e4SLinus Torvalds continue; 42221da177e4SLinus Torvalds } 42231da177e4SLinus Torvalds 42241da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 42251da177e4SLinus Torvalds /* Don't process data packets in this states. */ 4226d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 42271da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 42281da177e4SLinus Torvalds case HCI_SCODATA_PKT: 42291da177e4SLinus Torvalds kfree_skb(skb); 42301da177e4SLinus Torvalds continue; 42313ff50b79SStephen Hemminger } 42321da177e4SLinus Torvalds } 42331da177e4SLinus Torvalds 42341da177e4SLinus Torvalds /* Process frame */ 4235d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 42361da177e4SLinus Torvalds case HCI_EVENT_PKT: 4237b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 42381da177e4SLinus Torvalds hci_event_packet(hdev, skb); 42391da177e4SLinus Torvalds break; 42401da177e4SLinus Torvalds 42411da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 42421da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 42431da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 42441da177e4SLinus Torvalds break; 42451da177e4SLinus Torvalds 42461da177e4SLinus Torvalds case HCI_SCODATA_PKT: 42471da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 42481da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 42491da177e4SLinus Torvalds break; 42501da177e4SLinus Torvalds 42511da177e4SLinus Torvalds default: 42521da177e4SLinus Torvalds kfree_skb(skb); 42531da177e4SLinus Torvalds break; 42541da177e4SLinus Torvalds } 42551da177e4SLinus Torvalds } 42561da177e4SLinus Torvalds } 42571da177e4SLinus Torvalds 4258c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 42591da177e4SLinus Torvalds { 4260c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 42611da177e4SLinus Torvalds struct sk_buff *skb; 42621da177e4SLinus Torvalds 42632104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 42642104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 42651da177e4SLinus Torvalds 42661da177e4SLinus Torvalds /* Send queued commands */ 42675a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 42685a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 42695a08ecceSAndrei Emeltchenko if (!skb) 42705a08ecceSAndrei Emeltchenko return; 42715a08ecceSAndrei Emeltchenko 42721da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 42731da177e4SLinus Torvalds 4274a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 427570f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 42761da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 427757d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 42787bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 427965cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 42807bdb8a5cSSzymon Janc else 428165cc2b49SMarcel Holtmann schedule_delayed_work(&hdev->cmd_timer, 428265cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT); 42831da177e4SLinus Torvalds } else { 42841da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4285c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 42861da177e4SLinus Torvalds } 42871da177e4SLinus Torvalds } 42881da177e4SLinus Torvalds } 4289