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 17940ebca7d6SMarcel Holtmann static void hci_init0_req(struct hci_request *req, unsigned long opt) 17950ebca7d6SMarcel Holtmann { 17960ebca7d6SMarcel Holtmann struct hci_dev *hdev = req->hdev; 17970ebca7d6SMarcel Holtmann 17980ebca7d6SMarcel Holtmann BT_DBG("%s %ld", hdev->name, opt); 17990ebca7d6SMarcel Holtmann 18000ebca7d6SMarcel Holtmann /* Reset */ 18010ebca7d6SMarcel Holtmann if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 18020ebca7d6SMarcel Holtmann hci_reset_req(req, 0); 18030ebca7d6SMarcel Holtmann 18040ebca7d6SMarcel Holtmann /* Read Local Version */ 18050ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 18060ebca7d6SMarcel Holtmann 18070ebca7d6SMarcel Holtmann /* Read BD Address */ 18080ebca7d6SMarcel Holtmann if (hdev->set_bdaddr) 18090ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 18100ebca7d6SMarcel Holtmann } 18110ebca7d6SMarcel Holtmann 18120ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev) 18130ebca7d6SMarcel Holtmann { 18140ebca7d6SMarcel Holtmann int err; 18150ebca7d6SMarcel Holtmann 18160ebca7d6SMarcel Holtmann err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT); 18170ebca7d6SMarcel Holtmann if (err < 0) 18180ebca7d6SMarcel Holtmann return err; 18190ebca7d6SMarcel Holtmann 18200ebca7d6SMarcel Holtmann return 0; 18210ebca7d6SMarcel Holtmann } 18220ebca7d6SMarcel Holtmann 182342c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 18241da177e4SLinus Torvalds { 18251da177e4SLinus Torvalds __u8 scan = opt; 18261da177e4SLinus Torvalds 182742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 18281da177e4SLinus Torvalds 18291da177e4SLinus Torvalds /* Inquiry and Page scans */ 183042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 18311da177e4SLinus Torvalds } 18321da177e4SLinus Torvalds 183342c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 18341da177e4SLinus Torvalds { 18351da177e4SLinus Torvalds __u8 auth = opt; 18361da177e4SLinus Torvalds 183742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 18381da177e4SLinus Torvalds 18391da177e4SLinus Torvalds /* Authentication */ 184042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 18411da177e4SLinus Torvalds } 18421da177e4SLinus Torvalds 184342c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 18441da177e4SLinus Torvalds { 18451da177e4SLinus Torvalds __u8 encrypt = opt; 18461da177e4SLinus Torvalds 184742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 18481da177e4SLinus Torvalds 1849e4e8e37cSMarcel Holtmann /* Encryption */ 185042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 18511da177e4SLinus Torvalds } 18521da177e4SLinus Torvalds 185342c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 1854e4e8e37cSMarcel Holtmann { 1855e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1856e4e8e37cSMarcel Holtmann 185742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1858e4e8e37cSMarcel Holtmann 1859e4e8e37cSMarcel Holtmann /* Default link policy */ 186042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1861e4e8e37cSMarcel Holtmann } 1862e4e8e37cSMarcel Holtmann 18631da177e4SLinus Torvalds /* Get HCI device by index. 18641da177e4SLinus Torvalds * Device is held on return. */ 18651da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 18661da177e4SLinus Torvalds { 18678035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 18681da177e4SLinus Torvalds 18691da177e4SLinus Torvalds BT_DBG("%d", index); 18701da177e4SLinus Torvalds 18711da177e4SLinus Torvalds if (index < 0) 18721da177e4SLinus Torvalds return NULL; 18731da177e4SLinus Torvalds 18741da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 18758035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 18761da177e4SLinus Torvalds if (d->id == index) { 18771da177e4SLinus Torvalds hdev = hci_dev_hold(d); 18781da177e4SLinus Torvalds break; 18791da177e4SLinus Torvalds } 18801da177e4SLinus Torvalds } 18811da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 18821da177e4SLinus Torvalds return hdev; 18831da177e4SLinus Torvalds } 18841da177e4SLinus Torvalds 18851da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1886ff9ef578SJohan Hedberg 188730dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 188830dc78e1SJohan Hedberg { 188930dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 189030dc78e1SJohan Hedberg 18916fbe195dSAndre Guedes switch (discov->state) { 1892343f935bSAndre Guedes case DISCOVERY_FINDING: 18936fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 189430dc78e1SJohan Hedberg return true; 189530dc78e1SJohan Hedberg 18966fbe195dSAndre Guedes default: 189730dc78e1SJohan Hedberg return false; 189830dc78e1SJohan Hedberg } 18996fbe195dSAndre Guedes } 190030dc78e1SJohan Hedberg 1901ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1902ff9ef578SJohan Hedberg { 1903ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1904ff9ef578SJohan Hedberg 1905ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 1906ff9ef578SJohan Hedberg return; 1907ff9ef578SJohan Hedberg 1908ff9ef578SJohan Hedberg switch (state) { 1909ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 1910c54c3860SAndre Guedes hci_update_background_scan(hdev); 1911c54c3860SAndre Guedes 19127b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 1913ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1914ff9ef578SJohan Hedberg break; 1915ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1916ff9ef578SJohan Hedberg break; 1917343f935bSAndre Guedes case DISCOVERY_FINDING: 1918ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1919ff9ef578SJohan Hedberg break; 192030dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 192130dc78e1SJohan Hedberg break; 1922ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1923ff9ef578SJohan Hedberg break; 1924ff9ef578SJohan Hedberg } 1925ff9ef578SJohan Hedberg 1926ff9ef578SJohan Hedberg hdev->discovery.state = state; 1927ff9ef578SJohan Hedberg } 1928ff9ef578SJohan Hedberg 19291f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 19301da177e4SLinus Torvalds { 193130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1932b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 19331da177e4SLinus Torvalds 1934561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1935561aafbcSJohan Hedberg list_del(&p->all); 1936b57c1a56SJohan Hedberg kfree(p); 19371da177e4SLinus Torvalds } 1938561aafbcSJohan Hedberg 1939561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1940561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 19411da177e4SLinus Torvalds } 19421da177e4SLinus Torvalds 1943a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1944a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 19451da177e4SLinus Torvalds { 194630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 19471da177e4SLinus Torvalds struct inquiry_entry *e; 19481da177e4SLinus Torvalds 19496ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 19501da177e4SLinus Torvalds 1951561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 19521da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 19531da177e4SLinus Torvalds return e; 19541da177e4SLinus Torvalds } 19551da177e4SLinus Torvalds 1956b57c1a56SJohan Hedberg return NULL; 1957b57c1a56SJohan Hedberg } 1958b57c1a56SJohan Hedberg 1959561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1960561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1961561aafbcSJohan Hedberg { 196230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1963561aafbcSJohan Hedberg struct inquiry_entry *e; 1964561aafbcSJohan Hedberg 19656ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1966561aafbcSJohan Hedberg 1967561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1968561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1969561aafbcSJohan Hedberg return e; 1970561aafbcSJohan Hedberg } 1971561aafbcSJohan Hedberg 1972561aafbcSJohan Hedberg return NULL; 1973561aafbcSJohan Hedberg } 1974561aafbcSJohan Hedberg 197530dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 197630dc78e1SJohan Hedberg bdaddr_t *bdaddr, 197730dc78e1SJohan Hedberg int state) 197830dc78e1SJohan Hedberg { 197930dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 198030dc78e1SJohan Hedberg struct inquiry_entry *e; 198130dc78e1SJohan Hedberg 19826ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 198330dc78e1SJohan Hedberg 198430dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 198530dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 198630dc78e1SJohan Hedberg return e; 198730dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 198830dc78e1SJohan Hedberg return e; 198930dc78e1SJohan Hedberg } 199030dc78e1SJohan Hedberg 199130dc78e1SJohan Hedberg return NULL; 199230dc78e1SJohan Hedberg } 199330dc78e1SJohan Hedberg 1994a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1995a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1996a3d4e20aSJohan Hedberg { 1997a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1998a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1999a3d4e20aSJohan Hedberg struct inquiry_entry *p; 2000a3d4e20aSJohan Hedberg 2001a3d4e20aSJohan Hedberg list_del(&ie->list); 2002a3d4e20aSJohan Hedberg 2003a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 2004a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 2005a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 2006a3d4e20aSJohan Hedberg break; 2007a3d4e20aSJohan Hedberg pos = &p->list; 2008a3d4e20aSJohan Hedberg } 2009a3d4e20aSJohan Hedberg 2010a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 2011a3d4e20aSJohan Hedberg } 2012a3d4e20aSJohan Hedberg 2013af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 2014af58925cSMarcel Holtmann bool name_known) 20151da177e4SLinus Torvalds { 201630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 201770f23020SAndrei Emeltchenko struct inquiry_entry *ie; 2018af58925cSMarcel Holtmann u32 flags = 0; 20191da177e4SLinus Torvalds 20206ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 20211da177e4SLinus Torvalds 20222b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 20232b2fec4dSSzymon Janc 2024af58925cSMarcel Holtmann if (!data->ssp_mode) 2025af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 2026388fc8faSJohan Hedberg 202770f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 2028a3d4e20aSJohan Hedberg if (ie) { 2029af58925cSMarcel Holtmann if (!ie->data.ssp_mode) 2030af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 2031388fc8faSJohan Hedberg 2032a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 2033a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 2034a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 2035a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 2036a3d4e20aSJohan Hedberg } 2037a3d4e20aSJohan Hedberg 2038561aafbcSJohan Hedberg goto update; 2039a3d4e20aSJohan Hedberg } 2040561aafbcSJohan Hedberg 20411da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 204270f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 2043af58925cSMarcel Holtmann if (!ie) { 2044af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 2045af58925cSMarcel Holtmann goto done; 2046af58925cSMarcel Holtmann } 204770f23020SAndrei Emeltchenko 2048561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 2049561aafbcSJohan Hedberg 2050561aafbcSJohan Hedberg if (name_known) { 2051561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 2052561aafbcSJohan Hedberg } else { 2053561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 2054561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 2055561aafbcSJohan Hedberg } 2056561aafbcSJohan Hedberg 2057561aafbcSJohan Hedberg update: 2058561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 2059561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 2060561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 2061561aafbcSJohan Hedberg list_del(&ie->list); 20621da177e4SLinus Torvalds } 20631da177e4SLinus Torvalds 206470f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 206570f23020SAndrei Emeltchenko ie->timestamp = jiffies; 20661da177e4SLinus Torvalds cache->timestamp = jiffies; 20673175405bSJohan Hedberg 20683175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 2069af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 20703175405bSJohan Hedberg 2071af58925cSMarcel Holtmann done: 2072af58925cSMarcel Holtmann return flags; 20731da177e4SLinus Torvalds } 20741da177e4SLinus Torvalds 20751da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 20761da177e4SLinus Torvalds { 207730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 20781da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 20791da177e4SLinus Torvalds struct inquiry_entry *e; 20801da177e4SLinus Torvalds int copied = 0; 20811da177e4SLinus Torvalds 2082561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 20831da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 2084b57c1a56SJohan Hedberg 2085b57c1a56SJohan Hedberg if (copied >= num) 2086b57c1a56SJohan Hedberg break; 2087b57c1a56SJohan Hedberg 20881da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 20891da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 20901da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 20911da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 20921da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 20931da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 2094b57c1a56SJohan Hedberg 20951da177e4SLinus Torvalds info++; 2096b57c1a56SJohan Hedberg copied++; 20971da177e4SLinus Torvalds } 20981da177e4SLinus Torvalds 20991da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 21001da177e4SLinus Torvalds return copied; 21011da177e4SLinus Torvalds } 21021da177e4SLinus Torvalds 210342c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 21041da177e4SLinus Torvalds { 21051da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 210642c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 21071da177e4SLinus Torvalds struct hci_cp_inquiry cp; 21081da177e4SLinus Torvalds 21091da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 21101da177e4SLinus Torvalds 21111da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 21121da177e4SLinus Torvalds return; 21131da177e4SLinus Torvalds 21141da177e4SLinus Torvalds /* Start Inquiry */ 21151da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 21161da177e4SLinus Torvalds cp.length = ir->length; 21171da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 211842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 21191da177e4SLinus Torvalds } 21201da177e4SLinus Torvalds 21213e13fa1eSAndre Guedes static int wait_inquiry(void *word) 21223e13fa1eSAndre Guedes { 21233e13fa1eSAndre Guedes schedule(); 21243e13fa1eSAndre Guedes return signal_pending(current); 21253e13fa1eSAndre Guedes } 21263e13fa1eSAndre Guedes 21271da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 21281da177e4SLinus Torvalds { 21291da177e4SLinus Torvalds __u8 __user *ptr = arg; 21301da177e4SLinus Torvalds struct hci_inquiry_req ir; 21311da177e4SLinus Torvalds struct hci_dev *hdev; 21321da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 21331da177e4SLinus Torvalds long timeo; 21341da177e4SLinus Torvalds __u8 *buf; 21351da177e4SLinus Torvalds 21361da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 21371da177e4SLinus Torvalds return -EFAULT; 21381da177e4SLinus Torvalds 21395a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 21405a08ecceSAndrei Emeltchenko if (!hdev) 21411da177e4SLinus Torvalds return -ENODEV; 21421da177e4SLinus Torvalds 21430736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 21440736cfa8SMarcel Holtmann err = -EBUSY; 21450736cfa8SMarcel Holtmann goto done; 21460736cfa8SMarcel Holtmann } 21470736cfa8SMarcel Holtmann 21484a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 2149fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2150fee746b0SMarcel Holtmann goto done; 2151fee746b0SMarcel Holtmann } 2152fee746b0SMarcel Holtmann 21535b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 21545b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 21555b69bef5SMarcel Holtmann goto done; 21565b69bef5SMarcel Holtmann } 21575b69bef5SMarcel Holtmann 215856f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 215956f87901SJohan Hedberg err = -EOPNOTSUPP; 216056f87901SJohan Hedberg goto done; 216156f87901SJohan Hedberg } 216256f87901SJohan Hedberg 216309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 21641da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 2165a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 21661f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 21671da177e4SLinus Torvalds do_inquiry = 1; 21681da177e4SLinus Torvalds } 216909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 21701da177e4SLinus Torvalds 217104837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 217270f23020SAndrei Emeltchenko 217370f23020SAndrei Emeltchenko if (do_inquiry) { 217401178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 217501178cd4SJohan Hedberg timeo); 217670f23020SAndrei Emeltchenko if (err < 0) 21771da177e4SLinus Torvalds goto done; 21783e13fa1eSAndre Guedes 21793e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 21803e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 21813e13fa1eSAndre Guedes */ 21823e13fa1eSAndre Guedes if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, 21833e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 21843e13fa1eSAndre Guedes return -EINTR; 218570f23020SAndrei Emeltchenko } 21861da177e4SLinus Torvalds 21878fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 21888fc9ced3SGustavo Padovan * 255 entries 21898fc9ced3SGustavo Padovan */ 21901da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 21911da177e4SLinus Torvalds 21921da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 21931da177e4SLinus Torvalds * copy it to the user space. 21941da177e4SLinus Torvalds */ 219570f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 219670f23020SAndrei Emeltchenko if (!buf) { 21971da177e4SLinus Torvalds err = -ENOMEM; 21981da177e4SLinus Torvalds goto done; 21991da177e4SLinus Torvalds } 22001da177e4SLinus Torvalds 220109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 22021da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 220309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 22041da177e4SLinus Torvalds 22051da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 22061da177e4SLinus Torvalds 22071da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 22081da177e4SLinus Torvalds ptr += sizeof(ir); 22091da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 22101da177e4SLinus Torvalds ir.num_rsp)) 22111da177e4SLinus Torvalds err = -EFAULT; 22121da177e4SLinus Torvalds } else 22131da177e4SLinus Torvalds err = -EFAULT; 22141da177e4SLinus Torvalds 22151da177e4SLinus Torvalds kfree(buf); 22161da177e4SLinus Torvalds 22171da177e4SLinus Torvalds done: 22181da177e4SLinus Torvalds hci_dev_put(hdev); 22191da177e4SLinus Torvalds return err; 22201da177e4SLinus Torvalds } 22211da177e4SLinus Torvalds 2222cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 22231da177e4SLinus Torvalds { 22241da177e4SLinus Torvalds int ret = 0; 22251da177e4SLinus Torvalds 22261da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 22271da177e4SLinus Torvalds 22281da177e4SLinus Torvalds hci_req_lock(hdev); 22291da177e4SLinus Torvalds 223094324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 223194324962SJohan Hovold ret = -ENODEV; 223294324962SJohan Hovold goto done; 223394324962SJohan Hovold } 223494324962SJohan Hovold 2235*d603b76bSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 2236*d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags)) { 2237a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 2238a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 2239bf543036SJohan Hedberg */ 2240a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 2241611b30f7SMarcel Holtmann ret = -ERFKILL; 2242611b30f7SMarcel Holtmann goto done; 2243611b30f7SMarcel Holtmann } 2244611b30f7SMarcel Holtmann 2245a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 2246a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 2247a5c8f270SMarcel Holtmann * be able to determine if there is a public address 2248a5c8f270SMarcel Holtmann * or not. 2249a5c8f270SMarcel Holtmann * 2250c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 2251c6beca0eSMarcel Holtmann * if a public address or static random address is 2252c6beca0eSMarcel Holtmann * available. 2253c6beca0eSMarcel Holtmann * 2254a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 2255a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 2256a5c8f270SMarcel Holtmann */ 2257c6beca0eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 2258c6beca0eSMarcel Holtmann hdev->dev_type == HCI_BREDR && 2259a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2260a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 2261a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 2262a5c8f270SMarcel Holtmann goto done; 2263a5c8f270SMarcel Holtmann } 2264a5c8f270SMarcel Holtmann } 2265a5c8f270SMarcel Holtmann 22661da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 22671da177e4SLinus Torvalds ret = -EALREADY; 22681da177e4SLinus Torvalds goto done; 22691da177e4SLinus Torvalds } 22701da177e4SLinus Torvalds 22711da177e4SLinus Torvalds if (hdev->open(hdev)) { 22721da177e4SLinus Torvalds ret = -EIO; 22731da177e4SLinus Torvalds goto done; 22741da177e4SLinus Torvalds } 22751da177e4SLinus Torvalds 22761da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 22771da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 2278f41c70c4SMarcel Holtmann 2279af202f84SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 2280af202f84SMarcel Holtmann if (hdev->setup) 2281f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 2282f41c70c4SMarcel Holtmann 2283af202f84SMarcel Holtmann /* The transport driver can set these quirks before 2284af202f84SMarcel Holtmann * creating the HCI device or in its setup callback. 2285af202f84SMarcel Holtmann * 2286af202f84SMarcel Holtmann * In case any of them is set, the controller has to 2287af202f84SMarcel Holtmann * start up as unconfigured. 2288af202f84SMarcel Holtmann */ 2289eb1904f4SMarcel Holtmann if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) || 2290eb1904f4SMarcel Holtmann test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks)) 229189bc22d2SMarcel Holtmann set_bit(HCI_UNCONFIGURED, &hdev->dev_flags); 22920ebca7d6SMarcel Holtmann 22930ebca7d6SMarcel Holtmann /* For an unconfigured controller it is required to 22940ebca7d6SMarcel Holtmann * read at least the version information provided by 22950ebca7d6SMarcel Holtmann * the Read Local Version Information command. 22960ebca7d6SMarcel Holtmann * 22970ebca7d6SMarcel Holtmann * If the set_bdaddr driver callback is provided, then 22980ebca7d6SMarcel Holtmann * also the original Bluetooth public device address 22990ebca7d6SMarcel Holtmann * will be read using the Read BD Address command. 23000ebca7d6SMarcel Holtmann */ 23010ebca7d6SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) 23020ebca7d6SMarcel Holtmann ret = __hci_unconf_init(hdev); 230389bc22d2SMarcel Holtmann } 230489bc22d2SMarcel Holtmann 230524c457e2SMarcel Holtmann /* If public address change is configured, ensure that the 230624c457e2SMarcel Holtmann * address gets programmed. If the driver does not support 230724c457e2SMarcel Holtmann * changing the public address, fail the power on procedure. 230824c457e2SMarcel Holtmann */ 230924c457e2SMarcel Holtmann if (!ret && bacmp(&hdev->public_addr, BDADDR_ANY)) { 231024c457e2SMarcel Holtmann if (hdev->set_bdaddr) 231124c457e2SMarcel Holtmann ret = hdev->set_bdaddr(hdev, &hdev->public_addr); 231224c457e2SMarcel Holtmann else 231324c457e2SMarcel Holtmann ret = -EADDRNOTAVAIL; 231424c457e2SMarcel Holtmann } 231524c457e2SMarcel Holtmann 2316f41c70c4SMarcel Holtmann if (!ret) { 23174a964404SMarcel Holtmann if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 23180736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 23192177bab5SJohan Hedberg ret = __hci_init(hdev); 23201da177e4SLinus Torvalds } 23211da177e4SLinus Torvalds 2322f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 2323f41c70c4SMarcel Holtmann 23241da177e4SLinus Torvalds if (!ret) { 23251da177e4SLinus Torvalds hci_dev_hold(hdev); 2326d6bfd59cSJohan Hedberg set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); 23271da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 23281da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 2329bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 2330*d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags) && 23314a964404SMarcel Holtmann !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 23320736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 23331514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 233409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2335744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 233609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 233756e5cb86SJohan Hedberg } 23381da177e4SLinus Torvalds } else { 23391da177e4SLinus Torvalds /* Init failed, cleanup */ 23403eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2341c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 2342b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 23431da177e4SLinus Torvalds 23441da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 23451da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 23461da177e4SLinus Torvalds 23471da177e4SLinus Torvalds if (hdev->flush) 23481da177e4SLinus Torvalds hdev->flush(hdev); 23491da177e4SLinus Torvalds 23501da177e4SLinus Torvalds if (hdev->sent_cmd) { 23511da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 23521da177e4SLinus Torvalds hdev->sent_cmd = NULL; 23531da177e4SLinus Torvalds } 23541da177e4SLinus Torvalds 23551da177e4SLinus Torvalds hdev->close(hdev); 2356fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 23571da177e4SLinus Torvalds } 23581da177e4SLinus Torvalds 23591da177e4SLinus Torvalds done: 23601da177e4SLinus Torvalds hci_req_unlock(hdev); 23611da177e4SLinus Torvalds return ret; 23621da177e4SLinus Torvalds } 23631da177e4SLinus Torvalds 2364cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 2365cbed0ca1SJohan Hedberg 2366cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 2367cbed0ca1SJohan Hedberg { 2368cbed0ca1SJohan Hedberg struct hci_dev *hdev; 2369cbed0ca1SJohan Hedberg int err; 2370cbed0ca1SJohan Hedberg 2371cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 2372cbed0ca1SJohan Hedberg if (!hdev) 2373cbed0ca1SJohan Hedberg return -ENODEV; 2374cbed0ca1SJohan Hedberg 23754a964404SMarcel Holtmann /* Devices that are marked as unconfigured can only be powered 2376fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices 2377fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is 2378fee746b0SMarcel Holtmann * possible. 2379fee746b0SMarcel Holtmann * 2380fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag 2381fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to 2382fee746b0SMarcel Holtmann * open the device. 2383fee746b0SMarcel Holtmann */ 23844a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 2385fee746b0SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 2386fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2387fee746b0SMarcel Holtmann goto done; 2388fee746b0SMarcel Holtmann } 2389fee746b0SMarcel Holtmann 2390e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 2391e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 2392e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 2393e1d08f40SJohan Hedberg * completed. 2394e1d08f40SJohan Hedberg */ 2395e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2396e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 2397e1d08f40SJohan Hedberg 2398a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 2399a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 2400a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 2401a5c8f270SMarcel Holtmann */ 2402e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 2403e1d08f40SJohan Hedberg 2404cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 2405cbed0ca1SJohan Hedberg 2406fee746b0SMarcel Holtmann done: 2407cbed0ca1SJohan Hedberg hci_dev_put(hdev); 2408cbed0ca1SJohan Hedberg return err; 2409cbed0ca1SJohan Hedberg } 2410cbed0ca1SJohan Hedberg 2411d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */ 2412d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev) 2413d7347f3cSJohan Hedberg { 2414d7347f3cSJohan Hedberg struct hci_conn_params *p; 2415d7347f3cSJohan Hedberg 2416d7347f3cSJohan Hedberg list_for_each_entry(p, &hdev->le_conn_params, list) 2417d7347f3cSJohan Hedberg list_del_init(&p->action); 2418d7347f3cSJohan Hedberg 2419d7347f3cSJohan Hedberg BT_DBG("All LE pending actions cleared"); 2420d7347f3cSJohan Hedberg } 2421d7347f3cSJohan Hedberg 24221da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 24231da177e4SLinus Torvalds { 24241da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 24251da177e4SLinus Torvalds 242678c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 242778c04c0bSVinicius Costa Gomes 24281da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 24291da177e4SLinus Torvalds hci_req_lock(hdev); 24301da177e4SLinus Torvalds 24311da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 243265cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 24331da177e4SLinus Torvalds hci_req_unlock(hdev); 24341da177e4SLinus Torvalds return 0; 24351da177e4SLinus Torvalds } 24361da177e4SLinus Torvalds 24373eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 24383eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2439b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 24401da177e4SLinus Torvalds 244116ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 2442e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 244316ab91abSJohan Hedberg hdev->discov_timeout = 0; 24445e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 2445310a3d48SMarcel Holtmann clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 244616ab91abSJohan Hedberg } 244716ab91abSJohan Hedberg 2448a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 24497d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 24507d78525dSJohan Hedberg 24517ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 24524518bb0fSJohan Hedberg 24534518bb0fSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 2454d6bfd59cSJohan Hedberg cancel_delayed_work_sync(&hdev->rpa_expired); 24557ba8b4beSAndre Guedes 245609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 24571f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 24581da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 2459d7347f3cSJohan Hedberg hci_pend_le_actions_clear(hdev); 246009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 24611da177e4SLinus Torvalds 24621da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 24631da177e4SLinus Torvalds 24641da177e4SLinus Torvalds if (hdev->flush) 24651da177e4SLinus Torvalds hdev->flush(hdev); 24661da177e4SLinus Torvalds 24671da177e4SLinus Torvalds /* Reset device */ 24681da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 24691da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 24704a964404SMarcel Holtmann if (!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 24714a964404SMarcel Holtmann !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 2472a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 24731da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 247401178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 24751da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 24761da177e4SLinus Torvalds } 24771da177e4SLinus Torvalds 2478c347b765SGustavo F. Padovan /* flush cmd work */ 2479c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 24801da177e4SLinus Torvalds 24811da177e4SLinus Torvalds /* Drop queues */ 24821da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 24831da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 24841da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 24851da177e4SLinus Torvalds 24861da177e4SLinus Torvalds /* Drop last sent command */ 24871da177e4SLinus Torvalds if (hdev->sent_cmd) { 248865cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 24891da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 24901da177e4SLinus Torvalds hdev->sent_cmd = NULL; 24911da177e4SLinus Torvalds } 24921da177e4SLinus Torvalds 2493b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 2494b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 2495b6ddb638SJohan Hedberg 24961da177e4SLinus Torvalds /* After this point our queues are empty 24971da177e4SLinus Torvalds * and no tasks are scheduled. */ 24981da177e4SLinus Torvalds hdev->close(hdev); 24991da177e4SLinus Torvalds 250035b973c9SJohan Hedberg /* Clear flags */ 2501fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 250235b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 250335b973c9SJohan Hedberg 250493c311a0SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 250593c311a0SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 250609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2507744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 250809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 25098ee56540SMarcel Holtmann } 251093c311a0SMarcel Holtmann } 25115add6af8SJohan Hedberg 2512ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 2513536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 2514ced5c338SAndrei Emeltchenko 2515e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 251609b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 25177a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, BDADDR_ANY); 2518e59fda8dSJohan Hedberg 25191da177e4SLinus Torvalds hci_req_unlock(hdev); 25201da177e4SLinus Torvalds 25211da177e4SLinus Torvalds hci_dev_put(hdev); 25221da177e4SLinus Torvalds return 0; 25231da177e4SLinus Torvalds } 25241da177e4SLinus Torvalds 25251da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 25261da177e4SLinus Torvalds { 25271da177e4SLinus Torvalds struct hci_dev *hdev; 25281da177e4SLinus Torvalds int err; 25291da177e4SLinus Torvalds 253070f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 253170f23020SAndrei Emeltchenko if (!hdev) 25321da177e4SLinus Torvalds return -ENODEV; 25338ee56540SMarcel Holtmann 25340736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 25350736cfa8SMarcel Holtmann err = -EBUSY; 25360736cfa8SMarcel Holtmann goto done; 25370736cfa8SMarcel Holtmann } 25380736cfa8SMarcel Holtmann 25398ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 25408ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 25418ee56540SMarcel Holtmann 25421da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 25438ee56540SMarcel Holtmann 25440736cfa8SMarcel Holtmann done: 25451da177e4SLinus Torvalds hci_dev_put(hdev); 25461da177e4SLinus Torvalds return err; 25471da177e4SLinus Torvalds } 25481da177e4SLinus Torvalds 25491da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 25501da177e4SLinus Torvalds { 25511da177e4SLinus Torvalds struct hci_dev *hdev; 25521da177e4SLinus Torvalds int ret = 0; 25531da177e4SLinus Torvalds 255470f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 255570f23020SAndrei Emeltchenko if (!hdev) 25561da177e4SLinus Torvalds return -ENODEV; 25571da177e4SLinus Torvalds 25581da177e4SLinus Torvalds hci_req_lock(hdev); 25591da177e4SLinus Torvalds 2560808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 2561808a049eSMarcel Holtmann ret = -ENETDOWN; 25621da177e4SLinus Torvalds goto done; 2563808a049eSMarcel Holtmann } 25641da177e4SLinus Torvalds 25650736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 25660736cfa8SMarcel Holtmann ret = -EBUSY; 25670736cfa8SMarcel Holtmann goto done; 25680736cfa8SMarcel Holtmann } 25690736cfa8SMarcel Holtmann 25704a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 2571fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 2572fee746b0SMarcel Holtmann goto done; 2573fee746b0SMarcel Holtmann } 2574fee746b0SMarcel Holtmann 25751da177e4SLinus Torvalds /* Drop queues */ 25761da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 25771da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 25781da177e4SLinus Torvalds 257909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 25801f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 25811da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 258209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 25831da177e4SLinus Torvalds 25841da177e4SLinus Torvalds if (hdev->flush) 25851da177e4SLinus Torvalds hdev->flush(hdev); 25861da177e4SLinus Torvalds 25871da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 25886ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 25891da177e4SLinus Torvalds 259001178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 25911da177e4SLinus Torvalds 25921da177e4SLinus Torvalds done: 25931da177e4SLinus Torvalds hci_req_unlock(hdev); 25941da177e4SLinus Torvalds hci_dev_put(hdev); 25951da177e4SLinus Torvalds return ret; 25961da177e4SLinus Torvalds } 25971da177e4SLinus Torvalds 25981da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 25991da177e4SLinus Torvalds { 26001da177e4SLinus Torvalds struct hci_dev *hdev; 26011da177e4SLinus Torvalds int ret = 0; 26021da177e4SLinus Torvalds 260370f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 260470f23020SAndrei Emeltchenko if (!hdev) 26051da177e4SLinus Torvalds return -ENODEV; 26061da177e4SLinus Torvalds 26070736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 26080736cfa8SMarcel Holtmann ret = -EBUSY; 26090736cfa8SMarcel Holtmann goto done; 26100736cfa8SMarcel Holtmann } 26110736cfa8SMarcel Holtmann 26124a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 2613fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 2614fee746b0SMarcel Holtmann goto done; 2615fee746b0SMarcel Holtmann } 2616fee746b0SMarcel Holtmann 26171da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 26181da177e4SLinus Torvalds 26190736cfa8SMarcel Holtmann done: 26201da177e4SLinus Torvalds hci_dev_put(hdev); 26211da177e4SLinus Torvalds return ret; 26221da177e4SLinus Torvalds } 26231da177e4SLinus Torvalds 26241da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 26251da177e4SLinus Torvalds { 26261da177e4SLinus Torvalds struct hci_dev *hdev; 26271da177e4SLinus Torvalds struct hci_dev_req dr; 26281da177e4SLinus Torvalds int err = 0; 26291da177e4SLinus Torvalds 26301da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 26311da177e4SLinus Torvalds return -EFAULT; 26321da177e4SLinus Torvalds 263370f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 263470f23020SAndrei Emeltchenko if (!hdev) 26351da177e4SLinus Torvalds return -ENODEV; 26361da177e4SLinus Torvalds 26370736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 26380736cfa8SMarcel Holtmann err = -EBUSY; 26390736cfa8SMarcel Holtmann goto done; 26400736cfa8SMarcel Holtmann } 26410736cfa8SMarcel Holtmann 26424a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 2643fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2644fee746b0SMarcel Holtmann goto done; 2645fee746b0SMarcel Holtmann } 2646fee746b0SMarcel Holtmann 26475b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 26485b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 26495b69bef5SMarcel Holtmann goto done; 26505b69bef5SMarcel Holtmann } 26515b69bef5SMarcel Holtmann 265256f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 265356f87901SJohan Hedberg err = -EOPNOTSUPP; 265456f87901SJohan Hedberg goto done; 265556f87901SJohan Hedberg } 265656f87901SJohan Hedberg 26571da177e4SLinus Torvalds switch (cmd) { 26581da177e4SLinus Torvalds case HCISETAUTH: 265901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 26605f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26611da177e4SLinus Torvalds break; 26621da177e4SLinus Torvalds 26631da177e4SLinus Torvalds case HCISETENCRYPT: 26641da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 26651da177e4SLinus Torvalds err = -EOPNOTSUPP; 26661da177e4SLinus Torvalds break; 26671da177e4SLinus Torvalds } 26681da177e4SLinus Torvalds 26691da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 26701da177e4SLinus Torvalds /* Auth must be enabled first */ 267101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 26725f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26731da177e4SLinus Torvalds if (err) 26741da177e4SLinus Torvalds break; 26751da177e4SLinus Torvalds } 26761da177e4SLinus Torvalds 267701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 26785f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26791da177e4SLinus Torvalds break; 26801da177e4SLinus Torvalds 26811da177e4SLinus Torvalds case HCISETSCAN: 268201178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 26835f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26841da177e4SLinus Torvalds break; 26851da177e4SLinus Torvalds 26861da177e4SLinus Torvalds case HCISETLINKPOL: 268701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 26885f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26891da177e4SLinus Torvalds break; 26901da177e4SLinus Torvalds 26911da177e4SLinus Torvalds case HCISETLINKMODE: 2692e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2693e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2694e4e8e37cSMarcel Holtmann break; 2695e4e8e37cSMarcel Holtmann 2696e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2697e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 26981da177e4SLinus Torvalds break; 26991da177e4SLinus Torvalds 27001da177e4SLinus Torvalds case HCISETACLMTU: 27011da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 27021da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 27031da177e4SLinus Torvalds break; 27041da177e4SLinus Torvalds 27051da177e4SLinus Torvalds case HCISETSCOMTU: 27061da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 27071da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 27081da177e4SLinus Torvalds break; 27091da177e4SLinus Torvalds 27101da177e4SLinus Torvalds default: 27111da177e4SLinus Torvalds err = -EINVAL; 27121da177e4SLinus Torvalds break; 27131da177e4SLinus Torvalds } 2714e4e8e37cSMarcel Holtmann 27150736cfa8SMarcel Holtmann done: 27161da177e4SLinus Torvalds hci_dev_put(hdev); 27171da177e4SLinus Torvalds return err; 27181da177e4SLinus Torvalds } 27191da177e4SLinus Torvalds 27201da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 27211da177e4SLinus Torvalds { 27228035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 27231da177e4SLinus Torvalds struct hci_dev_list_req *dl; 27241da177e4SLinus Torvalds struct hci_dev_req *dr; 27251da177e4SLinus Torvalds int n = 0, size, err; 27261da177e4SLinus Torvalds __u16 dev_num; 27271da177e4SLinus Torvalds 27281da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 27291da177e4SLinus Torvalds return -EFAULT; 27301da177e4SLinus Torvalds 27311da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 27321da177e4SLinus Torvalds return -EINVAL; 27331da177e4SLinus Torvalds 27341da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 27351da177e4SLinus Torvalds 273670f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 273770f23020SAndrei Emeltchenko if (!dl) 27381da177e4SLinus Torvalds return -ENOMEM; 27391da177e4SLinus Torvalds 27401da177e4SLinus Torvalds dr = dl->dev_req; 27411da177e4SLinus Torvalds 2742f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 27438035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 2744a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2745e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 2746c542a06cSJohan Hedberg 2747a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2748a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2749c542a06cSJohan Hedberg 27501da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 27511da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 2752c542a06cSJohan Hedberg 27531da177e4SLinus Torvalds if (++n >= dev_num) 27541da177e4SLinus Torvalds break; 27551da177e4SLinus Torvalds } 2756f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 27571da177e4SLinus Torvalds 27581da177e4SLinus Torvalds dl->dev_num = n; 27591da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 27601da177e4SLinus Torvalds 27611da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 27621da177e4SLinus Torvalds kfree(dl); 27631da177e4SLinus Torvalds 27641da177e4SLinus Torvalds return err ? -EFAULT : 0; 27651da177e4SLinus Torvalds } 27661da177e4SLinus Torvalds 27671da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 27681da177e4SLinus Torvalds { 27691da177e4SLinus Torvalds struct hci_dev *hdev; 27701da177e4SLinus Torvalds struct hci_dev_info di; 27711da177e4SLinus Torvalds int err = 0; 27721da177e4SLinus Torvalds 27731da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 27741da177e4SLinus Torvalds return -EFAULT; 27751da177e4SLinus Torvalds 277670f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 277770f23020SAndrei Emeltchenko if (!hdev) 27781da177e4SLinus Torvalds return -ENODEV; 27791da177e4SLinus Torvalds 2780a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 27813243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 2782ab81cbf9SJohan Hedberg 2783a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2784a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2785c542a06cSJohan Hedberg 27861da177e4SLinus Torvalds strcpy(di.name, hdev->name); 27871da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 278860f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 27891da177e4SLinus Torvalds di.flags = hdev->flags; 27901da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2791572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 27921da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 27931da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 27941da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 27951da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2796572c7f84SJohan Hedberg } else { 2797572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2798572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2799572c7f84SJohan Hedberg di.sco_mtu = 0; 2800572c7f84SJohan Hedberg di.sco_pkts = 0; 2801572c7f84SJohan Hedberg } 28021da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 28031da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 28041da177e4SLinus Torvalds 28051da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 28061da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 28071da177e4SLinus Torvalds 28081da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 28091da177e4SLinus Torvalds err = -EFAULT; 28101da177e4SLinus Torvalds 28111da177e4SLinus Torvalds hci_dev_put(hdev); 28121da177e4SLinus Torvalds 28131da177e4SLinus Torvalds return err; 28141da177e4SLinus Torvalds } 28151da177e4SLinus Torvalds 28161da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 28171da177e4SLinus Torvalds 2818611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2819611b30f7SMarcel Holtmann { 2820611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2821611b30f7SMarcel Holtmann 2822611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2823611b30f7SMarcel Holtmann 28240736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 28250736cfa8SMarcel Holtmann return -EBUSY; 28260736cfa8SMarcel Holtmann 28275e130367SJohan Hedberg if (blocked) { 28285e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 2829*d603b76bSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 2830*d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags)) 2831611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 28325e130367SJohan Hedberg } else { 28335e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 28345e130367SJohan Hedberg } 2835611b30f7SMarcel Holtmann 2836611b30f7SMarcel Holtmann return 0; 2837611b30f7SMarcel Holtmann } 2838611b30f7SMarcel Holtmann 2839611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2840611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2841611b30f7SMarcel Holtmann }; 2842611b30f7SMarcel Holtmann 2843ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2844ab81cbf9SJohan Hedberg { 2845ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 284696570ffcSJohan Hedberg int err; 2847ab81cbf9SJohan Hedberg 2848ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2849ab81cbf9SJohan Hedberg 2850cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 285196570ffcSJohan Hedberg if (err < 0) { 285296570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 2853ab81cbf9SJohan Hedberg return; 285496570ffcSJohan Hedberg } 2855ab81cbf9SJohan Hedberg 2856a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2857a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2858a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2859a5c8f270SMarcel Holtmann */ 2860a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 28614a964404SMarcel Holtmann test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) || 2862a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 2863a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2864a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2865bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2866bf543036SJohan Hedberg hci_dev_do_close(hdev); 2867bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 286819202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 286919202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2870bf543036SJohan Hedberg } 2871ab81cbf9SJohan Hedberg 2872fee746b0SMarcel Holtmann if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) { 28734a964404SMarcel Holtmann /* For unconfigured devices, set the HCI_RAW flag 28744a964404SMarcel Holtmann * so that userspace can easily identify them. 28754a964404SMarcel Holtmann */ 28764a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) 28774a964404SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 28780602a8adSMarcel Holtmann 28790602a8adSMarcel Holtmann /* For fully configured devices, this will send 28800602a8adSMarcel Holtmann * the Index Added event. For unconfigured devices, 28810602a8adSMarcel Holtmann * it will send Unconfigued Index Added event. 28820602a8adSMarcel Holtmann * 28830602a8adSMarcel Holtmann * Devices with HCI_QUIRK_RAW_DEVICE are ignored 28840602a8adSMarcel Holtmann * and no event will be send. 28850602a8adSMarcel Holtmann */ 2886744cf19eSJohan Hedberg mgmt_index_added(hdev); 2887*d603b76bSMarcel Holtmann } else if (test_and_clear_bit(HCI_CONFIG, &hdev->dev_flags)) { 2888*d603b76bSMarcel Holtmann /* Powering on the controller with HCI_CONFIG set only 2889*d603b76bSMarcel Holtmann * happens with the transition from unconfigured to 2890*d603b76bSMarcel Holtmann * configured. This will send the Index Added event. 2891*d603b76bSMarcel Holtmann */ 2892*d603b76bSMarcel Holtmann mgmt_index_added(hdev); 2893ab81cbf9SJohan Hedberg } 2894fee746b0SMarcel Holtmann } 2895ab81cbf9SJohan Hedberg 2896ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2897ab81cbf9SJohan Hedberg { 28983243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 28993243553fSJohan Hedberg power_off.work); 2900ab81cbf9SJohan Hedberg 2901ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2902ab81cbf9SJohan Hedberg 29038ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2904ab81cbf9SJohan Hedberg } 2905ab81cbf9SJohan Hedberg 290616ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 290716ab91abSJohan Hedberg { 290816ab91abSJohan Hedberg struct hci_dev *hdev; 290916ab91abSJohan Hedberg 291016ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 291116ab91abSJohan Hedberg 291216ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 291316ab91abSJohan Hedberg 2914d1967ff8SMarcel Holtmann mgmt_discoverable_timeout(hdev); 291516ab91abSJohan Hedberg } 291616ab91abSJohan Hedberg 291735f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 29182aeb9a1aSJohan Hedberg { 29194821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 29202aeb9a1aSJohan Hedberg 29214821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 29224821002cSJohan Hedberg list_del(&uuid->list); 29232aeb9a1aSJohan Hedberg kfree(uuid); 29242aeb9a1aSJohan Hedberg } 29252aeb9a1aSJohan Hedberg } 29262aeb9a1aSJohan Hedberg 292735f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 292855ed8ca1SJohan Hedberg { 292955ed8ca1SJohan Hedberg struct list_head *p, *n; 293055ed8ca1SJohan Hedberg 293155ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 293255ed8ca1SJohan Hedberg struct link_key *key; 293355ed8ca1SJohan Hedberg 293455ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 293555ed8ca1SJohan Hedberg 293655ed8ca1SJohan Hedberg list_del(p); 293755ed8ca1SJohan Hedberg kfree(key); 293855ed8ca1SJohan Hedberg } 293955ed8ca1SJohan Hedberg } 294055ed8ca1SJohan Hedberg 294135f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2942b899efafSVinicius Costa Gomes { 2943b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2944b899efafSVinicius Costa Gomes 2945b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2946b899efafSVinicius Costa Gomes list_del(&k->list); 2947b899efafSVinicius Costa Gomes kfree(k); 2948b899efafSVinicius Costa Gomes } 2949b899efafSVinicius Costa Gomes } 2950b899efafSVinicius Costa Gomes 2951970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2952970c4e46SJohan Hedberg { 2953970c4e46SJohan Hedberg struct smp_irk *k, *tmp; 2954970c4e46SJohan Hedberg 2955970c4e46SJohan Hedberg list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { 2956970c4e46SJohan Hedberg list_del(&k->list); 2957970c4e46SJohan Hedberg kfree(k); 2958970c4e46SJohan Hedberg } 2959970c4e46SJohan Hedberg } 2960970c4e46SJohan Hedberg 296155ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 296255ed8ca1SJohan Hedberg { 296355ed8ca1SJohan Hedberg struct link_key *k; 296455ed8ca1SJohan Hedberg 29658035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 296655ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 296755ed8ca1SJohan Hedberg return k; 296855ed8ca1SJohan Hedberg 296955ed8ca1SJohan Hedberg return NULL; 297055ed8ca1SJohan Hedberg } 297155ed8ca1SJohan Hedberg 2972745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2973d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2974d25e28abSJohan Hedberg { 2975d25e28abSJohan Hedberg /* Legacy key */ 2976d25e28abSJohan Hedberg if (key_type < 0x03) 2977745c0ce3SVishal Agarwal return true; 2978d25e28abSJohan Hedberg 2979d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2980d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2981745c0ce3SVishal Agarwal return false; 2982d25e28abSJohan Hedberg 2983d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2984d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2985745c0ce3SVishal Agarwal return false; 2986d25e28abSJohan Hedberg 2987d25e28abSJohan Hedberg /* Security mode 3 case */ 2988d25e28abSJohan Hedberg if (!conn) 2989745c0ce3SVishal Agarwal return true; 2990d25e28abSJohan Hedberg 2991d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2992d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2993745c0ce3SVishal Agarwal return true; 2994d25e28abSJohan Hedberg 2995d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2996d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2997745c0ce3SVishal Agarwal return true; 2998d25e28abSJohan Hedberg 2999d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 3000d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 3001745c0ce3SVishal Agarwal return true; 3002d25e28abSJohan Hedberg 3003d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 3004d25e28abSJohan Hedberg * persistently */ 3005745c0ce3SVishal Agarwal return false; 3006d25e28abSJohan Hedberg } 3007d25e28abSJohan Hedberg 300898a0b845SJohan Hedberg static bool ltk_type_master(u8 type) 300998a0b845SJohan Hedberg { 3010d97c9fb0SJohan Hedberg return (type == SMP_LTK); 301198a0b845SJohan Hedberg } 301298a0b845SJohan Hedberg 3013fe39c7b2SMarcel Holtmann struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand, 301498a0b845SJohan Hedberg bool master) 301575d262c2SVinicius Costa Gomes { 3016c9839a11SVinicius Costa Gomes struct smp_ltk *k; 301775d262c2SVinicius Costa Gomes 3018c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 3019fe39c7b2SMarcel Holtmann if (k->ediv != ediv || k->rand != rand) 302075d262c2SVinicius Costa Gomes continue; 302175d262c2SVinicius Costa Gomes 302298a0b845SJohan Hedberg if (ltk_type_master(k->type) != master) 302398a0b845SJohan Hedberg continue; 302498a0b845SJohan Hedberg 302575d262c2SVinicius Costa Gomes return k; 302675d262c2SVinicius Costa Gomes } 302775d262c2SVinicius Costa Gomes 302875d262c2SVinicius Costa Gomes return NULL; 302975d262c2SVinicius Costa Gomes } 303075d262c2SVinicius Costa Gomes 3031c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 303298a0b845SJohan Hedberg u8 addr_type, bool master) 303375d262c2SVinicius Costa Gomes { 3034c9839a11SVinicius Costa Gomes struct smp_ltk *k; 303575d262c2SVinicius Costa Gomes 3036c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 3037c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 303898a0b845SJohan Hedberg bacmp(bdaddr, &k->bdaddr) == 0 && 303998a0b845SJohan Hedberg ltk_type_master(k->type) == master) 304075d262c2SVinicius Costa Gomes return k; 304175d262c2SVinicius Costa Gomes 304275d262c2SVinicius Costa Gomes return NULL; 304375d262c2SVinicius Costa Gomes } 304475d262c2SVinicius Costa Gomes 3045970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 3046970c4e46SJohan Hedberg { 3047970c4e46SJohan Hedberg struct smp_irk *irk; 3048970c4e46SJohan Hedberg 3049970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 3050970c4e46SJohan Hedberg if (!bacmp(&irk->rpa, rpa)) 3051970c4e46SJohan Hedberg return irk; 3052970c4e46SJohan Hedberg } 3053970c4e46SJohan Hedberg 3054970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 3055970c4e46SJohan Hedberg if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) { 3056970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 3057970c4e46SJohan Hedberg return irk; 3058970c4e46SJohan Hedberg } 3059970c4e46SJohan Hedberg } 3060970c4e46SJohan Hedberg 3061970c4e46SJohan Hedberg return NULL; 3062970c4e46SJohan Hedberg } 3063970c4e46SJohan Hedberg 3064970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 3065970c4e46SJohan Hedberg u8 addr_type) 3066970c4e46SJohan Hedberg { 3067970c4e46SJohan Hedberg struct smp_irk *irk; 3068970c4e46SJohan Hedberg 30696cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 30706cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 30716cfc9988SJohan Hedberg return NULL; 30726cfc9988SJohan Hedberg 3073970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 3074970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 3075970c4e46SJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) 3076970c4e46SJohan Hedberg return irk; 3077970c4e46SJohan Hedberg } 3078970c4e46SJohan Hedberg 3079970c4e46SJohan Hedberg return NULL; 3080970c4e46SJohan Hedberg } 3081970c4e46SJohan Hedberg 3082567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 30837652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 30847652ff6aSJohan Hedberg u8 pin_len, bool *persistent) 308555ed8ca1SJohan Hedberg { 308655ed8ca1SJohan Hedberg struct link_key *key, *old_key; 3087745c0ce3SVishal Agarwal u8 old_key_type; 308855ed8ca1SJohan Hedberg 308955ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 309055ed8ca1SJohan Hedberg if (old_key) { 309155ed8ca1SJohan Hedberg old_key_type = old_key->type; 309255ed8ca1SJohan Hedberg key = old_key; 309355ed8ca1SJohan Hedberg } else { 309412adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 30950a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 309655ed8ca1SJohan Hedberg if (!key) 3097567fa2aaSJohan Hedberg return NULL; 309855ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 309955ed8ca1SJohan Hedberg } 310055ed8ca1SJohan Hedberg 31016ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 310255ed8ca1SJohan Hedberg 3103d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 3104d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 3105d25e28abSJohan Hedberg * previous key */ 3106d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 3107a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 3108d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 3109655fe6ecSJohan Hedberg if (conn) 3110655fe6ecSJohan Hedberg conn->key_type = type; 3111655fe6ecSJohan Hedberg } 3112d25e28abSJohan Hedberg 311355ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 31149b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 311555ed8ca1SJohan Hedberg key->pin_len = pin_len; 311655ed8ca1SJohan Hedberg 3117b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 311855ed8ca1SJohan Hedberg key->type = old_key_type; 31194748fed2SJohan Hedberg else 31204748fed2SJohan Hedberg key->type = type; 31214748fed2SJohan Hedberg 31227652ff6aSJohan Hedberg if (persistent) 31237652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type, 31247652ff6aSJohan Hedberg old_key_type); 312555ed8ca1SJohan Hedberg 3126567fa2aaSJohan Hedberg return key; 312755ed8ca1SJohan Hedberg } 312855ed8ca1SJohan Hedberg 3129ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 313035d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 3131fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand) 313275d262c2SVinicius Costa Gomes { 3133c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 313498a0b845SJohan Hedberg bool master = ltk_type_master(type); 313575d262c2SVinicius Costa Gomes 313698a0b845SJohan Hedberg old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master); 3137c9839a11SVinicius Costa Gomes if (old_key) 313875d262c2SVinicius Costa Gomes key = old_key; 3139c9839a11SVinicius Costa Gomes else { 31400a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 314175d262c2SVinicius Costa Gomes if (!key) 3142ca9142b8SJohan Hedberg return NULL; 3143c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 314475d262c2SVinicius Costa Gomes } 314575d262c2SVinicius Costa Gomes 314675d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 3147c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 3148c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 3149c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 3150c9839a11SVinicius Costa Gomes key->ediv = ediv; 3151fe39c7b2SMarcel Holtmann key->rand = rand; 3152c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 3153c9839a11SVinicius Costa Gomes key->type = type; 315475d262c2SVinicius Costa Gomes 3155ca9142b8SJohan Hedberg return key; 315675d262c2SVinicius Costa Gomes } 315775d262c2SVinicius Costa Gomes 3158ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 3159ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 3160970c4e46SJohan Hedberg { 3161970c4e46SJohan Hedberg struct smp_irk *irk; 3162970c4e46SJohan Hedberg 3163970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 3164970c4e46SJohan Hedberg if (!irk) { 3165970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 3166970c4e46SJohan Hedberg if (!irk) 3167ca9142b8SJohan Hedberg return NULL; 3168970c4e46SJohan Hedberg 3169970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 3170970c4e46SJohan Hedberg irk->addr_type = addr_type; 3171970c4e46SJohan Hedberg 3172970c4e46SJohan Hedberg list_add(&irk->list, &hdev->identity_resolving_keys); 3173970c4e46SJohan Hedberg } 3174970c4e46SJohan Hedberg 3175970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 3176970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 3177970c4e46SJohan Hedberg 3178ca9142b8SJohan Hedberg return irk; 3179970c4e46SJohan Hedberg } 3180970c4e46SJohan Hedberg 318155ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 318255ed8ca1SJohan Hedberg { 318355ed8ca1SJohan Hedberg struct link_key *key; 318455ed8ca1SJohan Hedberg 318555ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 318655ed8ca1SJohan Hedberg if (!key) 318755ed8ca1SJohan Hedberg return -ENOENT; 318855ed8ca1SJohan Hedberg 31896ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 319055ed8ca1SJohan Hedberg 319155ed8ca1SJohan Hedberg list_del(&key->list); 319255ed8ca1SJohan Hedberg kfree(key); 319355ed8ca1SJohan Hedberg 319455ed8ca1SJohan Hedberg return 0; 319555ed8ca1SJohan Hedberg } 319655ed8ca1SJohan Hedberg 3197e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 3198b899efafSVinicius Costa Gomes { 3199b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 3200c51ffa0bSJohan Hedberg int removed = 0; 3201b899efafSVinicius Costa Gomes 3202b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 3203e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 3204b899efafSVinicius Costa Gomes continue; 3205b899efafSVinicius Costa Gomes 32066ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 3207b899efafSVinicius Costa Gomes 3208b899efafSVinicius Costa Gomes list_del(&k->list); 3209b899efafSVinicius Costa Gomes kfree(k); 3210c51ffa0bSJohan Hedberg removed++; 3211b899efafSVinicius Costa Gomes } 3212b899efafSVinicius Costa Gomes 3213c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 3214b899efafSVinicius Costa Gomes } 3215b899efafSVinicius Costa Gomes 3216a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 3217a7ec7338SJohan Hedberg { 3218a7ec7338SJohan Hedberg struct smp_irk *k, *tmp; 3219a7ec7338SJohan Hedberg 3220668b7b19SJohan Hedberg list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { 3221a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 3222a7ec7338SJohan Hedberg continue; 3223a7ec7338SJohan Hedberg 3224a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 3225a7ec7338SJohan Hedberg 3226a7ec7338SJohan Hedberg list_del(&k->list); 3227a7ec7338SJohan Hedberg kfree(k); 3228a7ec7338SJohan Hedberg } 3229a7ec7338SJohan Hedberg } 3230a7ec7338SJohan Hedberg 32316bd32326SVille Tervo /* HCI command timer function */ 323265cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work) 32336bd32326SVille Tervo { 323465cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, 323565cc2b49SMarcel Holtmann cmd_timer.work); 32366bd32326SVille Tervo 3237bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 3238bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 3239bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 3240bda4f23aSAndrei Emeltchenko 3241bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 3242bda4f23aSAndrei Emeltchenko } else { 32436bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 3244bda4f23aSAndrei Emeltchenko } 3245bda4f23aSAndrei Emeltchenko 32466bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 3247c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 32486bd32326SVille Tervo } 32496bd32326SVille Tervo 32502763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 32512763eda6SSzymon Janc bdaddr_t *bdaddr) 32522763eda6SSzymon Janc { 32532763eda6SSzymon Janc struct oob_data *data; 32542763eda6SSzymon Janc 32552763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 32562763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 32572763eda6SSzymon Janc return data; 32582763eda6SSzymon Janc 32592763eda6SSzymon Janc return NULL; 32602763eda6SSzymon Janc } 32612763eda6SSzymon Janc 32622763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 32632763eda6SSzymon Janc { 32642763eda6SSzymon Janc struct oob_data *data; 32652763eda6SSzymon Janc 32662763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 32672763eda6SSzymon Janc if (!data) 32682763eda6SSzymon Janc return -ENOENT; 32692763eda6SSzymon Janc 32706ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 32712763eda6SSzymon Janc 32722763eda6SSzymon Janc list_del(&data->list); 32732763eda6SSzymon Janc kfree(data); 32742763eda6SSzymon Janc 32752763eda6SSzymon Janc return 0; 32762763eda6SSzymon Janc } 32772763eda6SSzymon Janc 327835f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 32792763eda6SSzymon Janc { 32802763eda6SSzymon Janc struct oob_data *data, *n; 32812763eda6SSzymon Janc 32822763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 32832763eda6SSzymon Janc list_del(&data->list); 32842763eda6SSzymon Janc kfree(data); 32852763eda6SSzymon Janc } 32862763eda6SSzymon Janc } 32872763eda6SSzymon Janc 32880798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 32890798872eSMarcel Holtmann u8 *hash, u8 *randomizer) 32902763eda6SSzymon Janc { 32912763eda6SSzymon Janc struct oob_data *data; 32922763eda6SSzymon Janc 32932763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 32942763eda6SSzymon Janc if (!data) { 32950a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 32962763eda6SSzymon Janc if (!data) 32972763eda6SSzymon Janc return -ENOMEM; 32982763eda6SSzymon Janc 32992763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 33002763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 33012763eda6SSzymon Janc } 33022763eda6SSzymon Janc 3303519ca9d0SMarcel Holtmann memcpy(data->hash192, hash, sizeof(data->hash192)); 3304519ca9d0SMarcel Holtmann memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192)); 33052763eda6SSzymon Janc 33060798872eSMarcel Holtmann memset(data->hash256, 0, sizeof(data->hash256)); 33070798872eSMarcel Holtmann memset(data->randomizer256, 0, sizeof(data->randomizer256)); 33080798872eSMarcel Holtmann 33090798872eSMarcel Holtmann BT_DBG("%s for %pMR", hdev->name, bdaddr); 33100798872eSMarcel Holtmann 33110798872eSMarcel Holtmann return 0; 33120798872eSMarcel Holtmann } 33130798872eSMarcel Holtmann 33140798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 33150798872eSMarcel Holtmann u8 *hash192, u8 *randomizer192, 33160798872eSMarcel Holtmann u8 *hash256, u8 *randomizer256) 33170798872eSMarcel Holtmann { 33180798872eSMarcel Holtmann struct oob_data *data; 33190798872eSMarcel Holtmann 33200798872eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, bdaddr); 33210798872eSMarcel Holtmann if (!data) { 33220a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 33230798872eSMarcel Holtmann if (!data) 33240798872eSMarcel Holtmann return -ENOMEM; 33250798872eSMarcel Holtmann 33260798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 33270798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 33280798872eSMarcel Holtmann } 33290798872eSMarcel Holtmann 33300798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 33310798872eSMarcel Holtmann memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192)); 33320798872eSMarcel Holtmann 33330798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 33340798872eSMarcel Holtmann memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256)); 33350798872eSMarcel Holtmann 33366ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 33372763eda6SSzymon Janc 33382763eda6SSzymon Janc return 0; 33392763eda6SSzymon Janc } 33402763eda6SSzymon Janc 3341b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 3342b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 3343b2a66aadSAntti Julku { 3344b2a66aadSAntti Julku struct bdaddr_list *b; 3345b2a66aadSAntti Julku 3346b9ee0a78SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) { 3347b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3348b2a66aadSAntti Julku return b; 3349b9ee0a78SMarcel Holtmann } 3350b2a66aadSAntti Julku 3351b2a66aadSAntti Julku return NULL; 3352b2a66aadSAntti Julku } 3353b2a66aadSAntti Julku 3354c9507490SMarcel Holtmann static void hci_blacklist_clear(struct hci_dev *hdev) 3355b2a66aadSAntti Julku { 3356b2a66aadSAntti Julku struct list_head *p, *n; 3357b2a66aadSAntti Julku 3358b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 3359b9ee0a78SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 3360b2a66aadSAntti Julku 3361b2a66aadSAntti Julku list_del(p); 3362b2a66aadSAntti Julku kfree(b); 3363b2a66aadSAntti Julku } 3364b2a66aadSAntti Julku } 3365b2a66aadSAntti Julku 336688c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3367b2a66aadSAntti Julku { 3368b2a66aadSAntti Julku struct bdaddr_list *entry; 3369b2a66aadSAntti Julku 3370b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3371b2a66aadSAntti Julku return -EBADF; 3372b2a66aadSAntti Julku 3373b9ee0a78SMarcel Holtmann if (hci_blacklist_lookup(hdev, bdaddr, type)) 33745e762444SAntti Julku return -EEXIST; 3375b2a66aadSAntti Julku 3376b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 33775e762444SAntti Julku if (!entry) 33785e762444SAntti Julku return -ENOMEM; 3379b2a66aadSAntti Julku 3380b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 3381b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 3382b2a66aadSAntti Julku 3383b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 3384b2a66aadSAntti Julku 33852a8357f2SJohan Hedberg return 0; 3386b2a66aadSAntti Julku } 3387b2a66aadSAntti Julku 338888c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3389b2a66aadSAntti Julku { 3390b2a66aadSAntti Julku struct bdaddr_list *entry; 3391b2a66aadSAntti Julku 339235f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 339335f7498aSJohan Hedberg hci_blacklist_clear(hdev); 339435f7498aSJohan Hedberg return 0; 339535f7498aSJohan Hedberg } 3396b2a66aadSAntti Julku 3397b9ee0a78SMarcel Holtmann entry = hci_blacklist_lookup(hdev, bdaddr, type); 33981ec918ceSSzymon Janc if (!entry) 33995e762444SAntti Julku return -ENOENT; 3400b2a66aadSAntti Julku 3401b2a66aadSAntti Julku list_del(&entry->list); 3402b2a66aadSAntti Julku kfree(entry); 3403b2a66aadSAntti Julku 34042a8357f2SJohan Hedberg return 0; 3405b2a66aadSAntti Julku } 3406b2a66aadSAntti Julku 3407d2ab0ac1SMarcel Holtmann struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev, 3408d2ab0ac1SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 3409d2ab0ac1SMarcel Holtmann { 3410d2ab0ac1SMarcel Holtmann struct bdaddr_list *b; 3411d2ab0ac1SMarcel Holtmann 3412d2ab0ac1SMarcel Holtmann list_for_each_entry(b, &hdev->le_white_list, list) { 3413d2ab0ac1SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3414d2ab0ac1SMarcel Holtmann return b; 3415d2ab0ac1SMarcel Holtmann } 3416d2ab0ac1SMarcel Holtmann 3417d2ab0ac1SMarcel Holtmann return NULL; 3418d2ab0ac1SMarcel Holtmann } 3419d2ab0ac1SMarcel Holtmann 3420d2ab0ac1SMarcel Holtmann void hci_white_list_clear(struct hci_dev *hdev) 3421d2ab0ac1SMarcel Holtmann { 3422d2ab0ac1SMarcel Holtmann struct list_head *p, *n; 3423d2ab0ac1SMarcel Holtmann 3424d2ab0ac1SMarcel Holtmann list_for_each_safe(p, n, &hdev->le_white_list) { 3425d2ab0ac1SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 3426d2ab0ac1SMarcel Holtmann 3427d2ab0ac1SMarcel Holtmann list_del(p); 3428d2ab0ac1SMarcel Holtmann kfree(b); 3429d2ab0ac1SMarcel Holtmann } 3430d2ab0ac1SMarcel Holtmann } 3431d2ab0ac1SMarcel Holtmann 3432d2ab0ac1SMarcel Holtmann int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3433d2ab0ac1SMarcel Holtmann { 3434d2ab0ac1SMarcel Holtmann struct bdaddr_list *entry; 3435d2ab0ac1SMarcel Holtmann 3436d2ab0ac1SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3437d2ab0ac1SMarcel Holtmann return -EBADF; 3438d2ab0ac1SMarcel Holtmann 3439d2ab0ac1SMarcel Holtmann entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 3440d2ab0ac1SMarcel Holtmann if (!entry) 3441d2ab0ac1SMarcel Holtmann return -ENOMEM; 3442d2ab0ac1SMarcel Holtmann 3443d2ab0ac1SMarcel Holtmann bacpy(&entry->bdaddr, bdaddr); 3444d2ab0ac1SMarcel Holtmann entry->bdaddr_type = type; 3445d2ab0ac1SMarcel Holtmann 3446d2ab0ac1SMarcel Holtmann list_add(&entry->list, &hdev->le_white_list); 3447d2ab0ac1SMarcel Holtmann 3448d2ab0ac1SMarcel Holtmann return 0; 3449d2ab0ac1SMarcel Holtmann } 3450d2ab0ac1SMarcel Holtmann 3451d2ab0ac1SMarcel Holtmann int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3452d2ab0ac1SMarcel Holtmann { 3453d2ab0ac1SMarcel Holtmann struct bdaddr_list *entry; 3454d2ab0ac1SMarcel Holtmann 3455d2ab0ac1SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3456d2ab0ac1SMarcel Holtmann return -EBADF; 3457d2ab0ac1SMarcel Holtmann 3458d2ab0ac1SMarcel Holtmann entry = hci_white_list_lookup(hdev, bdaddr, type); 3459d2ab0ac1SMarcel Holtmann if (!entry) 3460d2ab0ac1SMarcel Holtmann return -ENOENT; 3461d2ab0ac1SMarcel Holtmann 3462d2ab0ac1SMarcel Holtmann list_del(&entry->list); 3463d2ab0ac1SMarcel Holtmann kfree(entry); 3464d2ab0ac1SMarcel Holtmann 3465d2ab0ac1SMarcel Holtmann return 0; 3466d2ab0ac1SMarcel Holtmann } 3467d2ab0ac1SMarcel Holtmann 346815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 346915819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 347015819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 347115819a70SAndre Guedes { 347215819a70SAndre Guedes struct hci_conn_params *params; 347315819a70SAndre Guedes 3474738f6185SJohan Hedberg /* The conn params list only contains identity addresses */ 3475738f6185SJohan Hedberg if (!hci_is_identity_address(addr, addr_type)) 3476738f6185SJohan Hedberg return NULL; 3477738f6185SJohan Hedberg 347815819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 347915819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 348015819a70SAndre Guedes params->addr_type == addr_type) { 348115819a70SAndre Guedes return params; 348215819a70SAndre Guedes } 348315819a70SAndre Guedes } 348415819a70SAndre Guedes 348515819a70SAndre Guedes return NULL; 348615819a70SAndre Guedes } 348715819a70SAndre Guedes 3488cef952ceSAndre Guedes static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type) 3489cef952ceSAndre Guedes { 3490cef952ceSAndre Guedes struct hci_conn *conn; 3491cef952ceSAndre Guedes 3492cef952ceSAndre Guedes conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr); 3493cef952ceSAndre Guedes if (!conn) 3494cef952ceSAndre Guedes return false; 3495cef952ceSAndre Guedes 3496cef952ceSAndre Guedes if (conn->dst_type != type) 3497cef952ceSAndre Guedes return false; 3498cef952ceSAndre Guedes 3499cef952ceSAndre Guedes if (conn->state != BT_CONNECTED) 3500cef952ceSAndre Guedes return false; 3501cef952ceSAndre Guedes 3502cef952ceSAndre Guedes return true; 3503cef952ceSAndre Guedes } 3504cef952ceSAndre Guedes 350515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 3506501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 35074b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type) 35084b10966fSMarcel Holtmann { 3509912b42efSJohan Hedberg struct hci_conn_params *param; 35104b10966fSMarcel Holtmann 3511738f6185SJohan Hedberg /* The list only contains identity addresses */ 3512738f6185SJohan Hedberg if (!hci_is_identity_address(addr, addr_type)) 3513738f6185SJohan Hedberg return NULL; 3514738f6185SJohan Hedberg 3515501f8827SJohan Hedberg list_for_each_entry(param, list, action) { 3516912b42efSJohan Hedberg if (bacmp(¶m->addr, addr) == 0 && 3517912b42efSJohan Hedberg param->addr_type == addr_type) 3518912b42efSJohan Hedberg return param; 35194b10966fSMarcel Holtmann } 35204b10966fSMarcel Holtmann 35214b10966fSMarcel Holtmann return NULL; 35224b10966fSMarcel Holtmann } 35234b10966fSMarcel Holtmann 35244b10966fSMarcel Holtmann /* This function requires the caller holds hdev->lock */ 352551d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 352651d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type) 3527bf5b3c8bSMarcel Holtmann { 3528bf5b3c8bSMarcel Holtmann struct hci_conn_params *params; 3529bf5b3c8bSMarcel Holtmann 3530c46245b3SJohan Hedberg if (!hci_is_identity_address(addr, addr_type)) 353151d167c0SMarcel Holtmann return NULL; 3532bf5b3c8bSMarcel Holtmann 3533bf5b3c8bSMarcel Holtmann params = hci_conn_params_lookup(hdev, addr, addr_type); 3534bf5b3c8bSMarcel Holtmann if (params) 353551d167c0SMarcel Holtmann return params; 3536bf5b3c8bSMarcel Holtmann 3537bf5b3c8bSMarcel Holtmann params = kzalloc(sizeof(*params), GFP_KERNEL); 3538bf5b3c8bSMarcel Holtmann if (!params) { 3539bf5b3c8bSMarcel Holtmann BT_ERR("Out of memory"); 354051d167c0SMarcel Holtmann return NULL; 3541bf5b3c8bSMarcel Holtmann } 3542bf5b3c8bSMarcel Holtmann 3543bf5b3c8bSMarcel Holtmann bacpy(¶ms->addr, addr); 3544bf5b3c8bSMarcel Holtmann params->addr_type = addr_type; 3545bf5b3c8bSMarcel Holtmann 3546bf5b3c8bSMarcel Holtmann list_add(¶ms->list, &hdev->le_conn_params); 354793450c75SJohan Hedberg INIT_LIST_HEAD(¶ms->action); 3548bf5b3c8bSMarcel Holtmann 3549bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval; 3550bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval; 3551bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency; 3552bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout; 3553bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED; 3554bf5b3c8bSMarcel Holtmann 3555bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 3556bf5b3c8bSMarcel Holtmann 355751d167c0SMarcel Holtmann return params; 3558bf5b3c8bSMarcel Holtmann } 3559bf5b3c8bSMarcel Holtmann 3560bf5b3c8bSMarcel Holtmann /* This function requires the caller holds hdev->lock */ 3561bf5b3c8bSMarcel Holtmann int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, 3562d06b50ceSMarcel Holtmann u8 auto_connect) 356315819a70SAndre Guedes { 356415819a70SAndre Guedes struct hci_conn_params *params; 356515819a70SAndre Guedes 35668c87aae1SMarcel Holtmann params = hci_conn_params_add(hdev, addr, addr_type); 35678c87aae1SMarcel Holtmann if (!params) 35688c87aae1SMarcel Holtmann return -EIO; 3569a9b0a04cSAndre Guedes 357042ce26deSJohan Hedberg if (params->auto_connect == auto_connect) 357142ce26deSJohan Hedberg return 0; 357242ce26deSJohan Hedberg 357366f8455aSJohan Hedberg list_del_init(¶ms->action); 357415819a70SAndre Guedes 3575cef952ceSAndre Guedes switch (auto_connect) { 3576cef952ceSAndre Guedes case HCI_AUTO_CONN_DISABLED: 3577cef952ceSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 357895305baaSJohan Hedberg hci_update_background_scan(hdev); 3579cef952ceSAndre Guedes break; 3580851efca8SJohan Hedberg case HCI_AUTO_CONN_REPORT: 358195305baaSJohan Hedberg list_add(¶ms->action, &hdev->pend_le_reports); 358295305baaSJohan Hedberg hci_update_background_scan(hdev); 3583851efca8SJohan Hedberg break; 3584cef952ceSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 358595305baaSJohan Hedberg if (!is_connected(hdev, addr, addr_type)) { 358695305baaSJohan Hedberg list_add(¶ms->action, &hdev->pend_le_conns); 358795305baaSJohan Hedberg hci_update_background_scan(hdev); 358895305baaSJohan Hedberg } 3589cef952ceSAndre Guedes break; 3590cef952ceSAndre Guedes } 359115819a70SAndre Guedes 3592851efca8SJohan Hedberg params->auto_connect = auto_connect; 3593851efca8SJohan Hedberg 3594d06b50ceSMarcel Holtmann BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type, 3595d06b50ceSMarcel Holtmann auto_connect); 3596a9b0a04cSAndre Guedes 3597a9b0a04cSAndre Guedes return 0; 359815819a70SAndre Guedes } 359915819a70SAndre Guedes 360015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 360115819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 360215819a70SAndre Guedes { 360315819a70SAndre Guedes struct hci_conn_params *params; 360415819a70SAndre Guedes 360515819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 360615819a70SAndre Guedes if (!params) 360715819a70SAndre Guedes return; 360815819a70SAndre Guedes 360995305baaSJohan Hedberg list_del(¶ms->action); 361015819a70SAndre Guedes list_del(¶ms->list); 361115819a70SAndre Guedes kfree(params); 361215819a70SAndre Guedes 361395305baaSJohan Hedberg hci_update_background_scan(hdev); 361495305baaSJohan Hedberg 361515819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 361615819a70SAndre Guedes } 361715819a70SAndre Guedes 361815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 361955af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev) 362055af49a8SJohan Hedberg { 362155af49a8SJohan Hedberg struct hci_conn_params *params, *tmp; 362255af49a8SJohan Hedberg 362355af49a8SJohan Hedberg list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 362455af49a8SJohan Hedberg if (params->auto_connect != HCI_AUTO_CONN_DISABLED) 362555af49a8SJohan Hedberg continue; 362655af49a8SJohan Hedberg list_del(¶ms->list); 362755af49a8SJohan Hedberg kfree(params); 362855af49a8SJohan Hedberg } 362955af49a8SJohan Hedberg 363055af49a8SJohan Hedberg BT_DBG("All LE disabled connection parameters were removed"); 363155af49a8SJohan Hedberg } 363255af49a8SJohan Hedberg 363355af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */ 3634373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev) 363515819a70SAndre Guedes { 363615819a70SAndre Guedes struct hci_conn_params *params, *tmp; 363715819a70SAndre Guedes 363815819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 3639a2f41a8fSJohan Hedberg list_del(¶ms->action); 364015819a70SAndre Guedes list_del(¶ms->list); 364115819a70SAndre Guedes kfree(params); 364215819a70SAndre Guedes } 364315819a70SAndre Guedes 3644a2f41a8fSJohan Hedberg hci_update_background_scan(hdev); 36451089b67dSMarcel Holtmann 364615819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 364715819a70SAndre Guedes } 364815819a70SAndre Guedes 36494c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 36507ba8b4beSAndre Guedes { 36514c87eaabSAndre Guedes if (status) { 36524c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 36537ba8b4beSAndre Guedes 36544c87eaabSAndre Guedes hci_dev_lock(hdev); 36554c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 36564c87eaabSAndre Guedes hci_dev_unlock(hdev); 36574c87eaabSAndre Guedes return; 36584c87eaabSAndre Guedes } 36597ba8b4beSAndre Guedes } 36607ba8b4beSAndre Guedes 36614c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 36627ba8b4beSAndre Guedes { 36634c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 36644c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 36654c87eaabSAndre Guedes struct hci_request req; 36664c87eaabSAndre Guedes struct hci_cp_inquiry cp; 36677ba8b4beSAndre Guedes int err; 36687ba8b4beSAndre Guedes 36694c87eaabSAndre Guedes if (status) { 36704c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 36714c87eaabSAndre Guedes return; 36727ba8b4beSAndre Guedes } 36737ba8b4beSAndre Guedes 36744c87eaabSAndre Guedes switch (hdev->discovery.type) { 36754c87eaabSAndre Guedes case DISCOV_TYPE_LE: 36764c87eaabSAndre Guedes hci_dev_lock(hdev); 36774c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 36784c87eaabSAndre Guedes hci_dev_unlock(hdev); 36794c87eaabSAndre Guedes break; 36807dbfac1dSAndre Guedes 36814c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 36824c87eaabSAndre Guedes hci_req_init(&req, hdev); 36837dbfac1dSAndre Guedes 36847dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 36854c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 36864c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 36874c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 36884c87eaabSAndre Guedes 36894c87eaabSAndre Guedes hci_dev_lock(hdev); 36904c87eaabSAndre Guedes 36914c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 36924c87eaabSAndre Guedes 36934c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 36944c87eaabSAndre Guedes if (err) { 36954c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 36964c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 36977dbfac1dSAndre Guedes } 36987dbfac1dSAndre Guedes 36994c87eaabSAndre Guedes hci_dev_unlock(hdev); 37004c87eaabSAndre Guedes break; 37014c87eaabSAndre Guedes } 37027dbfac1dSAndre Guedes } 37037dbfac1dSAndre Guedes 37047ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 37057ba8b4beSAndre Guedes { 37067ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 37077ba8b4beSAndre Guedes le_scan_disable.work); 37084c87eaabSAndre Guedes struct hci_request req; 37094c87eaabSAndre Guedes int err; 37107ba8b4beSAndre Guedes 37117ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 37127ba8b4beSAndre Guedes 37134c87eaabSAndre Guedes hci_req_init(&req, hdev); 37147ba8b4beSAndre Guedes 3715b1efcc28SAndre Guedes hci_req_add_le_scan_disable(&req); 37167ba8b4beSAndre Guedes 37174c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 37184c87eaabSAndre Guedes if (err) 37194c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 372028b75a89SAndre Guedes } 372128b75a89SAndre Guedes 37228d97250eSJohan Hedberg static void set_random_addr(struct hci_request *req, bdaddr_t *rpa) 37238d97250eSJohan Hedberg { 37248d97250eSJohan Hedberg struct hci_dev *hdev = req->hdev; 37258d97250eSJohan Hedberg 37268d97250eSJohan Hedberg /* If we're advertising or initiating an LE connection we can't 37278d97250eSJohan Hedberg * go ahead and change the random address at this time. This is 37288d97250eSJohan Hedberg * because the eventual initiator address used for the 37298d97250eSJohan Hedberg * subsequently created connection will be undefined (some 37308d97250eSJohan Hedberg * controllers use the new address and others the one we had 37318d97250eSJohan Hedberg * when the operation started). 37328d97250eSJohan Hedberg * 37338d97250eSJohan Hedberg * In this kind of scenario skip the update and let the random 37348d97250eSJohan Hedberg * address be updated at the next cycle. 37358d97250eSJohan Hedberg */ 37368d97250eSJohan Hedberg if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) || 37378d97250eSJohan Hedberg hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { 37388d97250eSJohan Hedberg BT_DBG("Deferring random address update"); 37398d97250eSJohan Hedberg return; 37408d97250eSJohan Hedberg } 37418d97250eSJohan Hedberg 37428d97250eSJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa); 37438d97250eSJohan Hedberg } 37448d97250eSJohan Hedberg 374594b1fc92SMarcel Holtmann int hci_update_random_address(struct hci_request *req, bool require_privacy, 374694b1fc92SMarcel Holtmann u8 *own_addr_type) 3747ebd3a747SJohan Hedberg { 3748ebd3a747SJohan Hedberg struct hci_dev *hdev = req->hdev; 3749ebd3a747SJohan Hedberg int err; 3750ebd3a747SJohan Hedberg 3751ebd3a747SJohan Hedberg /* If privacy is enabled use a resolvable private address. If 37522b5224dcSMarcel Holtmann * current RPA has expired or there is something else than 37532b5224dcSMarcel Holtmann * the current RPA in use, then generate a new one. 3754ebd3a747SJohan Hedberg */ 3755ebd3a747SJohan Hedberg if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) { 3756ebd3a747SJohan Hedberg int to; 3757ebd3a747SJohan Hedberg 3758ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_RANDOM; 3759ebd3a747SJohan Hedberg 3760ebd3a747SJohan Hedberg if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) && 37612b5224dcSMarcel Holtmann !bacmp(&hdev->random_addr, &hdev->rpa)) 3762ebd3a747SJohan Hedberg return 0; 3763ebd3a747SJohan Hedberg 37642b5224dcSMarcel Holtmann err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa); 3765ebd3a747SJohan Hedberg if (err < 0) { 3766ebd3a747SJohan Hedberg BT_ERR("%s failed to generate new RPA", hdev->name); 3767ebd3a747SJohan Hedberg return err; 3768ebd3a747SJohan Hedberg } 3769ebd3a747SJohan Hedberg 37708d97250eSJohan Hedberg set_random_addr(req, &hdev->rpa); 3771ebd3a747SJohan Hedberg 3772ebd3a747SJohan Hedberg to = msecs_to_jiffies(hdev->rpa_timeout * 1000); 3773ebd3a747SJohan Hedberg queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to); 3774ebd3a747SJohan Hedberg 3775ebd3a747SJohan Hedberg return 0; 3776ebd3a747SJohan Hedberg } 3777ebd3a747SJohan Hedberg 377894b1fc92SMarcel Holtmann /* In case of required privacy without resolvable private address, 377994b1fc92SMarcel Holtmann * use an unresolvable private address. This is useful for active 378094b1fc92SMarcel Holtmann * scanning and non-connectable advertising. 378194b1fc92SMarcel Holtmann */ 378294b1fc92SMarcel Holtmann if (require_privacy) { 378394b1fc92SMarcel Holtmann bdaddr_t urpa; 378494b1fc92SMarcel Holtmann 378594b1fc92SMarcel Holtmann get_random_bytes(&urpa, 6); 378694b1fc92SMarcel Holtmann urpa.b[5] &= 0x3f; /* Clear two most significant bits */ 378794b1fc92SMarcel Holtmann 378894b1fc92SMarcel Holtmann *own_addr_type = ADDR_LE_DEV_RANDOM; 37898d97250eSJohan Hedberg set_random_addr(req, &urpa); 379094b1fc92SMarcel Holtmann return 0; 379194b1fc92SMarcel Holtmann } 379294b1fc92SMarcel Holtmann 3793ebd3a747SJohan Hedberg /* If forcing static address is in use or there is no public 3794ebd3a747SJohan Hedberg * address use the static address as random address (but skip 3795ebd3a747SJohan Hedberg * the HCI command if the current random address is already the 3796ebd3a747SJohan Hedberg * static one. 3797ebd3a747SJohan Hedberg */ 3798111902f7SMarcel Holtmann if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) || 3799ebd3a747SJohan Hedberg !bacmp(&hdev->bdaddr, BDADDR_ANY)) { 3800ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_RANDOM; 3801ebd3a747SJohan Hedberg if (bacmp(&hdev->static_addr, &hdev->random_addr)) 3802ebd3a747SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, 3803ebd3a747SJohan Hedberg &hdev->static_addr); 3804ebd3a747SJohan Hedberg return 0; 3805ebd3a747SJohan Hedberg } 3806ebd3a747SJohan Hedberg 3807ebd3a747SJohan Hedberg /* Neither privacy nor static address is being used so use a 3808ebd3a747SJohan Hedberg * public address. 3809ebd3a747SJohan Hedberg */ 3810ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_PUBLIC; 3811ebd3a747SJohan Hedberg 3812ebd3a747SJohan Hedberg return 0; 3813ebd3a747SJohan Hedberg } 3814ebd3a747SJohan Hedberg 3815a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 3816a1f4c318SJohan Hedberg * 3817a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 3818a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 3819a1f4c318SJohan Hedberg * the static random address. 3820a1f4c318SJohan Hedberg * 3821a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 3822a1f4c318SJohan Hedberg * public address to use the static random address instead. 3823a1f4c318SJohan Hedberg */ 3824a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 3825a1f4c318SJohan Hedberg u8 *bdaddr_type) 3826a1f4c318SJohan Hedberg { 3827111902f7SMarcel Holtmann if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) || 3828a1f4c318SJohan Hedberg !bacmp(&hdev->bdaddr, BDADDR_ANY)) { 3829a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 3830a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 3831a1f4c318SJohan Hedberg } else { 3832a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 3833a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 3834a1f4c318SJohan Hedberg } 3835a1f4c318SJohan Hedberg } 3836a1f4c318SJohan Hedberg 38379be0dab7SDavid Herrmann /* Alloc HCI device */ 38389be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 38399be0dab7SDavid Herrmann { 38409be0dab7SDavid Herrmann struct hci_dev *hdev; 38419be0dab7SDavid Herrmann 38429be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 38439be0dab7SDavid Herrmann if (!hdev) 38449be0dab7SDavid Herrmann return NULL; 38459be0dab7SDavid Herrmann 3846b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3847b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3848b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3849b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3850b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 385196c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */ 3852bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3853bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3854b1b813d4SDavid Herrmann 3855b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3856b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3857b1b813d4SDavid Herrmann 38583f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 3859bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3860bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 38614e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = 0x0028; 38624e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = 0x0038; 386304fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000; 386404fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a; 3865bef64738SMarcel Holtmann 3866d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 3867b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 386831ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 386931ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 3870d6bfd59cSJohan Hedberg 3871b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3872b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3873b1b813d4SDavid Herrmann 3874b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3875b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 3876b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3877b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3878b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3879970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3880b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 3881d2ab0ac1SMarcel Holtmann INIT_LIST_HEAD(&hdev->le_white_list); 388215819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 388377a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 388466f8455aSJohan Hedberg INIT_LIST_HEAD(&hdev->pend_le_reports); 38856b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3886b1b813d4SDavid Herrmann 3887b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3888b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3889b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3890b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3891b1b813d4SDavid Herrmann 3892b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3893b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 3894b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 3895b1b813d4SDavid Herrmann 3896b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3897b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3898b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3899b1b813d4SDavid Herrmann 3900b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 3901b1b813d4SDavid Herrmann 390265cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout); 3903b1b813d4SDavid Herrmann 3904b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3905b1b813d4SDavid Herrmann discovery_init(hdev); 39069be0dab7SDavid Herrmann 39079be0dab7SDavid Herrmann return hdev; 39089be0dab7SDavid Herrmann } 39099be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 39109be0dab7SDavid Herrmann 39119be0dab7SDavid Herrmann /* Free HCI device */ 39129be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 39139be0dab7SDavid Herrmann { 39149be0dab7SDavid Herrmann /* will free via device release */ 39159be0dab7SDavid Herrmann put_device(&hdev->dev); 39169be0dab7SDavid Herrmann } 39179be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 39189be0dab7SDavid Herrmann 39191da177e4SLinus Torvalds /* Register HCI device */ 39201da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 39211da177e4SLinus Torvalds { 3922b1b813d4SDavid Herrmann int id, error; 39231da177e4SLinus Torvalds 3924010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 39251da177e4SLinus Torvalds return -EINVAL; 39261da177e4SLinus Torvalds 392708add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 392808add513SMat Martineau * so the index can be used as the AMP controller ID. 392908add513SMat Martineau */ 39303df92b31SSasha Levin switch (hdev->dev_type) { 39313df92b31SSasha Levin case HCI_BREDR: 39323df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 39331da177e4SLinus Torvalds break; 39343df92b31SSasha Levin case HCI_AMP: 39353df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 39363df92b31SSasha Levin break; 39373df92b31SSasha Levin default: 39383df92b31SSasha Levin return -EINVAL; 39391da177e4SLinus Torvalds } 39401da177e4SLinus Torvalds 39413df92b31SSasha Levin if (id < 0) 39423df92b31SSasha Levin return id; 39433df92b31SSasha Levin 39441da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 39451da177e4SLinus Torvalds hdev->id = id; 39462d8b3a11SAndrei Emeltchenko 39472d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 39482d8b3a11SAndrei Emeltchenko 3949d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3950d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 395133ca954dSDavid Herrmann if (!hdev->workqueue) { 395233ca954dSDavid Herrmann error = -ENOMEM; 395333ca954dSDavid Herrmann goto err; 395433ca954dSDavid Herrmann } 3955f48fd9c8SMarcel Holtmann 3956d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3957d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 39586ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 39596ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 39606ead1bbcSJohan Hedberg error = -ENOMEM; 39616ead1bbcSJohan Hedberg goto err; 39626ead1bbcSJohan Hedberg } 39636ead1bbcSJohan Hedberg 39640153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 39650153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 39660153e2ecSMarcel Holtmann 3967bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3968bdc3e0f1SMarcel Holtmann 396999780a7bSJohan Hedberg hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 397099780a7bSJohan Hedberg CRYPTO_ALG_ASYNC); 397199780a7bSJohan Hedberg if (IS_ERR(hdev->tfm_aes)) { 397299780a7bSJohan Hedberg BT_ERR("Unable to create crypto context"); 397399780a7bSJohan Hedberg error = PTR_ERR(hdev->tfm_aes); 397499780a7bSJohan Hedberg hdev->tfm_aes = NULL; 397599780a7bSJohan Hedberg goto err_wqueue; 397699780a7bSJohan Hedberg } 397799780a7bSJohan Hedberg 3978bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 397933ca954dSDavid Herrmann if (error < 0) 398099780a7bSJohan Hedberg goto err_tfm; 39811da177e4SLinus Torvalds 3982611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3983a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3984a8c5fb1aSGustavo Padovan hdev); 3985611b30f7SMarcel Holtmann if (hdev->rfkill) { 3986611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3987611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3988611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3989611b30f7SMarcel Holtmann } 3990611b30f7SMarcel Holtmann } 3991611b30f7SMarcel Holtmann 39925e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 39935e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 39945e130367SJohan Hedberg 3995a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 3996004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 3997ce2be9acSAndrei Emeltchenko 399801cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 399956f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 400056f87901SJohan Hedberg * through reading supported features during init. 400156f87901SJohan Hedberg */ 400256f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 400356f87901SJohan Hedberg } 4004ce2be9acSAndrei Emeltchenko 4005fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 4006fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 4007fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 4008fcee3377SGustavo Padovan 40094a964404SMarcel Holtmann /* Devices that are marked for raw-only usage are unconfigured 40104a964404SMarcel Holtmann * and should not be included in normal operation. 4011fee746b0SMarcel Holtmann */ 4012fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 40134a964404SMarcel Holtmann set_bit(HCI_UNCONFIGURED, &hdev->dev_flags); 4014fee746b0SMarcel Holtmann 40151da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 4016dc946bd8SDavid Herrmann hci_dev_hold(hdev); 40171da177e4SLinus Torvalds 401819202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 4019fbe96d6fSMarcel Holtmann 40201da177e4SLinus Torvalds return id; 4021f48fd9c8SMarcel Holtmann 402299780a7bSJohan Hedberg err_tfm: 402399780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 402433ca954dSDavid Herrmann err_wqueue: 402533ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 40266ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 402733ca954dSDavid Herrmann err: 40283df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 4029f48fd9c8SMarcel Holtmann 403033ca954dSDavid Herrmann return error; 40311da177e4SLinus Torvalds } 40321da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 40331da177e4SLinus Torvalds 40341da177e4SLinus Torvalds /* Unregister HCI device */ 403559735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 40361da177e4SLinus Torvalds { 40373df92b31SSasha Levin int i, id; 4038ef222013SMarcel Holtmann 4039c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 40401da177e4SLinus Torvalds 404194324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 404294324962SJohan Hovold 40433df92b31SSasha Levin id = hdev->id; 40443df92b31SSasha Levin 4045f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 40461da177e4SLinus Torvalds list_del(&hdev->list); 4047f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 40481da177e4SLinus Torvalds 40491da177e4SLinus Torvalds hci_dev_do_close(hdev); 40501da177e4SLinus Torvalds 4051cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 4052ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 4053ef222013SMarcel Holtmann 4054b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 4055b9b5ef18SGustavo Padovan 4056ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 4057*d603b76bSMarcel Holtmann !test_bit(HCI_SETUP, &hdev->dev_flags) && 4058*d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags)) { 405909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4060744cf19eSJohan Hedberg mgmt_index_removed(hdev); 406109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 406256e5cb86SJohan Hedberg } 4063ab81cbf9SJohan Hedberg 40642e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 40652e58ef3eSJohan Hedberg * pending list */ 40662e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 40672e58ef3eSJohan Hedberg 40681da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 40691da177e4SLinus Torvalds 4070611b30f7SMarcel Holtmann if (hdev->rfkill) { 4071611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 4072611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 4073611b30f7SMarcel Holtmann } 4074611b30f7SMarcel Holtmann 407599780a7bSJohan Hedberg if (hdev->tfm_aes) 407699780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 407799780a7bSJohan Hedberg 4078bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 4079147e2d59SDave Young 40800153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 40810153e2ecSMarcel Holtmann 4082f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 40836ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 4084f48fd9c8SMarcel Holtmann 408509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4086e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 40872aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 408855ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 4089b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 4090970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 40912763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 4092d2ab0ac1SMarcel Holtmann hci_white_list_clear(hdev); 4093373110c5SJohan Hedberg hci_conn_params_clear_all(hdev); 409409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 4095e2e0cacbSJohan Hedberg 4096dc946bd8SDavid Herrmann hci_dev_put(hdev); 40973df92b31SSasha Levin 40983df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 40991da177e4SLinus Torvalds } 41001da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 41011da177e4SLinus Torvalds 41021da177e4SLinus Torvalds /* Suspend HCI device */ 41031da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 41041da177e4SLinus Torvalds { 41051da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 41061da177e4SLinus Torvalds return 0; 41071da177e4SLinus Torvalds } 41081da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 41091da177e4SLinus Torvalds 41101da177e4SLinus Torvalds /* Resume HCI device */ 41111da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 41121da177e4SLinus Torvalds { 41131da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 41141da177e4SLinus Torvalds return 0; 41151da177e4SLinus Torvalds } 41161da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 41171da177e4SLinus Torvalds 411876bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 4119e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 412076bca880SMarcel Holtmann { 412176bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 412276bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 412376bca880SMarcel Holtmann kfree_skb(skb); 412476bca880SMarcel Holtmann return -ENXIO; 412576bca880SMarcel Holtmann } 412676bca880SMarcel Holtmann 4127d82603c6SJorrit Schippers /* Incoming skb */ 412876bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 412976bca880SMarcel Holtmann 413076bca880SMarcel Holtmann /* Time stamp */ 413176bca880SMarcel Holtmann __net_timestamp(skb); 413276bca880SMarcel Holtmann 413376bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 4134b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 4135c78ae283SMarcel Holtmann 413676bca880SMarcel Holtmann return 0; 413776bca880SMarcel Holtmann } 413876bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 413976bca880SMarcel Holtmann 414033e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 41411e429f38SGustavo F. Padovan int count, __u8 index) 414233e882a5SSuraj Sumangala { 414333e882a5SSuraj Sumangala int len = 0; 414433e882a5SSuraj Sumangala int hlen = 0; 414533e882a5SSuraj Sumangala int remain = count; 414633e882a5SSuraj Sumangala struct sk_buff *skb; 414733e882a5SSuraj Sumangala struct bt_skb_cb *scb; 414833e882a5SSuraj Sumangala 414933e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 415033e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 415133e882a5SSuraj Sumangala return -EILSEQ; 415233e882a5SSuraj Sumangala 415333e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 415433e882a5SSuraj Sumangala 415533e882a5SSuraj Sumangala if (!skb) { 415633e882a5SSuraj Sumangala switch (type) { 415733e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 415833e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 415933e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 416033e882a5SSuraj Sumangala break; 416133e882a5SSuraj Sumangala case HCI_EVENT_PKT: 416233e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 416333e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 416433e882a5SSuraj Sumangala break; 416533e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 416633e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 416733e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 416833e882a5SSuraj Sumangala break; 416933e882a5SSuraj Sumangala } 417033e882a5SSuraj Sumangala 41711e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 417233e882a5SSuraj Sumangala if (!skb) 417333e882a5SSuraj Sumangala return -ENOMEM; 417433e882a5SSuraj Sumangala 417533e882a5SSuraj Sumangala scb = (void *) skb->cb; 417633e882a5SSuraj Sumangala scb->expect = hlen; 417733e882a5SSuraj Sumangala scb->pkt_type = type; 417833e882a5SSuraj Sumangala 417933e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 418033e882a5SSuraj Sumangala } 418133e882a5SSuraj Sumangala 418233e882a5SSuraj Sumangala while (count) { 418333e882a5SSuraj Sumangala scb = (void *) skb->cb; 418489bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 418533e882a5SSuraj Sumangala 418633e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 418733e882a5SSuraj Sumangala 418833e882a5SSuraj Sumangala count -= len; 418933e882a5SSuraj Sumangala data += len; 419033e882a5SSuraj Sumangala scb->expect -= len; 419133e882a5SSuraj Sumangala remain = count; 419233e882a5SSuraj Sumangala 419333e882a5SSuraj Sumangala switch (type) { 419433e882a5SSuraj Sumangala case HCI_EVENT_PKT: 419533e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 419633e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 419733e882a5SSuraj Sumangala scb->expect = h->plen; 419833e882a5SSuraj Sumangala 419933e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 420033e882a5SSuraj Sumangala kfree_skb(skb); 420133e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 420233e882a5SSuraj Sumangala return -ENOMEM; 420333e882a5SSuraj Sumangala } 420433e882a5SSuraj Sumangala } 420533e882a5SSuraj Sumangala break; 420633e882a5SSuraj Sumangala 420733e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 420833e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 420933e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 421033e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 421133e882a5SSuraj Sumangala 421233e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 421333e882a5SSuraj Sumangala kfree_skb(skb); 421433e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 421533e882a5SSuraj Sumangala return -ENOMEM; 421633e882a5SSuraj Sumangala } 421733e882a5SSuraj Sumangala } 421833e882a5SSuraj Sumangala break; 421933e882a5SSuraj Sumangala 422033e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 422133e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 422233e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 422333e882a5SSuraj Sumangala scb->expect = h->dlen; 422433e882a5SSuraj Sumangala 422533e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 422633e882a5SSuraj Sumangala kfree_skb(skb); 422733e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 422833e882a5SSuraj Sumangala return -ENOMEM; 422933e882a5SSuraj Sumangala } 423033e882a5SSuraj Sumangala } 423133e882a5SSuraj Sumangala break; 423233e882a5SSuraj Sumangala } 423333e882a5SSuraj Sumangala 423433e882a5SSuraj Sumangala if (scb->expect == 0) { 423533e882a5SSuraj Sumangala /* Complete frame */ 423633e882a5SSuraj Sumangala 423733e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 4238e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 423933e882a5SSuraj Sumangala 424033e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 424133e882a5SSuraj Sumangala return remain; 424233e882a5SSuraj Sumangala } 424333e882a5SSuraj Sumangala } 424433e882a5SSuraj Sumangala 424533e882a5SSuraj Sumangala return remain; 424633e882a5SSuraj Sumangala } 424733e882a5SSuraj Sumangala 4248ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 4249ef222013SMarcel Holtmann { 4250f39a3c06SSuraj Sumangala int rem = 0; 4251f39a3c06SSuraj Sumangala 4252ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 4253ef222013SMarcel Holtmann return -EILSEQ; 4254ef222013SMarcel Holtmann 4255da5f6c37SGustavo F. Padovan while (count) { 42561e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 4257f39a3c06SSuraj Sumangala if (rem < 0) 4258f39a3c06SSuraj Sumangala return rem; 4259ef222013SMarcel Holtmann 4260f39a3c06SSuraj Sumangala data += (count - rem); 4261f39a3c06SSuraj Sumangala count = rem; 4262f81c6224SJoe Perches } 4263ef222013SMarcel Holtmann 4264f39a3c06SSuraj Sumangala return rem; 4265ef222013SMarcel Holtmann } 4266ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 4267ef222013SMarcel Holtmann 426899811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 426999811510SSuraj Sumangala 427099811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 427199811510SSuraj Sumangala { 427299811510SSuraj Sumangala int type; 427399811510SSuraj Sumangala int rem = 0; 427499811510SSuraj Sumangala 4275da5f6c37SGustavo F. Padovan while (count) { 427699811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 427799811510SSuraj Sumangala 427899811510SSuraj Sumangala if (!skb) { 427999811510SSuraj Sumangala struct { char type; } *pkt; 428099811510SSuraj Sumangala 428199811510SSuraj Sumangala /* Start of the frame */ 428299811510SSuraj Sumangala pkt = data; 428399811510SSuraj Sumangala type = pkt->type; 428499811510SSuraj Sumangala 428599811510SSuraj Sumangala data++; 428699811510SSuraj Sumangala count--; 428799811510SSuraj Sumangala } else 428899811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 428999811510SSuraj Sumangala 42901e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 42911e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 429299811510SSuraj Sumangala if (rem < 0) 429399811510SSuraj Sumangala return rem; 429499811510SSuraj Sumangala 429599811510SSuraj Sumangala data += (count - rem); 429699811510SSuraj Sumangala count = rem; 4297f81c6224SJoe Perches } 429899811510SSuraj Sumangala 429999811510SSuraj Sumangala return rem; 430099811510SSuraj Sumangala } 430199811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 430299811510SSuraj Sumangala 43031da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 43041da177e4SLinus Torvalds 43051da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 43061da177e4SLinus Torvalds { 43071da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 43081da177e4SLinus Torvalds 4309f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 43101da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 4311f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 43121da177e4SLinus Torvalds 43131da177e4SLinus Torvalds return 0; 43141da177e4SLinus Torvalds } 43151da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 43161da177e4SLinus Torvalds 43171da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 43181da177e4SLinus Torvalds { 43191da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 43201da177e4SLinus Torvalds 4321f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 43221da177e4SLinus Torvalds list_del(&cb->list); 4323f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 43241da177e4SLinus Torvalds 43251da177e4SLinus Torvalds return 0; 43261da177e4SLinus Torvalds } 43271da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 43281da177e4SLinus Torvalds 432951086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 43301da177e4SLinus Torvalds { 43310d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 43321da177e4SLinus Torvalds 43331da177e4SLinus Torvalds /* Time stamp */ 4334a61bbcf2SPatrick McHardy __net_timestamp(skb); 43351da177e4SLinus Torvalds 4336cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4337cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4338cd82e61cSMarcel Holtmann 4339cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 4340cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 4341470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 43421da177e4SLinus Torvalds } 43431da177e4SLinus Torvalds 43441da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 43451da177e4SLinus Torvalds skb_orphan(skb); 43461da177e4SLinus Torvalds 43477bd8f09fSMarcel Holtmann if (hdev->send(hdev, skb) < 0) 434851086991SMarcel Holtmann BT_ERR("%s sending frame failed", hdev->name); 43491da177e4SLinus Torvalds } 43501da177e4SLinus Torvalds 43513119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 43523119ae95SJohan Hedberg { 43533119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 43543119ae95SJohan Hedberg req->hdev = hdev; 43555d73e034SAndre Guedes req->err = 0; 43563119ae95SJohan Hedberg } 43573119ae95SJohan Hedberg 43583119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 43593119ae95SJohan Hedberg { 43603119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 43613119ae95SJohan Hedberg struct sk_buff *skb; 43623119ae95SJohan Hedberg unsigned long flags; 43633119ae95SJohan Hedberg 43643119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 43653119ae95SJohan Hedberg 43665d73e034SAndre Guedes /* If an error occured during request building, remove all HCI 43675d73e034SAndre Guedes * commands queued on the HCI request queue. 43685d73e034SAndre Guedes */ 43695d73e034SAndre Guedes if (req->err) { 43705d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 43715d73e034SAndre Guedes return req->err; 43725d73e034SAndre Guedes } 43735d73e034SAndre Guedes 43743119ae95SJohan Hedberg /* Do not allow empty requests */ 43753119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 4376382b0c39SAndre Guedes return -ENODATA; 43773119ae95SJohan Hedberg 43783119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 43793119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 43803119ae95SJohan Hedberg 43813119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 43823119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 43833119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 43843119ae95SJohan Hedberg 43853119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 43863119ae95SJohan Hedberg 43873119ae95SJohan Hedberg return 0; 43883119ae95SJohan Hedberg } 43893119ae95SJohan Hedberg 43901ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 439107dc93ddSJohan Hedberg u32 plen, const void *param) 43921da177e4SLinus Torvalds { 43931da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 43941da177e4SLinus Torvalds struct hci_command_hdr *hdr; 43951da177e4SLinus Torvalds struct sk_buff *skb; 43961da177e4SLinus Torvalds 43971da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 43981ca3a9d0SJohan Hedberg if (!skb) 43991ca3a9d0SJohan Hedberg return NULL; 44001da177e4SLinus Torvalds 44011da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 4402a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 44031da177e4SLinus Torvalds hdr->plen = plen; 44041da177e4SLinus Torvalds 44051da177e4SLinus Torvalds if (plen) 44061da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 44071da177e4SLinus Torvalds 44081da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 44091da177e4SLinus Torvalds 44100d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 4411c78ae283SMarcel Holtmann 44121ca3a9d0SJohan Hedberg return skb; 44131ca3a9d0SJohan Hedberg } 44141ca3a9d0SJohan Hedberg 44151ca3a9d0SJohan Hedberg /* Send HCI command */ 441607dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 441707dc93ddSJohan Hedberg const void *param) 44181ca3a9d0SJohan Hedberg { 44191ca3a9d0SJohan Hedberg struct sk_buff *skb; 44201ca3a9d0SJohan Hedberg 44211ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 44221ca3a9d0SJohan Hedberg 44231ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 44241ca3a9d0SJohan Hedberg if (!skb) { 44251ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 44261ca3a9d0SJohan Hedberg return -ENOMEM; 44271ca3a9d0SJohan Hedberg } 44281ca3a9d0SJohan Hedberg 442911714b3dSJohan Hedberg /* Stand-alone HCI commands must be flaged as 443011714b3dSJohan Hedberg * single-command requests. 443111714b3dSJohan Hedberg */ 443211714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 443311714b3dSJohan Hedberg 44341da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 4435c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 44361da177e4SLinus Torvalds 44371da177e4SLinus Torvalds return 0; 44381da177e4SLinus Torvalds } 44391da177e4SLinus Torvalds 444071c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 444107dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 444207dc93ddSJohan Hedberg const void *param, u8 event) 444371c76a17SJohan Hedberg { 444471c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 444571c76a17SJohan Hedberg struct sk_buff *skb; 444671c76a17SJohan Hedberg 444771c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 444871c76a17SJohan Hedberg 444934739c1eSAndre Guedes /* If an error occured during request building, there is no point in 445034739c1eSAndre Guedes * queueing the HCI command. We can simply return. 445134739c1eSAndre Guedes */ 445234739c1eSAndre Guedes if (req->err) 445334739c1eSAndre Guedes return; 445434739c1eSAndre Guedes 445571c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 445671c76a17SJohan Hedberg if (!skb) { 44575d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 44585d73e034SAndre Guedes hdev->name, opcode); 44595d73e034SAndre Guedes req->err = -ENOMEM; 4460e348fe6bSAndre Guedes return; 446171c76a17SJohan Hedberg } 446271c76a17SJohan Hedberg 446371c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 446471c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 446571c76a17SJohan Hedberg 446602350a72SJohan Hedberg bt_cb(skb)->req.event = event; 446702350a72SJohan Hedberg 446871c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 446971c76a17SJohan Hedberg } 447071c76a17SJohan Hedberg 447107dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 447207dc93ddSJohan Hedberg const void *param) 447302350a72SJohan Hedberg { 447402350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 447502350a72SJohan Hedberg } 447602350a72SJohan Hedberg 44771da177e4SLinus Torvalds /* Get data from the previously sent command */ 4478a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 44791da177e4SLinus Torvalds { 44801da177e4SLinus Torvalds struct hci_command_hdr *hdr; 44811da177e4SLinus Torvalds 44821da177e4SLinus Torvalds if (!hdev->sent_cmd) 44831da177e4SLinus Torvalds return NULL; 44841da177e4SLinus Torvalds 44851da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 44861da177e4SLinus Torvalds 4487a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 44881da177e4SLinus Torvalds return NULL; 44891da177e4SLinus Torvalds 4490f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 44911da177e4SLinus Torvalds 44921da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 44931da177e4SLinus Torvalds } 44941da177e4SLinus Torvalds 44951da177e4SLinus Torvalds /* Send ACL data */ 44961da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 44971da177e4SLinus Torvalds { 44981da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 44991da177e4SLinus Torvalds int len = skb->len; 45001da177e4SLinus Torvalds 4501badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 4502badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 45039c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 4504aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 4505aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 45061da177e4SLinus Torvalds } 45071da177e4SLinus Torvalds 4508ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 450973d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 45101da177e4SLinus Torvalds { 4511ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 45121da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 45131da177e4SLinus Torvalds struct sk_buff *list; 45141da177e4SLinus Torvalds 4515087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 4516087bfd99SGustavo Padovan skb->data_len = 0; 4517087bfd99SGustavo Padovan 4518087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 4519204a6e54SAndrei Emeltchenko 4520204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 4521204a6e54SAndrei Emeltchenko case HCI_BREDR: 4522087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 4523204a6e54SAndrei Emeltchenko break; 4524204a6e54SAndrei Emeltchenko case HCI_AMP: 4525204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 4526204a6e54SAndrei Emeltchenko break; 4527204a6e54SAndrei Emeltchenko default: 4528204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 4529204a6e54SAndrei Emeltchenko return; 4530204a6e54SAndrei Emeltchenko } 4531087bfd99SGustavo Padovan 453270f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 453370f23020SAndrei Emeltchenko if (!list) { 45341da177e4SLinus Torvalds /* Non fragmented */ 45351da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 45361da177e4SLinus Torvalds 453773d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 45381da177e4SLinus Torvalds } else { 45391da177e4SLinus Torvalds /* Fragmented */ 45401da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 45411da177e4SLinus Torvalds 45421da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 45431da177e4SLinus Torvalds 45441da177e4SLinus Torvalds /* Queue all fragments atomically */ 4545af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 45461da177e4SLinus Torvalds 454773d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 4548e702112fSAndrei Emeltchenko 4549e702112fSAndrei Emeltchenko flags &= ~ACL_START; 4550e702112fSAndrei Emeltchenko flags |= ACL_CONT; 45511da177e4SLinus Torvalds do { 45521da177e4SLinus Torvalds skb = list; list = list->next; 45531da177e4SLinus Torvalds 45540d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 4555e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 45561da177e4SLinus Torvalds 45571da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 45581da177e4SLinus Torvalds 455973d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 45601da177e4SLinus Torvalds } while (list); 45611da177e4SLinus Torvalds 4562af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 45631da177e4SLinus Torvalds } 456473d80debSLuiz Augusto von Dentz } 456573d80debSLuiz Augusto von Dentz 456673d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 456773d80debSLuiz Augusto von Dentz { 4568ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 456973d80debSLuiz Augusto von Dentz 4570f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 457173d80debSLuiz Augusto von Dentz 4572ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 45731da177e4SLinus Torvalds 45743eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 45751da177e4SLinus Torvalds } 45761da177e4SLinus Torvalds 45771da177e4SLinus Torvalds /* Send SCO data */ 45780d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 45791da177e4SLinus Torvalds { 45801da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 45811da177e4SLinus Torvalds struct hci_sco_hdr hdr; 45821da177e4SLinus Torvalds 45831da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 45841da177e4SLinus Torvalds 4585aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 45861da177e4SLinus Torvalds hdr.dlen = skb->len; 45871da177e4SLinus Torvalds 4588badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 4589badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 45909c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 45911da177e4SLinus Torvalds 45920d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 4593c78ae283SMarcel Holtmann 45941da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 45953eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 45961da177e4SLinus Torvalds } 45971da177e4SLinus Torvalds 45981da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 45991da177e4SLinus Torvalds 46001da177e4SLinus Torvalds /* HCI Connection scheduler */ 46016039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 4602a8c5fb1aSGustavo Padovan int *quote) 46031da177e4SLinus Torvalds { 46041da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 46058035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 4606abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 46071da177e4SLinus Torvalds 46081da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 46091da177e4SLinus Torvalds * added and removed with TX task disabled. */ 4610bf4c6325SGustavo F. Padovan 4611bf4c6325SGustavo F. Padovan rcu_read_lock(); 4612bf4c6325SGustavo F. Padovan 4613bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4614769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 46151da177e4SLinus Torvalds continue; 4616769be974SMarcel Holtmann 4617769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 4618769be974SMarcel Holtmann continue; 4619769be974SMarcel Holtmann 46201da177e4SLinus Torvalds num++; 46211da177e4SLinus Torvalds 46221da177e4SLinus Torvalds if (c->sent < min) { 46231da177e4SLinus Torvalds min = c->sent; 46241da177e4SLinus Torvalds conn = c; 46251da177e4SLinus Torvalds } 462652087a79SLuiz Augusto von Dentz 462752087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 462852087a79SLuiz Augusto von Dentz break; 46291da177e4SLinus Torvalds } 46301da177e4SLinus Torvalds 4631bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4632bf4c6325SGustavo F. Padovan 46331da177e4SLinus Torvalds if (conn) { 46346ed58ec5SVille Tervo int cnt, q; 46356ed58ec5SVille Tervo 46366ed58ec5SVille Tervo switch (conn->type) { 46376ed58ec5SVille Tervo case ACL_LINK: 46386ed58ec5SVille Tervo cnt = hdev->acl_cnt; 46396ed58ec5SVille Tervo break; 46406ed58ec5SVille Tervo case SCO_LINK: 46416ed58ec5SVille Tervo case ESCO_LINK: 46426ed58ec5SVille Tervo cnt = hdev->sco_cnt; 46436ed58ec5SVille Tervo break; 46446ed58ec5SVille Tervo case LE_LINK: 46456ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 46466ed58ec5SVille Tervo break; 46476ed58ec5SVille Tervo default: 46486ed58ec5SVille Tervo cnt = 0; 46496ed58ec5SVille Tervo BT_ERR("Unknown link type"); 46506ed58ec5SVille Tervo } 46516ed58ec5SVille Tervo 46526ed58ec5SVille Tervo q = cnt / num; 46531da177e4SLinus Torvalds *quote = q ? q : 1; 46541da177e4SLinus Torvalds } else 46551da177e4SLinus Torvalds *quote = 0; 46561da177e4SLinus Torvalds 46571da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 46581da177e4SLinus Torvalds return conn; 46591da177e4SLinus Torvalds } 46601da177e4SLinus Torvalds 46616039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 46621da177e4SLinus Torvalds { 46631da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 46641da177e4SLinus Torvalds struct hci_conn *c; 46651da177e4SLinus Torvalds 4666bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 46671da177e4SLinus Torvalds 4668bf4c6325SGustavo F. Padovan rcu_read_lock(); 4669bf4c6325SGustavo F. Padovan 46701da177e4SLinus Torvalds /* Kill stalled connections */ 4671bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4672bae1f5d9SVille Tervo if (c->type == type && c->sent) { 46736ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 46746ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 4675bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 46761da177e4SLinus Torvalds } 46771da177e4SLinus Torvalds } 4678bf4c6325SGustavo F. Padovan 4679bf4c6325SGustavo F. Padovan rcu_read_unlock(); 46801da177e4SLinus Torvalds } 46811da177e4SLinus Torvalds 46826039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 468373d80debSLuiz Augusto von Dentz int *quote) 468473d80debSLuiz Augusto von Dentz { 468573d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 468673d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 4687abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 468873d80debSLuiz Augusto von Dentz struct hci_conn *conn; 468973d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 469073d80debSLuiz Augusto von Dentz 469173d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 469273d80debSLuiz Augusto von Dentz 4693bf4c6325SGustavo F. Padovan rcu_read_lock(); 4694bf4c6325SGustavo F. Padovan 4695bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 469673d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 469773d80debSLuiz Augusto von Dentz 469873d80debSLuiz Augusto von Dentz if (conn->type != type) 469973d80debSLuiz Augusto von Dentz continue; 470073d80debSLuiz Augusto von Dentz 470173d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 470273d80debSLuiz Augusto von Dentz continue; 470373d80debSLuiz Augusto von Dentz 470473d80debSLuiz Augusto von Dentz conn_num++; 470573d80debSLuiz Augusto von Dentz 47068192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 470773d80debSLuiz Augusto von Dentz struct sk_buff *skb; 470873d80debSLuiz Augusto von Dentz 470973d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 471073d80debSLuiz Augusto von Dentz continue; 471173d80debSLuiz Augusto von Dentz 471273d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 471373d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 471473d80debSLuiz Augusto von Dentz continue; 471573d80debSLuiz Augusto von Dentz 471673d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 471773d80debSLuiz Augusto von Dentz num = 0; 471873d80debSLuiz Augusto von Dentz min = ~0; 471973d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 472073d80debSLuiz Augusto von Dentz } 472173d80debSLuiz Augusto von Dentz 472273d80debSLuiz Augusto von Dentz num++; 472373d80debSLuiz Augusto von Dentz 472473d80debSLuiz Augusto von Dentz if (conn->sent < min) { 472573d80debSLuiz Augusto von Dentz min = conn->sent; 472673d80debSLuiz Augusto von Dentz chan = tmp; 472773d80debSLuiz Augusto von Dentz } 472873d80debSLuiz Augusto von Dentz } 472973d80debSLuiz Augusto von Dentz 473073d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 473173d80debSLuiz Augusto von Dentz break; 473273d80debSLuiz Augusto von Dentz } 473373d80debSLuiz Augusto von Dentz 4734bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4735bf4c6325SGustavo F. Padovan 473673d80debSLuiz Augusto von Dentz if (!chan) 473773d80debSLuiz Augusto von Dentz return NULL; 473873d80debSLuiz Augusto von Dentz 473973d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 474073d80debSLuiz Augusto von Dentz case ACL_LINK: 474173d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 474273d80debSLuiz Augusto von Dentz break; 4743bd1eb66bSAndrei Emeltchenko case AMP_LINK: 4744bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 4745bd1eb66bSAndrei Emeltchenko break; 474673d80debSLuiz Augusto von Dentz case SCO_LINK: 474773d80debSLuiz Augusto von Dentz case ESCO_LINK: 474873d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 474973d80debSLuiz Augusto von Dentz break; 475073d80debSLuiz Augusto von Dentz case LE_LINK: 475173d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 475273d80debSLuiz Augusto von Dentz break; 475373d80debSLuiz Augusto von Dentz default: 475473d80debSLuiz Augusto von Dentz cnt = 0; 475573d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 475673d80debSLuiz Augusto von Dentz } 475773d80debSLuiz Augusto von Dentz 475873d80debSLuiz Augusto von Dentz q = cnt / num; 475973d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 476073d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 476173d80debSLuiz Augusto von Dentz return chan; 476273d80debSLuiz Augusto von Dentz } 476373d80debSLuiz Augusto von Dentz 476402b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 476502b20f0bSLuiz Augusto von Dentz { 476602b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 476702b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 476802b20f0bSLuiz Augusto von Dentz int num = 0; 476902b20f0bSLuiz Augusto von Dentz 477002b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 477102b20f0bSLuiz Augusto von Dentz 4772bf4c6325SGustavo F. Padovan rcu_read_lock(); 4773bf4c6325SGustavo F. Padovan 4774bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 477502b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 477602b20f0bSLuiz Augusto von Dentz 477702b20f0bSLuiz Augusto von Dentz if (conn->type != type) 477802b20f0bSLuiz Augusto von Dentz continue; 477902b20f0bSLuiz Augusto von Dentz 478002b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 478102b20f0bSLuiz Augusto von Dentz continue; 478202b20f0bSLuiz Augusto von Dentz 478302b20f0bSLuiz Augusto von Dentz num++; 478402b20f0bSLuiz Augusto von Dentz 47858192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 478602b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 478702b20f0bSLuiz Augusto von Dentz 478802b20f0bSLuiz Augusto von Dentz if (chan->sent) { 478902b20f0bSLuiz Augusto von Dentz chan->sent = 0; 479002b20f0bSLuiz Augusto von Dentz continue; 479102b20f0bSLuiz Augusto von Dentz } 479202b20f0bSLuiz Augusto von Dentz 479302b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 479402b20f0bSLuiz Augusto von Dentz continue; 479502b20f0bSLuiz Augusto von Dentz 479602b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 479702b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 479802b20f0bSLuiz Augusto von Dentz continue; 479902b20f0bSLuiz Augusto von Dentz 480002b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 480102b20f0bSLuiz Augusto von Dentz 480202b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 480302b20f0bSLuiz Augusto von Dentz skb->priority); 480402b20f0bSLuiz Augusto von Dentz } 480502b20f0bSLuiz Augusto von Dentz 480602b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 480702b20f0bSLuiz Augusto von Dentz break; 480802b20f0bSLuiz Augusto von Dentz } 4809bf4c6325SGustavo F. Padovan 4810bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4811bf4c6325SGustavo F. Padovan 481202b20f0bSLuiz Augusto von Dentz } 481302b20f0bSLuiz Augusto von Dentz 4814b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4815b71d385aSAndrei Emeltchenko { 4816b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4817b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4818b71d385aSAndrei Emeltchenko } 4819b71d385aSAndrei Emeltchenko 48206039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 48211da177e4SLinus Torvalds { 48224a964404SMarcel Holtmann if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 48231da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 48241da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 482563d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 48265f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 4827bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 48281da177e4SLinus Torvalds } 482963d2bc1bSAndrei Emeltchenko } 48301da177e4SLinus Torvalds 48316039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 483263d2bc1bSAndrei Emeltchenko { 483363d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 483463d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 483563d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 483663d2bc1bSAndrei Emeltchenko int quote; 483763d2bc1bSAndrei Emeltchenko 483863d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 483904837f64SMarcel Holtmann 484073d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 484173d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 4842ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4843ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 484473d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 484573d80debSLuiz Augusto von Dentz skb->len, skb->priority); 484673d80debSLuiz Augusto von Dentz 4847ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4848ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4849ec1cce24SLuiz Augusto von Dentz break; 4850ec1cce24SLuiz Augusto von Dentz 4851ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4852ec1cce24SLuiz Augusto von Dentz 485373d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 485473d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 485504837f64SMarcel Holtmann 485657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 48571da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 48581da177e4SLinus Torvalds 48591da177e4SLinus Torvalds hdev->acl_cnt--; 486073d80debSLuiz Augusto von Dentz chan->sent++; 486173d80debSLuiz Augusto von Dentz chan->conn->sent++; 48621da177e4SLinus Torvalds } 48631da177e4SLinus Torvalds } 486402b20f0bSLuiz Augusto von Dentz 486502b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 486602b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 48671da177e4SLinus Torvalds } 48681da177e4SLinus Torvalds 48696039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4870b71d385aSAndrei Emeltchenko { 487163d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4872b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4873b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4874b71d385aSAndrei Emeltchenko int quote; 4875bd1eb66bSAndrei Emeltchenko u8 type; 4876b71d385aSAndrei Emeltchenko 487763d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4878b71d385aSAndrei Emeltchenko 4879bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4880bd1eb66bSAndrei Emeltchenko 4881bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4882bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4883bd1eb66bSAndrei Emeltchenko else 4884bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4885bd1eb66bSAndrei Emeltchenko 4886b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4887bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4888b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4889b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4890b71d385aSAndrei Emeltchenko int blocks; 4891b71d385aSAndrei Emeltchenko 4892b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4893b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4894b71d385aSAndrei Emeltchenko 4895b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4896b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4897b71d385aSAndrei Emeltchenko break; 4898b71d385aSAndrei Emeltchenko 4899b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4900b71d385aSAndrei Emeltchenko 4901b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4902b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4903b71d385aSAndrei Emeltchenko return; 4904b71d385aSAndrei Emeltchenko 4905b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4906b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4907b71d385aSAndrei Emeltchenko 490857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4909b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4910b71d385aSAndrei Emeltchenko 4911b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4912b71d385aSAndrei Emeltchenko quote -= blocks; 4913b71d385aSAndrei Emeltchenko 4914b71d385aSAndrei Emeltchenko chan->sent += blocks; 4915b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4916b71d385aSAndrei Emeltchenko } 4917b71d385aSAndrei Emeltchenko } 4918b71d385aSAndrei Emeltchenko 4919b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4920bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4921b71d385aSAndrei Emeltchenko } 4922b71d385aSAndrei Emeltchenko 49236039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4924b71d385aSAndrei Emeltchenko { 4925b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4926b71d385aSAndrei Emeltchenko 4927bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4928bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 4929bd1eb66bSAndrei Emeltchenko return; 4930bd1eb66bSAndrei Emeltchenko 4931bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4932bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4933b71d385aSAndrei Emeltchenko return; 4934b71d385aSAndrei Emeltchenko 4935b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4936b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4937b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4938b71d385aSAndrei Emeltchenko break; 4939b71d385aSAndrei Emeltchenko 4940b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4941b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4942b71d385aSAndrei Emeltchenko break; 4943b71d385aSAndrei Emeltchenko } 4944b71d385aSAndrei Emeltchenko } 4945b71d385aSAndrei Emeltchenko 49461da177e4SLinus Torvalds /* Schedule SCO */ 49476039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 49481da177e4SLinus Torvalds { 49491da177e4SLinus Torvalds struct hci_conn *conn; 49501da177e4SLinus Torvalds struct sk_buff *skb; 49511da177e4SLinus Torvalds int quote; 49521da177e4SLinus Torvalds 49531da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 49541da177e4SLinus Torvalds 495552087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 495652087a79SLuiz Augusto von Dentz return; 495752087a79SLuiz Augusto von Dentz 49581da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 49591da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 49601da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 496157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 49621da177e4SLinus Torvalds 49631da177e4SLinus Torvalds conn->sent++; 49641da177e4SLinus Torvalds if (conn->sent == ~0) 49651da177e4SLinus Torvalds conn->sent = 0; 49661da177e4SLinus Torvalds } 49671da177e4SLinus Torvalds } 49681da177e4SLinus Torvalds } 49691da177e4SLinus Torvalds 49706039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 4971b6a0dc82SMarcel Holtmann { 4972b6a0dc82SMarcel Holtmann struct hci_conn *conn; 4973b6a0dc82SMarcel Holtmann struct sk_buff *skb; 4974b6a0dc82SMarcel Holtmann int quote; 4975b6a0dc82SMarcel Holtmann 4976b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 4977b6a0dc82SMarcel Holtmann 497852087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 497952087a79SLuiz Augusto von Dentz return; 498052087a79SLuiz Augusto von Dentz 49818fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 49828fc9ced3SGustavo Padovan "e))) { 4983b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 4984b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 498557d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4986b6a0dc82SMarcel Holtmann 4987b6a0dc82SMarcel Holtmann conn->sent++; 4988b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 4989b6a0dc82SMarcel Holtmann conn->sent = 0; 4990b6a0dc82SMarcel Holtmann } 4991b6a0dc82SMarcel Holtmann } 4992b6a0dc82SMarcel Holtmann } 4993b6a0dc82SMarcel Holtmann 49946039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 49956ed58ec5SVille Tervo { 499673d80debSLuiz Augusto von Dentz struct hci_chan *chan; 49976ed58ec5SVille Tervo struct sk_buff *skb; 499802b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 49996ed58ec5SVille Tervo 50006ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 50016ed58ec5SVille Tervo 500252087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 500352087a79SLuiz Augusto von Dentz return; 500452087a79SLuiz Augusto von Dentz 50054a964404SMarcel Holtmann if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 50066ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 50076ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 5008bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 50096ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 5010bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 50116ed58ec5SVille Tervo } 50126ed58ec5SVille Tervo 50136ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 501402b20f0bSLuiz Augusto von Dentz tmp = cnt; 501573d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 5016ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 5017ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 501873d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 501973d80debSLuiz Augusto von Dentz skb->len, skb->priority); 50206ed58ec5SVille Tervo 5021ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 5022ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 5023ec1cce24SLuiz Augusto von Dentz break; 5024ec1cce24SLuiz Augusto von Dentz 5025ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 5026ec1cce24SLuiz Augusto von Dentz 502757d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 50286ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 50296ed58ec5SVille Tervo 50306ed58ec5SVille Tervo cnt--; 503173d80debSLuiz Augusto von Dentz chan->sent++; 503273d80debSLuiz Augusto von Dentz chan->conn->sent++; 50336ed58ec5SVille Tervo } 50346ed58ec5SVille Tervo } 503573d80debSLuiz Augusto von Dentz 50366ed58ec5SVille Tervo if (hdev->le_pkts) 50376ed58ec5SVille Tervo hdev->le_cnt = cnt; 50386ed58ec5SVille Tervo else 50396ed58ec5SVille Tervo hdev->acl_cnt = cnt; 504002b20f0bSLuiz Augusto von Dentz 504102b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 504202b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 50436ed58ec5SVille Tervo } 50446ed58ec5SVille Tervo 50453eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 50461da177e4SLinus Torvalds { 50473eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 50481da177e4SLinus Torvalds struct sk_buff *skb; 50491da177e4SLinus Torvalds 50506ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 50516ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 50521da177e4SLinus Torvalds 505352de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 50541da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 50551da177e4SLinus Torvalds hci_sched_acl(hdev); 50561da177e4SLinus Torvalds hci_sched_sco(hdev); 5057b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 50586ed58ec5SVille Tervo hci_sched_le(hdev); 505952de599eSMarcel Holtmann } 50606ed58ec5SVille Tervo 50611da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 50621da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 506357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 50641da177e4SLinus Torvalds } 50651da177e4SLinus Torvalds 506625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 50671da177e4SLinus Torvalds 50681da177e4SLinus Torvalds /* ACL data packet */ 50696039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 50701da177e4SLinus Torvalds { 50711da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 50721da177e4SLinus Torvalds struct hci_conn *conn; 50731da177e4SLinus Torvalds __u16 handle, flags; 50741da177e4SLinus Torvalds 50751da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 50761da177e4SLinus Torvalds 50771da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 50781da177e4SLinus Torvalds flags = hci_flags(handle); 50791da177e4SLinus Torvalds handle = hci_handle(handle); 50801da177e4SLinus Torvalds 5081f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 5082a8c5fb1aSGustavo Padovan handle, flags); 50831da177e4SLinus Torvalds 50841da177e4SLinus Torvalds hdev->stat.acl_rx++; 50851da177e4SLinus Torvalds 50861da177e4SLinus Torvalds hci_dev_lock(hdev); 50871da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 50881da177e4SLinus Torvalds hci_dev_unlock(hdev); 50891da177e4SLinus Torvalds 50901da177e4SLinus Torvalds if (conn) { 509165983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 509204837f64SMarcel Holtmann 50931da177e4SLinus Torvalds /* Send to upper protocol */ 5094686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 50951da177e4SLinus Torvalds return; 50961da177e4SLinus Torvalds } else { 50971da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 50981da177e4SLinus Torvalds hdev->name, handle); 50991da177e4SLinus Torvalds } 51001da177e4SLinus Torvalds 51011da177e4SLinus Torvalds kfree_skb(skb); 51021da177e4SLinus Torvalds } 51031da177e4SLinus Torvalds 51041da177e4SLinus Torvalds /* SCO data packet */ 51056039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 51061da177e4SLinus Torvalds { 51071da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 51081da177e4SLinus Torvalds struct hci_conn *conn; 51091da177e4SLinus Torvalds __u16 handle; 51101da177e4SLinus Torvalds 51111da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 51121da177e4SLinus Torvalds 51131da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 51141da177e4SLinus Torvalds 5115f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 51161da177e4SLinus Torvalds 51171da177e4SLinus Torvalds hdev->stat.sco_rx++; 51181da177e4SLinus Torvalds 51191da177e4SLinus Torvalds hci_dev_lock(hdev); 51201da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 51211da177e4SLinus Torvalds hci_dev_unlock(hdev); 51221da177e4SLinus Torvalds 51231da177e4SLinus Torvalds if (conn) { 51241da177e4SLinus Torvalds /* Send to upper protocol */ 5125686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 51261da177e4SLinus Torvalds return; 51271da177e4SLinus Torvalds } else { 51281da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 51291da177e4SLinus Torvalds hdev->name, handle); 51301da177e4SLinus Torvalds } 51311da177e4SLinus Torvalds 51321da177e4SLinus Torvalds kfree_skb(skb); 51331da177e4SLinus Torvalds } 51341da177e4SLinus Torvalds 51359238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 51369238f36aSJohan Hedberg { 51379238f36aSJohan Hedberg struct sk_buff *skb; 51389238f36aSJohan Hedberg 51399238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 51409238f36aSJohan Hedberg if (!skb) 51419238f36aSJohan Hedberg return true; 51429238f36aSJohan Hedberg 51439238f36aSJohan Hedberg return bt_cb(skb)->req.start; 51449238f36aSJohan Hedberg } 51459238f36aSJohan Hedberg 514642c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 514742c6b129SJohan Hedberg { 514842c6b129SJohan Hedberg struct hci_command_hdr *sent; 514942c6b129SJohan Hedberg struct sk_buff *skb; 515042c6b129SJohan Hedberg u16 opcode; 515142c6b129SJohan Hedberg 515242c6b129SJohan Hedberg if (!hdev->sent_cmd) 515342c6b129SJohan Hedberg return; 515442c6b129SJohan Hedberg 515542c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 515642c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 515742c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 515842c6b129SJohan Hedberg return; 515942c6b129SJohan Hedberg 516042c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 516142c6b129SJohan Hedberg if (!skb) 516242c6b129SJohan Hedberg return; 516342c6b129SJohan Hedberg 516442c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 516542c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 516642c6b129SJohan Hedberg } 516742c6b129SJohan Hedberg 51689238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 51699238f36aSJohan Hedberg { 51709238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 51719238f36aSJohan Hedberg struct sk_buff *skb; 51729238f36aSJohan Hedberg unsigned long flags; 51739238f36aSJohan Hedberg 51749238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 51759238f36aSJohan Hedberg 517642c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 517742c6b129SJohan Hedberg * sent we need to do special handling of it. 51789238f36aSJohan Hedberg */ 517942c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 518042c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 518142c6b129SJohan Hedberg * reset complete event during init and any pending 518242c6b129SJohan Hedberg * command will never be completed. In such a case we 518342c6b129SJohan Hedberg * need to resend whatever was the last sent 518442c6b129SJohan Hedberg * command. 518542c6b129SJohan Hedberg */ 518642c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 518742c6b129SJohan Hedberg hci_resend_last(hdev); 518842c6b129SJohan Hedberg 51899238f36aSJohan Hedberg return; 519042c6b129SJohan Hedberg } 51919238f36aSJohan Hedberg 51929238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 51939238f36aSJohan Hedberg * this request the request is not yet complete. 51949238f36aSJohan Hedberg */ 51959238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 51969238f36aSJohan Hedberg return; 51979238f36aSJohan Hedberg 51989238f36aSJohan Hedberg /* If this was the last command in a request the complete 51999238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 52009238f36aSJohan Hedberg * command queue (hdev->cmd_q). 52019238f36aSJohan Hedberg */ 52029238f36aSJohan Hedberg if (hdev->sent_cmd) { 52039238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 520453e21fbcSJohan Hedberg 520553e21fbcSJohan Hedberg if (req_complete) { 520653e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 520753e21fbcSJohan Hedberg * avoid calling the callback more than once if 520853e21fbcSJohan Hedberg * this function gets called again. 520953e21fbcSJohan Hedberg */ 521053e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 521153e21fbcSJohan Hedberg 52129238f36aSJohan Hedberg goto call_complete; 52139238f36aSJohan Hedberg } 521453e21fbcSJohan Hedberg } 52159238f36aSJohan Hedberg 52169238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 52179238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 52189238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 52199238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 52209238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 52219238f36aSJohan Hedberg break; 52229238f36aSJohan Hedberg } 52239238f36aSJohan Hedberg 52249238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 52259238f36aSJohan Hedberg kfree_skb(skb); 52269238f36aSJohan Hedberg } 52279238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 52289238f36aSJohan Hedberg 52299238f36aSJohan Hedberg call_complete: 52309238f36aSJohan Hedberg if (req_complete) 52319238f36aSJohan Hedberg req_complete(hdev, status); 52329238f36aSJohan Hedberg } 52339238f36aSJohan Hedberg 5234b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 52351da177e4SLinus Torvalds { 5236b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 52371da177e4SLinus Torvalds struct sk_buff *skb; 52381da177e4SLinus Torvalds 52391da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 52401da177e4SLinus Torvalds 52411da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 5242cd82e61cSMarcel Holtmann /* Send copy to monitor */ 5243cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 5244cd82e61cSMarcel Holtmann 52451da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 52461da177e4SLinus Torvalds /* Send copy to the sockets */ 5247470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 52481da177e4SLinus Torvalds } 52491da177e4SLinus Torvalds 5250fee746b0SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 52511da177e4SLinus Torvalds kfree_skb(skb); 52521da177e4SLinus Torvalds continue; 52531da177e4SLinus Torvalds } 52541da177e4SLinus Torvalds 52551da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 52561da177e4SLinus Torvalds /* Don't process data packets in this states. */ 52570d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 52581da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 52591da177e4SLinus Torvalds case HCI_SCODATA_PKT: 52601da177e4SLinus Torvalds kfree_skb(skb); 52611da177e4SLinus Torvalds continue; 52623ff50b79SStephen Hemminger } 52631da177e4SLinus Torvalds } 52641da177e4SLinus Torvalds 52651da177e4SLinus Torvalds /* Process frame */ 52660d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 52671da177e4SLinus Torvalds case HCI_EVENT_PKT: 5268b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 52691da177e4SLinus Torvalds hci_event_packet(hdev, skb); 52701da177e4SLinus Torvalds break; 52711da177e4SLinus Torvalds 52721da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 52731da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 52741da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 52751da177e4SLinus Torvalds break; 52761da177e4SLinus Torvalds 52771da177e4SLinus Torvalds case HCI_SCODATA_PKT: 52781da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 52791da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 52801da177e4SLinus Torvalds break; 52811da177e4SLinus Torvalds 52821da177e4SLinus Torvalds default: 52831da177e4SLinus Torvalds kfree_skb(skb); 52841da177e4SLinus Torvalds break; 52851da177e4SLinus Torvalds } 52861da177e4SLinus Torvalds } 52871da177e4SLinus Torvalds } 52881da177e4SLinus Torvalds 5289c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 52901da177e4SLinus Torvalds { 5291c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 52921da177e4SLinus Torvalds struct sk_buff *skb; 52931da177e4SLinus Torvalds 52942104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 52952104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 52961da177e4SLinus Torvalds 52971da177e4SLinus Torvalds /* Send queued commands */ 52985a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 52995a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 53005a08ecceSAndrei Emeltchenko if (!skb) 53015a08ecceSAndrei Emeltchenko return; 53025a08ecceSAndrei Emeltchenko 53031da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 53041da177e4SLinus Torvalds 5305a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 530670f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 53071da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 530857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 53097bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 531065cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 53117bdb8a5cSSzymon Janc else 531265cc2b49SMarcel Holtmann schedule_delayed_work(&hdev->cmd_timer, 531365cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT); 53141da177e4SLinus Torvalds } else { 53151da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 5316c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 53171da177e4SLinus Torvalds } 53181da177e4SLinus Torvalds } 53191da177e4SLinus Torvalds } 5320b1efcc28SAndre Guedes 5321b1efcc28SAndre Guedes void hci_req_add_le_scan_disable(struct hci_request *req) 5322b1efcc28SAndre Guedes { 5323b1efcc28SAndre Guedes struct hci_cp_le_set_scan_enable cp; 5324b1efcc28SAndre Guedes 5325b1efcc28SAndre Guedes memset(&cp, 0, sizeof(cp)); 5326b1efcc28SAndre Guedes cp.enable = LE_SCAN_DISABLE; 5327b1efcc28SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 5328b1efcc28SAndre Guedes } 5329a4790dbdSAndre Guedes 53308ef30fd3SAndre Guedes void hci_req_add_le_passive_scan(struct hci_request *req) 53318ef30fd3SAndre Guedes { 53328ef30fd3SAndre Guedes struct hci_cp_le_set_scan_param param_cp; 53338ef30fd3SAndre Guedes struct hci_cp_le_set_scan_enable enable_cp; 53348ef30fd3SAndre Guedes struct hci_dev *hdev = req->hdev; 53358ef30fd3SAndre Guedes u8 own_addr_type; 53368ef30fd3SAndre Guedes 53376ab535a7SMarcel Holtmann /* Set require_privacy to false since no SCAN_REQ are send 53386ab535a7SMarcel Holtmann * during passive scanning. Not using an unresolvable address 53396ab535a7SMarcel Holtmann * here is important so that peer devices using direct 53406ab535a7SMarcel Holtmann * advertising with our address will be correctly reported 53416ab535a7SMarcel Holtmann * by the controller. 53428ef30fd3SAndre Guedes */ 53436ab535a7SMarcel Holtmann if (hci_update_random_address(req, false, &own_addr_type)) 53448ef30fd3SAndre Guedes return; 53458ef30fd3SAndre Guedes 53468ef30fd3SAndre Guedes memset(¶m_cp, 0, sizeof(param_cp)); 53478ef30fd3SAndre Guedes param_cp.type = LE_SCAN_PASSIVE; 53488ef30fd3SAndre Guedes param_cp.interval = cpu_to_le16(hdev->le_scan_interval); 53498ef30fd3SAndre Guedes param_cp.window = cpu_to_le16(hdev->le_scan_window); 53508ef30fd3SAndre Guedes param_cp.own_address_type = own_addr_type; 53518ef30fd3SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), 53528ef30fd3SAndre Guedes ¶m_cp); 53538ef30fd3SAndre Guedes 53548ef30fd3SAndre Guedes memset(&enable_cp, 0, sizeof(enable_cp)); 53558ef30fd3SAndre Guedes enable_cp.enable = LE_SCAN_ENABLE; 53564340a124SAndre Guedes enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; 53578ef30fd3SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), 53588ef30fd3SAndre Guedes &enable_cp); 53598ef30fd3SAndre Guedes } 53608ef30fd3SAndre Guedes 5361a4790dbdSAndre Guedes static void update_background_scan_complete(struct hci_dev *hdev, u8 status) 5362a4790dbdSAndre Guedes { 5363a4790dbdSAndre Guedes if (status) 5364a4790dbdSAndre Guedes BT_DBG("HCI request failed to update background scanning: " 5365a4790dbdSAndre Guedes "status 0x%2.2x", status); 5366a4790dbdSAndre Guedes } 5367a4790dbdSAndre Guedes 5368a4790dbdSAndre Guedes /* This function controls the background scanning based on hdev->pend_le_conns 5369a4790dbdSAndre Guedes * list. If there are pending LE connection we start the background scanning, 5370a4790dbdSAndre Guedes * otherwise we stop it. 5371a4790dbdSAndre Guedes * 5372a4790dbdSAndre Guedes * This function requires the caller holds hdev->lock. 5373a4790dbdSAndre Guedes */ 5374a4790dbdSAndre Guedes void hci_update_background_scan(struct hci_dev *hdev) 5375a4790dbdSAndre Guedes { 5376a4790dbdSAndre Guedes struct hci_request req; 5377a4790dbdSAndre Guedes struct hci_conn *conn; 5378a4790dbdSAndre Guedes int err; 5379a4790dbdSAndre Guedes 5380c20c02d5SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags) || 5381c20c02d5SMarcel Holtmann test_bit(HCI_INIT, &hdev->flags) || 5382c20c02d5SMarcel Holtmann test_bit(HCI_SETUP, &hdev->dev_flags) || 5383*d603b76bSMarcel Holtmann test_bit(HCI_CONFIG, &hdev->dev_flags) || 5384b8221770SMarcel Holtmann test_bit(HCI_AUTO_OFF, &hdev->dev_flags) || 5385c20c02d5SMarcel Holtmann test_bit(HCI_UNREGISTER, &hdev->dev_flags)) 53861c1697c0SMarcel Holtmann return; 53871c1697c0SMarcel Holtmann 5388a4790dbdSAndre Guedes hci_req_init(&req, hdev); 5389a4790dbdSAndre Guedes 539066f8455aSJohan Hedberg if (list_empty(&hdev->pend_le_conns) && 539166f8455aSJohan Hedberg list_empty(&hdev->pend_le_reports)) { 53920d2bf134SJohan Hedberg /* If there is no pending LE connections or devices 53930d2bf134SJohan Hedberg * to be scanned for, we should stop the background 53940d2bf134SJohan Hedberg * scanning. 5395a4790dbdSAndre Guedes */ 5396a4790dbdSAndre Guedes 5397a4790dbdSAndre Guedes /* If controller is not scanning we are done. */ 5398a4790dbdSAndre Guedes if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 5399a4790dbdSAndre Guedes return; 5400a4790dbdSAndre Guedes 5401a4790dbdSAndre Guedes hci_req_add_le_scan_disable(&req); 5402a4790dbdSAndre Guedes 5403a4790dbdSAndre Guedes BT_DBG("%s stopping background scanning", hdev->name); 5404a4790dbdSAndre Guedes } else { 5405a4790dbdSAndre Guedes /* If there is at least one pending LE connection, we should 5406a4790dbdSAndre Guedes * keep the background scan running. 5407a4790dbdSAndre Guedes */ 5408a4790dbdSAndre Guedes 5409a4790dbdSAndre Guedes /* If controller is connecting, we should not start scanning 5410a4790dbdSAndre Guedes * since some controllers are not able to scan and connect at 5411a4790dbdSAndre Guedes * the same time. 5412a4790dbdSAndre Guedes */ 5413a4790dbdSAndre Guedes conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 5414a4790dbdSAndre Guedes if (conn) 5415a4790dbdSAndre Guedes return; 5416a4790dbdSAndre Guedes 54174340a124SAndre Guedes /* If controller is currently scanning, we stop it to ensure we 54184340a124SAndre Guedes * don't miss any advertising (due to duplicates filter). 54194340a124SAndre Guedes */ 54204340a124SAndre Guedes if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 54214340a124SAndre Guedes hci_req_add_le_scan_disable(&req); 54224340a124SAndre Guedes 54238ef30fd3SAndre Guedes hci_req_add_le_passive_scan(&req); 5424a4790dbdSAndre Guedes 5425a4790dbdSAndre Guedes BT_DBG("%s starting background scanning", hdev->name); 5426a4790dbdSAndre Guedes } 5427a4790dbdSAndre Guedes 5428a4790dbdSAndre Guedes err = hci_req_run(&req, update_background_scan_complete); 5429a4790dbdSAndre Guedes if (err) 5430a4790dbdSAndre Guedes BT_ERR("Failed to run HCI request: err %d", err); 5431a4790dbdSAndre Guedes } 5432