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 40970c4e46SJohan Hedberg #include "smp.h" 41970c4e46SJohan Hedberg 42b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 43c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 443eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds /* HCI device list */ 471da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 481da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds /* HCI callback list */ 511da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 521da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 531da177e4SLinus Torvalds 543df92b31SSasha Levin /* HCI ID Numbering */ 553df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 563df92b31SSasha Levin 571da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 581da177e4SLinus Torvalds 596516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 601da177e4SLinus Torvalds { 61040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 621da177e4SLinus Torvalds } 631da177e4SLinus Torvalds 64baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */ 65baf27f6eSMarcel Holtmann 664b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf, 674b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 684b4148e9SMarcel Holtmann { 694b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 704b4148e9SMarcel Holtmann char buf[3]; 714b4148e9SMarcel Holtmann 72111902f7SMarcel Holtmann buf[0] = test_bit(HCI_DUT_MODE, &hdev->dbg_flags) ? 'Y': 'N'; 734b4148e9SMarcel Holtmann buf[1] = '\n'; 744b4148e9SMarcel Holtmann buf[2] = '\0'; 754b4148e9SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 764b4148e9SMarcel Holtmann } 774b4148e9SMarcel Holtmann 784b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf, 794b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 804b4148e9SMarcel Holtmann { 814b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 824b4148e9SMarcel Holtmann struct sk_buff *skb; 834b4148e9SMarcel Holtmann char buf[32]; 844b4148e9SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 854b4148e9SMarcel Holtmann bool enable; 864b4148e9SMarcel Holtmann int err; 874b4148e9SMarcel Holtmann 884b4148e9SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 894b4148e9SMarcel Holtmann return -ENETDOWN; 904b4148e9SMarcel Holtmann 914b4148e9SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 924b4148e9SMarcel Holtmann return -EFAULT; 934b4148e9SMarcel Holtmann 944b4148e9SMarcel Holtmann buf[buf_size] = '\0'; 954b4148e9SMarcel Holtmann if (strtobool(buf, &enable)) 964b4148e9SMarcel Holtmann return -EINVAL; 974b4148e9SMarcel Holtmann 98111902f7SMarcel Holtmann if (enable == test_bit(HCI_DUT_MODE, &hdev->dbg_flags)) 994b4148e9SMarcel Holtmann return -EALREADY; 1004b4148e9SMarcel Holtmann 1014b4148e9SMarcel Holtmann hci_req_lock(hdev); 1024b4148e9SMarcel Holtmann if (enable) 1034b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL, 1044b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1054b4148e9SMarcel Holtmann else 1064b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, 1074b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1084b4148e9SMarcel Holtmann hci_req_unlock(hdev); 1094b4148e9SMarcel Holtmann 1104b4148e9SMarcel Holtmann if (IS_ERR(skb)) 1114b4148e9SMarcel Holtmann return PTR_ERR(skb); 1124b4148e9SMarcel Holtmann 1134b4148e9SMarcel Holtmann err = -bt_to_errno(skb->data[0]); 1144b4148e9SMarcel Holtmann kfree_skb(skb); 1154b4148e9SMarcel Holtmann 1164b4148e9SMarcel Holtmann if (err < 0) 1174b4148e9SMarcel Holtmann return err; 1184b4148e9SMarcel Holtmann 119111902f7SMarcel Holtmann change_bit(HCI_DUT_MODE, &hdev->dbg_flags); 1204b4148e9SMarcel Holtmann 1214b4148e9SMarcel Holtmann return count; 1224b4148e9SMarcel Holtmann } 1234b4148e9SMarcel Holtmann 1244b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = { 1254b4148e9SMarcel Holtmann .open = simple_open, 1264b4148e9SMarcel Holtmann .read = dut_mode_read, 1274b4148e9SMarcel Holtmann .write = dut_mode_write, 1284b4148e9SMarcel Holtmann .llseek = default_llseek, 1294b4148e9SMarcel Holtmann }; 1304b4148e9SMarcel Holtmann 131dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr) 132dfb826a8SMarcel Holtmann { 133dfb826a8SMarcel Holtmann struct hci_dev *hdev = f->private; 134dfb826a8SMarcel Holtmann u8 p; 135dfb826a8SMarcel Holtmann 136dfb826a8SMarcel Holtmann hci_dev_lock(hdev); 137dfb826a8SMarcel Holtmann for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 138cfbb2b5bSMarcel Holtmann seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 139dfb826a8SMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p, 140dfb826a8SMarcel Holtmann hdev->features[p][0], hdev->features[p][1], 141dfb826a8SMarcel Holtmann hdev->features[p][2], hdev->features[p][3], 142dfb826a8SMarcel Holtmann hdev->features[p][4], hdev->features[p][5], 143dfb826a8SMarcel Holtmann hdev->features[p][6], hdev->features[p][7]); 144dfb826a8SMarcel Holtmann } 145cfbb2b5bSMarcel Holtmann if (lmp_le_capable(hdev)) 146cfbb2b5bSMarcel Holtmann seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 147cfbb2b5bSMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", 148cfbb2b5bSMarcel Holtmann hdev->le_features[0], hdev->le_features[1], 149cfbb2b5bSMarcel Holtmann hdev->le_features[2], hdev->le_features[3], 150cfbb2b5bSMarcel Holtmann hdev->le_features[4], hdev->le_features[5], 151cfbb2b5bSMarcel Holtmann hdev->le_features[6], hdev->le_features[7]); 152dfb826a8SMarcel Holtmann hci_dev_unlock(hdev); 153dfb826a8SMarcel Holtmann 154dfb826a8SMarcel Holtmann return 0; 155dfb826a8SMarcel Holtmann } 156dfb826a8SMarcel Holtmann 157dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file) 158dfb826a8SMarcel Holtmann { 159dfb826a8SMarcel Holtmann return single_open(file, features_show, inode->i_private); 160dfb826a8SMarcel Holtmann } 161dfb826a8SMarcel Holtmann 162dfb826a8SMarcel Holtmann static const struct file_operations features_fops = { 163dfb826a8SMarcel Holtmann .open = features_open, 164dfb826a8SMarcel Holtmann .read = seq_read, 165dfb826a8SMarcel Holtmann .llseek = seq_lseek, 166dfb826a8SMarcel Holtmann .release = single_release, 167dfb826a8SMarcel Holtmann }; 168dfb826a8SMarcel Holtmann 16970afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p) 17070afe0b8SMarcel Holtmann { 17170afe0b8SMarcel Holtmann struct hci_dev *hdev = f->private; 17270afe0b8SMarcel Holtmann struct bdaddr_list *b; 17370afe0b8SMarcel Holtmann 17470afe0b8SMarcel Holtmann hci_dev_lock(hdev); 17570afe0b8SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) 176b25f0785SMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 17770afe0b8SMarcel Holtmann hci_dev_unlock(hdev); 17870afe0b8SMarcel Holtmann 17970afe0b8SMarcel Holtmann return 0; 18070afe0b8SMarcel Holtmann } 18170afe0b8SMarcel Holtmann 18270afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file) 18370afe0b8SMarcel Holtmann { 18470afe0b8SMarcel Holtmann return single_open(file, blacklist_show, inode->i_private); 18570afe0b8SMarcel Holtmann } 18670afe0b8SMarcel Holtmann 18770afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = { 18870afe0b8SMarcel Holtmann .open = blacklist_open, 18970afe0b8SMarcel Holtmann .read = seq_read, 19070afe0b8SMarcel Holtmann .llseek = seq_lseek, 19170afe0b8SMarcel Holtmann .release = single_release, 19270afe0b8SMarcel Holtmann }; 19370afe0b8SMarcel Holtmann 19447219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p) 19547219839SMarcel Holtmann { 19647219839SMarcel Holtmann struct hci_dev *hdev = f->private; 19747219839SMarcel Holtmann struct bt_uuid *uuid; 19847219839SMarcel Holtmann 19947219839SMarcel Holtmann hci_dev_lock(hdev); 20047219839SMarcel Holtmann list_for_each_entry(uuid, &hdev->uuids, list) { 20158f01aa9SMarcel Holtmann u8 i, val[16]; 20247219839SMarcel Holtmann 20358f01aa9SMarcel Holtmann /* The Bluetooth UUID values are stored in big endian, 20458f01aa9SMarcel Holtmann * but with reversed byte order. So convert them into 20558f01aa9SMarcel Holtmann * the right order for the %pUb modifier. 20658f01aa9SMarcel Holtmann */ 20758f01aa9SMarcel Holtmann for (i = 0; i < 16; i++) 20858f01aa9SMarcel Holtmann val[i] = uuid->uuid[15 - i]; 20947219839SMarcel Holtmann 21058f01aa9SMarcel Holtmann seq_printf(f, "%pUb\n", val); 21147219839SMarcel Holtmann } 21247219839SMarcel Holtmann hci_dev_unlock(hdev); 21347219839SMarcel Holtmann 21447219839SMarcel Holtmann return 0; 21547219839SMarcel Holtmann } 21647219839SMarcel Holtmann 21747219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file) 21847219839SMarcel Holtmann { 21947219839SMarcel Holtmann return single_open(file, uuids_show, inode->i_private); 22047219839SMarcel Holtmann } 22147219839SMarcel Holtmann 22247219839SMarcel Holtmann static const struct file_operations uuids_fops = { 22347219839SMarcel Holtmann .open = uuids_open, 22447219839SMarcel Holtmann .read = seq_read, 22547219839SMarcel Holtmann .llseek = seq_lseek, 22647219839SMarcel Holtmann .release = single_release, 22747219839SMarcel Holtmann }; 22847219839SMarcel Holtmann 229baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p) 230baf27f6eSMarcel Holtmann { 231baf27f6eSMarcel Holtmann struct hci_dev *hdev = f->private; 232baf27f6eSMarcel Holtmann struct discovery_state *cache = &hdev->discovery; 233baf27f6eSMarcel Holtmann struct inquiry_entry *e; 234baf27f6eSMarcel Holtmann 235baf27f6eSMarcel Holtmann hci_dev_lock(hdev); 236baf27f6eSMarcel Holtmann 237baf27f6eSMarcel Holtmann list_for_each_entry(e, &cache->all, all) { 238baf27f6eSMarcel Holtmann struct inquiry_data *data = &e->data; 239baf27f6eSMarcel Holtmann seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", 240baf27f6eSMarcel Holtmann &data->bdaddr, 241baf27f6eSMarcel Holtmann data->pscan_rep_mode, data->pscan_period_mode, 242baf27f6eSMarcel Holtmann data->pscan_mode, data->dev_class[2], 243baf27f6eSMarcel Holtmann data->dev_class[1], data->dev_class[0], 244baf27f6eSMarcel Holtmann __le16_to_cpu(data->clock_offset), 245baf27f6eSMarcel Holtmann data->rssi, data->ssp_mode, e->timestamp); 246baf27f6eSMarcel Holtmann } 247baf27f6eSMarcel Holtmann 248baf27f6eSMarcel Holtmann hci_dev_unlock(hdev); 249baf27f6eSMarcel Holtmann 250baf27f6eSMarcel Holtmann return 0; 251baf27f6eSMarcel Holtmann } 252baf27f6eSMarcel Holtmann 253baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file) 254baf27f6eSMarcel Holtmann { 255baf27f6eSMarcel Holtmann return single_open(file, inquiry_cache_show, inode->i_private); 256baf27f6eSMarcel Holtmann } 257baf27f6eSMarcel Holtmann 258baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = { 259baf27f6eSMarcel Holtmann .open = inquiry_cache_open, 260baf27f6eSMarcel Holtmann .read = seq_read, 261baf27f6eSMarcel Holtmann .llseek = seq_lseek, 262baf27f6eSMarcel Holtmann .release = single_release, 263baf27f6eSMarcel Holtmann }; 264baf27f6eSMarcel Holtmann 26502d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr) 26602d08d15SMarcel Holtmann { 26702d08d15SMarcel Holtmann struct hci_dev *hdev = f->private; 26802d08d15SMarcel Holtmann struct list_head *p, *n; 26902d08d15SMarcel Holtmann 27002d08d15SMarcel Holtmann hci_dev_lock(hdev); 27102d08d15SMarcel Holtmann list_for_each_safe(p, n, &hdev->link_keys) { 27202d08d15SMarcel Holtmann struct link_key *key = list_entry(p, struct link_key, list); 27302d08d15SMarcel Holtmann seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type, 27402d08d15SMarcel Holtmann HCI_LINK_KEY_SIZE, key->val, key->pin_len); 27502d08d15SMarcel Holtmann } 27602d08d15SMarcel Holtmann hci_dev_unlock(hdev); 27702d08d15SMarcel Holtmann 27802d08d15SMarcel Holtmann return 0; 27902d08d15SMarcel Holtmann } 28002d08d15SMarcel Holtmann 28102d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file) 28202d08d15SMarcel Holtmann { 28302d08d15SMarcel Holtmann return single_open(file, link_keys_show, inode->i_private); 28402d08d15SMarcel Holtmann } 28502d08d15SMarcel Holtmann 28602d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = { 28702d08d15SMarcel Holtmann .open = link_keys_open, 28802d08d15SMarcel Holtmann .read = seq_read, 28902d08d15SMarcel Holtmann .llseek = seq_lseek, 29002d08d15SMarcel Holtmann .release = single_release, 29102d08d15SMarcel Holtmann }; 29202d08d15SMarcel Holtmann 293babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr) 294babdbb3cSMarcel Holtmann { 295babdbb3cSMarcel Holtmann struct hci_dev *hdev = f->private; 296babdbb3cSMarcel Holtmann 297babdbb3cSMarcel Holtmann hci_dev_lock(hdev); 298babdbb3cSMarcel Holtmann seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], 299babdbb3cSMarcel Holtmann hdev->dev_class[1], hdev->dev_class[0]); 300babdbb3cSMarcel Holtmann hci_dev_unlock(hdev); 301babdbb3cSMarcel Holtmann 302babdbb3cSMarcel Holtmann return 0; 303babdbb3cSMarcel Holtmann } 304babdbb3cSMarcel Holtmann 305babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file) 306babdbb3cSMarcel Holtmann { 307babdbb3cSMarcel Holtmann return single_open(file, dev_class_show, inode->i_private); 308babdbb3cSMarcel Holtmann } 309babdbb3cSMarcel Holtmann 310babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = { 311babdbb3cSMarcel Holtmann .open = dev_class_open, 312babdbb3cSMarcel Holtmann .read = seq_read, 313babdbb3cSMarcel Holtmann .llseek = seq_lseek, 314babdbb3cSMarcel Holtmann .release = single_release, 315babdbb3cSMarcel Holtmann }; 316babdbb3cSMarcel Holtmann 317041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val) 318041000b9SMarcel Holtmann { 319041000b9SMarcel Holtmann struct hci_dev *hdev = data; 320041000b9SMarcel Holtmann 321041000b9SMarcel Holtmann hci_dev_lock(hdev); 322041000b9SMarcel Holtmann *val = hdev->voice_setting; 323041000b9SMarcel Holtmann hci_dev_unlock(hdev); 324041000b9SMarcel Holtmann 325041000b9SMarcel Holtmann return 0; 326041000b9SMarcel Holtmann } 327041000b9SMarcel Holtmann 328041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get, 329041000b9SMarcel Holtmann NULL, "0x%4.4llx\n"); 330041000b9SMarcel Holtmann 331ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val) 332ebd1e33bSMarcel Holtmann { 333ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 334ebd1e33bSMarcel Holtmann 335ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 336ebd1e33bSMarcel Holtmann hdev->auto_accept_delay = val; 337ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 338ebd1e33bSMarcel Holtmann 339ebd1e33bSMarcel Holtmann return 0; 340ebd1e33bSMarcel Holtmann } 341ebd1e33bSMarcel Holtmann 342ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val) 343ebd1e33bSMarcel Holtmann { 344ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 345ebd1e33bSMarcel Holtmann 346ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 347ebd1e33bSMarcel Holtmann *val = hdev->auto_accept_delay; 348ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 349ebd1e33bSMarcel Holtmann 350ebd1e33bSMarcel Holtmann return 0; 351ebd1e33bSMarcel Holtmann } 352ebd1e33bSMarcel Holtmann 353ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, 354ebd1e33bSMarcel Holtmann auto_accept_delay_set, "%llu\n"); 355ebd1e33bSMarcel Holtmann 3565afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf, 3575afeac14SMarcel Holtmann size_t count, loff_t *ppos) 3585afeac14SMarcel Holtmann { 3595afeac14SMarcel Holtmann struct hci_dev *hdev = file->private_data; 3605afeac14SMarcel Holtmann char buf[3]; 3615afeac14SMarcel Holtmann 362111902f7SMarcel Holtmann buf[0] = test_bit(HCI_FORCE_SC, &hdev->dbg_flags) ? 'Y': 'N'; 3635afeac14SMarcel Holtmann buf[1] = '\n'; 3645afeac14SMarcel Holtmann buf[2] = '\0'; 3655afeac14SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 3665afeac14SMarcel Holtmann } 3675afeac14SMarcel Holtmann 3685afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file, 3695afeac14SMarcel Holtmann const char __user *user_buf, 3705afeac14SMarcel Holtmann size_t count, loff_t *ppos) 3715afeac14SMarcel Holtmann { 3725afeac14SMarcel Holtmann struct hci_dev *hdev = file->private_data; 3735afeac14SMarcel Holtmann char buf[32]; 3745afeac14SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 3755afeac14SMarcel Holtmann bool enable; 3765afeac14SMarcel Holtmann 3775afeac14SMarcel Holtmann if (test_bit(HCI_UP, &hdev->flags)) 3785afeac14SMarcel Holtmann return -EBUSY; 3795afeac14SMarcel Holtmann 3805afeac14SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 3815afeac14SMarcel Holtmann return -EFAULT; 3825afeac14SMarcel Holtmann 3835afeac14SMarcel Holtmann buf[buf_size] = '\0'; 3845afeac14SMarcel Holtmann if (strtobool(buf, &enable)) 3855afeac14SMarcel Holtmann return -EINVAL; 3865afeac14SMarcel Holtmann 387111902f7SMarcel Holtmann if (enable == test_bit(HCI_FORCE_SC, &hdev->dbg_flags)) 3885afeac14SMarcel Holtmann return -EALREADY; 3895afeac14SMarcel Holtmann 390111902f7SMarcel Holtmann change_bit(HCI_FORCE_SC, &hdev->dbg_flags); 3915afeac14SMarcel Holtmann 3925afeac14SMarcel Holtmann return count; 3935afeac14SMarcel Holtmann } 3945afeac14SMarcel Holtmann 3955afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = { 3965afeac14SMarcel Holtmann .open = simple_open, 3975afeac14SMarcel Holtmann .read = force_sc_support_read, 3985afeac14SMarcel Holtmann .write = force_sc_support_write, 3995afeac14SMarcel Holtmann .llseek = default_llseek, 4005afeac14SMarcel Holtmann }; 4015afeac14SMarcel Holtmann 402134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf, 403134c2a89SMarcel Holtmann size_t count, loff_t *ppos) 404134c2a89SMarcel Holtmann { 405134c2a89SMarcel Holtmann struct hci_dev *hdev = file->private_data; 406134c2a89SMarcel Holtmann char buf[3]; 407134c2a89SMarcel Holtmann 408134c2a89SMarcel Holtmann buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N'; 409134c2a89SMarcel Holtmann buf[1] = '\n'; 410134c2a89SMarcel Holtmann buf[2] = '\0'; 411134c2a89SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 412134c2a89SMarcel Holtmann } 413134c2a89SMarcel Holtmann 414134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = { 415134c2a89SMarcel Holtmann .open = simple_open, 416134c2a89SMarcel Holtmann .read = sc_only_mode_read, 417134c2a89SMarcel Holtmann .llseek = default_llseek, 418134c2a89SMarcel Holtmann }; 419134c2a89SMarcel Holtmann 4202bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val) 4212bfa3531SMarcel Holtmann { 4222bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4232bfa3531SMarcel Holtmann 4242bfa3531SMarcel Holtmann if (val != 0 && (val < 500 || val > 3600000)) 4252bfa3531SMarcel Holtmann return -EINVAL; 4262bfa3531SMarcel Holtmann 4272bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4282bfa3531SMarcel Holtmann hdev->idle_timeout = val; 4292bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4302bfa3531SMarcel Holtmann 4312bfa3531SMarcel Holtmann return 0; 4322bfa3531SMarcel Holtmann } 4332bfa3531SMarcel Holtmann 4342bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val) 4352bfa3531SMarcel Holtmann { 4362bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4372bfa3531SMarcel Holtmann 4382bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4392bfa3531SMarcel Holtmann *val = hdev->idle_timeout; 4402bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4412bfa3531SMarcel Holtmann 4422bfa3531SMarcel Holtmann return 0; 4432bfa3531SMarcel Holtmann } 4442bfa3531SMarcel Holtmann 4452bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get, 4462bfa3531SMarcel Holtmann idle_timeout_set, "%llu\n"); 4472bfa3531SMarcel Holtmann 448c982b2eaSJohan Hedberg static int rpa_timeout_set(void *data, u64 val) 449c982b2eaSJohan Hedberg { 450c982b2eaSJohan Hedberg struct hci_dev *hdev = data; 451c982b2eaSJohan Hedberg 452c982b2eaSJohan Hedberg /* Require the RPA timeout to be at least 30 seconds and at most 453c982b2eaSJohan Hedberg * 24 hours. 454c982b2eaSJohan Hedberg */ 455c982b2eaSJohan Hedberg if (val < 30 || val > (60 * 60 * 24)) 456c982b2eaSJohan Hedberg return -EINVAL; 457c982b2eaSJohan Hedberg 458c982b2eaSJohan Hedberg hci_dev_lock(hdev); 459c982b2eaSJohan Hedberg hdev->rpa_timeout = val; 460c982b2eaSJohan Hedberg hci_dev_unlock(hdev); 461c982b2eaSJohan Hedberg 462c982b2eaSJohan Hedberg return 0; 463c982b2eaSJohan Hedberg } 464c982b2eaSJohan Hedberg 465c982b2eaSJohan Hedberg static int rpa_timeout_get(void *data, u64 *val) 466c982b2eaSJohan Hedberg { 467c982b2eaSJohan Hedberg struct hci_dev *hdev = data; 468c982b2eaSJohan Hedberg 469c982b2eaSJohan Hedberg hci_dev_lock(hdev); 470c982b2eaSJohan Hedberg *val = hdev->rpa_timeout; 471c982b2eaSJohan Hedberg hci_dev_unlock(hdev); 472c982b2eaSJohan Hedberg 473c982b2eaSJohan Hedberg return 0; 474c982b2eaSJohan Hedberg } 475c982b2eaSJohan Hedberg 476c982b2eaSJohan Hedberg DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get, 477c982b2eaSJohan Hedberg rpa_timeout_set, "%llu\n"); 478c982b2eaSJohan Hedberg 4792bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val) 4802bfa3531SMarcel Holtmann { 4812bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4822bfa3531SMarcel Holtmann 4832bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val > hdev->sniff_max_interval) 4842bfa3531SMarcel Holtmann return -EINVAL; 4852bfa3531SMarcel Holtmann 4862bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4872bfa3531SMarcel Holtmann hdev->sniff_min_interval = val; 4882bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4892bfa3531SMarcel Holtmann 4902bfa3531SMarcel Holtmann return 0; 4912bfa3531SMarcel Holtmann } 4922bfa3531SMarcel Holtmann 4932bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val) 4942bfa3531SMarcel Holtmann { 4952bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4962bfa3531SMarcel Holtmann 4972bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4982bfa3531SMarcel Holtmann *val = hdev->sniff_min_interval; 4992bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5002bfa3531SMarcel Holtmann 5012bfa3531SMarcel Holtmann return 0; 5022bfa3531SMarcel Holtmann } 5032bfa3531SMarcel Holtmann 5042bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get, 5052bfa3531SMarcel Holtmann sniff_min_interval_set, "%llu\n"); 5062bfa3531SMarcel Holtmann 5072bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val) 5082bfa3531SMarcel Holtmann { 5092bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5102bfa3531SMarcel Holtmann 5112bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val < hdev->sniff_min_interval) 5122bfa3531SMarcel Holtmann return -EINVAL; 5132bfa3531SMarcel Holtmann 5142bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5152bfa3531SMarcel Holtmann hdev->sniff_max_interval = val; 5162bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5172bfa3531SMarcel Holtmann 5182bfa3531SMarcel Holtmann return 0; 5192bfa3531SMarcel Holtmann } 5202bfa3531SMarcel Holtmann 5212bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val) 5222bfa3531SMarcel Holtmann { 5232bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5242bfa3531SMarcel Holtmann 5252bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5262bfa3531SMarcel Holtmann *val = hdev->sniff_max_interval; 5272bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5282bfa3531SMarcel Holtmann 5292bfa3531SMarcel Holtmann return 0; 5302bfa3531SMarcel Holtmann } 5312bfa3531SMarcel Holtmann 5322bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, 5332bfa3531SMarcel Holtmann sniff_max_interval_set, "%llu\n"); 5342bfa3531SMarcel Holtmann 53531ad1691SAndrzej Kaczmarek static int conn_info_min_age_set(void *data, u64 val) 53631ad1691SAndrzej Kaczmarek { 53731ad1691SAndrzej Kaczmarek struct hci_dev *hdev = data; 53831ad1691SAndrzej Kaczmarek 53931ad1691SAndrzej Kaczmarek if (val == 0 || val > hdev->conn_info_max_age) 54031ad1691SAndrzej Kaczmarek return -EINVAL; 54131ad1691SAndrzej Kaczmarek 54231ad1691SAndrzej Kaczmarek hci_dev_lock(hdev); 54331ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = val; 54431ad1691SAndrzej Kaczmarek hci_dev_unlock(hdev); 54531ad1691SAndrzej Kaczmarek 54631ad1691SAndrzej Kaczmarek return 0; 54731ad1691SAndrzej Kaczmarek } 54831ad1691SAndrzej Kaczmarek 54931ad1691SAndrzej Kaczmarek static int conn_info_min_age_get(void *data, u64 *val) 55031ad1691SAndrzej Kaczmarek { 55131ad1691SAndrzej Kaczmarek struct hci_dev *hdev = data; 55231ad1691SAndrzej Kaczmarek 55331ad1691SAndrzej Kaczmarek hci_dev_lock(hdev); 55431ad1691SAndrzej Kaczmarek *val = hdev->conn_info_min_age; 55531ad1691SAndrzej Kaczmarek hci_dev_unlock(hdev); 55631ad1691SAndrzej Kaczmarek 55731ad1691SAndrzej Kaczmarek return 0; 55831ad1691SAndrzej Kaczmarek } 55931ad1691SAndrzej Kaczmarek 56031ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_min_age_fops, conn_info_min_age_get, 56131ad1691SAndrzej Kaczmarek conn_info_min_age_set, "%llu\n"); 56231ad1691SAndrzej Kaczmarek 56331ad1691SAndrzej Kaczmarek static int conn_info_max_age_set(void *data, u64 val) 56431ad1691SAndrzej Kaczmarek { 56531ad1691SAndrzej Kaczmarek struct hci_dev *hdev = data; 56631ad1691SAndrzej Kaczmarek 56731ad1691SAndrzej Kaczmarek if (val == 0 || val < hdev->conn_info_min_age) 56831ad1691SAndrzej Kaczmarek return -EINVAL; 56931ad1691SAndrzej Kaczmarek 57031ad1691SAndrzej Kaczmarek hci_dev_lock(hdev); 57131ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = val; 57231ad1691SAndrzej Kaczmarek hci_dev_unlock(hdev); 57331ad1691SAndrzej Kaczmarek 57431ad1691SAndrzej Kaczmarek return 0; 57531ad1691SAndrzej Kaczmarek } 57631ad1691SAndrzej Kaczmarek 57731ad1691SAndrzej Kaczmarek static int conn_info_max_age_get(void *data, u64 *val) 57831ad1691SAndrzej Kaczmarek { 57931ad1691SAndrzej Kaczmarek struct hci_dev *hdev = data; 58031ad1691SAndrzej Kaczmarek 58131ad1691SAndrzej Kaczmarek hci_dev_lock(hdev); 58231ad1691SAndrzej Kaczmarek *val = hdev->conn_info_max_age; 58331ad1691SAndrzej Kaczmarek hci_dev_unlock(hdev); 58431ad1691SAndrzej Kaczmarek 58531ad1691SAndrzej Kaczmarek return 0; 58631ad1691SAndrzej Kaczmarek } 58731ad1691SAndrzej Kaczmarek 58831ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get, 58931ad1691SAndrzej Kaczmarek conn_info_max_age_set, "%llu\n"); 59031ad1691SAndrzej Kaczmarek 591ac345813SMarcel Holtmann static int identity_show(struct seq_file *f, void *p) 592ac345813SMarcel Holtmann { 593ac345813SMarcel Holtmann struct hci_dev *hdev = f->private; 594a1f4c318SJohan Hedberg bdaddr_t addr; 595ac345813SMarcel Holtmann u8 addr_type; 596ac345813SMarcel Holtmann 597ac345813SMarcel Holtmann hci_dev_lock(hdev); 598ac345813SMarcel Holtmann 599a1f4c318SJohan Hedberg hci_copy_identity_address(hdev, &addr, &addr_type); 600ac345813SMarcel Holtmann 601a1f4c318SJohan Hedberg seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type, 602473deef2SMarcel Holtmann 16, hdev->irk, &hdev->rpa); 603ac345813SMarcel Holtmann 604ac345813SMarcel Holtmann hci_dev_unlock(hdev); 605ac345813SMarcel Holtmann 606ac345813SMarcel Holtmann return 0; 607ac345813SMarcel Holtmann } 608ac345813SMarcel Holtmann 609ac345813SMarcel Holtmann static int identity_open(struct inode *inode, struct file *file) 610ac345813SMarcel Holtmann { 611ac345813SMarcel Holtmann return single_open(file, identity_show, inode->i_private); 612ac345813SMarcel Holtmann } 613ac345813SMarcel Holtmann 614ac345813SMarcel Holtmann static const struct file_operations identity_fops = { 615ac345813SMarcel Holtmann .open = identity_open, 616ac345813SMarcel Holtmann .read = seq_read, 617ac345813SMarcel Holtmann .llseek = seq_lseek, 618ac345813SMarcel Holtmann .release = single_release, 619ac345813SMarcel Holtmann }; 620ac345813SMarcel Holtmann 6217a4cd51dSMarcel Holtmann static int random_address_show(struct seq_file *f, void *p) 6227a4cd51dSMarcel Holtmann { 6237a4cd51dSMarcel Holtmann struct hci_dev *hdev = f->private; 6247a4cd51dSMarcel Holtmann 6257a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 6267a4cd51dSMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->random_addr); 6277a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 6287a4cd51dSMarcel Holtmann 6297a4cd51dSMarcel Holtmann return 0; 6307a4cd51dSMarcel Holtmann } 6317a4cd51dSMarcel Holtmann 6327a4cd51dSMarcel Holtmann static int random_address_open(struct inode *inode, struct file *file) 6337a4cd51dSMarcel Holtmann { 6347a4cd51dSMarcel Holtmann return single_open(file, random_address_show, inode->i_private); 6357a4cd51dSMarcel Holtmann } 6367a4cd51dSMarcel Holtmann 6377a4cd51dSMarcel Holtmann static const struct file_operations random_address_fops = { 6387a4cd51dSMarcel Holtmann .open = random_address_open, 6397a4cd51dSMarcel Holtmann .read = seq_read, 6407a4cd51dSMarcel Holtmann .llseek = seq_lseek, 6417a4cd51dSMarcel Holtmann .release = single_release, 6427a4cd51dSMarcel Holtmann }; 6437a4cd51dSMarcel Holtmann 644e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p) 645e7b8fc92SMarcel Holtmann { 646e7b8fc92SMarcel Holtmann struct hci_dev *hdev = f->private; 647e7b8fc92SMarcel Holtmann 648e7b8fc92SMarcel Holtmann hci_dev_lock(hdev); 649e7b8fc92SMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->static_addr); 650e7b8fc92SMarcel Holtmann hci_dev_unlock(hdev); 651e7b8fc92SMarcel Holtmann 652e7b8fc92SMarcel Holtmann return 0; 653e7b8fc92SMarcel Holtmann } 654e7b8fc92SMarcel Holtmann 655e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file) 656e7b8fc92SMarcel Holtmann { 657e7b8fc92SMarcel Holtmann return single_open(file, static_address_show, inode->i_private); 658e7b8fc92SMarcel Holtmann } 659e7b8fc92SMarcel Holtmann 660e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = { 661e7b8fc92SMarcel Holtmann .open = static_address_open, 662e7b8fc92SMarcel Holtmann .read = seq_read, 663e7b8fc92SMarcel Holtmann .llseek = seq_lseek, 664e7b8fc92SMarcel Holtmann .release = single_release, 665e7b8fc92SMarcel Holtmann }; 666e7b8fc92SMarcel Holtmann 667b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file, 668b32bba6cSMarcel Holtmann char __user *user_buf, 669b32bba6cSMarcel Holtmann size_t count, loff_t *ppos) 67092202185SMarcel Holtmann { 671b32bba6cSMarcel Holtmann struct hci_dev *hdev = file->private_data; 672b32bba6cSMarcel Holtmann char buf[3]; 67392202185SMarcel Holtmann 674111902f7SMarcel Holtmann buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N'; 675b32bba6cSMarcel Holtmann buf[1] = '\n'; 676b32bba6cSMarcel Holtmann buf[2] = '\0'; 677b32bba6cSMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 678b32bba6cSMarcel Holtmann } 679b32bba6cSMarcel Holtmann 680b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file, 681b32bba6cSMarcel Holtmann const char __user *user_buf, 682b32bba6cSMarcel Holtmann size_t count, loff_t *ppos) 683b32bba6cSMarcel Holtmann { 684b32bba6cSMarcel Holtmann struct hci_dev *hdev = file->private_data; 685b32bba6cSMarcel Holtmann char buf[32]; 686b32bba6cSMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 687b32bba6cSMarcel Holtmann bool enable; 688b32bba6cSMarcel Holtmann 689b32bba6cSMarcel Holtmann if (test_bit(HCI_UP, &hdev->flags)) 690b32bba6cSMarcel Holtmann return -EBUSY; 691b32bba6cSMarcel Holtmann 692b32bba6cSMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 693b32bba6cSMarcel Holtmann return -EFAULT; 694b32bba6cSMarcel Holtmann 695b32bba6cSMarcel Holtmann buf[buf_size] = '\0'; 696b32bba6cSMarcel Holtmann if (strtobool(buf, &enable)) 69792202185SMarcel Holtmann return -EINVAL; 69892202185SMarcel Holtmann 699111902f7SMarcel Holtmann if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags)) 700b32bba6cSMarcel Holtmann return -EALREADY; 70192202185SMarcel Holtmann 702111902f7SMarcel Holtmann change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags); 703b32bba6cSMarcel Holtmann 704b32bba6cSMarcel Holtmann return count; 70592202185SMarcel Holtmann } 70692202185SMarcel Holtmann 707b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = { 708b32bba6cSMarcel Holtmann .open = simple_open, 709b32bba6cSMarcel Holtmann .read = force_static_address_read, 710b32bba6cSMarcel Holtmann .write = force_static_address_write, 711b32bba6cSMarcel Holtmann .llseek = default_llseek, 712b32bba6cSMarcel Holtmann }; 71392202185SMarcel Holtmann 714d2ab0ac1SMarcel Holtmann static int white_list_show(struct seq_file *f, void *ptr) 715d2ab0ac1SMarcel Holtmann { 716d2ab0ac1SMarcel Holtmann struct hci_dev *hdev = f->private; 717d2ab0ac1SMarcel Holtmann struct bdaddr_list *b; 718d2ab0ac1SMarcel Holtmann 719d2ab0ac1SMarcel Holtmann hci_dev_lock(hdev); 720d2ab0ac1SMarcel Holtmann list_for_each_entry(b, &hdev->le_white_list, list) 721d2ab0ac1SMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 722d2ab0ac1SMarcel Holtmann hci_dev_unlock(hdev); 723d2ab0ac1SMarcel Holtmann 724d2ab0ac1SMarcel Holtmann return 0; 725d2ab0ac1SMarcel Holtmann } 726d2ab0ac1SMarcel Holtmann 727d2ab0ac1SMarcel Holtmann static int white_list_open(struct inode *inode, struct file *file) 728d2ab0ac1SMarcel Holtmann { 729d2ab0ac1SMarcel Holtmann return single_open(file, white_list_show, inode->i_private); 730d2ab0ac1SMarcel Holtmann } 731d2ab0ac1SMarcel Holtmann 732d2ab0ac1SMarcel Holtmann static const struct file_operations white_list_fops = { 733d2ab0ac1SMarcel Holtmann .open = white_list_open, 734d2ab0ac1SMarcel Holtmann .read = seq_read, 735d2ab0ac1SMarcel Holtmann .llseek = seq_lseek, 736d2ab0ac1SMarcel Holtmann .release = single_release, 737d2ab0ac1SMarcel Holtmann }; 738d2ab0ac1SMarcel Holtmann 7393698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr) 7403698d704SMarcel Holtmann { 7413698d704SMarcel Holtmann struct hci_dev *hdev = f->private; 7423698d704SMarcel Holtmann struct list_head *p, *n; 7433698d704SMarcel Holtmann 7443698d704SMarcel Holtmann hci_dev_lock(hdev); 7453698d704SMarcel Holtmann list_for_each_safe(p, n, &hdev->identity_resolving_keys) { 7463698d704SMarcel Holtmann struct smp_irk *irk = list_entry(p, struct smp_irk, list); 7473698d704SMarcel Holtmann seq_printf(f, "%pMR (type %u) %*phN %pMR\n", 7483698d704SMarcel Holtmann &irk->bdaddr, irk->addr_type, 7493698d704SMarcel Holtmann 16, irk->val, &irk->rpa); 7503698d704SMarcel Holtmann } 7513698d704SMarcel Holtmann hci_dev_unlock(hdev); 7523698d704SMarcel Holtmann 7533698d704SMarcel Holtmann return 0; 7543698d704SMarcel Holtmann } 7553698d704SMarcel Holtmann 7563698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file) 7573698d704SMarcel Holtmann { 7583698d704SMarcel Holtmann return single_open(file, identity_resolving_keys_show, 7593698d704SMarcel Holtmann inode->i_private); 7603698d704SMarcel Holtmann } 7613698d704SMarcel Holtmann 7623698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = { 7633698d704SMarcel Holtmann .open = identity_resolving_keys_open, 7643698d704SMarcel Holtmann .read = seq_read, 7653698d704SMarcel Holtmann .llseek = seq_lseek, 7663698d704SMarcel Holtmann .release = single_release, 7673698d704SMarcel Holtmann }; 7683698d704SMarcel Holtmann 7698f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr) 7708f8625cdSMarcel Holtmann { 7718f8625cdSMarcel Holtmann struct hci_dev *hdev = f->private; 7728f8625cdSMarcel Holtmann struct list_head *p, *n; 7738f8625cdSMarcel Holtmann 7748f8625cdSMarcel Holtmann hci_dev_lock(hdev); 775f813f1beSJohan Hedberg list_for_each_safe(p, n, &hdev->long_term_keys) { 7768f8625cdSMarcel Holtmann struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list); 777fe39c7b2SMarcel Holtmann seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n", 7788f8625cdSMarcel Holtmann <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, 7798f8625cdSMarcel Holtmann ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), 780fe39c7b2SMarcel Holtmann __le64_to_cpu(ltk->rand), 16, ltk->val); 7818f8625cdSMarcel Holtmann } 7828f8625cdSMarcel Holtmann hci_dev_unlock(hdev); 7838f8625cdSMarcel Holtmann 7848f8625cdSMarcel Holtmann return 0; 7858f8625cdSMarcel Holtmann } 7868f8625cdSMarcel Holtmann 7878f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file) 7888f8625cdSMarcel Holtmann { 7898f8625cdSMarcel Holtmann return single_open(file, long_term_keys_show, inode->i_private); 7908f8625cdSMarcel Holtmann } 7918f8625cdSMarcel Holtmann 7928f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = { 7938f8625cdSMarcel Holtmann .open = long_term_keys_open, 7948f8625cdSMarcel Holtmann .read = seq_read, 7958f8625cdSMarcel Holtmann .llseek = seq_lseek, 7968f8625cdSMarcel Holtmann .release = single_release, 7978f8625cdSMarcel Holtmann }; 7988f8625cdSMarcel Holtmann 7994e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val) 8004e70c7e7SMarcel Holtmann { 8014e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 8024e70c7e7SMarcel Holtmann 8034e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval) 8044e70c7e7SMarcel Holtmann return -EINVAL; 8054e70c7e7SMarcel Holtmann 8064e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 8074e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = val; 8084e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8094e70c7e7SMarcel Holtmann 8104e70c7e7SMarcel Holtmann return 0; 8114e70c7e7SMarcel Holtmann } 8124e70c7e7SMarcel Holtmann 8134e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val) 8144e70c7e7SMarcel Holtmann { 8154e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 8164e70c7e7SMarcel Holtmann 8174e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 8184e70c7e7SMarcel Holtmann *val = hdev->le_conn_min_interval; 8194e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8204e70c7e7SMarcel Holtmann 8214e70c7e7SMarcel Holtmann return 0; 8224e70c7e7SMarcel Holtmann } 8234e70c7e7SMarcel Holtmann 8244e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get, 8254e70c7e7SMarcel Holtmann conn_min_interval_set, "%llu\n"); 8264e70c7e7SMarcel Holtmann 8274e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val) 8284e70c7e7SMarcel Holtmann { 8294e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 8304e70c7e7SMarcel Holtmann 8314e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval) 8324e70c7e7SMarcel Holtmann return -EINVAL; 8334e70c7e7SMarcel Holtmann 8344e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 8354e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = val; 8364e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8374e70c7e7SMarcel Holtmann 8384e70c7e7SMarcel Holtmann return 0; 8394e70c7e7SMarcel Holtmann } 8404e70c7e7SMarcel Holtmann 8414e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val) 8424e70c7e7SMarcel Holtmann { 8434e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 8444e70c7e7SMarcel Holtmann 8454e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 8464e70c7e7SMarcel Holtmann *val = hdev->le_conn_max_interval; 8474e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8484e70c7e7SMarcel Holtmann 8494e70c7e7SMarcel Holtmann return 0; 8504e70c7e7SMarcel Holtmann } 8514e70c7e7SMarcel Holtmann 8524e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, 8534e70c7e7SMarcel Holtmann conn_max_interval_set, "%llu\n"); 8544e70c7e7SMarcel Holtmann 855816a93d1SMarcel Holtmann static int conn_latency_set(void *data, u64 val) 856816a93d1SMarcel Holtmann { 857816a93d1SMarcel Holtmann struct hci_dev *hdev = data; 858816a93d1SMarcel Holtmann 859816a93d1SMarcel Holtmann if (val > 0x01f3) 860816a93d1SMarcel Holtmann return -EINVAL; 861816a93d1SMarcel Holtmann 862816a93d1SMarcel Holtmann hci_dev_lock(hdev); 863816a93d1SMarcel Holtmann hdev->le_conn_latency = val; 864816a93d1SMarcel Holtmann hci_dev_unlock(hdev); 865816a93d1SMarcel Holtmann 866816a93d1SMarcel Holtmann return 0; 867816a93d1SMarcel Holtmann } 868816a93d1SMarcel Holtmann 869816a93d1SMarcel Holtmann static int conn_latency_get(void *data, u64 *val) 870816a93d1SMarcel Holtmann { 871816a93d1SMarcel Holtmann struct hci_dev *hdev = data; 872816a93d1SMarcel Holtmann 873816a93d1SMarcel Holtmann hci_dev_lock(hdev); 874816a93d1SMarcel Holtmann *val = hdev->le_conn_latency; 875816a93d1SMarcel Holtmann hci_dev_unlock(hdev); 876816a93d1SMarcel Holtmann 877816a93d1SMarcel Holtmann return 0; 878816a93d1SMarcel Holtmann } 879816a93d1SMarcel Holtmann 880816a93d1SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get, 881816a93d1SMarcel Holtmann conn_latency_set, "%llu\n"); 882816a93d1SMarcel Holtmann 883f1649577SMarcel Holtmann static int supervision_timeout_set(void *data, u64 val) 884f1649577SMarcel Holtmann { 885f1649577SMarcel Holtmann struct hci_dev *hdev = data; 886f1649577SMarcel Holtmann 887f1649577SMarcel Holtmann if (val < 0x000a || val > 0x0c80) 888f1649577SMarcel Holtmann return -EINVAL; 889f1649577SMarcel Holtmann 890f1649577SMarcel Holtmann hci_dev_lock(hdev); 891f1649577SMarcel Holtmann hdev->le_supv_timeout = val; 892f1649577SMarcel Holtmann hci_dev_unlock(hdev); 893f1649577SMarcel Holtmann 894f1649577SMarcel Holtmann return 0; 895f1649577SMarcel Holtmann } 896f1649577SMarcel Holtmann 897f1649577SMarcel Holtmann static int supervision_timeout_get(void *data, u64 *val) 898f1649577SMarcel Holtmann { 899f1649577SMarcel Holtmann struct hci_dev *hdev = data; 900f1649577SMarcel Holtmann 901f1649577SMarcel Holtmann hci_dev_lock(hdev); 902f1649577SMarcel Holtmann *val = hdev->le_supv_timeout; 903f1649577SMarcel Holtmann hci_dev_unlock(hdev); 904f1649577SMarcel Holtmann 905f1649577SMarcel Holtmann return 0; 906f1649577SMarcel Holtmann } 907f1649577SMarcel Holtmann 908f1649577SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get, 909f1649577SMarcel Holtmann supervision_timeout_set, "%llu\n"); 910f1649577SMarcel Holtmann 9113f959d46SMarcel Holtmann static int adv_channel_map_set(void *data, u64 val) 9123f959d46SMarcel Holtmann { 9133f959d46SMarcel Holtmann struct hci_dev *hdev = data; 9143f959d46SMarcel Holtmann 9153f959d46SMarcel Holtmann if (val < 0x01 || val > 0x07) 9163f959d46SMarcel Holtmann return -EINVAL; 9173f959d46SMarcel Holtmann 9183f959d46SMarcel Holtmann hci_dev_lock(hdev); 9193f959d46SMarcel Holtmann hdev->le_adv_channel_map = val; 9203f959d46SMarcel Holtmann hci_dev_unlock(hdev); 9213f959d46SMarcel Holtmann 9223f959d46SMarcel Holtmann return 0; 9233f959d46SMarcel Holtmann } 9243f959d46SMarcel Holtmann 9253f959d46SMarcel Holtmann static int adv_channel_map_get(void *data, u64 *val) 9263f959d46SMarcel Holtmann { 9273f959d46SMarcel Holtmann struct hci_dev *hdev = data; 9283f959d46SMarcel Holtmann 9293f959d46SMarcel Holtmann hci_dev_lock(hdev); 9303f959d46SMarcel Holtmann *val = hdev->le_adv_channel_map; 9313f959d46SMarcel Holtmann hci_dev_unlock(hdev); 9323f959d46SMarcel Holtmann 9333f959d46SMarcel Holtmann return 0; 9343f959d46SMarcel Holtmann } 9353f959d46SMarcel Holtmann 9363f959d46SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get, 9373f959d46SMarcel Holtmann adv_channel_map_set, "%llu\n"); 9383f959d46SMarcel Holtmann 9390b3c7d37SMarcel Holtmann static int device_list_show(struct seq_file *f, void *ptr) 9407d474e06SAndre Guedes { 9410b3c7d37SMarcel Holtmann struct hci_dev *hdev = f->private; 9427d474e06SAndre Guedes struct hci_conn_params *p; 9437d474e06SAndre Guedes 9447d474e06SAndre Guedes hci_dev_lock(hdev); 9457d474e06SAndre Guedes list_for_each_entry(p, &hdev->le_conn_params, list) { 9460b3c7d37SMarcel Holtmann seq_printf(f, "%pMR %u %u\n", &p->addr, p->addr_type, 9477d474e06SAndre Guedes p->auto_connect); 9487d474e06SAndre Guedes } 9497d474e06SAndre Guedes hci_dev_unlock(hdev); 9507d474e06SAndre Guedes 9517d474e06SAndre Guedes return 0; 9527d474e06SAndre Guedes } 9537d474e06SAndre Guedes 9540b3c7d37SMarcel Holtmann static int device_list_open(struct inode *inode, struct file *file) 9557d474e06SAndre Guedes { 9560b3c7d37SMarcel Holtmann return single_open(file, device_list_show, inode->i_private); 9577d474e06SAndre Guedes } 9587d474e06SAndre Guedes 9590b3c7d37SMarcel Holtmann static const struct file_operations device_list_fops = { 9600b3c7d37SMarcel Holtmann .open = device_list_open, 9617d474e06SAndre Guedes .read = seq_read, 9627d474e06SAndre Guedes .llseek = seq_lseek, 9637d474e06SAndre Guedes .release = single_release, 9647d474e06SAndre Guedes }; 9657d474e06SAndre Guedes 9661da177e4SLinus Torvalds /* ---- HCI requests ---- */ 9671da177e4SLinus Torvalds 96842c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 9691da177e4SLinus Torvalds { 97042c6b129SJohan Hedberg BT_DBG("%s result 0x%2.2x", hdev->name, result); 97175fb0e32SJohan Hedberg 9721da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 9731da177e4SLinus Torvalds hdev->req_result = result; 9741da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 9751da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 9761da177e4SLinus Torvalds } 9771da177e4SLinus Torvalds } 9781da177e4SLinus Torvalds 9791da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 9801da177e4SLinus Torvalds { 9811da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 9821da177e4SLinus Torvalds 9831da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 9841da177e4SLinus Torvalds hdev->req_result = err; 9851da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 9861da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 9871da177e4SLinus Torvalds } 9881da177e4SLinus Torvalds } 9891da177e4SLinus Torvalds 99077a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 99177a63e0aSFengguang Wu u8 event) 99275e84b7cSJohan Hedberg { 99375e84b7cSJohan Hedberg struct hci_ev_cmd_complete *ev; 99475e84b7cSJohan Hedberg struct hci_event_hdr *hdr; 99575e84b7cSJohan Hedberg struct sk_buff *skb; 99675e84b7cSJohan Hedberg 99775e84b7cSJohan Hedberg hci_dev_lock(hdev); 99875e84b7cSJohan Hedberg 99975e84b7cSJohan Hedberg skb = hdev->recv_evt; 100075e84b7cSJohan Hedberg hdev->recv_evt = NULL; 100175e84b7cSJohan Hedberg 100275e84b7cSJohan Hedberg hci_dev_unlock(hdev); 100375e84b7cSJohan Hedberg 100475e84b7cSJohan Hedberg if (!skb) 100575e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 100675e84b7cSJohan Hedberg 100775e84b7cSJohan Hedberg if (skb->len < sizeof(*hdr)) { 100875e84b7cSJohan Hedberg BT_ERR("Too short HCI event"); 100975e84b7cSJohan Hedberg goto failed; 101075e84b7cSJohan Hedberg } 101175e84b7cSJohan Hedberg 101275e84b7cSJohan Hedberg hdr = (void *) skb->data; 101375e84b7cSJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 101475e84b7cSJohan Hedberg 10157b1abbbeSJohan Hedberg if (event) { 10167b1abbbeSJohan Hedberg if (hdr->evt != event) 10177b1abbbeSJohan Hedberg goto failed; 10187b1abbbeSJohan Hedberg return skb; 10197b1abbbeSJohan Hedberg } 10207b1abbbeSJohan Hedberg 102175e84b7cSJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 102275e84b7cSJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 102375e84b7cSJohan Hedberg goto failed; 102475e84b7cSJohan Hedberg } 102575e84b7cSJohan Hedberg 102675e84b7cSJohan Hedberg if (skb->len < sizeof(*ev)) { 102775e84b7cSJohan Hedberg BT_ERR("Too short cmd_complete event"); 102875e84b7cSJohan Hedberg goto failed; 102975e84b7cSJohan Hedberg } 103075e84b7cSJohan Hedberg 103175e84b7cSJohan Hedberg ev = (void *) skb->data; 103275e84b7cSJohan Hedberg skb_pull(skb, sizeof(*ev)); 103375e84b7cSJohan Hedberg 103475e84b7cSJohan Hedberg if (opcode == __le16_to_cpu(ev->opcode)) 103575e84b7cSJohan Hedberg return skb; 103675e84b7cSJohan Hedberg 103775e84b7cSJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 103875e84b7cSJohan Hedberg __le16_to_cpu(ev->opcode)); 103975e84b7cSJohan Hedberg 104075e84b7cSJohan Hedberg failed: 104175e84b7cSJohan Hedberg kfree_skb(skb); 104275e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 104375e84b7cSJohan Hedberg } 104475e84b7cSJohan Hedberg 10457b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 104607dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout) 104775e84b7cSJohan Hedberg { 104875e84b7cSJohan Hedberg DECLARE_WAITQUEUE(wait, current); 104975e84b7cSJohan Hedberg struct hci_request req; 105075e84b7cSJohan Hedberg int err = 0; 105175e84b7cSJohan Hedberg 105275e84b7cSJohan Hedberg BT_DBG("%s", hdev->name); 105375e84b7cSJohan Hedberg 105475e84b7cSJohan Hedberg hci_req_init(&req, hdev); 105575e84b7cSJohan Hedberg 10567b1abbbeSJohan Hedberg hci_req_add_ev(&req, opcode, plen, param, event); 105775e84b7cSJohan Hedberg 105875e84b7cSJohan Hedberg hdev->req_status = HCI_REQ_PEND; 105975e84b7cSJohan Hedberg 106075e84b7cSJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 106175e84b7cSJohan Hedberg if (err < 0) 106275e84b7cSJohan Hedberg return ERR_PTR(err); 106375e84b7cSJohan Hedberg 106475e84b7cSJohan Hedberg add_wait_queue(&hdev->req_wait_q, &wait); 106575e84b7cSJohan Hedberg set_current_state(TASK_INTERRUPTIBLE); 106675e84b7cSJohan Hedberg 106775e84b7cSJohan Hedberg schedule_timeout(timeout); 106875e84b7cSJohan Hedberg 106975e84b7cSJohan Hedberg remove_wait_queue(&hdev->req_wait_q, &wait); 107075e84b7cSJohan Hedberg 107175e84b7cSJohan Hedberg if (signal_pending(current)) 107275e84b7cSJohan Hedberg return ERR_PTR(-EINTR); 107375e84b7cSJohan Hedberg 107475e84b7cSJohan Hedberg switch (hdev->req_status) { 107575e84b7cSJohan Hedberg case HCI_REQ_DONE: 107675e84b7cSJohan Hedberg err = -bt_to_errno(hdev->req_result); 107775e84b7cSJohan Hedberg break; 107875e84b7cSJohan Hedberg 107975e84b7cSJohan Hedberg case HCI_REQ_CANCELED: 108075e84b7cSJohan Hedberg err = -hdev->req_result; 108175e84b7cSJohan Hedberg break; 108275e84b7cSJohan Hedberg 108375e84b7cSJohan Hedberg default: 108475e84b7cSJohan Hedberg err = -ETIMEDOUT; 108575e84b7cSJohan Hedberg break; 108675e84b7cSJohan Hedberg } 108775e84b7cSJohan Hedberg 108875e84b7cSJohan Hedberg hdev->req_status = hdev->req_result = 0; 108975e84b7cSJohan Hedberg 109075e84b7cSJohan Hedberg BT_DBG("%s end: err %d", hdev->name, err); 109175e84b7cSJohan Hedberg 109275e84b7cSJohan Hedberg if (err < 0) 109375e84b7cSJohan Hedberg return ERR_PTR(err); 109475e84b7cSJohan Hedberg 10957b1abbbeSJohan Hedberg return hci_get_cmd_complete(hdev, opcode, event); 10967b1abbbeSJohan Hedberg } 10977b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev); 10987b1abbbeSJohan Hedberg 10997b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 110007dc93ddSJohan Hedberg const void *param, u32 timeout) 11017b1abbbeSJohan Hedberg { 11027b1abbbeSJohan Hedberg return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); 110375e84b7cSJohan Hedberg } 110475e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync); 110575e84b7cSJohan Hedberg 11061da177e4SLinus Torvalds /* Execute request and wait for completion. */ 110701178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev, 110842c6b129SJohan Hedberg void (*func)(struct hci_request *req, 110942c6b129SJohan Hedberg unsigned long opt), 11101da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 11111da177e4SLinus Torvalds { 111242c6b129SJohan Hedberg struct hci_request req; 11131da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 11141da177e4SLinus Torvalds int err = 0; 11151da177e4SLinus Torvalds 11161da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 11171da177e4SLinus Torvalds 111842c6b129SJohan Hedberg hci_req_init(&req, hdev); 111942c6b129SJohan Hedberg 11201da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 11211da177e4SLinus Torvalds 112242c6b129SJohan Hedberg func(&req, opt); 112353cce22dSJohan Hedberg 112442c6b129SJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 112542c6b129SJohan Hedberg if (err < 0) { 112653cce22dSJohan Hedberg hdev->req_status = 0; 1127920c8300SAndre Guedes 1128920c8300SAndre Guedes /* ENODATA means the HCI request command queue is empty. 1129920c8300SAndre Guedes * This can happen when a request with conditionals doesn't 1130920c8300SAndre Guedes * trigger any commands to be sent. This is normal behavior 1131920c8300SAndre Guedes * and should not trigger an error return. 113242c6b129SJohan Hedberg */ 1133920c8300SAndre Guedes if (err == -ENODATA) 113442c6b129SJohan Hedberg return 0; 1135920c8300SAndre Guedes 1136920c8300SAndre Guedes return err; 113753cce22dSJohan Hedberg } 113853cce22dSJohan Hedberg 1139bc4445c7SAndre Guedes add_wait_queue(&hdev->req_wait_q, &wait); 1140bc4445c7SAndre Guedes set_current_state(TASK_INTERRUPTIBLE); 1141bc4445c7SAndre Guedes 11421da177e4SLinus Torvalds schedule_timeout(timeout); 11431da177e4SLinus Torvalds 11441da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 11451da177e4SLinus Torvalds 11461da177e4SLinus Torvalds if (signal_pending(current)) 11471da177e4SLinus Torvalds return -EINTR; 11481da177e4SLinus Torvalds 11491da177e4SLinus Torvalds switch (hdev->req_status) { 11501da177e4SLinus Torvalds case HCI_REQ_DONE: 1151e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 11521da177e4SLinus Torvalds break; 11531da177e4SLinus Torvalds 11541da177e4SLinus Torvalds case HCI_REQ_CANCELED: 11551da177e4SLinus Torvalds err = -hdev->req_result; 11561da177e4SLinus Torvalds break; 11571da177e4SLinus Torvalds 11581da177e4SLinus Torvalds default: 11591da177e4SLinus Torvalds err = -ETIMEDOUT; 11601da177e4SLinus Torvalds break; 11613ff50b79SStephen Hemminger } 11621da177e4SLinus Torvalds 1163a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 11641da177e4SLinus Torvalds 11651da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 11661da177e4SLinus Torvalds 11671da177e4SLinus Torvalds return err; 11681da177e4SLinus Torvalds } 11691da177e4SLinus Torvalds 117001178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev, 117142c6b129SJohan Hedberg void (*req)(struct hci_request *req, 117242c6b129SJohan Hedberg unsigned long opt), 11731da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 11741da177e4SLinus Torvalds { 11751da177e4SLinus Torvalds int ret; 11761da177e4SLinus Torvalds 11777c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 11787c6a329eSMarcel Holtmann return -ENETDOWN; 11797c6a329eSMarcel Holtmann 11801da177e4SLinus Torvalds /* Serialize all requests */ 11811da177e4SLinus Torvalds hci_req_lock(hdev); 118201178cd4SJohan Hedberg ret = __hci_req_sync(hdev, req, opt, timeout); 11831da177e4SLinus Torvalds hci_req_unlock(hdev); 11841da177e4SLinus Torvalds 11851da177e4SLinus Torvalds return ret; 11861da177e4SLinus Torvalds } 11871da177e4SLinus Torvalds 118842c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt) 11891da177e4SLinus Torvalds { 119042c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 11911da177e4SLinus Torvalds 11921da177e4SLinus Torvalds /* Reset device */ 119342c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 119442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 11951da177e4SLinus Torvalds } 11961da177e4SLinus Torvalds 119742c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 11981da177e4SLinus Torvalds { 119942c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 12002455a3eaSAndrei Emeltchenko 12011da177e4SLinus Torvalds /* Read Local Supported Features */ 120242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 12031da177e4SLinus Torvalds 12041143e5a6SMarcel Holtmann /* Read Local Version */ 120542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 12062177bab5SJohan Hedberg 12072177bab5SJohan Hedberg /* Read BD Address */ 120842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 12091da177e4SLinus Torvalds } 12101da177e4SLinus Torvalds 121142c6b129SJohan Hedberg static void amp_init(struct hci_request *req) 1212e61ef499SAndrei Emeltchenko { 121342c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 12142455a3eaSAndrei Emeltchenko 1215e61ef499SAndrei Emeltchenko /* Read Local Version */ 121642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 12176bcbc489SAndrei Emeltchenko 1218f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 1219f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 1220f6996cfeSMarcel Holtmann 1221f6996cfeSMarcel Holtmann /* Read Local Supported Features */ 1222f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 1223f6996cfeSMarcel Holtmann 12246bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 122542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 1226e71dfabaSAndrei Emeltchenko 1227e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 122842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 12297528ca1cSMarcel Holtmann 1230f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 1231f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 1232f38ba941SMarcel Holtmann 12337528ca1cSMarcel Holtmann /* Read Location Data */ 12347528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 1235e61ef499SAndrei Emeltchenko } 1236e61ef499SAndrei Emeltchenko 123742c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 1238e61ef499SAndrei Emeltchenko { 123942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1240e61ef499SAndrei Emeltchenko 1241e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 1242e61ef499SAndrei Emeltchenko 124311778716SAndrei Emeltchenko /* Reset */ 124411778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 124542c6b129SJohan Hedberg hci_reset_req(req, 0); 124611778716SAndrei Emeltchenko 1247e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 1248e61ef499SAndrei Emeltchenko case HCI_BREDR: 124942c6b129SJohan Hedberg bredr_init(req); 1250e61ef499SAndrei Emeltchenko break; 1251e61ef499SAndrei Emeltchenko 1252e61ef499SAndrei Emeltchenko case HCI_AMP: 125342c6b129SJohan Hedberg amp_init(req); 1254e61ef499SAndrei Emeltchenko break; 1255e61ef499SAndrei Emeltchenko 1256e61ef499SAndrei Emeltchenko default: 1257e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 1258e61ef499SAndrei Emeltchenko break; 1259e61ef499SAndrei Emeltchenko } 1260e61ef499SAndrei Emeltchenko } 1261e61ef499SAndrei Emeltchenko 126242c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 12632177bab5SJohan Hedberg { 12644ca048e3SMarcel Holtmann struct hci_dev *hdev = req->hdev; 12654ca048e3SMarcel Holtmann 12662177bab5SJohan Hedberg __le16 param; 12672177bab5SJohan Hedberg __u8 flt_type; 12682177bab5SJohan Hedberg 12692177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 127042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 12712177bab5SJohan Hedberg 12722177bab5SJohan Hedberg /* Read Class of Device */ 127342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 12742177bab5SJohan Hedberg 12752177bab5SJohan Hedberg /* Read Local Name */ 127642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 12772177bab5SJohan Hedberg 12782177bab5SJohan Hedberg /* Read Voice Setting */ 127942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 12802177bab5SJohan Hedberg 1281b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 1282b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 1283b4cb9fb2SMarcel Holtmann 12844b836f39SMarcel Holtmann /* Read Current IAC LAP */ 12854b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 12864b836f39SMarcel Holtmann 12872177bab5SJohan Hedberg /* Clear Event Filters */ 12882177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 128942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 12902177bab5SJohan Hedberg 12912177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 1292dcf4adbfSJoe Perches param = cpu_to_le16(0x7d00); 129342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 12942177bab5SJohan Hedberg 12954ca048e3SMarcel Holtmann /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, 12964ca048e3SMarcel Holtmann * but it does not support page scan related HCI commands. 12974ca048e3SMarcel Holtmann */ 12984ca048e3SMarcel Holtmann if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) { 1299f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 1300f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 1301f332ec66SJohan Hedberg } 13022177bab5SJohan Hedberg } 13032177bab5SJohan Hedberg 130442c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 13052177bab5SJohan Hedberg { 1306c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 1307c73eee91SJohan Hedberg 13082177bab5SJohan Hedberg /* Read LE Buffer Size */ 130942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 13102177bab5SJohan Hedberg 13112177bab5SJohan Hedberg /* Read LE Local Supported Features */ 131242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 13132177bab5SJohan Hedberg 1314747d3f03SMarcel Holtmann /* Read LE Supported States */ 1315747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 1316747d3f03SMarcel Holtmann 13172177bab5SJohan Hedberg /* Read LE Advertising Channel TX Power */ 131842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 13192177bab5SJohan Hedberg 13202177bab5SJohan Hedberg /* Read LE White List Size */ 132142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 13222177bab5SJohan Hedberg 1323747d3f03SMarcel Holtmann /* Clear LE White List */ 1324747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL); 1325c73eee91SJohan Hedberg 1326c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 1327c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1328c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 13292177bab5SJohan Hedberg } 13302177bab5SJohan Hedberg 13312177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 13322177bab5SJohan Hedberg { 13332177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 13342177bab5SJohan Hedberg return 0x02; 13352177bab5SJohan Hedberg 13362177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 13372177bab5SJohan Hedberg return 0x01; 13382177bab5SJohan Hedberg 13392177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 13402177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 13412177bab5SJohan Hedberg return 0x01; 13422177bab5SJohan Hedberg 13432177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 13442177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 13452177bab5SJohan Hedberg return 0x01; 13462177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 13472177bab5SJohan Hedberg return 0x01; 13482177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 13492177bab5SJohan Hedberg return 0x01; 13502177bab5SJohan Hedberg } 13512177bab5SJohan Hedberg 13522177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 13532177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 13542177bab5SJohan Hedberg return 0x01; 13552177bab5SJohan Hedberg 13562177bab5SJohan Hedberg return 0x00; 13572177bab5SJohan Hedberg } 13582177bab5SJohan Hedberg 135942c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 13602177bab5SJohan Hedberg { 13612177bab5SJohan Hedberg u8 mode; 13622177bab5SJohan Hedberg 136342c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 13642177bab5SJohan Hedberg 136542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 13662177bab5SJohan Hedberg } 13672177bab5SJohan Hedberg 136842c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 13692177bab5SJohan Hedberg { 137042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 137142c6b129SJohan Hedberg 13722177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 13732177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 13742177bab5SJohan Hedberg * command otherwise. 13752177bab5SJohan Hedberg */ 13762177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 13772177bab5SJohan Hedberg 13782177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 13792177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 13802177bab5SJohan Hedberg */ 13812177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 13822177bab5SJohan Hedberg return; 13832177bab5SJohan Hedberg 13842177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 13852177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 13862177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 13872177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 13882177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 13892177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 1390c7882cbdSMarcel Holtmann } else { 1391c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 1392c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 1393c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 1394c7882cbdSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 1395c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 1396c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 1397c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 1398c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 1399c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 1400c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 1401c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 14022177bab5SJohan Hedberg } 14032177bab5SJohan Hedberg 14042177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 14052177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 14062177bab5SJohan Hedberg 14072177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 14082177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 14092177bab5SJohan Hedberg 14102177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 14112177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 14122177bab5SJohan Hedberg 14132177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 14142177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 14152177bab5SJohan Hedberg 14162177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 14172177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 14182177bab5SJohan Hedberg 14192177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 14202177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 14212177bab5SJohan Hedberg 14222177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 14232177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 14242177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 14252177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 14262177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 14272177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 14282177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 14292177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 14302177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 14312177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 14322177bab5SJohan Hedberg * Features Notification 14332177bab5SJohan Hedberg */ 14342177bab5SJohan Hedberg } 14352177bab5SJohan Hedberg 14362177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 14372177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 14382177bab5SJohan Hedberg 143942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 14402177bab5SJohan Hedberg } 14412177bab5SJohan Hedberg 144242c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 14432177bab5SJohan Hedberg { 144442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 144542c6b129SJohan Hedberg 14462177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 144742c6b129SJohan Hedberg bredr_setup(req); 144856f87901SJohan Hedberg else 144956f87901SJohan Hedberg clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 14502177bab5SJohan Hedberg 14512177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 145242c6b129SJohan Hedberg le_setup(req); 14532177bab5SJohan Hedberg 145442c6b129SJohan Hedberg hci_setup_event_mask(req); 14552177bab5SJohan Hedberg 14563f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 14573f8e2d75SJohan Hedberg * local supported commands HCI command. 14583f8e2d75SJohan Hedberg */ 14593f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 146042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 14612177bab5SJohan Hedberg 14622177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 146357af75a8SMarcel Holtmann /* When SSP is available, then the host features page 146457af75a8SMarcel Holtmann * should also be available as well. However some 146557af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 146657af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 146757af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 146857af75a8SMarcel Holtmann */ 146957af75a8SMarcel Holtmann hdev->max_page = 0x01; 147057af75a8SMarcel Holtmann 14712177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 14722177bab5SJohan Hedberg u8 mode = 0x01; 147342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 14742177bab5SJohan Hedberg sizeof(mode), &mode); 14752177bab5SJohan Hedberg } else { 14762177bab5SJohan Hedberg struct hci_cp_write_eir cp; 14772177bab5SJohan Hedberg 14782177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 14792177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 14802177bab5SJohan Hedberg 148142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 14822177bab5SJohan Hedberg } 14832177bab5SJohan Hedberg } 14842177bab5SJohan Hedberg 14852177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 148642c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 14872177bab5SJohan Hedberg 14882177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 148942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 14902177bab5SJohan Hedberg 14912177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 14922177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 14932177bab5SJohan Hedberg 14942177bab5SJohan Hedberg cp.page = 0x01; 149542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 149642c6b129SJohan Hedberg sizeof(cp), &cp); 14972177bab5SJohan Hedberg } 14982177bab5SJohan Hedberg 14992177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 15002177bab5SJohan Hedberg u8 enable = 1; 150142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 15022177bab5SJohan Hedberg &enable); 15032177bab5SJohan Hedberg } 15042177bab5SJohan Hedberg } 15052177bab5SJohan Hedberg 150642c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 15072177bab5SJohan Hedberg { 150842c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 15092177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 15102177bab5SJohan Hedberg u16 link_policy = 0; 15112177bab5SJohan Hedberg 15122177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 15132177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 15142177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 15152177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 15162177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 15172177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 15182177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 15192177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 15202177bab5SJohan Hedberg 15212177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 152242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 15232177bab5SJohan Hedberg } 15242177bab5SJohan Hedberg 152542c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 15262177bab5SJohan Hedberg { 152742c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 15282177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 15292177bab5SJohan Hedberg 1530c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 1531c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1532c73eee91SJohan Hedberg return; 1533c73eee91SJohan Hedberg 15342177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 15352177bab5SJohan Hedberg 15362177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 15372177bab5SJohan Hedberg cp.le = 0x01; 15382177bab5SJohan Hedberg cp.simul = lmp_le_br_capable(hdev); 15392177bab5SJohan Hedberg } 15402177bab5SJohan Hedberg 15412177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 154242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 15432177bab5SJohan Hedberg &cp); 15442177bab5SJohan Hedberg } 15452177bab5SJohan Hedberg 1546d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 1547d62e6d67SJohan Hedberg { 1548d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 1549d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1550d62e6d67SJohan Hedberg 1551d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 1552d62e6d67SJohan Hedberg * enable all necessary events for it. 1553d62e6d67SJohan Hedberg */ 155453b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 1555d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 1556d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 1557d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 1558d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 1559d62e6d67SJohan Hedberg } 1560d62e6d67SJohan Hedberg 1561d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 1562d62e6d67SJohan Hedberg * enable all necessary events for it. 1563d62e6d67SJohan Hedberg */ 156453b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 1565d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 1566d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 1567d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 1568d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 1569d62e6d67SJohan Hedberg } 1570d62e6d67SJohan Hedberg 157140c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 157240c59fcbSMarcel Holtmann if (lmp_ping_capable(hdev)) 157340c59fcbSMarcel Holtmann events[2] |= 0x80; 157440c59fcbSMarcel Holtmann 1575d62e6d67SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 1576d62e6d67SJohan Hedberg } 1577d62e6d67SJohan Hedberg 157842c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 15792177bab5SJohan Hedberg { 158042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1581d2c5d77fSJohan Hedberg u8 p; 158242c6b129SJohan Hedberg 1583b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 1584b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 1585b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 1586b8f4e068SGustavo Padovan * 1587b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 1588b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 1589b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 1590b8f4e068SGustavo Padovan * command redundant anyway. 1591f9f462faSMarcel Holtmann * 1592f9f462faSMarcel Holtmann * Some controllers indicate that they support handling deleting 1593f9f462faSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 1594f9f462faSMarcel Holtmann * just disable this command. 1595b8f4e068SGustavo Padovan */ 1596f9f462faSMarcel Holtmann if (hdev->commands[6] & 0x80 && 1597f9f462faSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 159859f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 159959f45d57SJohan Hedberg 160059f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 160159f45d57SJohan Hedberg cp.delete_all = 0x01; 160259f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 160359f45d57SJohan Hedberg sizeof(cp), &cp); 160459f45d57SJohan Hedberg } 160559f45d57SJohan Hedberg 16062177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 160742c6b129SJohan Hedberg hci_setup_link_policy(req); 16082177bab5SJohan Hedberg 16099193c6e8SAndre Guedes if (lmp_le_capable(hdev)) { 16109193c6e8SAndre Guedes u8 events[8]; 16119193c6e8SAndre Guedes 16129193c6e8SAndre Guedes memset(events, 0, sizeof(events)); 16139193c6e8SAndre Guedes events[0] = 0x1f; 1614662bc2e6SAndre Guedes 1615662bc2e6SAndre Guedes /* If controller supports the Connection Parameters Request 1616662bc2e6SAndre Guedes * Link Layer Procedure, enable the corresponding event. 1617662bc2e6SAndre Guedes */ 1618662bc2e6SAndre Guedes if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC) 1619662bc2e6SAndre Guedes events[0] |= 0x20; /* LE Remote Connection 1620662bc2e6SAndre Guedes * Parameter Request 1621662bc2e6SAndre Guedes */ 1622662bc2e6SAndre Guedes 16239193c6e8SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), 16249193c6e8SAndre Guedes events); 16259193c6e8SAndre Guedes 162642c6b129SJohan Hedberg hci_set_le_support(req); 16279193c6e8SAndre Guedes } 1628d2c5d77fSJohan Hedberg 1629d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 1630d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 1631d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 1632d2c5d77fSJohan Hedberg 1633d2c5d77fSJohan Hedberg cp.page = p; 1634d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 1635d2c5d77fSJohan Hedberg sizeof(cp), &cp); 1636d2c5d77fSJohan Hedberg } 16372177bab5SJohan Hedberg } 16382177bab5SJohan Hedberg 16395d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt) 16405d4e7e8dSJohan Hedberg { 16415d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 16425d4e7e8dSJohan Hedberg 1643d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 1644d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 1645d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 1646d62e6d67SJohan Hedberg 16475d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 164853b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 16495d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 1650a6d0d690SMarcel Holtmann 1651a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 16525afeac14SMarcel Holtmann if ((lmp_sc_capable(hdev) || 1653111902f7SMarcel Holtmann test_bit(HCI_FORCE_SC, &hdev->dbg_flags)) && 1654a6d0d690SMarcel Holtmann test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) { 1655a6d0d690SMarcel Holtmann u8 support = 0x01; 1656a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 1657a6d0d690SMarcel Holtmann sizeof(support), &support); 1658a6d0d690SMarcel Holtmann } 16595d4e7e8dSJohan Hedberg } 16605d4e7e8dSJohan Hedberg 16612177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 16622177bab5SJohan Hedberg { 16632177bab5SJohan Hedberg int err; 16642177bab5SJohan Hedberg 16652177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 16662177bab5SJohan Hedberg if (err < 0) 16672177bab5SJohan Hedberg return err; 16682177bab5SJohan Hedberg 16694b4148e9SMarcel Holtmann /* The Device Under Test (DUT) mode is special and available for 16704b4148e9SMarcel Holtmann * all controller types. So just create it early on. 16714b4148e9SMarcel Holtmann */ 16724b4148e9SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 16734b4148e9SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 16744b4148e9SMarcel Holtmann &dut_mode_fops); 16754b4148e9SMarcel Holtmann } 16764b4148e9SMarcel Holtmann 16772177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 16782177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 16792177bab5SJohan Hedberg * first stage init. 16802177bab5SJohan Hedberg */ 16812177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 16822177bab5SJohan Hedberg return 0; 16832177bab5SJohan Hedberg 16842177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 16852177bab5SJohan Hedberg if (err < 0) 16862177bab5SJohan Hedberg return err; 16872177bab5SJohan Hedberg 16885d4e7e8dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 16895d4e7e8dSJohan Hedberg if (err < 0) 16905d4e7e8dSJohan Hedberg return err; 16915d4e7e8dSJohan Hedberg 1692baf27f6eSMarcel Holtmann err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 1693baf27f6eSMarcel Holtmann if (err < 0) 1694baf27f6eSMarcel Holtmann return err; 1695baf27f6eSMarcel Holtmann 1696baf27f6eSMarcel Holtmann /* Only create debugfs entries during the initial setup 1697baf27f6eSMarcel Holtmann * phase and not every time the controller gets powered on. 1698baf27f6eSMarcel Holtmann */ 1699baf27f6eSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 1700baf27f6eSMarcel Holtmann return 0; 1701baf27f6eSMarcel Holtmann 1702dfb826a8SMarcel Holtmann debugfs_create_file("features", 0444, hdev->debugfs, hdev, 1703dfb826a8SMarcel Holtmann &features_fops); 1704ceeb3bc0SMarcel Holtmann debugfs_create_u16("manufacturer", 0444, hdev->debugfs, 1705ceeb3bc0SMarcel Holtmann &hdev->manufacturer); 1706ceeb3bc0SMarcel Holtmann debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); 1707ceeb3bc0SMarcel Holtmann debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); 170870afe0b8SMarcel Holtmann debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, 170970afe0b8SMarcel Holtmann &blacklist_fops); 171047219839SMarcel Holtmann debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); 171147219839SMarcel Holtmann 171231ad1691SAndrzej Kaczmarek debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev, 171331ad1691SAndrzej Kaczmarek &conn_info_min_age_fops); 171431ad1691SAndrzej Kaczmarek debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev, 171531ad1691SAndrzej Kaczmarek &conn_info_max_age_fops); 171631ad1691SAndrzej Kaczmarek 1717baf27f6eSMarcel Holtmann if (lmp_bredr_capable(hdev)) { 1718baf27f6eSMarcel Holtmann debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, 1719baf27f6eSMarcel Holtmann hdev, &inquiry_cache_fops); 172002d08d15SMarcel Holtmann debugfs_create_file("link_keys", 0400, hdev->debugfs, 172102d08d15SMarcel Holtmann hdev, &link_keys_fops); 1722babdbb3cSMarcel Holtmann debugfs_create_file("dev_class", 0444, hdev->debugfs, 1723babdbb3cSMarcel Holtmann hdev, &dev_class_fops); 1724041000b9SMarcel Holtmann debugfs_create_file("voice_setting", 0444, hdev->debugfs, 1725041000b9SMarcel Holtmann hdev, &voice_setting_fops); 1726baf27f6eSMarcel Holtmann } 1727baf27f6eSMarcel Holtmann 172806f5b778SMarcel Holtmann if (lmp_ssp_capable(hdev)) { 1729ebd1e33bSMarcel Holtmann debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, 1730ebd1e33bSMarcel Holtmann hdev, &auto_accept_delay_fops); 17315afeac14SMarcel Holtmann debugfs_create_file("force_sc_support", 0644, hdev->debugfs, 17325afeac14SMarcel Holtmann hdev, &force_sc_support_fops); 1733134c2a89SMarcel Holtmann debugfs_create_file("sc_only_mode", 0444, hdev->debugfs, 1734134c2a89SMarcel Holtmann hdev, &sc_only_mode_fops); 173506f5b778SMarcel Holtmann } 1736ebd1e33bSMarcel Holtmann 17372bfa3531SMarcel Holtmann if (lmp_sniff_capable(hdev)) { 17382bfa3531SMarcel Holtmann debugfs_create_file("idle_timeout", 0644, hdev->debugfs, 17392bfa3531SMarcel Holtmann hdev, &idle_timeout_fops); 17402bfa3531SMarcel Holtmann debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs, 17412bfa3531SMarcel Holtmann hdev, &sniff_min_interval_fops); 17422bfa3531SMarcel Holtmann debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs, 17432bfa3531SMarcel Holtmann hdev, &sniff_max_interval_fops); 17442bfa3531SMarcel Holtmann } 17452bfa3531SMarcel Holtmann 1746d0f729b8SMarcel Holtmann if (lmp_le_capable(hdev)) { 1747ac345813SMarcel Holtmann debugfs_create_file("identity", 0400, hdev->debugfs, 1748ac345813SMarcel Holtmann hdev, &identity_fops); 1749ac345813SMarcel Holtmann debugfs_create_file("rpa_timeout", 0644, hdev->debugfs, 1750ac345813SMarcel Holtmann hdev, &rpa_timeout_fops); 17517a4cd51dSMarcel Holtmann debugfs_create_file("random_address", 0444, hdev->debugfs, 17527a4cd51dSMarcel Holtmann hdev, &random_address_fops); 1753e7b8fc92SMarcel Holtmann debugfs_create_file("static_address", 0444, hdev->debugfs, 1754e7b8fc92SMarcel Holtmann hdev, &static_address_fops); 1755b32bba6cSMarcel Holtmann 1756b32bba6cSMarcel Holtmann /* For controllers with a public address, provide a debug 1757b32bba6cSMarcel Holtmann * option to force the usage of the configured static 1758b32bba6cSMarcel Holtmann * address. By default the public address is used. 1759b32bba6cSMarcel Holtmann */ 1760b32bba6cSMarcel Holtmann if (bacmp(&hdev->bdaddr, BDADDR_ANY)) 1761b32bba6cSMarcel Holtmann debugfs_create_file("force_static_address", 0644, 1762b32bba6cSMarcel Holtmann hdev->debugfs, hdev, 1763b32bba6cSMarcel Holtmann &force_static_address_fops); 1764b32bba6cSMarcel Holtmann 1765b32bba6cSMarcel Holtmann debugfs_create_u8("white_list_size", 0444, hdev->debugfs, 1766b32bba6cSMarcel Holtmann &hdev->le_white_list_size); 1767d2ab0ac1SMarcel Holtmann debugfs_create_file("white_list", 0444, hdev->debugfs, hdev, 1768d2ab0ac1SMarcel Holtmann &white_list_fops); 17693698d704SMarcel Holtmann debugfs_create_file("identity_resolving_keys", 0400, 17703698d704SMarcel Holtmann hdev->debugfs, hdev, 17713698d704SMarcel Holtmann &identity_resolving_keys_fops); 17728f8625cdSMarcel Holtmann debugfs_create_file("long_term_keys", 0400, hdev->debugfs, 17738f8625cdSMarcel Holtmann hdev, &long_term_keys_fops); 17744e70c7e7SMarcel Holtmann debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, 17754e70c7e7SMarcel Holtmann hdev, &conn_min_interval_fops); 17764e70c7e7SMarcel Holtmann debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, 17774e70c7e7SMarcel Holtmann hdev, &conn_max_interval_fops); 1778816a93d1SMarcel Holtmann debugfs_create_file("conn_latency", 0644, hdev->debugfs, 1779816a93d1SMarcel Holtmann hdev, &conn_latency_fops); 1780f1649577SMarcel Holtmann debugfs_create_file("supervision_timeout", 0644, hdev->debugfs, 1781f1649577SMarcel Holtmann hdev, &supervision_timeout_fops); 17823f959d46SMarcel Holtmann debugfs_create_file("adv_channel_map", 0644, hdev->debugfs, 17833f959d46SMarcel Holtmann hdev, &adv_channel_map_fops); 17840b3c7d37SMarcel Holtmann debugfs_create_file("device_list", 0444, hdev->debugfs, hdev, 17850b3c7d37SMarcel Holtmann &device_list_fops); 1786b9a7a61eSLukasz Rymanowski debugfs_create_u16("discov_interleaved_timeout", 0644, 1787b9a7a61eSLukasz Rymanowski hdev->debugfs, 1788b9a7a61eSLukasz Rymanowski &hdev->discov_interleaved_timeout); 1789d0f729b8SMarcel Holtmann } 1790e7b8fc92SMarcel Holtmann 1791baf27f6eSMarcel Holtmann return 0; 17922177bab5SJohan Hedberg } 17932177bab5SJohan Hedberg 179442c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 17951da177e4SLinus Torvalds { 17961da177e4SLinus Torvalds __u8 scan = opt; 17971da177e4SLinus Torvalds 179842c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 17991da177e4SLinus Torvalds 18001da177e4SLinus Torvalds /* Inquiry and Page scans */ 180142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 18021da177e4SLinus Torvalds } 18031da177e4SLinus Torvalds 180442c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 18051da177e4SLinus Torvalds { 18061da177e4SLinus Torvalds __u8 auth = opt; 18071da177e4SLinus Torvalds 180842c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 18091da177e4SLinus Torvalds 18101da177e4SLinus Torvalds /* Authentication */ 181142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 18121da177e4SLinus Torvalds } 18131da177e4SLinus Torvalds 181442c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 18151da177e4SLinus Torvalds { 18161da177e4SLinus Torvalds __u8 encrypt = opt; 18171da177e4SLinus Torvalds 181842c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 18191da177e4SLinus Torvalds 1820e4e8e37cSMarcel Holtmann /* Encryption */ 182142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 18221da177e4SLinus Torvalds } 18231da177e4SLinus Torvalds 182442c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 1825e4e8e37cSMarcel Holtmann { 1826e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1827e4e8e37cSMarcel Holtmann 182842c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1829e4e8e37cSMarcel Holtmann 1830e4e8e37cSMarcel Holtmann /* Default link policy */ 183142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1832e4e8e37cSMarcel Holtmann } 1833e4e8e37cSMarcel Holtmann 18341da177e4SLinus Torvalds /* Get HCI device by index. 18351da177e4SLinus Torvalds * Device is held on return. */ 18361da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 18371da177e4SLinus Torvalds { 18388035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 18391da177e4SLinus Torvalds 18401da177e4SLinus Torvalds BT_DBG("%d", index); 18411da177e4SLinus Torvalds 18421da177e4SLinus Torvalds if (index < 0) 18431da177e4SLinus Torvalds return NULL; 18441da177e4SLinus Torvalds 18451da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 18468035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 18471da177e4SLinus Torvalds if (d->id == index) { 18481da177e4SLinus Torvalds hdev = hci_dev_hold(d); 18491da177e4SLinus Torvalds break; 18501da177e4SLinus Torvalds } 18511da177e4SLinus Torvalds } 18521da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 18531da177e4SLinus Torvalds return hdev; 18541da177e4SLinus Torvalds } 18551da177e4SLinus Torvalds 18561da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1857ff9ef578SJohan Hedberg 185830dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 185930dc78e1SJohan Hedberg { 186030dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 186130dc78e1SJohan Hedberg 18626fbe195dSAndre Guedes switch (discov->state) { 1863343f935bSAndre Guedes case DISCOVERY_FINDING: 18646fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 186530dc78e1SJohan Hedberg return true; 186630dc78e1SJohan Hedberg 18676fbe195dSAndre Guedes default: 186830dc78e1SJohan Hedberg return false; 186930dc78e1SJohan Hedberg } 18706fbe195dSAndre Guedes } 187130dc78e1SJohan Hedberg 1872ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1873ff9ef578SJohan Hedberg { 1874ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1875ff9ef578SJohan Hedberg 1876ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 1877ff9ef578SJohan Hedberg return; 1878ff9ef578SJohan Hedberg 1879ff9ef578SJohan Hedberg switch (state) { 1880ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 1881c54c3860SAndre Guedes hci_update_background_scan(hdev); 1882c54c3860SAndre Guedes 18837b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 1884ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1885ff9ef578SJohan Hedberg break; 1886ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1887ff9ef578SJohan Hedberg break; 1888343f935bSAndre Guedes case DISCOVERY_FINDING: 1889ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1890ff9ef578SJohan Hedberg break; 189130dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 189230dc78e1SJohan Hedberg break; 1893ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1894ff9ef578SJohan Hedberg break; 1895ff9ef578SJohan Hedberg } 1896ff9ef578SJohan Hedberg 1897ff9ef578SJohan Hedberg hdev->discovery.state = state; 1898ff9ef578SJohan Hedberg } 1899ff9ef578SJohan Hedberg 19001f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 19011da177e4SLinus Torvalds { 190230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1903b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 19041da177e4SLinus Torvalds 1905561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1906561aafbcSJohan Hedberg list_del(&p->all); 1907b57c1a56SJohan Hedberg kfree(p); 19081da177e4SLinus Torvalds } 1909561aafbcSJohan Hedberg 1910561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1911561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 19121da177e4SLinus Torvalds } 19131da177e4SLinus Torvalds 1914a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1915a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 19161da177e4SLinus Torvalds { 191730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 19181da177e4SLinus Torvalds struct inquiry_entry *e; 19191da177e4SLinus Torvalds 19206ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 19211da177e4SLinus Torvalds 1922561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 19231da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 19241da177e4SLinus Torvalds return e; 19251da177e4SLinus Torvalds } 19261da177e4SLinus Torvalds 1927b57c1a56SJohan Hedberg return NULL; 1928b57c1a56SJohan Hedberg } 1929b57c1a56SJohan Hedberg 1930561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1931561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1932561aafbcSJohan Hedberg { 193330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1934561aafbcSJohan Hedberg struct inquiry_entry *e; 1935561aafbcSJohan Hedberg 19366ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1937561aafbcSJohan Hedberg 1938561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1939561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1940561aafbcSJohan Hedberg return e; 1941561aafbcSJohan Hedberg } 1942561aafbcSJohan Hedberg 1943561aafbcSJohan Hedberg return NULL; 1944561aafbcSJohan Hedberg } 1945561aafbcSJohan Hedberg 194630dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 194730dc78e1SJohan Hedberg bdaddr_t *bdaddr, 194830dc78e1SJohan Hedberg int state) 194930dc78e1SJohan Hedberg { 195030dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 195130dc78e1SJohan Hedberg struct inquiry_entry *e; 195230dc78e1SJohan Hedberg 19536ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 195430dc78e1SJohan Hedberg 195530dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 195630dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 195730dc78e1SJohan Hedberg return e; 195830dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 195930dc78e1SJohan Hedberg return e; 196030dc78e1SJohan Hedberg } 196130dc78e1SJohan Hedberg 196230dc78e1SJohan Hedberg return NULL; 196330dc78e1SJohan Hedberg } 196430dc78e1SJohan Hedberg 1965a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1966a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1967a3d4e20aSJohan Hedberg { 1968a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1969a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1970a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1971a3d4e20aSJohan Hedberg 1972a3d4e20aSJohan Hedberg list_del(&ie->list); 1973a3d4e20aSJohan Hedberg 1974a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1975a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1976a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1977a3d4e20aSJohan Hedberg break; 1978a3d4e20aSJohan Hedberg pos = &p->list; 1979a3d4e20aSJohan Hedberg } 1980a3d4e20aSJohan Hedberg 1981a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1982a3d4e20aSJohan Hedberg } 1983a3d4e20aSJohan Hedberg 1984af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1985af58925cSMarcel Holtmann bool name_known) 19861da177e4SLinus Torvalds { 198730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 198870f23020SAndrei Emeltchenko struct inquiry_entry *ie; 1989af58925cSMarcel Holtmann u32 flags = 0; 19901da177e4SLinus Torvalds 19916ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 19921da177e4SLinus Torvalds 19932b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 19942b2fec4dSSzymon Janc 1995af58925cSMarcel Holtmann if (!data->ssp_mode) 1996af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1997388fc8faSJohan Hedberg 199870f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1999a3d4e20aSJohan Hedberg if (ie) { 2000af58925cSMarcel Holtmann if (!ie->data.ssp_mode) 2001af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 2002388fc8faSJohan Hedberg 2003a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 2004a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 2005a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 2006a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 2007a3d4e20aSJohan Hedberg } 2008a3d4e20aSJohan Hedberg 2009561aafbcSJohan Hedberg goto update; 2010a3d4e20aSJohan Hedberg } 2011561aafbcSJohan Hedberg 20121da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 201370f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 2014af58925cSMarcel Holtmann if (!ie) { 2015af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 2016af58925cSMarcel Holtmann goto done; 2017af58925cSMarcel Holtmann } 201870f23020SAndrei Emeltchenko 2019561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 2020561aafbcSJohan Hedberg 2021561aafbcSJohan Hedberg if (name_known) { 2022561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 2023561aafbcSJohan Hedberg } else { 2024561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 2025561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 2026561aafbcSJohan Hedberg } 2027561aafbcSJohan Hedberg 2028561aafbcSJohan Hedberg update: 2029561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 2030561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 2031561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 2032561aafbcSJohan Hedberg list_del(&ie->list); 20331da177e4SLinus Torvalds } 20341da177e4SLinus Torvalds 203570f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 203670f23020SAndrei Emeltchenko ie->timestamp = jiffies; 20371da177e4SLinus Torvalds cache->timestamp = jiffies; 20383175405bSJohan Hedberg 20393175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 2040af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 20413175405bSJohan Hedberg 2042af58925cSMarcel Holtmann done: 2043af58925cSMarcel Holtmann return flags; 20441da177e4SLinus Torvalds } 20451da177e4SLinus Torvalds 20461da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 20471da177e4SLinus Torvalds { 204830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 20491da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 20501da177e4SLinus Torvalds struct inquiry_entry *e; 20511da177e4SLinus Torvalds int copied = 0; 20521da177e4SLinus Torvalds 2053561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 20541da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 2055b57c1a56SJohan Hedberg 2056b57c1a56SJohan Hedberg if (copied >= num) 2057b57c1a56SJohan Hedberg break; 2058b57c1a56SJohan Hedberg 20591da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 20601da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 20611da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 20621da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 20631da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 20641da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 2065b57c1a56SJohan Hedberg 20661da177e4SLinus Torvalds info++; 2067b57c1a56SJohan Hedberg copied++; 20681da177e4SLinus Torvalds } 20691da177e4SLinus Torvalds 20701da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 20711da177e4SLinus Torvalds return copied; 20721da177e4SLinus Torvalds } 20731da177e4SLinus Torvalds 207442c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 20751da177e4SLinus Torvalds { 20761da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 207742c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 20781da177e4SLinus Torvalds struct hci_cp_inquiry cp; 20791da177e4SLinus Torvalds 20801da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 20811da177e4SLinus Torvalds 20821da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 20831da177e4SLinus Torvalds return; 20841da177e4SLinus Torvalds 20851da177e4SLinus Torvalds /* Start Inquiry */ 20861da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 20871da177e4SLinus Torvalds cp.length = ir->length; 20881da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 208942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 20901da177e4SLinus Torvalds } 20911da177e4SLinus Torvalds 20923e13fa1eSAndre Guedes static int wait_inquiry(void *word) 20933e13fa1eSAndre Guedes { 20943e13fa1eSAndre Guedes schedule(); 20953e13fa1eSAndre Guedes return signal_pending(current); 20963e13fa1eSAndre Guedes } 20973e13fa1eSAndre Guedes 20981da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 20991da177e4SLinus Torvalds { 21001da177e4SLinus Torvalds __u8 __user *ptr = arg; 21011da177e4SLinus Torvalds struct hci_inquiry_req ir; 21021da177e4SLinus Torvalds struct hci_dev *hdev; 21031da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 21041da177e4SLinus Torvalds long timeo; 21051da177e4SLinus Torvalds __u8 *buf; 21061da177e4SLinus Torvalds 21071da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 21081da177e4SLinus Torvalds return -EFAULT; 21091da177e4SLinus Torvalds 21105a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 21115a08ecceSAndrei Emeltchenko if (!hdev) 21121da177e4SLinus Torvalds return -ENODEV; 21131da177e4SLinus Torvalds 21140736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 21150736cfa8SMarcel Holtmann err = -EBUSY; 21160736cfa8SMarcel Holtmann goto done; 21170736cfa8SMarcel Holtmann } 21180736cfa8SMarcel Holtmann 2119fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) { 2120fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2121fee746b0SMarcel Holtmann goto done; 2122fee746b0SMarcel Holtmann } 2123fee746b0SMarcel Holtmann 21245b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 21255b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 21265b69bef5SMarcel Holtmann goto done; 21275b69bef5SMarcel Holtmann } 21285b69bef5SMarcel Holtmann 212956f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 213056f87901SJohan Hedberg err = -EOPNOTSUPP; 213156f87901SJohan Hedberg goto done; 213256f87901SJohan Hedberg } 213356f87901SJohan Hedberg 213409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 21351da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 2136a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 21371f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 21381da177e4SLinus Torvalds do_inquiry = 1; 21391da177e4SLinus Torvalds } 214009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 21411da177e4SLinus Torvalds 214204837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 214370f23020SAndrei Emeltchenko 214470f23020SAndrei Emeltchenko if (do_inquiry) { 214501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 214601178cd4SJohan Hedberg timeo); 214770f23020SAndrei Emeltchenko if (err < 0) 21481da177e4SLinus Torvalds goto done; 21493e13fa1eSAndre Guedes 21503e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 21513e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 21523e13fa1eSAndre Guedes */ 21533e13fa1eSAndre Guedes if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, 21543e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 21553e13fa1eSAndre Guedes return -EINTR; 215670f23020SAndrei Emeltchenko } 21571da177e4SLinus Torvalds 21588fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 21598fc9ced3SGustavo Padovan * 255 entries 21608fc9ced3SGustavo Padovan */ 21611da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 21621da177e4SLinus Torvalds 21631da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 21641da177e4SLinus Torvalds * copy it to the user space. 21651da177e4SLinus Torvalds */ 216670f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 216770f23020SAndrei Emeltchenko if (!buf) { 21681da177e4SLinus Torvalds err = -ENOMEM; 21691da177e4SLinus Torvalds goto done; 21701da177e4SLinus Torvalds } 21711da177e4SLinus Torvalds 217209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 21731da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 217409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 21751da177e4SLinus Torvalds 21761da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 21771da177e4SLinus Torvalds 21781da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 21791da177e4SLinus Torvalds ptr += sizeof(ir); 21801da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 21811da177e4SLinus Torvalds ir.num_rsp)) 21821da177e4SLinus Torvalds err = -EFAULT; 21831da177e4SLinus Torvalds } else 21841da177e4SLinus Torvalds err = -EFAULT; 21851da177e4SLinus Torvalds 21861da177e4SLinus Torvalds kfree(buf); 21871da177e4SLinus Torvalds 21881da177e4SLinus Torvalds done: 21891da177e4SLinus Torvalds hci_dev_put(hdev); 21901da177e4SLinus Torvalds return err; 21911da177e4SLinus Torvalds } 21921da177e4SLinus Torvalds 2193cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 21941da177e4SLinus Torvalds { 21951da177e4SLinus Torvalds int ret = 0; 21961da177e4SLinus Torvalds 21971da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 21981da177e4SLinus Torvalds 21991da177e4SLinus Torvalds hci_req_lock(hdev); 22001da177e4SLinus Torvalds 220194324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 220294324962SJohan Hovold ret = -ENODEV; 220394324962SJohan Hovold goto done; 220494324962SJohan Hovold } 220594324962SJohan Hovold 2206a5c8f270SMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 2207a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 2208a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 2209bf543036SJohan Hedberg */ 2210a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 2211611b30f7SMarcel Holtmann ret = -ERFKILL; 2212611b30f7SMarcel Holtmann goto done; 2213611b30f7SMarcel Holtmann } 2214611b30f7SMarcel Holtmann 2215a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 2216a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 2217a5c8f270SMarcel Holtmann * be able to determine if there is a public address 2218a5c8f270SMarcel Holtmann * or not. 2219a5c8f270SMarcel Holtmann * 2220c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 2221c6beca0eSMarcel Holtmann * if a public address or static random address is 2222c6beca0eSMarcel Holtmann * available. 2223c6beca0eSMarcel Holtmann * 2224a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 2225a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 2226a5c8f270SMarcel Holtmann */ 2227c6beca0eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 2228c6beca0eSMarcel Holtmann hdev->dev_type == HCI_BREDR && 2229a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2230a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 2231a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 2232a5c8f270SMarcel Holtmann goto done; 2233a5c8f270SMarcel Holtmann } 2234a5c8f270SMarcel Holtmann } 2235a5c8f270SMarcel Holtmann 22361da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 22371da177e4SLinus Torvalds ret = -EALREADY; 22381da177e4SLinus Torvalds goto done; 22391da177e4SLinus Torvalds } 22401da177e4SLinus Torvalds 22411da177e4SLinus Torvalds if (hdev->open(hdev)) { 22421da177e4SLinus Torvalds ret = -EIO; 22431da177e4SLinus Torvalds goto done; 22441da177e4SLinus Torvalds } 22451da177e4SLinus Torvalds 22461da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 22471da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 2248f41c70c4SMarcel Holtmann 2249f41c70c4SMarcel Holtmann if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags)) 2250f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 2251f41c70c4SMarcel Holtmann 225224c457e2SMarcel Holtmann /* If public address change is configured, ensure that the 225324c457e2SMarcel Holtmann * address gets programmed. If the driver does not support 225424c457e2SMarcel Holtmann * changing the public address, fail the power on procedure. 225524c457e2SMarcel Holtmann */ 225624c457e2SMarcel Holtmann if (!ret && bacmp(&hdev->public_addr, BDADDR_ANY)) { 225724c457e2SMarcel Holtmann if (hdev->set_bdaddr) 225824c457e2SMarcel Holtmann ret = hdev->set_bdaddr(hdev, &hdev->public_addr); 225924c457e2SMarcel Holtmann else 226024c457e2SMarcel Holtmann ret = -EADDRNOTAVAIL; 226124c457e2SMarcel Holtmann } 226224c457e2SMarcel Holtmann 2263f41c70c4SMarcel Holtmann if (!ret) { 2264fee746b0SMarcel Holtmann if (!test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks) && 22650736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 22662177bab5SJohan Hedberg ret = __hci_init(hdev); 22671da177e4SLinus Torvalds } 22681da177e4SLinus Torvalds 2269f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 2270f41c70c4SMarcel Holtmann 22711da177e4SLinus Torvalds if (!ret) { 22721da177e4SLinus Torvalds hci_dev_hold(hdev); 2273d6bfd59cSJohan Hedberg set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); 22741da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 22751da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 2276bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 22770736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 22781514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 227909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2280744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 228109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 228256e5cb86SJohan Hedberg } 22831da177e4SLinus Torvalds } else { 22841da177e4SLinus Torvalds /* Init failed, cleanup */ 22853eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2286c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 2287b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 22881da177e4SLinus Torvalds 22891da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 22901da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 22911da177e4SLinus Torvalds 22921da177e4SLinus Torvalds if (hdev->flush) 22931da177e4SLinus Torvalds hdev->flush(hdev); 22941da177e4SLinus Torvalds 22951da177e4SLinus Torvalds if (hdev->sent_cmd) { 22961da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 22971da177e4SLinus Torvalds hdev->sent_cmd = NULL; 22981da177e4SLinus Torvalds } 22991da177e4SLinus Torvalds 23001da177e4SLinus Torvalds hdev->close(hdev); 2301fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 23021da177e4SLinus Torvalds } 23031da177e4SLinus Torvalds 23041da177e4SLinus Torvalds done: 23051da177e4SLinus Torvalds hci_req_unlock(hdev); 23061da177e4SLinus Torvalds return ret; 23071da177e4SLinus Torvalds } 23081da177e4SLinus Torvalds 2309cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 2310cbed0ca1SJohan Hedberg 2311cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 2312cbed0ca1SJohan Hedberg { 2313cbed0ca1SJohan Hedberg struct hci_dev *hdev; 2314cbed0ca1SJohan Hedberg int err; 2315cbed0ca1SJohan Hedberg 2316cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 2317cbed0ca1SJohan Hedberg if (!hdev) 2318cbed0ca1SJohan Hedberg return -ENODEV; 2319cbed0ca1SJohan Hedberg 2320fee746b0SMarcel Holtmann /* Devices that are marked for raw-only usage can only be powered 2321fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices 2322fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is 2323fee746b0SMarcel Holtmann * possible. 2324fee746b0SMarcel Holtmann * 2325fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag 2326fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to 2327fee746b0SMarcel Holtmann * open the device. 2328fee746b0SMarcel Holtmann */ 2329fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks) && 2330fee746b0SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 2331fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2332fee746b0SMarcel Holtmann goto done; 2333fee746b0SMarcel Holtmann } 2334fee746b0SMarcel Holtmann 2335e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 2336e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 2337e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 2338e1d08f40SJohan Hedberg * completed. 2339e1d08f40SJohan Hedberg */ 2340e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2341e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 2342e1d08f40SJohan Hedberg 2343a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 2344a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 2345a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 2346a5c8f270SMarcel Holtmann */ 2347e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 2348e1d08f40SJohan Hedberg 2349cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 2350cbed0ca1SJohan Hedberg 2351fee746b0SMarcel Holtmann done: 2352cbed0ca1SJohan Hedberg hci_dev_put(hdev); 2353cbed0ca1SJohan Hedberg return err; 2354cbed0ca1SJohan Hedberg } 2355cbed0ca1SJohan Hedberg 23561da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 23571da177e4SLinus Torvalds { 23581da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 23591da177e4SLinus Torvalds 236078c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 236178c04c0bSVinicius Costa Gomes 23621da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 23631da177e4SLinus Torvalds hci_req_lock(hdev); 23641da177e4SLinus Torvalds 23651da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 236665cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 23671da177e4SLinus Torvalds hci_req_unlock(hdev); 23681da177e4SLinus Torvalds return 0; 23691da177e4SLinus Torvalds } 23701da177e4SLinus Torvalds 23713eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 23723eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2373b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 23741da177e4SLinus Torvalds 237516ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 2376e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 237716ab91abSJohan Hedberg hdev->discov_timeout = 0; 23785e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 2379310a3d48SMarcel Holtmann clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 238016ab91abSJohan Hedberg } 238116ab91abSJohan Hedberg 2382a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 23837d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 23847d78525dSJohan Hedberg 23857ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 23864518bb0fSJohan Hedberg 23874518bb0fSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 2388d6bfd59cSJohan Hedberg cancel_delayed_work_sync(&hdev->rpa_expired); 23897ba8b4beSAndre Guedes 239009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 23911f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 23921da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 23936046dc3eSAndre Guedes hci_pend_le_conns_clear(hdev); 239409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 23951da177e4SLinus Torvalds 23961da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 23971da177e4SLinus Torvalds 23981da177e4SLinus Torvalds if (hdev->flush) 23991da177e4SLinus Torvalds hdev->flush(hdev); 24001da177e4SLinus Torvalds 24011da177e4SLinus Torvalds /* Reset device */ 24021da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 24031da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 2404fee746b0SMarcel Holtmann if (!test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks) && 24053a6afbd2SMarcel Holtmann !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 2406a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 24071da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 240801178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 24091da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 24101da177e4SLinus Torvalds } 24111da177e4SLinus Torvalds 2412c347b765SGustavo F. Padovan /* flush cmd work */ 2413c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 24141da177e4SLinus Torvalds 24151da177e4SLinus Torvalds /* Drop queues */ 24161da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 24171da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 24181da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 24191da177e4SLinus Torvalds 24201da177e4SLinus Torvalds /* Drop last sent command */ 24211da177e4SLinus Torvalds if (hdev->sent_cmd) { 242265cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 24231da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 24241da177e4SLinus Torvalds hdev->sent_cmd = NULL; 24251da177e4SLinus Torvalds } 24261da177e4SLinus Torvalds 2427b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 2428b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 2429b6ddb638SJohan Hedberg 24301da177e4SLinus Torvalds /* After this point our queues are empty 24311da177e4SLinus Torvalds * and no tasks are scheduled. */ 24321da177e4SLinus Torvalds hdev->close(hdev); 24331da177e4SLinus Torvalds 243435b973c9SJohan Hedberg /* Clear flags */ 2435fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 243635b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 243735b973c9SJohan Hedberg 243893c311a0SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 243993c311a0SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 244009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2441744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 244209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 24438ee56540SMarcel Holtmann } 244493c311a0SMarcel Holtmann } 24455add6af8SJohan Hedberg 2446ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 2447536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 2448ced5c338SAndrei Emeltchenko 2449e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 245009b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 24517a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, BDADDR_ANY); 2452e59fda8dSJohan Hedberg 24531da177e4SLinus Torvalds hci_req_unlock(hdev); 24541da177e4SLinus Torvalds 24551da177e4SLinus Torvalds hci_dev_put(hdev); 24561da177e4SLinus Torvalds return 0; 24571da177e4SLinus Torvalds } 24581da177e4SLinus Torvalds 24591da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 24601da177e4SLinus Torvalds { 24611da177e4SLinus Torvalds struct hci_dev *hdev; 24621da177e4SLinus Torvalds int err; 24631da177e4SLinus Torvalds 246470f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 246570f23020SAndrei Emeltchenko if (!hdev) 24661da177e4SLinus Torvalds return -ENODEV; 24678ee56540SMarcel Holtmann 24680736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 24690736cfa8SMarcel Holtmann err = -EBUSY; 24700736cfa8SMarcel Holtmann goto done; 24710736cfa8SMarcel Holtmann } 24720736cfa8SMarcel Holtmann 24738ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 24748ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 24758ee56540SMarcel Holtmann 24761da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 24778ee56540SMarcel Holtmann 24780736cfa8SMarcel Holtmann done: 24791da177e4SLinus Torvalds hci_dev_put(hdev); 24801da177e4SLinus Torvalds return err; 24811da177e4SLinus Torvalds } 24821da177e4SLinus Torvalds 24831da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 24841da177e4SLinus Torvalds { 24851da177e4SLinus Torvalds struct hci_dev *hdev; 24861da177e4SLinus Torvalds int ret = 0; 24871da177e4SLinus Torvalds 248870f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 248970f23020SAndrei Emeltchenko if (!hdev) 24901da177e4SLinus Torvalds return -ENODEV; 24911da177e4SLinus Torvalds 24921da177e4SLinus Torvalds hci_req_lock(hdev); 24931da177e4SLinus Torvalds 2494808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 2495808a049eSMarcel Holtmann ret = -ENETDOWN; 24961da177e4SLinus Torvalds goto done; 2497808a049eSMarcel Holtmann } 24981da177e4SLinus Torvalds 24990736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 25000736cfa8SMarcel Holtmann ret = -EBUSY; 25010736cfa8SMarcel Holtmann goto done; 25020736cfa8SMarcel Holtmann } 25030736cfa8SMarcel Holtmann 2504fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) { 2505fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 2506fee746b0SMarcel Holtmann goto done; 2507fee746b0SMarcel Holtmann } 2508fee746b0SMarcel Holtmann 25091da177e4SLinus Torvalds /* Drop queues */ 25101da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 25111da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 25121da177e4SLinus Torvalds 251309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 25141f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 25151da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 251609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 25171da177e4SLinus Torvalds 25181da177e4SLinus Torvalds if (hdev->flush) 25191da177e4SLinus Torvalds hdev->flush(hdev); 25201da177e4SLinus Torvalds 25211da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 25226ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 25231da177e4SLinus Torvalds 252401178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 25251da177e4SLinus Torvalds 25261da177e4SLinus Torvalds done: 25271da177e4SLinus Torvalds hci_req_unlock(hdev); 25281da177e4SLinus Torvalds hci_dev_put(hdev); 25291da177e4SLinus Torvalds return ret; 25301da177e4SLinus Torvalds } 25311da177e4SLinus Torvalds 25321da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 25331da177e4SLinus Torvalds { 25341da177e4SLinus Torvalds struct hci_dev *hdev; 25351da177e4SLinus Torvalds int ret = 0; 25361da177e4SLinus Torvalds 253770f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 253870f23020SAndrei Emeltchenko if (!hdev) 25391da177e4SLinus Torvalds return -ENODEV; 25401da177e4SLinus Torvalds 25410736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 25420736cfa8SMarcel Holtmann ret = -EBUSY; 25430736cfa8SMarcel Holtmann goto done; 25440736cfa8SMarcel Holtmann } 25450736cfa8SMarcel Holtmann 2546fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) { 2547fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 2548fee746b0SMarcel Holtmann goto done; 2549fee746b0SMarcel Holtmann } 2550fee746b0SMarcel Holtmann 25511da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 25521da177e4SLinus Torvalds 25530736cfa8SMarcel Holtmann done: 25541da177e4SLinus Torvalds hci_dev_put(hdev); 25551da177e4SLinus Torvalds return ret; 25561da177e4SLinus Torvalds } 25571da177e4SLinus Torvalds 25581da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 25591da177e4SLinus Torvalds { 25601da177e4SLinus Torvalds struct hci_dev *hdev; 25611da177e4SLinus Torvalds struct hci_dev_req dr; 25621da177e4SLinus Torvalds int err = 0; 25631da177e4SLinus Torvalds 25641da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 25651da177e4SLinus Torvalds return -EFAULT; 25661da177e4SLinus Torvalds 256770f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 256870f23020SAndrei Emeltchenko if (!hdev) 25691da177e4SLinus Torvalds return -ENODEV; 25701da177e4SLinus Torvalds 25710736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 25720736cfa8SMarcel Holtmann err = -EBUSY; 25730736cfa8SMarcel Holtmann goto done; 25740736cfa8SMarcel Holtmann } 25750736cfa8SMarcel Holtmann 2576fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) { 2577fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2578fee746b0SMarcel Holtmann goto done; 2579fee746b0SMarcel Holtmann } 2580fee746b0SMarcel Holtmann 25815b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 25825b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 25835b69bef5SMarcel Holtmann goto done; 25845b69bef5SMarcel Holtmann } 25855b69bef5SMarcel Holtmann 258656f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 258756f87901SJohan Hedberg err = -EOPNOTSUPP; 258856f87901SJohan Hedberg goto done; 258956f87901SJohan Hedberg } 259056f87901SJohan Hedberg 25911da177e4SLinus Torvalds switch (cmd) { 25921da177e4SLinus Torvalds case HCISETAUTH: 259301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 25945f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 25951da177e4SLinus Torvalds break; 25961da177e4SLinus Torvalds 25971da177e4SLinus Torvalds case HCISETENCRYPT: 25981da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 25991da177e4SLinus Torvalds err = -EOPNOTSUPP; 26001da177e4SLinus Torvalds break; 26011da177e4SLinus Torvalds } 26021da177e4SLinus Torvalds 26031da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 26041da177e4SLinus Torvalds /* Auth must be enabled first */ 260501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 26065f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26071da177e4SLinus Torvalds if (err) 26081da177e4SLinus Torvalds break; 26091da177e4SLinus Torvalds } 26101da177e4SLinus Torvalds 261101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 26125f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26131da177e4SLinus Torvalds break; 26141da177e4SLinus Torvalds 26151da177e4SLinus Torvalds case HCISETSCAN: 261601178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 26175f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26181da177e4SLinus Torvalds break; 26191da177e4SLinus Torvalds 26201da177e4SLinus Torvalds case HCISETLINKPOL: 262101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 26225f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26231da177e4SLinus Torvalds break; 26241da177e4SLinus Torvalds 26251da177e4SLinus Torvalds case HCISETLINKMODE: 2626e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2627e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2628e4e8e37cSMarcel Holtmann break; 2629e4e8e37cSMarcel Holtmann 2630e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2631e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 26321da177e4SLinus Torvalds break; 26331da177e4SLinus Torvalds 26341da177e4SLinus Torvalds case HCISETACLMTU: 26351da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 26361da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 26371da177e4SLinus Torvalds break; 26381da177e4SLinus Torvalds 26391da177e4SLinus Torvalds case HCISETSCOMTU: 26401da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 26411da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 26421da177e4SLinus Torvalds break; 26431da177e4SLinus Torvalds 26441da177e4SLinus Torvalds default: 26451da177e4SLinus Torvalds err = -EINVAL; 26461da177e4SLinus Torvalds break; 26471da177e4SLinus Torvalds } 2648e4e8e37cSMarcel Holtmann 26490736cfa8SMarcel Holtmann done: 26501da177e4SLinus Torvalds hci_dev_put(hdev); 26511da177e4SLinus Torvalds return err; 26521da177e4SLinus Torvalds } 26531da177e4SLinus Torvalds 26541da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 26551da177e4SLinus Torvalds { 26568035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 26571da177e4SLinus Torvalds struct hci_dev_list_req *dl; 26581da177e4SLinus Torvalds struct hci_dev_req *dr; 26591da177e4SLinus Torvalds int n = 0, size, err; 26601da177e4SLinus Torvalds __u16 dev_num; 26611da177e4SLinus Torvalds 26621da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 26631da177e4SLinus Torvalds return -EFAULT; 26641da177e4SLinus Torvalds 26651da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 26661da177e4SLinus Torvalds return -EINVAL; 26671da177e4SLinus Torvalds 26681da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 26691da177e4SLinus Torvalds 267070f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 267170f23020SAndrei Emeltchenko if (!dl) 26721da177e4SLinus Torvalds return -ENOMEM; 26731da177e4SLinus Torvalds 26741da177e4SLinus Torvalds dr = dl->dev_req; 26751da177e4SLinus Torvalds 2676f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 26778035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 2678a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2679e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 2680c542a06cSJohan Hedberg 2681a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2682a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2683c542a06cSJohan Hedberg 26841da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 26851da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 2686c542a06cSJohan Hedberg 26871da177e4SLinus Torvalds if (++n >= dev_num) 26881da177e4SLinus Torvalds break; 26891da177e4SLinus Torvalds } 2690f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 26911da177e4SLinus Torvalds 26921da177e4SLinus Torvalds dl->dev_num = n; 26931da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 26941da177e4SLinus Torvalds 26951da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 26961da177e4SLinus Torvalds kfree(dl); 26971da177e4SLinus Torvalds 26981da177e4SLinus Torvalds return err ? -EFAULT : 0; 26991da177e4SLinus Torvalds } 27001da177e4SLinus Torvalds 27011da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 27021da177e4SLinus Torvalds { 27031da177e4SLinus Torvalds struct hci_dev *hdev; 27041da177e4SLinus Torvalds struct hci_dev_info di; 27051da177e4SLinus Torvalds int err = 0; 27061da177e4SLinus Torvalds 27071da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 27081da177e4SLinus Torvalds return -EFAULT; 27091da177e4SLinus Torvalds 271070f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 271170f23020SAndrei Emeltchenko if (!hdev) 27121da177e4SLinus Torvalds return -ENODEV; 27131da177e4SLinus Torvalds 2714a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 27153243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 2716ab81cbf9SJohan Hedberg 2717a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2718a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2719c542a06cSJohan Hedberg 27201da177e4SLinus Torvalds strcpy(di.name, hdev->name); 27211da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 272260f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 27231da177e4SLinus Torvalds di.flags = hdev->flags; 27241da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2725572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 27261da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 27271da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 27281da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 27291da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2730572c7f84SJohan Hedberg } else { 2731572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2732572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2733572c7f84SJohan Hedberg di.sco_mtu = 0; 2734572c7f84SJohan Hedberg di.sco_pkts = 0; 2735572c7f84SJohan Hedberg } 27361da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 27371da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 27381da177e4SLinus Torvalds 27391da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 27401da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 27411da177e4SLinus Torvalds 27421da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 27431da177e4SLinus Torvalds err = -EFAULT; 27441da177e4SLinus Torvalds 27451da177e4SLinus Torvalds hci_dev_put(hdev); 27461da177e4SLinus Torvalds 27471da177e4SLinus Torvalds return err; 27481da177e4SLinus Torvalds } 27491da177e4SLinus Torvalds 27501da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 27511da177e4SLinus Torvalds 2752611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2753611b30f7SMarcel Holtmann { 2754611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2755611b30f7SMarcel Holtmann 2756611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2757611b30f7SMarcel Holtmann 27580736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 27590736cfa8SMarcel Holtmann return -EBUSY; 27600736cfa8SMarcel Holtmann 27615e130367SJohan Hedberg if (blocked) { 27625e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 2763bf543036SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 2764611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 27655e130367SJohan Hedberg } else { 27665e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 27675e130367SJohan Hedberg } 2768611b30f7SMarcel Holtmann 2769611b30f7SMarcel Holtmann return 0; 2770611b30f7SMarcel Holtmann } 2771611b30f7SMarcel Holtmann 2772611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2773611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2774611b30f7SMarcel Holtmann }; 2775611b30f7SMarcel Holtmann 2776ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2777ab81cbf9SJohan Hedberg { 2778ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 277996570ffcSJohan Hedberg int err; 2780ab81cbf9SJohan Hedberg 2781ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2782ab81cbf9SJohan Hedberg 2783cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 278496570ffcSJohan Hedberg if (err < 0) { 278596570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 2786ab81cbf9SJohan Hedberg return; 278796570ffcSJohan Hedberg } 2788ab81cbf9SJohan Hedberg 2789a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2790a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2791a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2792a5c8f270SMarcel Holtmann */ 2793a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 2794a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 2795a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2796a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2797bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2798bf543036SJohan Hedberg hci_dev_do_close(hdev); 2799bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 280019202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 280119202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2802bf543036SJohan Hedberg } 2803ab81cbf9SJohan Hedberg 2804fee746b0SMarcel Holtmann if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) { 2805fee746b0SMarcel Holtmann if (!test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 2806744cf19eSJohan Hedberg mgmt_index_added(hdev); 2807ab81cbf9SJohan Hedberg } 2808fee746b0SMarcel Holtmann } 2809ab81cbf9SJohan Hedberg 2810ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2811ab81cbf9SJohan Hedberg { 28123243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 28133243553fSJohan Hedberg power_off.work); 2814ab81cbf9SJohan Hedberg 2815ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2816ab81cbf9SJohan Hedberg 28178ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2818ab81cbf9SJohan Hedberg } 2819ab81cbf9SJohan Hedberg 282016ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 282116ab91abSJohan Hedberg { 282216ab91abSJohan Hedberg struct hci_dev *hdev; 282316ab91abSJohan Hedberg 282416ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 282516ab91abSJohan Hedberg 282616ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 282716ab91abSJohan Hedberg 2828d1967ff8SMarcel Holtmann mgmt_discoverable_timeout(hdev); 282916ab91abSJohan Hedberg } 283016ab91abSJohan Hedberg 283135f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 28322aeb9a1aSJohan Hedberg { 28334821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 28342aeb9a1aSJohan Hedberg 28354821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 28364821002cSJohan Hedberg list_del(&uuid->list); 28372aeb9a1aSJohan Hedberg kfree(uuid); 28382aeb9a1aSJohan Hedberg } 28392aeb9a1aSJohan Hedberg } 28402aeb9a1aSJohan Hedberg 284135f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 284255ed8ca1SJohan Hedberg { 284355ed8ca1SJohan Hedberg struct list_head *p, *n; 284455ed8ca1SJohan Hedberg 284555ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 284655ed8ca1SJohan Hedberg struct link_key *key; 284755ed8ca1SJohan Hedberg 284855ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 284955ed8ca1SJohan Hedberg 285055ed8ca1SJohan Hedberg list_del(p); 285155ed8ca1SJohan Hedberg kfree(key); 285255ed8ca1SJohan Hedberg } 285355ed8ca1SJohan Hedberg } 285455ed8ca1SJohan Hedberg 285535f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2856b899efafSVinicius Costa Gomes { 2857b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2858b899efafSVinicius Costa Gomes 2859b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2860b899efafSVinicius Costa Gomes list_del(&k->list); 2861b899efafSVinicius Costa Gomes kfree(k); 2862b899efafSVinicius Costa Gomes } 2863b899efafSVinicius Costa Gomes } 2864b899efafSVinicius Costa Gomes 2865970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2866970c4e46SJohan Hedberg { 2867970c4e46SJohan Hedberg struct smp_irk *k, *tmp; 2868970c4e46SJohan Hedberg 2869970c4e46SJohan Hedberg list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { 2870970c4e46SJohan Hedberg list_del(&k->list); 2871970c4e46SJohan Hedberg kfree(k); 2872970c4e46SJohan Hedberg } 2873970c4e46SJohan Hedberg } 2874970c4e46SJohan Hedberg 287555ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 287655ed8ca1SJohan Hedberg { 287755ed8ca1SJohan Hedberg struct link_key *k; 287855ed8ca1SJohan Hedberg 28798035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 288055ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 288155ed8ca1SJohan Hedberg return k; 288255ed8ca1SJohan Hedberg 288355ed8ca1SJohan Hedberg return NULL; 288455ed8ca1SJohan Hedberg } 288555ed8ca1SJohan Hedberg 2886745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2887d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2888d25e28abSJohan Hedberg { 2889d25e28abSJohan Hedberg /* Legacy key */ 2890d25e28abSJohan Hedberg if (key_type < 0x03) 2891745c0ce3SVishal Agarwal return true; 2892d25e28abSJohan Hedberg 2893d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2894d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2895745c0ce3SVishal Agarwal return false; 2896d25e28abSJohan Hedberg 2897d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2898d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2899745c0ce3SVishal Agarwal return false; 2900d25e28abSJohan Hedberg 2901d25e28abSJohan Hedberg /* Security mode 3 case */ 2902d25e28abSJohan Hedberg if (!conn) 2903745c0ce3SVishal Agarwal return true; 2904d25e28abSJohan Hedberg 2905d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2906d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2907745c0ce3SVishal Agarwal return true; 2908d25e28abSJohan Hedberg 2909d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2910d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2911745c0ce3SVishal Agarwal return true; 2912d25e28abSJohan Hedberg 2913d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2914d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2915745c0ce3SVishal Agarwal return true; 2916d25e28abSJohan Hedberg 2917d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2918d25e28abSJohan Hedberg * persistently */ 2919745c0ce3SVishal Agarwal return false; 2920d25e28abSJohan Hedberg } 2921d25e28abSJohan Hedberg 292298a0b845SJohan Hedberg static bool ltk_type_master(u8 type) 292398a0b845SJohan Hedberg { 2924d97c9fb0SJohan Hedberg return (type == SMP_LTK); 292598a0b845SJohan Hedberg } 292698a0b845SJohan Hedberg 2927fe39c7b2SMarcel Holtmann struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand, 292898a0b845SJohan Hedberg bool master) 292975d262c2SVinicius Costa Gomes { 2930c9839a11SVinicius Costa Gomes struct smp_ltk *k; 293175d262c2SVinicius Costa Gomes 2932c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 2933fe39c7b2SMarcel Holtmann if (k->ediv != ediv || k->rand != rand) 293475d262c2SVinicius Costa Gomes continue; 293575d262c2SVinicius Costa Gomes 293698a0b845SJohan Hedberg if (ltk_type_master(k->type) != master) 293798a0b845SJohan Hedberg continue; 293898a0b845SJohan Hedberg 293975d262c2SVinicius Costa Gomes return k; 294075d262c2SVinicius Costa Gomes } 294175d262c2SVinicius Costa Gomes 294275d262c2SVinicius Costa Gomes return NULL; 294375d262c2SVinicius Costa Gomes } 294475d262c2SVinicius Costa Gomes 2945c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 294698a0b845SJohan Hedberg u8 addr_type, bool master) 294775d262c2SVinicius Costa Gomes { 2948c9839a11SVinicius Costa Gomes struct smp_ltk *k; 294975d262c2SVinicius Costa Gomes 2950c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 2951c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 295298a0b845SJohan Hedberg bacmp(bdaddr, &k->bdaddr) == 0 && 295398a0b845SJohan Hedberg ltk_type_master(k->type) == master) 295475d262c2SVinicius Costa Gomes return k; 295575d262c2SVinicius Costa Gomes 295675d262c2SVinicius Costa Gomes return NULL; 295775d262c2SVinicius Costa Gomes } 295875d262c2SVinicius Costa Gomes 2959970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 2960970c4e46SJohan Hedberg { 2961970c4e46SJohan Hedberg struct smp_irk *irk; 2962970c4e46SJohan Hedberg 2963970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2964970c4e46SJohan Hedberg if (!bacmp(&irk->rpa, rpa)) 2965970c4e46SJohan Hedberg return irk; 2966970c4e46SJohan Hedberg } 2967970c4e46SJohan Hedberg 2968970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2969970c4e46SJohan Hedberg if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) { 2970970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2971970c4e46SJohan Hedberg return irk; 2972970c4e46SJohan Hedberg } 2973970c4e46SJohan Hedberg } 2974970c4e46SJohan Hedberg 2975970c4e46SJohan Hedberg return NULL; 2976970c4e46SJohan Hedberg } 2977970c4e46SJohan Hedberg 2978970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2979970c4e46SJohan Hedberg u8 addr_type) 2980970c4e46SJohan Hedberg { 2981970c4e46SJohan Hedberg struct smp_irk *irk; 2982970c4e46SJohan Hedberg 29836cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 29846cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 29856cfc9988SJohan Hedberg return NULL; 29866cfc9988SJohan Hedberg 2987970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2988970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 2989970c4e46SJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) 2990970c4e46SJohan Hedberg return irk; 2991970c4e46SJohan Hedberg } 2992970c4e46SJohan Hedberg 2993970c4e46SJohan Hedberg return NULL; 2994970c4e46SJohan Hedberg } 2995970c4e46SJohan Hedberg 2996567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 29977652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 29987652ff6aSJohan Hedberg u8 pin_len, bool *persistent) 299955ed8ca1SJohan Hedberg { 300055ed8ca1SJohan Hedberg struct link_key *key, *old_key; 3001745c0ce3SVishal Agarwal u8 old_key_type; 300255ed8ca1SJohan Hedberg 300355ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 300455ed8ca1SJohan Hedberg if (old_key) { 300555ed8ca1SJohan Hedberg old_key_type = old_key->type; 300655ed8ca1SJohan Hedberg key = old_key; 300755ed8ca1SJohan Hedberg } else { 300812adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 30090a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 301055ed8ca1SJohan Hedberg if (!key) 3011567fa2aaSJohan Hedberg return NULL; 301255ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 301355ed8ca1SJohan Hedberg } 301455ed8ca1SJohan Hedberg 30156ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 301655ed8ca1SJohan Hedberg 3017d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 3018d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 3019d25e28abSJohan Hedberg * previous key */ 3020d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 3021a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 3022d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 3023655fe6ecSJohan Hedberg if (conn) 3024655fe6ecSJohan Hedberg conn->key_type = type; 3025655fe6ecSJohan Hedberg } 3026d25e28abSJohan Hedberg 302755ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 30289b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 302955ed8ca1SJohan Hedberg key->pin_len = pin_len; 303055ed8ca1SJohan Hedberg 3031b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 303255ed8ca1SJohan Hedberg key->type = old_key_type; 30334748fed2SJohan Hedberg else 30344748fed2SJohan Hedberg key->type = type; 30354748fed2SJohan Hedberg 30367652ff6aSJohan Hedberg if (persistent) 30377652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type, 30387652ff6aSJohan Hedberg old_key_type); 303955ed8ca1SJohan Hedberg 3040567fa2aaSJohan Hedberg return key; 304155ed8ca1SJohan Hedberg } 304255ed8ca1SJohan Hedberg 3043ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 304435d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 3045fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand) 304675d262c2SVinicius Costa Gomes { 3047c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 304898a0b845SJohan Hedberg bool master = ltk_type_master(type); 304975d262c2SVinicius Costa Gomes 305098a0b845SJohan Hedberg old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master); 3051c9839a11SVinicius Costa Gomes if (old_key) 305275d262c2SVinicius Costa Gomes key = old_key; 3053c9839a11SVinicius Costa Gomes else { 30540a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 305575d262c2SVinicius Costa Gomes if (!key) 3056ca9142b8SJohan Hedberg return NULL; 3057c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 305875d262c2SVinicius Costa Gomes } 305975d262c2SVinicius Costa Gomes 306075d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 3061c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 3062c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 3063c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 3064c9839a11SVinicius Costa Gomes key->ediv = ediv; 3065fe39c7b2SMarcel Holtmann key->rand = rand; 3066c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 3067c9839a11SVinicius Costa Gomes key->type = type; 306875d262c2SVinicius Costa Gomes 3069ca9142b8SJohan Hedberg return key; 307075d262c2SVinicius Costa Gomes } 307175d262c2SVinicius Costa Gomes 3072ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 3073ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 3074970c4e46SJohan Hedberg { 3075970c4e46SJohan Hedberg struct smp_irk *irk; 3076970c4e46SJohan Hedberg 3077970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 3078970c4e46SJohan Hedberg if (!irk) { 3079970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 3080970c4e46SJohan Hedberg if (!irk) 3081ca9142b8SJohan Hedberg return NULL; 3082970c4e46SJohan Hedberg 3083970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 3084970c4e46SJohan Hedberg irk->addr_type = addr_type; 3085970c4e46SJohan Hedberg 3086970c4e46SJohan Hedberg list_add(&irk->list, &hdev->identity_resolving_keys); 3087970c4e46SJohan Hedberg } 3088970c4e46SJohan Hedberg 3089970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 3090970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 3091970c4e46SJohan Hedberg 3092ca9142b8SJohan Hedberg return irk; 3093970c4e46SJohan Hedberg } 3094970c4e46SJohan Hedberg 309555ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 309655ed8ca1SJohan Hedberg { 309755ed8ca1SJohan Hedberg struct link_key *key; 309855ed8ca1SJohan Hedberg 309955ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 310055ed8ca1SJohan Hedberg if (!key) 310155ed8ca1SJohan Hedberg return -ENOENT; 310255ed8ca1SJohan Hedberg 31036ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 310455ed8ca1SJohan Hedberg 310555ed8ca1SJohan Hedberg list_del(&key->list); 310655ed8ca1SJohan Hedberg kfree(key); 310755ed8ca1SJohan Hedberg 310855ed8ca1SJohan Hedberg return 0; 310955ed8ca1SJohan Hedberg } 311055ed8ca1SJohan Hedberg 3111e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 3112b899efafSVinicius Costa Gomes { 3113b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 3114c51ffa0bSJohan Hedberg int removed = 0; 3115b899efafSVinicius Costa Gomes 3116b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 3117e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 3118b899efafSVinicius Costa Gomes continue; 3119b899efafSVinicius Costa Gomes 31206ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 3121b899efafSVinicius Costa Gomes 3122b899efafSVinicius Costa Gomes list_del(&k->list); 3123b899efafSVinicius Costa Gomes kfree(k); 3124c51ffa0bSJohan Hedberg removed++; 3125b899efafSVinicius Costa Gomes } 3126b899efafSVinicius Costa Gomes 3127c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 3128b899efafSVinicius Costa Gomes } 3129b899efafSVinicius Costa Gomes 3130a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 3131a7ec7338SJohan Hedberg { 3132a7ec7338SJohan Hedberg struct smp_irk *k, *tmp; 3133a7ec7338SJohan Hedberg 3134668b7b19SJohan Hedberg list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { 3135a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 3136a7ec7338SJohan Hedberg continue; 3137a7ec7338SJohan Hedberg 3138a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 3139a7ec7338SJohan Hedberg 3140a7ec7338SJohan Hedberg list_del(&k->list); 3141a7ec7338SJohan Hedberg kfree(k); 3142a7ec7338SJohan Hedberg } 3143a7ec7338SJohan Hedberg } 3144a7ec7338SJohan Hedberg 31456bd32326SVille Tervo /* HCI command timer function */ 314665cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work) 31476bd32326SVille Tervo { 314865cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, 314965cc2b49SMarcel Holtmann cmd_timer.work); 31506bd32326SVille Tervo 3151bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 3152bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 3153bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 3154bda4f23aSAndrei Emeltchenko 3155bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 3156bda4f23aSAndrei Emeltchenko } else { 31576bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 3158bda4f23aSAndrei Emeltchenko } 3159bda4f23aSAndrei Emeltchenko 31606bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 3161c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 31626bd32326SVille Tervo } 31636bd32326SVille Tervo 31642763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 31652763eda6SSzymon Janc bdaddr_t *bdaddr) 31662763eda6SSzymon Janc { 31672763eda6SSzymon Janc struct oob_data *data; 31682763eda6SSzymon Janc 31692763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 31702763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 31712763eda6SSzymon Janc return data; 31722763eda6SSzymon Janc 31732763eda6SSzymon Janc return NULL; 31742763eda6SSzymon Janc } 31752763eda6SSzymon Janc 31762763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 31772763eda6SSzymon Janc { 31782763eda6SSzymon Janc struct oob_data *data; 31792763eda6SSzymon Janc 31802763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 31812763eda6SSzymon Janc if (!data) 31822763eda6SSzymon Janc return -ENOENT; 31832763eda6SSzymon Janc 31846ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 31852763eda6SSzymon Janc 31862763eda6SSzymon Janc list_del(&data->list); 31872763eda6SSzymon Janc kfree(data); 31882763eda6SSzymon Janc 31892763eda6SSzymon Janc return 0; 31902763eda6SSzymon Janc } 31912763eda6SSzymon Janc 319235f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 31932763eda6SSzymon Janc { 31942763eda6SSzymon Janc struct oob_data *data, *n; 31952763eda6SSzymon Janc 31962763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 31972763eda6SSzymon Janc list_del(&data->list); 31982763eda6SSzymon Janc kfree(data); 31992763eda6SSzymon Janc } 32002763eda6SSzymon Janc } 32012763eda6SSzymon Janc 32020798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 32030798872eSMarcel Holtmann u8 *hash, u8 *randomizer) 32042763eda6SSzymon Janc { 32052763eda6SSzymon Janc struct oob_data *data; 32062763eda6SSzymon Janc 32072763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 32082763eda6SSzymon Janc if (!data) { 32090a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 32102763eda6SSzymon Janc if (!data) 32112763eda6SSzymon Janc return -ENOMEM; 32122763eda6SSzymon Janc 32132763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 32142763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 32152763eda6SSzymon Janc } 32162763eda6SSzymon Janc 3217519ca9d0SMarcel Holtmann memcpy(data->hash192, hash, sizeof(data->hash192)); 3218519ca9d0SMarcel Holtmann memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192)); 32192763eda6SSzymon Janc 32200798872eSMarcel Holtmann memset(data->hash256, 0, sizeof(data->hash256)); 32210798872eSMarcel Holtmann memset(data->randomizer256, 0, sizeof(data->randomizer256)); 32220798872eSMarcel Holtmann 32230798872eSMarcel Holtmann BT_DBG("%s for %pMR", hdev->name, bdaddr); 32240798872eSMarcel Holtmann 32250798872eSMarcel Holtmann return 0; 32260798872eSMarcel Holtmann } 32270798872eSMarcel Holtmann 32280798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 32290798872eSMarcel Holtmann u8 *hash192, u8 *randomizer192, 32300798872eSMarcel Holtmann u8 *hash256, u8 *randomizer256) 32310798872eSMarcel Holtmann { 32320798872eSMarcel Holtmann struct oob_data *data; 32330798872eSMarcel Holtmann 32340798872eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, bdaddr); 32350798872eSMarcel Holtmann if (!data) { 32360a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 32370798872eSMarcel Holtmann if (!data) 32380798872eSMarcel Holtmann return -ENOMEM; 32390798872eSMarcel Holtmann 32400798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 32410798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 32420798872eSMarcel Holtmann } 32430798872eSMarcel Holtmann 32440798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 32450798872eSMarcel Holtmann memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192)); 32460798872eSMarcel Holtmann 32470798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 32480798872eSMarcel Holtmann memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256)); 32490798872eSMarcel Holtmann 32506ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 32512763eda6SSzymon Janc 32522763eda6SSzymon Janc return 0; 32532763eda6SSzymon Janc } 32542763eda6SSzymon Janc 3255b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 3256b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 3257b2a66aadSAntti Julku { 3258b2a66aadSAntti Julku struct bdaddr_list *b; 3259b2a66aadSAntti Julku 3260b9ee0a78SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) { 3261b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3262b2a66aadSAntti Julku return b; 3263b9ee0a78SMarcel Holtmann } 3264b2a66aadSAntti Julku 3265b2a66aadSAntti Julku return NULL; 3266b2a66aadSAntti Julku } 3267b2a66aadSAntti Julku 3268c9507490SMarcel Holtmann static void hci_blacklist_clear(struct hci_dev *hdev) 3269b2a66aadSAntti Julku { 3270b2a66aadSAntti Julku struct list_head *p, *n; 3271b2a66aadSAntti Julku 3272b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 3273b9ee0a78SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 3274b2a66aadSAntti Julku 3275b2a66aadSAntti Julku list_del(p); 3276b2a66aadSAntti Julku kfree(b); 3277b2a66aadSAntti Julku } 3278b2a66aadSAntti Julku } 3279b2a66aadSAntti Julku 328088c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3281b2a66aadSAntti Julku { 3282b2a66aadSAntti Julku struct bdaddr_list *entry; 3283b2a66aadSAntti Julku 3284b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3285b2a66aadSAntti Julku return -EBADF; 3286b2a66aadSAntti Julku 3287b9ee0a78SMarcel Holtmann if (hci_blacklist_lookup(hdev, bdaddr, type)) 32885e762444SAntti Julku return -EEXIST; 3289b2a66aadSAntti Julku 3290b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 32915e762444SAntti Julku if (!entry) 32925e762444SAntti Julku return -ENOMEM; 3293b2a66aadSAntti Julku 3294b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 3295b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 3296b2a66aadSAntti Julku 3297b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 3298b2a66aadSAntti Julku 32992a8357f2SJohan Hedberg return 0; 3300b2a66aadSAntti Julku } 3301b2a66aadSAntti Julku 330288c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3303b2a66aadSAntti Julku { 3304b2a66aadSAntti Julku struct bdaddr_list *entry; 3305b2a66aadSAntti Julku 330635f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 330735f7498aSJohan Hedberg hci_blacklist_clear(hdev); 330835f7498aSJohan Hedberg return 0; 330935f7498aSJohan Hedberg } 3310b2a66aadSAntti Julku 3311b9ee0a78SMarcel Holtmann entry = hci_blacklist_lookup(hdev, bdaddr, type); 33121ec918ceSSzymon Janc if (!entry) 33135e762444SAntti Julku return -ENOENT; 3314b2a66aadSAntti Julku 3315b2a66aadSAntti Julku list_del(&entry->list); 3316b2a66aadSAntti Julku kfree(entry); 3317b2a66aadSAntti Julku 33182a8357f2SJohan Hedberg return 0; 3319b2a66aadSAntti Julku } 3320b2a66aadSAntti Julku 3321d2ab0ac1SMarcel Holtmann struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev, 3322d2ab0ac1SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 3323d2ab0ac1SMarcel Holtmann { 3324d2ab0ac1SMarcel Holtmann struct bdaddr_list *b; 3325d2ab0ac1SMarcel Holtmann 3326d2ab0ac1SMarcel Holtmann list_for_each_entry(b, &hdev->le_white_list, list) { 3327d2ab0ac1SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3328d2ab0ac1SMarcel Holtmann return b; 3329d2ab0ac1SMarcel Holtmann } 3330d2ab0ac1SMarcel Holtmann 3331d2ab0ac1SMarcel Holtmann return NULL; 3332d2ab0ac1SMarcel Holtmann } 3333d2ab0ac1SMarcel Holtmann 3334d2ab0ac1SMarcel Holtmann void hci_white_list_clear(struct hci_dev *hdev) 3335d2ab0ac1SMarcel Holtmann { 3336d2ab0ac1SMarcel Holtmann struct list_head *p, *n; 3337d2ab0ac1SMarcel Holtmann 3338d2ab0ac1SMarcel Holtmann list_for_each_safe(p, n, &hdev->le_white_list) { 3339d2ab0ac1SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 3340d2ab0ac1SMarcel Holtmann 3341d2ab0ac1SMarcel Holtmann list_del(p); 3342d2ab0ac1SMarcel Holtmann kfree(b); 3343d2ab0ac1SMarcel Holtmann } 3344d2ab0ac1SMarcel Holtmann } 3345d2ab0ac1SMarcel Holtmann 3346d2ab0ac1SMarcel Holtmann int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3347d2ab0ac1SMarcel Holtmann { 3348d2ab0ac1SMarcel Holtmann struct bdaddr_list *entry; 3349d2ab0ac1SMarcel Holtmann 3350d2ab0ac1SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3351d2ab0ac1SMarcel Holtmann return -EBADF; 3352d2ab0ac1SMarcel Holtmann 3353d2ab0ac1SMarcel Holtmann entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 3354d2ab0ac1SMarcel Holtmann if (!entry) 3355d2ab0ac1SMarcel Holtmann return -ENOMEM; 3356d2ab0ac1SMarcel Holtmann 3357d2ab0ac1SMarcel Holtmann bacpy(&entry->bdaddr, bdaddr); 3358d2ab0ac1SMarcel Holtmann entry->bdaddr_type = type; 3359d2ab0ac1SMarcel Holtmann 3360d2ab0ac1SMarcel Holtmann list_add(&entry->list, &hdev->le_white_list); 3361d2ab0ac1SMarcel Holtmann 3362d2ab0ac1SMarcel Holtmann return 0; 3363d2ab0ac1SMarcel Holtmann } 3364d2ab0ac1SMarcel Holtmann 3365d2ab0ac1SMarcel Holtmann int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3366d2ab0ac1SMarcel Holtmann { 3367d2ab0ac1SMarcel Holtmann struct bdaddr_list *entry; 3368d2ab0ac1SMarcel Holtmann 3369d2ab0ac1SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3370d2ab0ac1SMarcel Holtmann return -EBADF; 3371d2ab0ac1SMarcel Holtmann 3372d2ab0ac1SMarcel Holtmann entry = hci_white_list_lookup(hdev, bdaddr, type); 3373d2ab0ac1SMarcel Holtmann if (!entry) 3374d2ab0ac1SMarcel Holtmann return -ENOENT; 3375d2ab0ac1SMarcel Holtmann 3376d2ab0ac1SMarcel Holtmann list_del(&entry->list); 3377d2ab0ac1SMarcel Holtmann kfree(entry); 3378d2ab0ac1SMarcel Holtmann 3379d2ab0ac1SMarcel Holtmann return 0; 3380d2ab0ac1SMarcel Holtmann } 3381d2ab0ac1SMarcel Holtmann 338215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 338315819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 338415819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 338515819a70SAndre Guedes { 338615819a70SAndre Guedes struct hci_conn_params *params; 338715819a70SAndre Guedes 338815819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 338915819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 339015819a70SAndre Guedes params->addr_type == addr_type) { 339115819a70SAndre Guedes return params; 339215819a70SAndre Guedes } 339315819a70SAndre Guedes } 339415819a70SAndre Guedes 339515819a70SAndre Guedes return NULL; 339615819a70SAndre Guedes } 339715819a70SAndre Guedes 3398cef952ceSAndre Guedes static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type) 3399cef952ceSAndre Guedes { 3400cef952ceSAndre Guedes struct hci_conn *conn; 3401cef952ceSAndre Guedes 3402cef952ceSAndre Guedes conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr); 3403cef952ceSAndre Guedes if (!conn) 3404cef952ceSAndre Guedes return false; 3405cef952ceSAndre Guedes 3406cef952ceSAndre Guedes if (conn->dst_type != type) 3407cef952ceSAndre Guedes return false; 3408cef952ceSAndre Guedes 3409cef952ceSAndre Guedes if (conn->state != BT_CONNECTED) 3410cef952ceSAndre Guedes return false; 3411cef952ceSAndre Guedes 3412cef952ceSAndre Guedes return true; 3413cef952ceSAndre Guedes } 3414cef952ceSAndre Guedes 3415a9b0a04cSAndre Guedes static bool is_identity_address(bdaddr_t *addr, u8 addr_type) 3416a9b0a04cSAndre Guedes { 3417a9b0a04cSAndre Guedes if (addr_type == ADDR_LE_DEV_PUBLIC) 3418a9b0a04cSAndre Guedes return true; 3419a9b0a04cSAndre Guedes 3420a9b0a04cSAndre Guedes /* Check for Random Static address type */ 3421a9b0a04cSAndre Guedes if ((addr->b[5] & 0xc0) == 0xc0) 3422a9b0a04cSAndre Guedes return true; 3423a9b0a04cSAndre Guedes 3424a9b0a04cSAndre Guedes return false; 3425a9b0a04cSAndre Guedes } 3426a9b0a04cSAndre Guedes 342715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 34284b10966fSMarcel Holtmann struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev, 34294b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type) 34304b10966fSMarcel Holtmann { 34314b10966fSMarcel Holtmann struct bdaddr_list *entry; 34324b10966fSMarcel Holtmann 34334b10966fSMarcel Holtmann list_for_each_entry(entry, &hdev->pend_le_conns, list) { 34344b10966fSMarcel Holtmann if (bacmp(&entry->bdaddr, addr) == 0 && 34354b10966fSMarcel Holtmann entry->bdaddr_type == addr_type) 34364b10966fSMarcel Holtmann return entry; 34374b10966fSMarcel Holtmann } 34384b10966fSMarcel Holtmann 34394b10966fSMarcel Holtmann return NULL; 34404b10966fSMarcel Holtmann } 34414b10966fSMarcel Holtmann 34424b10966fSMarcel Holtmann /* This function requires the caller holds hdev->lock */ 34434b10966fSMarcel Holtmann void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 34444b10966fSMarcel Holtmann { 34454b10966fSMarcel Holtmann struct bdaddr_list *entry; 34464b10966fSMarcel Holtmann 34474b10966fSMarcel Holtmann entry = hci_pend_le_conn_lookup(hdev, addr, addr_type); 34484b10966fSMarcel Holtmann if (entry) 34494b10966fSMarcel Holtmann goto done; 34504b10966fSMarcel Holtmann 34514b10966fSMarcel Holtmann entry = kzalloc(sizeof(*entry), GFP_KERNEL); 34524b10966fSMarcel Holtmann if (!entry) { 34534b10966fSMarcel Holtmann BT_ERR("Out of memory"); 34544b10966fSMarcel Holtmann return; 34554b10966fSMarcel Holtmann } 34564b10966fSMarcel Holtmann 34574b10966fSMarcel Holtmann bacpy(&entry->bdaddr, addr); 34584b10966fSMarcel Holtmann entry->bdaddr_type = addr_type; 34594b10966fSMarcel Holtmann 34604b10966fSMarcel Holtmann list_add(&entry->list, &hdev->pend_le_conns); 34614b10966fSMarcel Holtmann 34624b10966fSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 34634b10966fSMarcel Holtmann 34644b10966fSMarcel Holtmann done: 34654b10966fSMarcel Holtmann hci_update_background_scan(hdev); 34664b10966fSMarcel Holtmann } 34674b10966fSMarcel Holtmann 34684b10966fSMarcel Holtmann /* This function requires the caller holds hdev->lock */ 34694b10966fSMarcel Holtmann void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 34704b10966fSMarcel Holtmann { 34714b10966fSMarcel Holtmann struct bdaddr_list *entry; 34724b10966fSMarcel Holtmann 34734b10966fSMarcel Holtmann entry = hci_pend_le_conn_lookup(hdev, addr, addr_type); 34744b10966fSMarcel Holtmann if (!entry) 34754b10966fSMarcel Holtmann goto done; 34764b10966fSMarcel Holtmann 34774b10966fSMarcel Holtmann list_del(&entry->list); 34784b10966fSMarcel Holtmann kfree(entry); 34794b10966fSMarcel Holtmann 34804b10966fSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 34814b10966fSMarcel Holtmann 34824b10966fSMarcel Holtmann done: 34834b10966fSMarcel Holtmann hci_update_background_scan(hdev); 34844b10966fSMarcel Holtmann } 34854b10966fSMarcel Holtmann 34864b10966fSMarcel Holtmann /* This function requires the caller holds hdev->lock */ 34874b10966fSMarcel Holtmann void hci_pend_le_conns_clear(struct hci_dev *hdev) 34884b10966fSMarcel Holtmann { 34894b10966fSMarcel Holtmann struct bdaddr_list *entry, *tmp; 34904b10966fSMarcel Holtmann 34914b10966fSMarcel Holtmann list_for_each_entry_safe(entry, tmp, &hdev->pend_le_conns, list) { 34924b10966fSMarcel Holtmann list_del(&entry->list); 34934b10966fSMarcel Holtmann kfree(entry); 34944b10966fSMarcel Holtmann } 34954b10966fSMarcel Holtmann 34964b10966fSMarcel Holtmann BT_DBG("All LE pending connections cleared"); 34971c1697c0SMarcel Holtmann 34981c1697c0SMarcel Holtmann hci_update_background_scan(hdev); 34994b10966fSMarcel Holtmann } 35004b10966fSMarcel Holtmann 35014b10966fSMarcel Holtmann /* This function requires the caller holds hdev->lock */ 350251d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 350351d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type) 3504bf5b3c8bSMarcel Holtmann { 3505bf5b3c8bSMarcel Holtmann struct hci_conn_params *params; 3506bf5b3c8bSMarcel Holtmann 3507bf5b3c8bSMarcel Holtmann if (!is_identity_address(addr, addr_type)) 350851d167c0SMarcel Holtmann return NULL; 3509bf5b3c8bSMarcel Holtmann 3510bf5b3c8bSMarcel Holtmann params = hci_conn_params_lookup(hdev, addr, addr_type); 3511bf5b3c8bSMarcel Holtmann if (params) 351251d167c0SMarcel Holtmann return params; 3513bf5b3c8bSMarcel Holtmann 3514bf5b3c8bSMarcel Holtmann params = kzalloc(sizeof(*params), GFP_KERNEL); 3515bf5b3c8bSMarcel Holtmann if (!params) { 3516bf5b3c8bSMarcel Holtmann BT_ERR("Out of memory"); 351751d167c0SMarcel Holtmann return NULL; 3518bf5b3c8bSMarcel Holtmann } 3519bf5b3c8bSMarcel Holtmann 3520bf5b3c8bSMarcel Holtmann bacpy(¶ms->addr, addr); 3521bf5b3c8bSMarcel Holtmann params->addr_type = addr_type; 3522bf5b3c8bSMarcel Holtmann 3523bf5b3c8bSMarcel Holtmann list_add(¶ms->list, &hdev->le_conn_params); 3524bf5b3c8bSMarcel Holtmann 3525bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval; 3526bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval; 3527bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency; 3528bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout; 3529bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED; 3530bf5b3c8bSMarcel Holtmann 3531bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 3532bf5b3c8bSMarcel Holtmann 353351d167c0SMarcel Holtmann return params; 3534bf5b3c8bSMarcel Holtmann } 3535bf5b3c8bSMarcel Holtmann 3536bf5b3c8bSMarcel Holtmann /* This function requires the caller holds hdev->lock */ 3537bf5b3c8bSMarcel Holtmann int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, 3538d06b50ceSMarcel Holtmann u8 auto_connect) 353915819a70SAndre Guedes { 354015819a70SAndre Guedes struct hci_conn_params *params; 354115819a70SAndre Guedes 35428c87aae1SMarcel Holtmann params = hci_conn_params_add(hdev, addr, addr_type); 35438c87aae1SMarcel Holtmann if (!params) 35448c87aae1SMarcel Holtmann return -EIO; 3545a9b0a04cSAndre Guedes 35469fcb18efSAndre Guedes params->auto_connect = auto_connect; 354715819a70SAndre Guedes 3548cef952ceSAndre Guedes switch (auto_connect) { 3549cef952ceSAndre Guedes case HCI_AUTO_CONN_DISABLED: 3550cef952ceSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 3551cef952ceSAndre Guedes hci_pend_le_conn_del(hdev, addr, addr_type); 3552cef952ceSAndre Guedes break; 3553cef952ceSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 3554cef952ceSAndre Guedes if (!is_connected(hdev, addr, addr_type)) 3555cef952ceSAndre Guedes hci_pend_le_conn_add(hdev, addr, addr_type); 3556cef952ceSAndre Guedes break; 3557cef952ceSAndre Guedes } 355815819a70SAndre Guedes 3559d06b50ceSMarcel Holtmann BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type, 3560d06b50ceSMarcel Holtmann auto_connect); 3561a9b0a04cSAndre Guedes 3562a9b0a04cSAndre Guedes return 0; 356315819a70SAndre Guedes } 356415819a70SAndre Guedes 356515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 356615819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 356715819a70SAndre Guedes { 356815819a70SAndre Guedes struct hci_conn_params *params; 356915819a70SAndre Guedes 357015819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 357115819a70SAndre Guedes if (!params) 357215819a70SAndre Guedes return; 357315819a70SAndre Guedes 3574cef952ceSAndre Guedes hci_pend_le_conn_del(hdev, addr, addr_type); 3575cef952ceSAndre Guedes 357615819a70SAndre Guedes list_del(¶ms->list); 357715819a70SAndre Guedes kfree(params); 357815819a70SAndre Guedes 357915819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 358015819a70SAndre Guedes } 358115819a70SAndre Guedes 358215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 358315819a70SAndre Guedes void hci_conn_params_clear(struct hci_dev *hdev) 358415819a70SAndre Guedes { 358515819a70SAndre Guedes struct hci_conn_params *params, *tmp; 358615819a70SAndre Guedes 358715819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 358815819a70SAndre Guedes list_del(¶ms->list); 358915819a70SAndre Guedes kfree(params); 359015819a70SAndre Guedes } 359115819a70SAndre Guedes 35921089b67dSMarcel Holtmann hci_pend_le_conns_clear(hdev); 35931089b67dSMarcel Holtmann 359415819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 359515819a70SAndre Guedes } 359615819a70SAndre Guedes 35974c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 35987ba8b4beSAndre Guedes { 35994c87eaabSAndre Guedes if (status) { 36004c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 36017ba8b4beSAndre Guedes 36024c87eaabSAndre Guedes hci_dev_lock(hdev); 36034c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 36044c87eaabSAndre Guedes hci_dev_unlock(hdev); 36054c87eaabSAndre Guedes return; 36064c87eaabSAndre Guedes } 36077ba8b4beSAndre Guedes } 36087ba8b4beSAndre Guedes 36094c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 36107ba8b4beSAndre Guedes { 36114c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 36124c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 36134c87eaabSAndre Guedes struct hci_request req; 36144c87eaabSAndre Guedes struct hci_cp_inquiry cp; 36157ba8b4beSAndre Guedes int err; 36167ba8b4beSAndre Guedes 36174c87eaabSAndre Guedes if (status) { 36184c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 36194c87eaabSAndre Guedes return; 36207ba8b4beSAndre Guedes } 36217ba8b4beSAndre Guedes 36224c87eaabSAndre Guedes switch (hdev->discovery.type) { 36234c87eaabSAndre Guedes case DISCOV_TYPE_LE: 36244c87eaabSAndre Guedes hci_dev_lock(hdev); 36254c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 36264c87eaabSAndre Guedes hci_dev_unlock(hdev); 36274c87eaabSAndre Guedes break; 36287dbfac1dSAndre Guedes 36294c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 36304c87eaabSAndre Guedes hci_req_init(&req, hdev); 36317dbfac1dSAndre Guedes 36327dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 36334c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 36344c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 36354c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 36364c87eaabSAndre Guedes 36374c87eaabSAndre Guedes hci_dev_lock(hdev); 36384c87eaabSAndre Guedes 36394c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 36404c87eaabSAndre Guedes 36414c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 36424c87eaabSAndre Guedes if (err) { 36434c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 36444c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 36457dbfac1dSAndre Guedes } 36467dbfac1dSAndre Guedes 36474c87eaabSAndre Guedes hci_dev_unlock(hdev); 36484c87eaabSAndre Guedes break; 36494c87eaabSAndre Guedes } 36507dbfac1dSAndre Guedes } 36517dbfac1dSAndre Guedes 36527ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 36537ba8b4beSAndre Guedes { 36547ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 36557ba8b4beSAndre Guedes le_scan_disable.work); 36564c87eaabSAndre Guedes struct hci_request req; 36574c87eaabSAndre Guedes int err; 36587ba8b4beSAndre Guedes 36597ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 36607ba8b4beSAndre Guedes 36614c87eaabSAndre Guedes hci_req_init(&req, hdev); 36627ba8b4beSAndre Guedes 3663b1efcc28SAndre Guedes hci_req_add_le_scan_disable(&req); 36647ba8b4beSAndre Guedes 36654c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 36664c87eaabSAndre Guedes if (err) 36674c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 366828b75a89SAndre Guedes } 366928b75a89SAndre Guedes 36708d97250eSJohan Hedberg static void set_random_addr(struct hci_request *req, bdaddr_t *rpa) 36718d97250eSJohan Hedberg { 36728d97250eSJohan Hedberg struct hci_dev *hdev = req->hdev; 36738d97250eSJohan Hedberg 36748d97250eSJohan Hedberg /* If we're advertising or initiating an LE connection we can't 36758d97250eSJohan Hedberg * go ahead and change the random address at this time. This is 36768d97250eSJohan Hedberg * because the eventual initiator address used for the 36778d97250eSJohan Hedberg * subsequently created connection will be undefined (some 36788d97250eSJohan Hedberg * controllers use the new address and others the one we had 36798d97250eSJohan Hedberg * when the operation started). 36808d97250eSJohan Hedberg * 36818d97250eSJohan Hedberg * In this kind of scenario skip the update and let the random 36828d97250eSJohan Hedberg * address be updated at the next cycle. 36838d97250eSJohan Hedberg */ 36848d97250eSJohan Hedberg if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) || 36858d97250eSJohan Hedberg hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { 36868d97250eSJohan Hedberg BT_DBG("Deferring random address update"); 36878d97250eSJohan Hedberg return; 36888d97250eSJohan Hedberg } 36898d97250eSJohan Hedberg 36908d97250eSJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa); 36918d97250eSJohan Hedberg } 36928d97250eSJohan Hedberg 369394b1fc92SMarcel Holtmann int hci_update_random_address(struct hci_request *req, bool require_privacy, 369494b1fc92SMarcel Holtmann u8 *own_addr_type) 3695ebd3a747SJohan Hedberg { 3696ebd3a747SJohan Hedberg struct hci_dev *hdev = req->hdev; 3697ebd3a747SJohan Hedberg int err; 3698ebd3a747SJohan Hedberg 3699ebd3a747SJohan Hedberg /* If privacy is enabled use a resolvable private address. If 37002b5224dcSMarcel Holtmann * current RPA has expired or there is something else than 37012b5224dcSMarcel Holtmann * the current RPA in use, then generate a new one. 3702ebd3a747SJohan Hedberg */ 3703ebd3a747SJohan Hedberg if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) { 3704ebd3a747SJohan Hedberg int to; 3705ebd3a747SJohan Hedberg 3706ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_RANDOM; 3707ebd3a747SJohan Hedberg 3708ebd3a747SJohan Hedberg if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) && 37092b5224dcSMarcel Holtmann !bacmp(&hdev->random_addr, &hdev->rpa)) 3710ebd3a747SJohan Hedberg return 0; 3711ebd3a747SJohan Hedberg 37122b5224dcSMarcel Holtmann err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa); 3713ebd3a747SJohan Hedberg if (err < 0) { 3714ebd3a747SJohan Hedberg BT_ERR("%s failed to generate new RPA", hdev->name); 3715ebd3a747SJohan Hedberg return err; 3716ebd3a747SJohan Hedberg } 3717ebd3a747SJohan Hedberg 37188d97250eSJohan Hedberg set_random_addr(req, &hdev->rpa); 3719ebd3a747SJohan Hedberg 3720ebd3a747SJohan Hedberg to = msecs_to_jiffies(hdev->rpa_timeout * 1000); 3721ebd3a747SJohan Hedberg queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to); 3722ebd3a747SJohan Hedberg 3723ebd3a747SJohan Hedberg return 0; 3724ebd3a747SJohan Hedberg } 3725ebd3a747SJohan Hedberg 372694b1fc92SMarcel Holtmann /* In case of required privacy without resolvable private address, 372794b1fc92SMarcel Holtmann * use an unresolvable private address. This is useful for active 372894b1fc92SMarcel Holtmann * scanning and non-connectable advertising. 372994b1fc92SMarcel Holtmann */ 373094b1fc92SMarcel Holtmann if (require_privacy) { 373194b1fc92SMarcel Holtmann bdaddr_t urpa; 373294b1fc92SMarcel Holtmann 373394b1fc92SMarcel Holtmann get_random_bytes(&urpa, 6); 373494b1fc92SMarcel Holtmann urpa.b[5] &= 0x3f; /* Clear two most significant bits */ 373594b1fc92SMarcel Holtmann 373694b1fc92SMarcel Holtmann *own_addr_type = ADDR_LE_DEV_RANDOM; 37378d97250eSJohan Hedberg set_random_addr(req, &urpa); 373894b1fc92SMarcel Holtmann return 0; 373994b1fc92SMarcel Holtmann } 374094b1fc92SMarcel Holtmann 3741ebd3a747SJohan Hedberg /* If forcing static address is in use or there is no public 3742ebd3a747SJohan Hedberg * address use the static address as random address (but skip 3743ebd3a747SJohan Hedberg * the HCI command if the current random address is already the 3744ebd3a747SJohan Hedberg * static one. 3745ebd3a747SJohan Hedberg */ 3746111902f7SMarcel Holtmann if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) || 3747ebd3a747SJohan Hedberg !bacmp(&hdev->bdaddr, BDADDR_ANY)) { 3748ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_RANDOM; 3749ebd3a747SJohan Hedberg if (bacmp(&hdev->static_addr, &hdev->random_addr)) 3750ebd3a747SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, 3751ebd3a747SJohan Hedberg &hdev->static_addr); 3752ebd3a747SJohan Hedberg return 0; 3753ebd3a747SJohan Hedberg } 3754ebd3a747SJohan Hedberg 3755ebd3a747SJohan Hedberg /* Neither privacy nor static address is being used so use a 3756ebd3a747SJohan Hedberg * public address. 3757ebd3a747SJohan Hedberg */ 3758ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_PUBLIC; 3759ebd3a747SJohan Hedberg 3760ebd3a747SJohan Hedberg return 0; 3761ebd3a747SJohan Hedberg } 3762ebd3a747SJohan Hedberg 3763a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 3764a1f4c318SJohan Hedberg * 3765a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 3766a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 3767a1f4c318SJohan Hedberg * the static random address. 3768a1f4c318SJohan Hedberg * 3769a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 3770a1f4c318SJohan Hedberg * public address to use the static random address instead. 3771a1f4c318SJohan Hedberg */ 3772a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 3773a1f4c318SJohan Hedberg u8 *bdaddr_type) 3774a1f4c318SJohan Hedberg { 3775111902f7SMarcel Holtmann if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) || 3776a1f4c318SJohan Hedberg !bacmp(&hdev->bdaddr, BDADDR_ANY)) { 3777a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 3778a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 3779a1f4c318SJohan Hedberg } else { 3780a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 3781a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 3782a1f4c318SJohan Hedberg } 3783a1f4c318SJohan Hedberg } 3784a1f4c318SJohan Hedberg 37859be0dab7SDavid Herrmann /* Alloc HCI device */ 37869be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 37879be0dab7SDavid Herrmann { 37889be0dab7SDavid Herrmann struct hci_dev *hdev; 37899be0dab7SDavid Herrmann 37909be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 37919be0dab7SDavid Herrmann if (!hdev) 37929be0dab7SDavid Herrmann return NULL; 37939be0dab7SDavid Herrmann 3794b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3795b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3796b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3797b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3798b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 3799*96c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */ 3800bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3801bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3802b1b813d4SDavid Herrmann 3803b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3804b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3805b1b813d4SDavid Herrmann 38063f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 3807bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3808bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 38094e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = 0x0028; 38104e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = 0x0038; 381104fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000; 381204fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a; 3813bef64738SMarcel Holtmann 3814d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 3815b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 381631ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 381731ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 3818d6bfd59cSJohan Hedberg 3819b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3820b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3821b1b813d4SDavid Herrmann 3822b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3823b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 3824b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3825b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3826b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3827970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3828b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 3829d2ab0ac1SMarcel Holtmann INIT_LIST_HEAD(&hdev->le_white_list); 383015819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 383177a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 38326b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3833b1b813d4SDavid Herrmann 3834b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3835b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3836b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3837b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3838b1b813d4SDavid Herrmann 3839b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3840b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 3841b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 3842b1b813d4SDavid Herrmann 3843b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3844b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3845b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3846b1b813d4SDavid Herrmann 3847b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 3848b1b813d4SDavid Herrmann 384965cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout); 3850b1b813d4SDavid Herrmann 3851b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3852b1b813d4SDavid Herrmann discovery_init(hdev); 38539be0dab7SDavid Herrmann 38549be0dab7SDavid Herrmann return hdev; 38559be0dab7SDavid Herrmann } 38569be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 38579be0dab7SDavid Herrmann 38589be0dab7SDavid Herrmann /* Free HCI device */ 38599be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 38609be0dab7SDavid Herrmann { 38619be0dab7SDavid Herrmann /* will free via device release */ 38629be0dab7SDavid Herrmann put_device(&hdev->dev); 38639be0dab7SDavid Herrmann } 38649be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 38659be0dab7SDavid Herrmann 38661da177e4SLinus Torvalds /* Register HCI device */ 38671da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 38681da177e4SLinus Torvalds { 3869b1b813d4SDavid Herrmann int id, error; 38701da177e4SLinus Torvalds 3871010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 38721da177e4SLinus Torvalds return -EINVAL; 38731da177e4SLinus Torvalds 387408add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 387508add513SMat Martineau * so the index can be used as the AMP controller ID. 387608add513SMat Martineau */ 38773df92b31SSasha Levin switch (hdev->dev_type) { 38783df92b31SSasha Levin case HCI_BREDR: 38793df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 38801da177e4SLinus Torvalds break; 38813df92b31SSasha Levin case HCI_AMP: 38823df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 38833df92b31SSasha Levin break; 38843df92b31SSasha Levin default: 38853df92b31SSasha Levin return -EINVAL; 38861da177e4SLinus Torvalds } 38871da177e4SLinus Torvalds 38883df92b31SSasha Levin if (id < 0) 38893df92b31SSasha Levin return id; 38903df92b31SSasha Levin 38911da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 38921da177e4SLinus Torvalds hdev->id = id; 38932d8b3a11SAndrei Emeltchenko 38942d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 38952d8b3a11SAndrei Emeltchenko 3896d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3897d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 389833ca954dSDavid Herrmann if (!hdev->workqueue) { 389933ca954dSDavid Herrmann error = -ENOMEM; 390033ca954dSDavid Herrmann goto err; 390133ca954dSDavid Herrmann } 3902f48fd9c8SMarcel Holtmann 3903d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3904d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 39056ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 39066ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 39076ead1bbcSJohan Hedberg error = -ENOMEM; 39086ead1bbcSJohan Hedberg goto err; 39096ead1bbcSJohan Hedberg } 39106ead1bbcSJohan Hedberg 39110153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 39120153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 39130153e2ecSMarcel Holtmann 3914bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3915bdc3e0f1SMarcel Holtmann 391699780a7bSJohan Hedberg hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 391799780a7bSJohan Hedberg CRYPTO_ALG_ASYNC); 391899780a7bSJohan Hedberg if (IS_ERR(hdev->tfm_aes)) { 391999780a7bSJohan Hedberg BT_ERR("Unable to create crypto context"); 392099780a7bSJohan Hedberg error = PTR_ERR(hdev->tfm_aes); 392199780a7bSJohan Hedberg hdev->tfm_aes = NULL; 392299780a7bSJohan Hedberg goto err_wqueue; 392399780a7bSJohan Hedberg } 392499780a7bSJohan Hedberg 3925bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 392633ca954dSDavid Herrmann if (error < 0) 392799780a7bSJohan Hedberg goto err_tfm; 39281da177e4SLinus Torvalds 3929611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3930a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3931a8c5fb1aSGustavo Padovan hdev); 3932611b30f7SMarcel Holtmann if (hdev->rfkill) { 3933611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3934611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3935611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3936611b30f7SMarcel Holtmann } 3937611b30f7SMarcel Holtmann } 3938611b30f7SMarcel Holtmann 39395e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 39405e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 39415e130367SJohan Hedberg 3942a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 3943004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 3944ce2be9acSAndrei Emeltchenko 394501cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 394656f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 394756f87901SJohan Hedberg * through reading supported features during init. 394856f87901SJohan Hedberg */ 394956f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 395056f87901SJohan Hedberg } 3951ce2be9acSAndrei Emeltchenko 3952fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3953fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3954fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3955fcee3377SGustavo Padovan 3956fee746b0SMarcel Holtmann /* Devices that are marked for raw-only usage need to set 3957fee746b0SMarcel Holtmann * the HCI_RAW flag to indicate that only user channel is 3958fee746b0SMarcel Holtmann * supported. 3959fee746b0SMarcel Holtmann */ 3960fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 3961fee746b0SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 3962fee746b0SMarcel Holtmann 39631da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 3964dc946bd8SDavid Herrmann hci_dev_hold(hdev); 39651da177e4SLinus Torvalds 396619202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3967fbe96d6fSMarcel Holtmann 39681da177e4SLinus Torvalds return id; 3969f48fd9c8SMarcel Holtmann 397099780a7bSJohan Hedberg err_tfm: 397199780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 397233ca954dSDavid Herrmann err_wqueue: 397333ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 39746ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 397533ca954dSDavid Herrmann err: 39763df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3977f48fd9c8SMarcel Holtmann 397833ca954dSDavid Herrmann return error; 39791da177e4SLinus Torvalds } 39801da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 39811da177e4SLinus Torvalds 39821da177e4SLinus Torvalds /* Unregister HCI device */ 398359735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 39841da177e4SLinus Torvalds { 39853df92b31SSasha Levin int i, id; 3986ef222013SMarcel Holtmann 3987c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 39881da177e4SLinus Torvalds 398994324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 399094324962SJohan Hovold 39913df92b31SSasha Levin id = hdev->id; 39923df92b31SSasha Levin 3993f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 39941da177e4SLinus Torvalds list_del(&hdev->list); 3995f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 39961da177e4SLinus Torvalds 39971da177e4SLinus Torvalds hci_dev_do_close(hdev); 39981da177e4SLinus Torvalds 3999cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 4000ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 4001ef222013SMarcel Holtmann 4002b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 4003b9b5ef18SGustavo Padovan 4004ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 4005fee746b0SMarcel Holtmann !test_bit(HCI_SETUP, &hdev->dev_flags) && 4006fee746b0SMarcel Holtmann !test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) { 400709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4008744cf19eSJohan Hedberg mgmt_index_removed(hdev); 400909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 401056e5cb86SJohan Hedberg } 4011ab81cbf9SJohan Hedberg 40122e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 40132e58ef3eSJohan Hedberg * pending list */ 40142e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 40152e58ef3eSJohan Hedberg 40161da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 40171da177e4SLinus Torvalds 4018611b30f7SMarcel Holtmann if (hdev->rfkill) { 4019611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 4020611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 4021611b30f7SMarcel Holtmann } 4022611b30f7SMarcel Holtmann 402399780a7bSJohan Hedberg if (hdev->tfm_aes) 402499780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 402599780a7bSJohan Hedberg 4026bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 4027147e2d59SDave Young 40280153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 40290153e2ecSMarcel Holtmann 4030f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 40316ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 4032f48fd9c8SMarcel Holtmann 403309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4034e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 40352aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 403655ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 4037b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 4038970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 40392763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 4040d2ab0ac1SMarcel Holtmann hci_white_list_clear(hdev); 404115819a70SAndre Guedes hci_conn_params_clear(hdev); 404209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 4043e2e0cacbSJohan Hedberg 4044dc946bd8SDavid Herrmann hci_dev_put(hdev); 40453df92b31SSasha Levin 40463df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 40471da177e4SLinus Torvalds } 40481da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 40491da177e4SLinus Torvalds 40501da177e4SLinus Torvalds /* Suspend HCI device */ 40511da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 40521da177e4SLinus Torvalds { 40531da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 40541da177e4SLinus Torvalds return 0; 40551da177e4SLinus Torvalds } 40561da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 40571da177e4SLinus Torvalds 40581da177e4SLinus Torvalds /* Resume HCI device */ 40591da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 40601da177e4SLinus Torvalds { 40611da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 40621da177e4SLinus Torvalds return 0; 40631da177e4SLinus Torvalds } 40641da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 40651da177e4SLinus Torvalds 406676bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 4067e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 406876bca880SMarcel Holtmann { 406976bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 407076bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 407176bca880SMarcel Holtmann kfree_skb(skb); 407276bca880SMarcel Holtmann return -ENXIO; 407376bca880SMarcel Holtmann } 407476bca880SMarcel Holtmann 4075d82603c6SJorrit Schippers /* Incoming skb */ 407676bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 407776bca880SMarcel Holtmann 407876bca880SMarcel Holtmann /* Time stamp */ 407976bca880SMarcel Holtmann __net_timestamp(skb); 408076bca880SMarcel Holtmann 408176bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 4082b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 4083c78ae283SMarcel Holtmann 408476bca880SMarcel Holtmann return 0; 408576bca880SMarcel Holtmann } 408676bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 408776bca880SMarcel Holtmann 408833e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 40891e429f38SGustavo F. Padovan int count, __u8 index) 409033e882a5SSuraj Sumangala { 409133e882a5SSuraj Sumangala int len = 0; 409233e882a5SSuraj Sumangala int hlen = 0; 409333e882a5SSuraj Sumangala int remain = count; 409433e882a5SSuraj Sumangala struct sk_buff *skb; 409533e882a5SSuraj Sumangala struct bt_skb_cb *scb; 409633e882a5SSuraj Sumangala 409733e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 409833e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 409933e882a5SSuraj Sumangala return -EILSEQ; 410033e882a5SSuraj Sumangala 410133e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 410233e882a5SSuraj Sumangala 410333e882a5SSuraj Sumangala if (!skb) { 410433e882a5SSuraj Sumangala switch (type) { 410533e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 410633e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 410733e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 410833e882a5SSuraj Sumangala break; 410933e882a5SSuraj Sumangala case HCI_EVENT_PKT: 411033e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 411133e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 411233e882a5SSuraj Sumangala break; 411333e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 411433e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 411533e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 411633e882a5SSuraj Sumangala break; 411733e882a5SSuraj Sumangala } 411833e882a5SSuraj Sumangala 41191e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 412033e882a5SSuraj Sumangala if (!skb) 412133e882a5SSuraj Sumangala return -ENOMEM; 412233e882a5SSuraj Sumangala 412333e882a5SSuraj Sumangala scb = (void *) skb->cb; 412433e882a5SSuraj Sumangala scb->expect = hlen; 412533e882a5SSuraj Sumangala scb->pkt_type = type; 412633e882a5SSuraj Sumangala 412733e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 412833e882a5SSuraj Sumangala } 412933e882a5SSuraj Sumangala 413033e882a5SSuraj Sumangala while (count) { 413133e882a5SSuraj Sumangala scb = (void *) skb->cb; 413289bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 413333e882a5SSuraj Sumangala 413433e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 413533e882a5SSuraj Sumangala 413633e882a5SSuraj Sumangala count -= len; 413733e882a5SSuraj Sumangala data += len; 413833e882a5SSuraj Sumangala scb->expect -= len; 413933e882a5SSuraj Sumangala remain = count; 414033e882a5SSuraj Sumangala 414133e882a5SSuraj Sumangala switch (type) { 414233e882a5SSuraj Sumangala case HCI_EVENT_PKT: 414333e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 414433e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 414533e882a5SSuraj Sumangala scb->expect = h->plen; 414633e882a5SSuraj Sumangala 414733e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 414833e882a5SSuraj Sumangala kfree_skb(skb); 414933e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 415033e882a5SSuraj Sumangala return -ENOMEM; 415133e882a5SSuraj Sumangala } 415233e882a5SSuraj Sumangala } 415333e882a5SSuraj Sumangala break; 415433e882a5SSuraj Sumangala 415533e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 415633e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 415733e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 415833e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 415933e882a5SSuraj Sumangala 416033e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 416133e882a5SSuraj Sumangala kfree_skb(skb); 416233e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 416333e882a5SSuraj Sumangala return -ENOMEM; 416433e882a5SSuraj Sumangala } 416533e882a5SSuraj Sumangala } 416633e882a5SSuraj Sumangala break; 416733e882a5SSuraj Sumangala 416833e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 416933e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 417033e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 417133e882a5SSuraj Sumangala scb->expect = h->dlen; 417233e882a5SSuraj Sumangala 417333e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 417433e882a5SSuraj Sumangala kfree_skb(skb); 417533e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 417633e882a5SSuraj Sumangala return -ENOMEM; 417733e882a5SSuraj Sumangala } 417833e882a5SSuraj Sumangala } 417933e882a5SSuraj Sumangala break; 418033e882a5SSuraj Sumangala } 418133e882a5SSuraj Sumangala 418233e882a5SSuraj Sumangala if (scb->expect == 0) { 418333e882a5SSuraj Sumangala /* Complete frame */ 418433e882a5SSuraj Sumangala 418533e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 4186e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 418733e882a5SSuraj Sumangala 418833e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 418933e882a5SSuraj Sumangala return remain; 419033e882a5SSuraj Sumangala } 419133e882a5SSuraj Sumangala } 419233e882a5SSuraj Sumangala 419333e882a5SSuraj Sumangala return remain; 419433e882a5SSuraj Sumangala } 419533e882a5SSuraj Sumangala 4196ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 4197ef222013SMarcel Holtmann { 4198f39a3c06SSuraj Sumangala int rem = 0; 4199f39a3c06SSuraj Sumangala 4200ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 4201ef222013SMarcel Holtmann return -EILSEQ; 4202ef222013SMarcel Holtmann 4203da5f6c37SGustavo F. Padovan while (count) { 42041e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 4205f39a3c06SSuraj Sumangala if (rem < 0) 4206f39a3c06SSuraj Sumangala return rem; 4207ef222013SMarcel Holtmann 4208f39a3c06SSuraj Sumangala data += (count - rem); 4209f39a3c06SSuraj Sumangala count = rem; 4210f81c6224SJoe Perches } 4211ef222013SMarcel Holtmann 4212f39a3c06SSuraj Sumangala return rem; 4213ef222013SMarcel Holtmann } 4214ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 4215ef222013SMarcel Holtmann 421699811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 421799811510SSuraj Sumangala 421899811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 421999811510SSuraj Sumangala { 422099811510SSuraj Sumangala int type; 422199811510SSuraj Sumangala int rem = 0; 422299811510SSuraj Sumangala 4223da5f6c37SGustavo F. Padovan while (count) { 422499811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 422599811510SSuraj Sumangala 422699811510SSuraj Sumangala if (!skb) { 422799811510SSuraj Sumangala struct { char type; } *pkt; 422899811510SSuraj Sumangala 422999811510SSuraj Sumangala /* Start of the frame */ 423099811510SSuraj Sumangala pkt = data; 423199811510SSuraj Sumangala type = pkt->type; 423299811510SSuraj Sumangala 423399811510SSuraj Sumangala data++; 423499811510SSuraj Sumangala count--; 423599811510SSuraj Sumangala } else 423699811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 423799811510SSuraj Sumangala 42381e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 42391e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 424099811510SSuraj Sumangala if (rem < 0) 424199811510SSuraj Sumangala return rem; 424299811510SSuraj Sumangala 424399811510SSuraj Sumangala data += (count - rem); 424499811510SSuraj Sumangala count = rem; 4245f81c6224SJoe Perches } 424699811510SSuraj Sumangala 424799811510SSuraj Sumangala return rem; 424899811510SSuraj Sumangala } 424999811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 425099811510SSuraj Sumangala 42511da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 42521da177e4SLinus Torvalds 42531da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 42541da177e4SLinus Torvalds { 42551da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 42561da177e4SLinus Torvalds 4257f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 42581da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 4259f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 42601da177e4SLinus Torvalds 42611da177e4SLinus Torvalds return 0; 42621da177e4SLinus Torvalds } 42631da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 42641da177e4SLinus Torvalds 42651da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 42661da177e4SLinus Torvalds { 42671da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 42681da177e4SLinus Torvalds 4269f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 42701da177e4SLinus Torvalds list_del(&cb->list); 4271f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 42721da177e4SLinus Torvalds 42731da177e4SLinus Torvalds return 0; 42741da177e4SLinus Torvalds } 42751da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 42761da177e4SLinus Torvalds 427751086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 42781da177e4SLinus Torvalds { 42790d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 42801da177e4SLinus Torvalds 42811da177e4SLinus Torvalds /* Time stamp */ 4282a61bbcf2SPatrick McHardy __net_timestamp(skb); 42831da177e4SLinus Torvalds 4284cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4285cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4286cd82e61cSMarcel Holtmann 4287cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 4288cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 4289470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 42901da177e4SLinus Torvalds } 42911da177e4SLinus Torvalds 42921da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 42931da177e4SLinus Torvalds skb_orphan(skb); 42941da177e4SLinus Torvalds 42957bd8f09fSMarcel Holtmann if (hdev->send(hdev, skb) < 0) 429651086991SMarcel Holtmann BT_ERR("%s sending frame failed", hdev->name); 42971da177e4SLinus Torvalds } 42981da177e4SLinus Torvalds 42993119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 43003119ae95SJohan Hedberg { 43013119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 43023119ae95SJohan Hedberg req->hdev = hdev; 43035d73e034SAndre Guedes req->err = 0; 43043119ae95SJohan Hedberg } 43053119ae95SJohan Hedberg 43063119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 43073119ae95SJohan Hedberg { 43083119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 43093119ae95SJohan Hedberg struct sk_buff *skb; 43103119ae95SJohan Hedberg unsigned long flags; 43113119ae95SJohan Hedberg 43123119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 43133119ae95SJohan Hedberg 43145d73e034SAndre Guedes /* If an error occured during request building, remove all HCI 43155d73e034SAndre Guedes * commands queued on the HCI request queue. 43165d73e034SAndre Guedes */ 43175d73e034SAndre Guedes if (req->err) { 43185d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 43195d73e034SAndre Guedes return req->err; 43205d73e034SAndre Guedes } 43215d73e034SAndre Guedes 43223119ae95SJohan Hedberg /* Do not allow empty requests */ 43233119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 4324382b0c39SAndre Guedes return -ENODATA; 43253119ae95SJohan Hedberg 43263119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 43273119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 43283119ae95SJohan Hedberg 43293119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 43303119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 43313119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 43323119ae95SJohan Hedberg 43333119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 43343119ae95SJohan Hedberg 43353119ae95SJohan Hedberg return 0; 43363119ae95SJohan Hedberg } 43373119ae95SJohan Hedberg 43381ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 433907dc93ddSJohan Hedberg u32 plen, const void *param) 43401da177e4SLinus Torvalds { 43411da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 43421da177e4SLinus Torvalds struct hci_command_hdr *hdr; 43431da177e4SLinus Torvalds struct sk_buff *skb; 43441da177e4SLinus Torvalds 43451da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 43461ca3a9d0SJohan Hedberg if (!skb) 43471ca3a9d0SJohan Hedberg return NULL; 43481da177e4SLinus Torvalds 43491da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 4350a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 43511da177e4SLinus Torvalds hdr->plen = plen; 43521da177e4SLinus Torvalds 43531da177e4SLinus Torvalds if (plen) 43541da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 43551da177e4SLinus Torvalds 43561da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 43571da177e4SLinus Torvalds 43580d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 4359c78ae283SMarcel Holtmann 43601ca3a9d0SJohan Hedberg return skb; 43611ca3a9d0SJohan Hedberg } 43621ca3a9d0SJohan Hedberg 43631ca3a9d0SJohan Hedberg /* Send HCI command */ 436407dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 436507dc93ddSJohan Hedberg const void *param) 43661ca3a9d0SJohan Hedberg { 43671ca3a9d0SJohan Hedberg struct sk_buff *skb; 43681ca3a9d0SJohan Hedberg 43691ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 43701ca3a9d0SJohan Hedberg 43711ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 43721ca3a9d0SJohan Hedberg if (!skb) { 43731ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 43741ca3a9d0SJohan Hedberg return -ENOMEM; 43751ca3a9d0SJohan Hedberg } 43761ca3a9d0SJohan Hedberg 437711714b3dSJohan Hedberg /* Stand-alone HCI commands must be flaged as 437811714b3dSJohan Hedberg * single-command requests. 437911714b3dSJohan Hedberg */ 438011714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 438111714b3dSJohan Hedberg 43821da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 4383c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 43841da177e4SLinus Torvalds 43851da177e4SLinus Torvalds return 0; 43861da177e4SLinus Torvalds } 43871da177e4SLinus Torvalds 438871c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 438907dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 439007dc93ddSJohan Hedberg const void *param, u8 event) 439171c76a17SJohan Hedberg { 439271c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 439371c76a17SJohan Hedberg struct sk_buff *skb; 439471c76a17SJohan Hedberg 439571c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 439671c76a17SJohan Hedberg 439734739c1eSAndre Guedes /* If an error occured during request building, there is no point in 439834739c1eSAndre Guedes * queueing the HCI command. We can simply return. 439934739c1eSAndre Guedes */ 440034739c1eSAndre Guedes if (req->err) 440134739c1eSAndre Guedes return; 440234739c1eSAndre Guedes 440371c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 440471c76a17SJohan Hedberg if (!skb) { 44055d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 44065d73e034SAndre Guedes hdev->name, opcode); 44075d73e034SAndre Guedes req->err = -ENOMEM; 4408e348fe6bSAndre Guedes return; 440971c76a17SJohan Hedberg } 441071c76a17SJohan Hedberg 441171c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 441271c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 441371c76a17SJohan Hedberg 441402350a72SJohan Hedberg bt_cb(skb)->req.event = event; 441502350a72SJohan Hedberg 441671c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 441771c76a17SJohan Hedberg } 441871c76a17SJohan Hedberg 441907dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 442007dc93ddSJohan Hedberg const void *param) 442102350a72SJohan Hedberg { 442202350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 442302350a72SJohan Hedberg } 442402350a72SJohan Hedberg 44251da177e4SLinus Torvalds /* Get data from the previously sent command */ 4426a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 44271da177e4SLinus Torvalds { 44281da177e4SLinus Torvalds struct hci_command_hdr *hdr; 44291da177e4SLinus Torvalds 44301da177e4SLinus Torvalds if (!hdev->sent_cmd) 44311da177e4SLinus Torvalds return NULL; 44321da177e4SLinus Torvalds 44331da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 44341da177e4SLinus Torvalds 4435a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 44361da177e4SLinus Torvalds return NULL; 44371da177e4SLinus Torvalds 4438f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 44391da177e4SLinus Torvalds 44401da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 44411da177e4SLinus Torvalds } 44421da177e4SLinus Torvalds 44431da177e4SLinus Torvalds /* Send ACL data */ 44441da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 44451da177e4SLinus Torvalds { 44461da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 44471da177e4SLinus Torvalds int len = skb->len; 44481da177e4SLinus Torvalds 4449badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 4450badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 44519c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 4452aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 4453aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 44541da177e4SLinus Torvalds } 44551da177e4SLinus Torvalds 4456ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 445773d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 44581da177e4SLinus Torvalds { 4459ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 44601da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 44611da177e4SLinus Torvalds struct sk_buff *list; 44621da177e4SLinus Torvalds 4463087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 4464087bfd99SGustavo Padovan skb->data_len = 0; 4465087bfd99SGustavo Padovan 4466087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 4467204a6e54SAndrei Emeltchenko 4468204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 4469204a6e54SAndrei Emeltchenko case HCI_BREDR: 4470087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 4471204a6e54SAndrei Emeltchenko break; 4472204a6e54SAndrei Emeltchenko case HCI_AMP: 4473204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 4474204a6e54SAndrei Emeltchenko break; 4475204a6e54SAndrei Emeltchenko default: 4476204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 4477204a6e54SAndrei Emeltchenko return; 4478204a6e54SAndrei Emeltchenko } 4479087bfd99SGustavo Padovan 448070f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 448170f23020SAndrei Emeltchenko if (!list) { 44821da177e4SLinus Torvalds /* Non fragmented */ 44831da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 44841da177e4SLinus Torvalds 448573d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 44861da177e4SLinus Torvalds } else { 44871da177e4SLinus Torvalds /* Fragmented */ 44881da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 44891da177e4SLinus Torvalds 44901da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 44911da177e4SLinus Torvalds 44921da177e4SLinus Torvalds /* Queue all fragments atomically */ 4493af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 44941da177e4SLinus Torvalds 449573d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 4496e702112fSAndrei Emeltchenko 4497e702112fSAndrei Emeltchenko flags &= ~ACL_START; 4498e702112fSAndrei Emeltchenko flags |= ACL_CONT; 44991da177e4SLinus Torvalds do { 45001da177e4SLinus Torvalds skb = list; list = list->next; 45011da177e4SLinus Torvalds 45020d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 4503e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 45041da177e4SLinus Torvalds 45051da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 45061da177e4SLinus Torvalds 450773d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 45081da177e4SLinus Torvalds } while (list); 45091da177e4SLinus Torvalds 4510af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 45111da177e4SLinus Torvalds } 451273d80debSLuiz Augusto von Dentz } 451373d80debSLuiz Augusto von Dentz 451473d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 451573d80debSLuiz Augusto von Dentz { 4516ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 451773d80debSLuiz Augusto von Dentz 4518f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 451973d80debSLuiz Augusto von Dentz 4520ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 45211da177e4SLinus Torvalds 45223eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 45231da177e4SLinus Torvalds } 45241da177e4SLinus Torvalds 45251da177e4SLinus Torvalds /* Send SCO data */ 45260d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 45271da177e4SLinus Torvalds { 45281da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 45291da177e4SLinus Torvalds struct hci_sco_hdr hdr; 45301da177e4SLinus Torvalds 45311da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 45321da177e4SLinus Torvalds 4533aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 45341da177e4SLinus Torvalds hdr.dlen = skb->len; 45351da177e4SLinus Torvalds 4536badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 4537badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 45389c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 45391da177e4SLinus Torvalds 45400d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 4541c78ae283SMarcel Holtmann 45421da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 45433eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 45441da177e4SLinus Torvalds } 45451da177e4SLinus Torvalds 45461da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 45471da177e4SLinus Torvalds 45481da177e4SLinus Torvalds /* HCI Connection scheduler */ 45496039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 4550a8c5fb1aSGustavo Padovan int *quote) 45511da177e4SLinus Torvalds { 45521da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 45538035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 4554abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 45551da177e4SLinus Torvalds 45561da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 45571da177e4SLinus Torvalds * added and removed with TX task disabled. */ 4558bf4c6325SGustavo F. Padovan 4559bf4c6325SGustavo F. Padovan rcu_read_lock(); 4560bf4c6325SGustavo F. Padovan 4561bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4562769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 45631da177e4SLinus Torvalds continue; 4564769be974SMarcel Holtmann 4565769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 4566769be974SMarcel Holtmann continue; 4567769be974SMarcel Holtmann 45681da177e4SLinus Torvalds num++; 45691da177e4SLinus Torvalds 45701da177e4SLinus Torvalds if (c->sent < min) { 45711da177e4SLinus Torvalds min = c->sent; 45721da177e4SLinus Torvalds conn = c; 45731da177e4SLinus Torvalds } 457452087a79SLuiz Augusto von Dentz 457552087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 457652087a79SLuiz Augusto von Dentz break; 45771da177e4SLinus Torvalds } 45781da177e4SLinus Torvalds 4579bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4580bf4c6325SGustavo F. Padovan 45811da177e4SLinus Torvalds if (conn) { 45826ed58ec5SVille Tervo int cnt, q; 45836ed58ec5SVille Tervo 45846ed58ec5SVille Tervo switch (conn->type) { 45856ed58ec5SVille Tervo case ACL_LINK: 45866ed58ec5SVille Tervo cnt = hdev->acl_cnt; 45876ed58ec5SVille Tervo break; 45886ed58ec5SVille Tervo case SCO_LINK: 45896ed58ec5SVille Tervo case ESCO_LINK: 45906ed58ec5SVille Tervo cnt = hdev->sco_cnt; 45916ed58ec5SVille Tervo break; 45926ed58ec5SVille Tervo case LE_LINK: 45936ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 45946ed58ec5SVille Tervo break; 45956ed58ec5SVille Tervo default: 45966ed58ec5SVille Tervo cnt = 0; 45976ed58ec5SVille Tervo BT_ERR("Unknown link type"); 45986ed58ec5SVille Tervo } 45996ed58ec5SVille Tervo 46006ed58ec5SVille Tervo q = cnt / num; 46011da177e4SLinus Torvalds *quote = q ? q : 1; 46021da177e4SLinus Torvalds } else 46031da177e4SLinus Torvalds *quote = 0; 46041da177e4SLinus Torvalds 46051da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 46061da177e4SLinus Torvalds return conn; 46071da177e4SLinus Torvalds } 46081da177e4SLinus Torvalds 46096039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 46101da177e4SLinus Torvalds { 46111da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 46121da177e4SLinus Torvalds struct hci_conn *c; 46131da177e4SLinus Torvalds 4614bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 46151da177e4SLinus Torvalds 4616bf4c6325SGustavo F. Padovan rcu_read_lock(); 4617bf4c6325SGustavo F. Padovan 46181da177e4SLinus Torvalds /* Kill stalled connections */ 4619bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4620bae1f5d9SVille Tervo if (c->type == type && c->sent) { 46216ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 46226ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 4623bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 46241da177e4SLinus Torvalds } 46251da177e4SLinus Torvalds } 4626bf4c6325SGustavo F. Padovan 4627bf4c6325SGustavo F. Padovan rcu_read_unlock(); 46281da177e4SLinus Torvalds } 46291da177e4SLinus Torvalds 46306039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 463173d80debSLuiz Augusto von Dentz int *quote) 463273d80debSLuiz Augusto von Dentz { 463373d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 463473d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 4635abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 463673d80debSLuiz Augusto von Dentz struct hci_conn *conn; 463773d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 463873d80debSLuiz Augusto von Dentz 463973d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 464073d80debSLuiz Augusto von Dentz 4641bf4c6325SGustavo F. Padovan rcu_read_lock(); 4642bf4c6325SGustavo F. Padovan 4643bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 464473d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 464573d80debSLuiz Augusto von Dentz 464673d80debSLuiz Augusto von Dentz if (conn->type != type) 464773d80debSLuiz Augusto von Dentz continue; 464873d80debSLuiz Augusto von Dentz 464973d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 465073d80debSLuiz Augusto von Dentz continue; 465173d80debSLuiz Augusto von Dentz 465273d80debSLuiz Augusto von Dentz conn_num++; 465373d80debSLuiz Augusto von Dentz 46548192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 465573d80debSLuiz Augusto von Dentz struct sk_buff *skb; 465673d80debSLuiz Augusto von Dentz 465773d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 465873d80debSLuiz Augusto von Dentz continue; 465973d80debSLuiz Augusto von Dentz 466073d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 466173d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 466273d80debSLuiz Augusto von Dentz continue; 466373d80debSLuiz Augusto von Dentz 466473d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 466573d80debSLuiz Augusto von Dentz num = 0; 466673d80debSLuiz Augusto von Dentz min = ~0; 466773d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 466873d80debSLuiz Augusto von Dentz } 466973d80debSLuiz Augusto von Dentz 467073d80debSLuiz Augusto von Dentz num++; 467173d80debSLuiz Augusto von Dentz 467273d80debSLuiz Augusto von Dentz if (conn->sent < min) { 467373d80debSLuiz Augusto von Dentz min = conn->sent; 467473d80debSLuiz Augusto von Dentz chan = tmp; 467573d80debSLuiz Augusto von Dentz } 467673d80debSLuiz Augusto von Dentz } 467773d80debSLuiz Augusto von Dentz 467873d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 467973d80debSLuiz Augusto von Dentz break; 468073d80debSLuiz Augusto von Dentz } 468173d80debSLuiz Augusto von Dentz 4682bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4683bf4c6325SGustavo F. Padovan 468473d80debSLuiz Augusto von Dentz if (!chan) 468573d80debSLuiz Augusto von Dentz return NULL; 468673d80debSLuiz Augusto von Dentz 468773d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 468873d80debSLuiz Augusto von Dentz case ACL_LINK: 468973d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 469073d80debSLuiz Augusto von Dentz break; 4691bd1eb66bSAndrei Emeltchenko case AMP_LINK: 4692bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 4693bd1eb66bSAndrei Emeltchenko break; 469473d80debSLuiz Augusto von Dentz case SCO_LINK: 469573d80debSLuiz Augusto von Dentz case ESCO_LINK: 469673d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 469773d80debSLuiz Augusto von Dentz break; 469873d80debSLuiz Augusto von Dentz case LE_LINK: 469973d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 470073d80debSLuiz Augusto von Dentz break; 470173d80debSLuiz Augusto von Dentz default: 470273d80debSLuiz Augusto von Dentz cnt = 0; 470373d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 470473d80debSLuiz Augusto von Dentz } 470573d80debSLuiz Augusto von Dentz 470673d80debSLuiz Augusto von Dentz q = cnt / num; 470773d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 470873d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 470973d80debSLuiz Augusto von Dentz return chan; 471073d80debSLuiz Augusto von Dentz } 471173d80debSLuiz Augusto von Dentz 471202b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 471302b20f0bSLuiz Augusto von Dentz { 471402b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 471502b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 471602b20f0bSLuiz Augusto von Dentz int num = 0; 471702b20f0bSLuiz Augusto von Dentz 471802b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 471902b20f0bSLuiz Augusto von Dentz 4720bf4c6325SGustavo F. Padovan rcu_read_lock(); 4721bf4c6325SGustavo F. Padovan 4722bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 472302b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 472402b20f0bSLuiz Augusto von Dentz 472502b20f0bSLuiz Augusto von Dentz if (conn->type != type) 472602b20f0bSLuiz Augusto von Dentz continue; 472702b20f0bSLuiz Augusto von Dentz 472802b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 472902b20f0bSLuiz Augusto von Dentz continue; 473002b20f0bSLuiz Augusto von Dentz 473102b20f0bSLuiz Augusto von Dentz num++; 473202b20f0bSLuiz Augusto von Dentz 47338192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 473402b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 473502b20f0bSLuiz Augusto von Dentz 473602b20f0bSLuiz Augusto von Dentz if (chan->sent) { 473702b20f0bSLuiz Augusto von Dentz chan->sent = 0; 473802b20f0bSLuiz Augusto von Dentz continue; 473902b20f0bSLuiz Augusto von Dentz } 474002b20f0bSLuiz Augusto von Dentz 474102b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 474202b20f0bSLuiz Augusto von Dentz continue; 474302b20f0bSLuiz Augusto von Dentz 474402b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 474502b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 474602b20f0bSLuiz Augusto von Dentz continue; 474702b20f0bSLuiz Augusto von Dentz 474802b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 474902b20f0bSLuiz Augusto von Dentz 475002b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 475102b20f0bSLuiz Augusto von Dentz skb->priority); 475202b20f0bSLuiz Augusto von Dentz } 475302b20f0bSLuiz Augusto von Dentz 475402b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 475502b20f0bSLuiz Augusto von Dentz break; 475602b20f0bSLuiz Augusto von Dentz } 4757bf4c6325SGustavo F. Padovan 4758bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4759bf4c6325SGustavo F. Padovan 476002b20f0bSLuiz Augusto von Dentz } 476102b20f0bSLuiz Augusto von Dentz 4762b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4763b71d385aSAndrei Emeltchenko { 4764b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4765b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4766b71d385aSAndrei Emeltchenko } 4767b71d385aSAndrei Emeltchenko 47686039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 47691da177e4SLinus Torvalds { 4770fee746b0SMarcel Holtmann if (!test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) { 47711da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 47721da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 477363d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 47745f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 4775bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 47761da177e4SLinus Torvalds } 477763d2bc1bSAndrei Emeltchenko } 47781da177e4SLinus Torvalds 47796039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 478063d2bc1bSAndrei Emeltchenko { 478163d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 478263d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 478363d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 478463d2bc1bSAndrei Emeltchenko int quote; 478563d2bc1bSAndrei Emeltchenko 478663d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 478704837f64SMarcel Holtmann 478873d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 478973d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 4790ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4791ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 479273d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 479373d80debSLuiz Augusto von Dentz skb->len, skb->priority); 479473d80debSLuiz Augusto von Dentz 4795ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4796ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4797ec1cce24SLuiz Augusto von Dentz break; 4798ec1cce24SLuiz Augusto von Dentz 4799ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4800ec1cce24SLuiz Augusto von Dentz 480173d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 480273d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 480304837f64SMarcel Holtmann 480457d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 48051da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 48061da177e4SLinus Torvalds 48071da177e4SLinus Torvalds hdev->acl_cnt--; 480873d80debSLuiz Augusto von Dentz chan->sent++; 480973d80debSLuiz Augusto von Dentz chan->conn->sent++; 48101da177e4SLinus Torvalds } 48111da177e4SLinus Torvalds } 481202b20f0bSLuiz Augusto von Dentz 481302b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 481402b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 48151da177e4SLinus Torvalds } 48161da177e4SLinus Torvalds 48176039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4818b71d385aSAndrei Emeltchenko { 481963d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4820b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4821b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4822b71d385aSAndrei Emeltchenko int quote; 4823bd1eb66bSAndrei Emeltchenko u8 type; 4824b71d385aSAndrei Emeltchenko 482563d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4826b71d385aSAndrei Emeltchenko 4827bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4828bd1eb66bSAndrei Emeltchenko 4829bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4830bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4831bd1eb66bSAndrei Emeltchenko else 4832bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4833bd1eb66bSAndrei Emeltchenko 4834b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4835bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4836b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4837b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4838b71d385aSAndrei Emeltchenko int blocks; 4839b71d385aSAndrei Emeltchenko 4840b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4841b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4842b71d385aSAndrei Emeltchenko 4843b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4844b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4845b71d385aSAndrei Emeltchenko break; 4846b71d385aSAndrei Emeltchenko 4847b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4848b71d385aSAndrei Emeltchenko 4849b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4850b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4851b71d385aSAndrei Emeltchenko return; 4852b71d385aSAndrei Emeltchenko 4853b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4854b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4855b71d385aSAndrei Emeltchenko 485657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4857b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4858b71d385aSAndrei Emeltchenko 4859b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4860b71d385aSAndrei Emeltchenko quote -= blocks; 4861b71d385aSAndrei Emeltchenko 4862b71d385aSAndrei Emeltchenko chan->sent += blocks; 4863b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4864b71d385aSAndrei Emeltchenko } 4865b71d385aSAndrei Emeltchenko } 4866b71d385aSAndrei Emeltchenko 4867b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4868bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4869b71d385aSAndrei Emeltchenko } 4870b71d385aSAndrei Emeltchenko 48716039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4872b71d385aSAndrei Emeltchenko { 4873b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4874b71d385aSAndrei Emeltchenko 4875bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4876bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 4877bd1eb66bSAndrei Emeltchenko return; 4878bd1eb66bSAndrei Emeltchenko 4879bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4880bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4881b71d385aSAndrei Emeltchenko return; 4882b71d385aSAndrei Emeltchenko 4883b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4884b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4885b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4886b71d385aSAndrei Emeltchenko break; 4887b71d385aSAndrei Emeltchenko 4888b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4889b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4890b71d385aSAndrei Emeltchenko break; 4891b71d385aSAndrei Emeltchenko } 4892b71d385aSAndrei Emeltchenko } 4893b71d385aSAndrei Emeltchenko 48941da177e4SLinus Torvalds /* Schedule SCO */ 48956039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 48961da177e4SLinus Torvalds { 48971da177e4SLinus Torvalds struct hci_conn *conn; 48981da177e4SLinus Torvalds struct sk_buff *skb; 48991da177e4SLinus Torvalds int quote; 49001da177e4SLinus Torvalds 49011da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 49021da177e4SLinus Torvalds 490352087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 490452087a79SLuiz Augusto von Dentz return; 490552087a79SLuiz Augusto von Dentz 49061da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 49071da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 49081da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 490957d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 49101da177e4SLinus Torvalds 49111da177e4SLinus Torvalds conn->sent++; 49121da177e4SLinus Torvalds if (conn->sent == ~0) 49131da177e4SLinus Torvalds conn->sent = 0; 49141da177e4SLinus Torvalds } 49151da177e4SLinus Torvalds } 49161da177e4SLinus Torvalds } 49171da177e4SLinus Torvalds 49186039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 4919b6a0dc82SMarcel Holtmann { 4920b6a0dc82SMarcel Holtmann struct hci_conn *conn; 4921b6a0dc82SMarcel Holtmann struct sk_buff *skb; 4922b6a0dc82SMarcel Holtmann int quote; 4923b6a0dc82SMarcel Holtmann 4924b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 4925b6a0dc82SMarcel Holtmann 492652087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 492752087a79SLuiz Augusto von Dentz return; 492852087a79SLuiz Augusto von Dentz 49298fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 49308fc9ced3SGustavo Padovan "e))) { 4931b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 4932b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 493357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4934b6a0dc82SMarcel Holtmann 4935b6a0dc82SMarcel Holtmann conn->sent++; 4936b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 4937b6a0dc82SMarcel Holtmann conn->sent = 0; 4938b6a0dc82SMarcel Holtmann } 4939b6a0dc82SMarcel Holtmann } 4940b6a0dc82SMarcel Holtmann } 4941b6a0dc82SMarcel Holtmann 49426039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 49436ed58ec5SVille Tervo { 494473d80debSLuiz Augusto von Dentz struct hci_chan *chan; 49456ed58ec5SVille Tervo struct sk_buff *skb; 494602b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 49476ed58ec5SVille Tervo 49486ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 49496ed58ec5SVille Tervo 495052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 495152087a79SLuiz Augusto von Dentz return; 495252087a79SLuiz Augusto von Dentz 4953fee746b0SMarcel Holtmann if (!test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) { 49546ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 49556ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 4956bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 49576ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 4958bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 49596ed58ec5SVille Tervo } 49606ed58ec5SVille Tervo 49616ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 496202b20f0bSLuiz Augusto von Dentz tmp = cnt; 496373d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 4964ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4965ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 496673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 496773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 49686ed58ec5SVille Tervo 4969ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4970ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4971ec1cce24SLuiz Augusto von Dentz break; 4972ec1cce24SLuiz Augusto von Dentz 4973ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4974ec1cce24SLuiz Augusto von Dentz 497557d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 49766ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 49776ed58ec5SVille Tervo 49786ed58ec5SVille Tervo cnt--; 497973d80debSLuiz Augusto von Dentz chan->sent++; 498073d80debSLuiz Augusto von Dentz chan->conn->sent++; 49816ed58ec5SVille Tervo } 49826ed58ec5SVille Tervo } 498373d80debSLuiz Augusto von Dentz 49846ed58ec5SVille Tervo if (hdev->le_pkts) 49856ed58ec5SVille Tervo hdev->le_cnt = cnt; 49866ed58ec5SVille Tervo else 49876ed58ec5SVille Tervo hdev->acl_cnt = cnt; 498802b20f0bSLuiz Augusto von Dentz 498902b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 499002b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 49916ed58ec5SVille Tervo } 49926ed58ec5SVille Tervo 49933eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 49941da177e4SLinus Torvalds { 49953eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 49961da177e4SLinus Torvalds struct sk_buff *skb; 49971da177e4SLinus Torvalds 49986ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 49996ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 50001da177e4SLinus Torvalds 500152de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 50021da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 50031da177e4SLinus Torvalds hci_sched_acl(hdev); 50041da177e4SLinus Torvalds hci_sched_sco(hdev); 5005b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 50066ed58ec5SVille Tervo hci_sched_le(hdev); 500752de599eSMarcel Holtmann } 50086ed58ec5SVille Tervo 50091da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 50101da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 501157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 50121da177e4SLinus Torvalds } 50131da177e4SLinus Torvalds 501425985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 50151da177e4SLinus Torvalds 50161da177e4SLinus Torvalds /* ACL data packet */ 50176039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 50181da177e4SLinus Torvalds { 50191da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 50201da177e4SLinus Torvalds struct hci_conn *conn; 50211da177e4SLinus Torvalds __u16 handle, flags; 50221da177e4SLinus Torvalds 50231da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 50241da177e4SLinus Torvalds 50251da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 50261da177e4SLinus Torvalds flags = hci_flags(handle); 50271da177e4SLinus Torvalds handle = hci_handle(handle); 50281da177e4SLinus Torvalds 5029f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 5030a8c5fb1aSGustavo Padovan handle, flags); 50311da177e4SLinus Torvalds 50321da177e4SLinus Torvalds hdev->stat.acl_rx++; 50331da177e4SLinus Torvalds 50341da177e4SLinus Torvalds hci_dev_lock(hdev); 50351da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 50361da177e4SLinus Torvalds hci_dev_unlock(hdev); 50371da177e4SLinus Torvalds 50381da177e4SLinus Torvalds if (conn) { 503965983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 504004837f64SMarcel Holtmann 50411da177e4SLinus Torvalds /* Send to upper protocol */ 5042686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 50431da177e4SLinus Torvalds return; 50441da177e4SLinus Torvalds } else { 50451da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 50461da177e4SLinus Torvalds hdev->name, handle); 50471da177e4SLinus Torvalds } 50481da177e4SLinus Torvalds 50491da177e4SLinus Torvalds kfree_skb(skb); 50501da177e4SLinus Torvalds } 50511da177e4SLinus Torvalds 50521da177e4SLinus Torvalds /* SCO data packet */ 50536039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 50541da177e4SLinus Torvalds { 50551da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 50561da177e4SLinus Torvalds struct hci_conn *conn; 50571da177e4SLinus Torvalds __u16 handle; 50581da177e4SLinus Torvalds 50591da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 50601da177e4SLinus Torvalds 50611da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 50621da177e4SLinus Torvalds 5063f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 50641da177e4SLinus Torvalds 50651da177e4SLinus Torvalds hdev->stat.sco_rx++; 50661da177e4SLinus Torvalds 50671da177e4SLinus Torvalds hci_dev_lock(hdev); 50681da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 50691da177e4SLinus Torvalds hci_dev_unlock(hdev); 50701da177e4SLinus Torvalds 50711da177e4SLinus Torvalds if (conn) { 50721da177e4SLinus Torvalds /* Send to upper protocol */ 5073686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 50741da177e4SLinus Torvalds return; 50751da177e4SLinus Torvalds } else { 50761da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 50771da177e4SLinus Torvalds hdev->name, handle); 50781da177e4SLinus Torvalds } 50791da177e4SLinus Torvalds 50801da177e4SLinus Torvalds kfree_skb(skb); 50811da177e4SLinus Torvalds } 50821da177e4SLinus Torvalds 50839238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 50849238f36aSJohan Hedberg { 50859238f36aSJohan Hedberg struct sk_buff *skb; 50869238f36aSJohan Hedberg 50879238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 50889238f36aSJohan Hedberg if (!skb) 50899238f36aSJohan Hedberg return true; 50909238f36aSJohan Hedberg 50919238f36aSJohan Hedberg return bt_cb(skb)->req.start; 50929238f36aSJohan Hedberg } 50939238f36aSJohan Hedberg 509442c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 509542c6b129SJohan Hedberg { 509642c6b129SJohan Hedberg struct hci_command_hdr *sent; 509742c6b129SJohan Hedberg struct sk_buff *skb; 509842c6b129SJohan Hedberg u16 opcode; 509942c6b129SJohan Hedberg 510042c6b129SJohan Hedberg if (!hdev->sent_cmd) 510142c6b129SJohan Hedberg return; 510242c6b129SJohan Hedberg 510342c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 510442c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 510542c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 510642c6b129SJohan Hedberg return; 510742c6b129SJohan Hedberg 510842c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 510942c6b129SJohan Hedberg if (!skb) 511042c6b129SJohan Hedberg return; 511142c6b129SJohan Hedberg 511242c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 511342c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 511442c6b129SJohan Hedberg } 511542c6b129SJohan Hedberg 51169238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 51179238f36aSJohan Hedberg { 51189238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 51199238f36aSJohan Hedberg struct sk_buff *skb; 51209238f36aSJohan Hedberg unsigned long flags; 51219238f36aSJohan Hedberg 51229238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 51239238f36aSJohan Hedberg 512442c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 512542c6b129SJohan Hedberg * sent we need to do special handling of it. 51269238f36aSJohan Hedberg */ 512742c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 512842c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 512942c6b129SJohan Hedberg * reset complete event during init and any pending 513042c6b129SJohan Hedberg * command will never be completed. In such a case we 513142c6b129SJohan Hedberg * need to resend whatever was the last sent 513242c6b129SJohan Hedberg * command. 513342c6b129SJohan Hedberg */ 513442c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 513542c6b129SJohan Hedberg hci_resend_last(hdev); 513642c6b129SJohan Hedberg 51379238f36aSJohan Hedberg return; 513842c6b129SJohan Hedberg } 51399238f36aSJohan Hedberg 51409238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 51419238f36aSJohan Hedberg * this request the request is not yet complete. 51429238f36aSJohan Hedberg */ 51439238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 51449238f36aSJohan Hedberg return; 51459238f36aSJohan Hedberg 51469238f36aSJohan Hedberg /* If this was the last command in a request the complete 51479238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 51489238f36aSJohan Hedberg * command queue (hdev->cmd_q). 51499238f36aSJohan Hedberg */ 51509238f36aSJohan Hedberg if (hdev->sent_cmd) { 51519238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 515253e21fbcSJohan Hedberg 515353e21fbcSJohan Hedberg if (req_complete) { 515453e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 515553e21fbcSJohan Hedberg * avoid calling the callback more than once if 515653e21fbcSJohan Hedberg * this function gets called again. 515753e21fbcSJohan Hedberg */ 515853e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 515953e21fbcSJohan Hedberg 51609238f36aSJohan Hedberg goto call_complete; 51619238f36aSJohan Hedberg } 516253e21fbcSJohan Hedberg } 51639238f36aSJohan Hedberg 51649238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 51659238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 51669238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 51679238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 51689238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 51699238f36aSJohan Hedberg break; 51709238f36aSJohan Hedberg } 51719238f36aSJohan Hedberg 51729238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 51739238f36aSJohan Hedberg kfree_skb(skb); 51749238f36aSJohan Hedberg } 51759238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 51769238f36aSJohan Hedberg 51779238f36aSJohan Hedberg call_complete: 51789238f36aSJohan Hedberg if (req_complete) 51799238f36aSJohan Hedberg req_complete(hdev, status); 51809238f36aSJohan Hedberg } 51819238f36aSJohan Hedberg 5182b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 51831da177e4SLinus Torvalds { 5184b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 51851da177e4SLinus Torvalds struct sk_buff *skb; 51861da177e4SLinus Torvalds 51871da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 51881da177e4SLinus Torvalds 51891da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 5190cd82e61cSMarcel Holtmann /* Send copy to monitor */ 5191cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 5192cd82e61cSMarcel Holtmann 51931da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 51941da177e4SLinus Torvalds /* Send copy to the sockets */ 5195470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 51961da177e4SLinus Torvalds } 51971da177e4SLinus Torvalds 5198fee746b0SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 51991da177e4SLinus Torvalds kfree_skb(skb); 52001da177e4SLinus Torvalds continue; 52011da177e4SLinus Torvalds } 52021da177e4SLinus Torvalds 52031da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 52041da177e4SLinus Torvalds /* Don't process data packets in this states. */ 52050d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 52061da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 52071da177e4SLinus Torvalds case HCI_SCODATA_PKT: 52081da177e4SLinus Torvalds kfree_skb(skb); 52091da177e4SLinus Torvalds continue; 52103ff50b79SStephen Hemminger } 52111da177e4SLinus Torvalds } 52121da177e4SLinus Torvalds 52131da177e4SLinus Torvalds /* Process frame */ 52140d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 52151da177e4SLinus Torvalds case HCI_EVENT_PKT: 5216b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 52171da177e4SLinus Torvalds hci_event_packet(hdev, skb); 52181da177e4SLinus Torvalds break; 52191da177e4SLinus Torvalds 52201da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 52211da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 52221da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 52231da177e4SLinus Torvalds break; 52241da177e4SLinus Torvalds 52251da177e4SLinus Torvalds case HCI_SCODATA_PKT: 52261da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 52271da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 52281da177e4SLinus Torvalds break; 52291da177e4SLinus Torvalds 52301da177e4SLinus Torvalds default: 52311da177e4SLinus Torvalds kfree_skb(skb); 52321da177e4SLinus Torvalds break; 52331da177e4SLinus Torvalds } 52341da177e4SLinus Torvalds } 52351da177e4SLinus Torvalds } 52361da177e4SLinus Torvalds 5237c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 52381da177e4SLinus Torvalds { 5239c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 52401da177e4SLinus Torvalds struct sk_buff *skb; 52411da177e4SLinus Torvalds 52422104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 52432104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 52441da177e4SLinus Torvalds 52451da177e4SLinus Torvalds /* Send queued commands */ 52465a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 52475a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 52485a08ecceSAndrei Emeltchenko if (!skb) 52495a08ecceSAndrei Emeltchenko return; 52505a08ecceSAndrei Emeltchenko 52511da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 52521da177e4SLinus Torvalds 5253a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 525470f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 52551da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 525657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 52577bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 525865cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 52597bdb8a5cSSzymon Janc else 526065cc2b49SMarcel Holtmann schedule_delayed_work(&hdev->cmd_timer, 526165cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT); 52621da177e4SLinus Torvalds } else { 52631da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 5264c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 52651da177e4SLinus Torvalds } 52661da177e4SLinus Torvalds } 52671da177e4SLinus Torvalds } 5268b1efcc28SAndre Guedes 5269b1efcc28SAndre Guedes void hci_req_add_le_scan_disable(struct hci_request *req) 5270b1efcc28SAndre Guedes { 5271b1efcc28SAndre Guedes struct hci_cp_le_set_scan_enable cp; 5272b1efcc28SAndre Guedes 5273b1efcc28SAndre Guedes memset(&cp, 0, sizeof(cp)); 5274b1efcc28SAndre Guedes cp.enable = LE_SCAN_DISABLE; 5275b1efcc28SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 5276b1efcc28SAndre Guedes } 5277a4790dbdSAndre Guedes 52788ef30fd3SAndre Guedes void hci_req_add_le_passive_scan(struct hci_request *req) 52798ef30fd3SAndre Guedes { 52808ef30fd3SAndre Guedes struct hci_cp_le_set_scan_param param_cp; 52818ef30fd3SAndre Guedes struct hci_cp_le_set_scan_enable enable_cp; 52828ef30fd3SAndre Guedes struct hci_dev *hdev = req->hdev; 52838ef30fd3SAndre Guedes u8 own_addr_type; 52848ef30fd3SAndre Guedes 52856ab535a7SMarcel Holtmann /* Set require_privacy to false since no SCAN_REQ are send 52866ab535a7SMarcel Holtmann * during passive scanning. Not using an unresolvable address 52876ab535a7SMarcel Holtmann * here is important so that peer devices using direct 52886ab535a7SMarcel Holtmann * advertising with our address will be correctly reported 52896ab535a7SMarcel Holtmann * by the controller. 52908ef30fd3SAndre Guedes */ 52916ab535a7SMarcel Holtmann if (hci_update_random_address(req, false, &own_addr_type)) 52928ef30fd3SAndre Guedes return; 52938ef30fd3SAndre Guedes 52948ef30fd3SAndre Guedes memset(¶m_cp, 0, sizeof(param_cp)); 52958ef30fd3SAndre Guedes param_cp.type = LE_SCAN_PASSIVE; 52968ef30fd3SAndre Guedes param_cp.interval = cpu_to_le16(hdev->le_scan_interval); 52978ef30fd3SAndre Guedes param_cp.window = cpu_to_le16(hdev->le_scan_window); 52988ef30fd3SAndre Guedes param_cp.own_address_type = own_addr_type; 52998ef30fd3SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), 53008ef30fd3SAndre Guedes ¶m_cp); 53018ef30fd3SAndre Guedes 53028ef30fd3SAndre Guedes memset(&enable_cp, 0, sizeof(enable_cp)); 53038ef30fd3SAndre Guedes enable_cp.enable = LE_SCAN_ENABLE; 53044340a124SAndre Guedes enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; 53058ef30fd3SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), 53068ef30fd3SAndre Guedes &enable_cp); 53078ef30fd3SAndre Guedes } 53088ef30fd3SAndre Guedes 5309a4790dbdSAndre Guedes static void update_background_scan_complete(struct hci_dev *hdev, u8 status) 5310a4790dbdSAndre Guedes { 5311a4790dbdSAndre Guedes if (status) 5312a4790dbdSAndre Guedes BT_DBG("HCI request failed to update background scanning: " 5313a4790dbdSAndre Guedes "status 0x%2.2x", status); 5314a4790dbdSAndre Guedes } 5315a4790dbdSAndre Guedes 5316a4790dbdSAndre Guedes /* This function controls the background scanning based on hdev->pend_le_conns 5317a4790dbdSAndre Guedes * list. If there are pending LE connection we start the background scanning, 5318a4790dbdSAndre Guedes * otherwise we stop it. 5319a4790dbdSAndre Guedes * 5320a4790dbdSAndre Guedes * This function requires the caller holds hdev->lock. 5321a4790dbdSAndre Guedes */ 5322a4790dbdSAndre Guedes void hci_update_background_scan(struct hci_dev *hdev) 5323a4790dbdSAndre Guedes { 5324a4790dbdSAndre Guedes struct hci_request req; 5325a4790dbdSAndre Guedes struct hci_conn *conn; 5326a4790dbdSAndre Guedes int err; 5327a4790dbdSAndre Guedes 5328c20c02d5SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags) || 5329c20c02d5SMarcel Holtmann test_bit(HCI_INIT, &hdev->flags) || 5330c20c02d5SMarcel Holtmann test_bit(HCI_SETUP, &hdev->dev_flags) || 5331b8221770SMarcel Holtmann test_bit(HCI_AUTO_OFF, &hdev->dev_flags) || 5332c20c02d5SMarcel Holtmann test_bit(HCI_UNREGISTER, &hdev->dev_flags)) 53331c1697c0SMarcel Holtmann return; 53341c1697c0SMarcel Holtmann 5335a4790dbdSAndre Guedes hci_req_init(&req, hdev); 5336a4790dbdSAndre Guedes 5337a4790dbdSAndre Guedes if (list_empty(&hdev->pend_le_conns)) { 5338a4790dbdSAndre Guedes /* If there is no pending LE connections, we should stop 5339a4790dbdSAndre Guedes * the background scanning. 5340a4790dbdSAndre Guedes */ 5341a4790dbdSAndre Guedes 5342a4790dbdSAndre Guedes /* If controller is not scanning we are done. */ 5343a4790dbdSAndre Guedes if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 5344a4790dbdSAndre Guedes return; 5345a4790dbdSAndre Guedes 5346a4790dbdSAndre Guedes hci_req_add_le_scan_disable(&req); 5347a4790dbdSAndre Guedes 5348a4790dbdSAndre Guedes BT_DBG("%s stopping background scanning", hdev->name); 5349a4790dbdSAndre Guedes } else { 5350a4790dbdSAndre Guedes /* If there is at least one pending LE connection, we should 5351a4790dbdSAndre Guedes * keep the background scan running. 5352a4790dbdSAndre Guedes */ 5353a4790dbdSAndre Guedes 5354a4790dbdSAndre Guedes /* If controller is connecting, we should not start scanning 5355a4790dbdSAndre Guedes * since some controllers are not able to scan and connect at 5356a4790dbdSAndre Guedes * the same time. 5357a4790dbdSAndre Guedes */ 5358a4790dbdSAndre Guedes conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 5359a4790dbdSAndre Guedes if (conn) 5360a4790dbdSAndre Guedes return; 5361a4790dbdSAndre Guedes 53624340a124SAndre Guedes /* If controller is currently scanning, we stop it to ensure we 53634340a124SAndre Guedes * don't miss any advertising (due to duplicates filter). 53644340a124SAndre Guedes */ 53654340a124SAndre Guedes if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 53664340a124SAndre Guedes hci_req_add_le_scan_disable(&req); 53674340a124SAndre Guedes 53688ef30fd3SAndre Guedes hci_req_add_le_passive_scan(&req); 5369a4790dbdSAndre Guedes 5370a4790dbdSAndre Guedes BT_DBG("%s starting background scanning", hdev->name); 5371a4790dbdSAndre Guedes } 5372a4790dbdSAndre Guedes 5373a4790dbdSAndre Guedes err = hci_req_run(&req, update_background_scan_complete); 5374a4790dbdSAndre Guedes if (err) 5375a4790dbdSAndre Guedes BT_ERR("Failed to run HCI request: err %d", err); 5376a4790dbdSAndre Guedes } 5377