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> 371da177e4SLinus Torvalds 38970c4e46SJohan Hedberg #include "smp.h" 39970c4e46SJohan Hedberg 40b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 41c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 423eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds /* HCI device list */ 451da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 461da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds /* HCI callback list */ 491da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 501da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 511da177e4SLinus Torvalds 523df92b31SSasha Levin /* HCI ID Numbering */ 533df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 543df92b31SSasha Levin 551da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 561da177e4SLinus Torvalds 576516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 581da177e4SLinus Torvalds { 59040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 601da177e4SLinus Torvalds } 611da177e4SLinus Torvalds 62baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */ 63baf27f6eSMarcel Holtmann 644b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf, 654b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 664b4148e9SMarcel Holtmann { 674b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 684b4148e9SMarcel Holtmann char buf[3]; 694b4148e9SMarcel Holtmann 704b4148e9SMarcel Holtmann buf[0] = test_bit(HCI_DUT_MODE, &hdev->dev_flags) ? 'Y': 'N'; 714b4148e9SMarcel Holtmann buf[1] = '\n'; 724b4148e9SMarcel Holtmann buf[2] = '\0'; 734b4148e9SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 744b4148e9SMarcel Holtmann } 754b4148e9SMarcel Holtmann 764b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf, 774b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 784b4148e9SMarcel Holtmann { 794b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 804b4148e9SMarcel Holtmann struct sk_buff *skb; 814b4148e9SMarcel Holtmann char buf[32]; 824b4148e9SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 834b4148e9SMarcel Holtmann bool enable; 844b4148e9SMarcel Holtmann int err; 854b4148e9SMarcel Holtmann 864b4148e9SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 874b4148e9SMarcel Holtmann return -ENETDOWN; 884b4148e9SMarcel Holtmann 894b4148e9SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 904b4148e9SMarcel Holtmann return -EFAULT; 914b4148e9SMarcel Holtmann 924b4148e9SMarcel Holtmann buf[buf_size] = '\0'; 934b4148e9SMarcel Holtmann if (strtobool(buf, &enable)) 944b4148e9SMarcel Holtmann return -EINVAL; 954b4148e9SMarcel Holtmann 964b4148e9SMarcel Holtmann if (enable == test_bit(HCI_DUT_MODE, &hdev->dev_flags)) 974b4148e9SMarcel Holtmann return -EALREADY; 984b4148e9SMarcel Holtmann 994b4148e9SMarcel Holtmann hci_req_lock(hdev); 1004b4148e9SMarcel Holtmann if (enable) 1014b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL, 1024b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1034b4148e9SMarcel Holtmann else 1044b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, 1054b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1064b4148e9SMarcel Holtmann hci_req_unlock(hdev); 1074b4148e9SMarcel Holtmann 1084b4148e9SMarcel Holtmann if (IS_ERR(skb)) 1094b4148e9SMarcel Holtmann return PTR_ERR(skb); 1104b4148e9SMarcel Holtmann 1114b4148e9SMarcel Holtmann err = -bt_to_errno(skb->data[0]); 1124b4148e9SMarcel Holtmann kfree_skb(skb); 1134b4148e9SMarcel Holtmann 1144b4148e9SMarcel Holtmann if (err < 0) 1154b4148e9SMarcel Holtmann return err; 1164b4148e9SMarcel Holtmann 1174b4148e9SMarcel Holtmann change_bit(HCI_DUT_MODE, &hdev->dev_flags); 1184b4148e9SMarcel Holtmann 1194b4148e9SMarcel Holtmann return count; 1204b4148e9SMarcel Holtmann } 1214b4148e9SMarcel Holtmann 1224b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = { 1234b4148e9SMarcel Holtmann .open = simple_open, 1244b4148e9SMarcel Holtmann .read = dut_mode_read, 1254b4148e9SMarcel Holtmann .write = dut_mode_write, 1264b4148e9SMarcel Holtmann .llseek = default_llseek, 1274b4148e9SMarcel Holtmann }; 1284b4148e9SMarcel Holtmann 129dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr) 130dfb826a8SMarcel Holtmann { 131dfb826a8SMarcel Holtmann struct hci_dev *hdev = f->private; 132dfb826a8SMarcel Holtmann u8 p; 133dfb826a8SMarcel Holtmann 134dfb826a8SMarcel Holtmann hci_dev_lock(hdev); 135dfb826a8SMarcel Holtmann for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 136cfbb2b5bSMarcel Holtmann seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 137dfb826a8SMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p, 138dfb826a8SMarcel Holtmann hdev->features[p][0], hdev->features[p][1], 139dfb826a8SMarcel Holtmann hdev->features[p][2], hdev->features[p][3], 140dfb826a8SMarcel Holtmann hdev->features[p][4], hdev->features[p][5], 141dfb826a8SMarcel Holtmann hdev->features[p][6], hdev->features[p][7]); 142dfb826a8SMarcel Holtmann } 143cfbb2b5bSMarcel Holtmann if (lmp_le_capable(hdev)) 144cfbb2b5bSMarcel Holtmann seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 145cfbb2b5bSMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", 146cfbb2b5bSMarcel Holtmann hdev->le_features[0], hdev->le_features[1], 147cfbb2b5bSMarcel Holtmann hdev->le_features[2], hdev->le_features[3], 148cfbb2b5bSMarcel Holtmann hdev->le_features[4], hdev->le_features[5], 149cfbb2b5bSMarcel Holtmann hdev->le_features[6], hdev->le_features[7]); 150dfb826a8SMarcel Holtmann hci_dev_unlock(hdev); 151dfb826a8SMarcel Holtmann 152dfb826a8SMarcel Holtmann return 0; 153dfb826a8SMarcel Holtmann } 154dfb826a8SMarcel Holtmann 155dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file) 156dfb826a8SMarcel Holtmann { 157dfb826a8SMarcel Holtmann return single_open(file, features_show, inode->i_private); 158dfb826a8SMarcel Holtmann } 159dfb826a8SMarcel Holtmann 160dfb826a8SMarcel Holtmann static const struct file_operations features_fops = { 161dfb826a8SMarcel Holtmann .open = features_open, 162dfb826a8SMarcel Holtmann .read = seq_read, 163dfb826a8SMarcel Holtmann .llseek = seq_lseek, 164dfb826a8SMarcel Holtmann .release = single_release, 165dfb826a8SMarcel Holtmann }; 166dfb826a8SMarcel Holtmann 16770afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p) 16870afe0b8SMarcel Holtmann { 16970afe0b8SMarcel Holtmann struct hci_dev *hdev = f->private; 17070afe0b8SMarcel Holtmann struct bdaddr_list *b; 17170afe0b8SMarcel Holtmann 17270afe0b8SMarcel Holtmann hci_dev_lock(hdev); 17370afe0b8SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) 174b25f0785SMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 17570afe0b8SMarcel Holtmann hci_dev_unlock(hdev); 17670afe0b8SMarcel Holtmann 17770afe0b8SMarcel Holtmann return 0; 17870afe0b8SMarcel Holtmann } 17970afe0b8SMarcel Holtmann 18070afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file) 18170afe0b8SMarcel Holtmann { 18270afe0b8SMarcel Holtmann return single_open(file, blacklist_show, inode->i_private); 18370afe0b8SMarcel Holtmann } 18470afe0b8SMarcel Holtmann 18570afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = { 18670afe0b8SMarcel Holtmann .open = blacklist_open, 18770afe0b8SMarcel Holtmann .read = seq_read, 18870afe0b8SMarcel Holtmann .llseek = seq_lseek, 18970afe0b8SMarcel Holtmann .release = single_release, 19070afe0b8SMarcel Holtmann }; 19170afe0b8SMarcel Holtmann 19247219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p) 19347219839SMarcel Holtmann { 19447219839SMarcel Holtmann struct hci_dev *hdev = f->private; 19547219839SMarcel Holtmann struct bt_uuid *uuid; 19647219839SMarcel Holtmann 19747219839SMarcel Holtmann hci_dev_lock(hdev); 19847219839SMarcel Holtmann list_for_each_entry(uuid, &hdev->uuids, list) { 19958f01aa9SMarcel Holtmann u8 i, val[16]; 20047219839SMarcel Holtmann 20158f01aa9SMarcel Holtmann /* The Bluetooth UUID values are stored in big endian, 20258f01aa9SMarcel Holtmann * but with reversed byte order. So convert them into 20358f01aa9SMarcel Holtmann * the right order for the %pUb modifier. 20458f01aa9SMarcel Holtmann */ 20558f01aa9SMarcel Holtmann for (i = 0; i < 16; i++) 20658f01aa9SMarcel Holtmann val[i] = uuid->uuid[15 - i]; 20747219839SMarcel Holtmann 20858f01aa9SMarcel Holtmann seq_printf(f, "%pUb\n", val); 20947219839SMarcel Holtmann } 21047219839SMarcel Holtmann hci_dev_unlock(hdev); 21147219839SMarcel Holtmann 21247219839SMarcel Holtmann return 0; 21347219839SMarcel Holtmann } 21447219839SMarcel Holtmann 21547219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file) 21647219839SMarcel Holtmann { 21747219839SMarcel Holtmann return single_open(file, uuids_show, inode->i_private); 21847219839SMarcel Holtmann } 21947219839SMarcel Holtmann 22047219839SMarcel Holtmann static const struct file_operations uuids_fops = { 22147219839SMarcel Holtmann .open = uuids_open, 22247219839SMarcel Holtmann .read = seq_read, 22347219839SMarcel Holtmann .llseek = seq_lseek, 22447219839SMarcel Holtmann .release = single_release, 22547219839SMarcel Holtmann }; 22647219839SMarcel Holtmann 227baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p) 228baf27f6eSMarcel Holtmann { 229baf27f6eSMarcel Holtmann struct hci_dev *hdev = f->private; 230baf27f6eSMarcel Holtmann struct discovery_state *cache = &hdev->discovery; 231baf27f6eSMarcel Holtmann struct inquiry_entry *e; 232baf27f6eSMarcel Holtmann 233baf27f6eSMarcel Holtmann hci_dev_lock(hdev); 234baf27f6eSMarcel Holtmann 235baf27f6eSMarcel Holtmann list_for_each_entry(e, &cache->all, all) { 236baf27f6eSMarcel Holtmann struct inquiry_data *data = &e->data; 237baf27f6eSMarcel Holtmann seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", 238baf27f6eSMarcel Holtmann &data->bdaddr, 239baf27f6eSMarcel Holtmann data->pscan_rep_mode, data->pscan_period_mode, 240baf27f6eSMarcel Holtmann data->pscan_mode, data->dev_class[2], 241baf27f6eSMarcel Holtmann data->dev_class[1], data->dev_class[0], 242baf27f6eSMarcel Holtmann __le16_to_cpu(data->clock_offset), 243baf27f6eSMarcel Holtmann data->rssi, data->ssp_mode, e->timestamp); 244baf27f6eSMarcel Holtmann } 245baf27f6eSMarcel Holtmann 246baf27f6eSMarcel Holtmann hci_dev_unlock(hdev); 247baf27f6eSMarcel Holtmann 248baf27f6eSMarcel Holtmann return 0; 249baf27f6eSMarcel Holtmann } 250baf27f6eSMarcel Holtmann 251baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file) 252baf27f6eSMarcel Holtmann { 253baf27f6eSMarcel Holtmann return single_open(file, inquiry_cache_show, inode->i_private); 254baf27f6eSMarcel Holtmann } 255baf27f6eSMarcel Holtmann 256baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = { 257baf27f6eSMarcel Holtmann .open = inquiry_cache_open, 258baf27f6eSMarcel Holtmann .read = seq_read, 259baf27f6eSMarcel Holtmann .llseek = seq_lseek, 260baf27f6eSMarcel Holtmann .release = single_release, 261baf27f6eSMarcel Holtmann }; 262baf27f6eSMarcel Holtmann 26302d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr) 26402d08d15SMarcel Holtmann { 26502d08d15SMarcel Holtmann struct hci_dev *hdev = f->private; 26602d08d15SMarcel Holtmann struct list_head *p, *n; 26702d08d15SMarcel Holtmann 26802d08d15SMarcel Holtmann hci_dev_lock(hdev); 26902d08d15SMarcel Holtmann list_for_each_safe(p, n, &hdev->link_keys) { 27002d08d15SMarcel Holtmann struct link_key *key = list_entry(p, struct link_key, list); 27102d08d15SMarcel Holtmann seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type, 27202d08d15SMarcel Holtmann HCI_LINK_KEY_SIZE, key->val, key->pin_len); 27302d08d15SMarcel Holtmann } 27402d08d15SMarcel Holtmann hci_dev_unlock(hdev); 27502d08d15SMarcel Holtmann 27602d08d15SMarcel Holtmann return 0; 27702d08d15SMarcel Holtmann } 27802d08d15SMarcel Holtmann 27902d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file) 28002d08d15SMarcel Holtmann { 28102d08d15SMarcel Holtmann return single_open(file, link_keys_show, inode->i_private); 28202d08d15SMarcel Holtmann } 28302d08d15SMarcel Holtmann 28402d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = { 28502d08d15SMarcel Holtmann .open = link_keys_open, 28602d08d15SMarcel Holtmann .read = seq_read, 28702d08d15SMarcel Holtmann .llseek = seq_lseek, 28802d08d15SMarcel Holtmann .release = single_release, 28902d08d15SMarcel Holtmann }; 29002d08d15SMarcel Holtmann 291babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr) 292babdbb3cSMarcel Holtmann { 293babdbb3cSMarcel Holtmann struct hci_dev *hdev = f->private; 294babdbb3cSMarcel Holtmann 295babdbb3cSMarcel Holtmann hci_dev_lock(hdev); 296babdbb3cSMarcel Holtmann seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], 297babdbb3cSMarcel Holtmann hdev->dev_class[1], hdev->dev_class[0]); 298babdbb3cSMarcel Holtmann hci_dev_unlock(hdev); 299babdbb3cSMarcel Holtmann 300babdbb3cSMarcel Holtmann return 0; 301babdbb3cSMarcel Holtmann } 302babdbb3cSMarcel Holtmann 303babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file) 304babdbb3cSMarcel Holtmann { 305babdbb3cSMarcel Holtmann return single_open(file, dev_class_show, inode->i_private); 306babdbb3cSMarcel Holtmann } 307babdbb3cSMarcel Holtmann 308babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = { 309babdbb3cSMarcel Holtmann .open = dev_class_open, 310babdbb3cSMarcel Holtmann .read = seq_read, 311babdbb3cSMarcel Holtmann .llseek = seq_lseek, 312babdbb3cSMarcel Holtmann .release = single_release, 313babdbb3cSMarcel Holtmann }; 314babdbb3cSMarcel Holtmann 315041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val) 316041000b9SMarcel Holtmann { 317041000b9SMarcel Holtmann struct hci_dev *hdev = data; 318041000b9SMarcel Holtmann 319041000b9SMarcel Holtmann hci_dev_lock(hdev); 320041000b9SMarcel Holtmann *val = hdev->voice_setting; 321041000b9SMarcel Holtmann hci_dev_unlock(hdev); 322041000b9SMarcel Holtmann 323041000b9SMarcel Holtmann return 0; 324041000b9SMarcel Holtmann } 325041000b9SMarcel Holtmann 326041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get, 327041000b9SMarcel Holtmann NULL, "0x%4.4llx\n"); 328041000b9SMarcel Holtmann 329ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val) 330ebd1e33bSMarcel Holtmann { 331ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 332ebd1e33bSMarcel Holtmann 333ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 334ebd1e33bSMarcel Holtmann hdev->auto_accept_delay = val; 335ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 336ebd1e33bSMarcel Holtmann 337ebd1e33bSMarcel Holtmann return 0; 338ebd1e33bSMarcel Holtmann } 339ebd1e33bSMarcel Holtmann 340ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val) 341ebd1e33bSMarcel Holtmann { 342ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 343ebd1e33bSMarcel Holtmann 344ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 345ebd1e33bSMarcel Holtmann *val = hdev->auto_accept_delay; 346ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 347ebd1e33bSMarcel Holtmann 348ebd1e33bSMarcel Holtmann return 0; 349ebd1e33bSMarcel Holtmann } 350ebd1e33bSMarcel Holtmann 351ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, 352ebd1e33bSMarcel Holtmann auto_accept_delay_set, "%llu\n"); 353ebd1e33bSMarcel Holtmann 35406f5b778SMarcel Holtmann static int ssp_debug_mode_set(void *data, u64 val) 35506f5b778SMarcel Holtmann { 35606f5b778SMarcel Holtmann struct hci_dev *hdev = data; 35706f5b778SMarcel Holtmann struct sk_buff *skb; 35806f5b778SMarcel Holtmann __u8 mode; 35906f5b778SMarcel Holtmann int err; 36006f5b778SMarcel Holtmann 36106f5b778SMarcel Holtmann if (val != 0 && val != 1) 36206f5b778SMarcel Holtmann return -EINVAL; 36306f5b778SMarcel Holtmann 36406f5b778SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 36506f5b778SMarcel Holtmann return -ENETDOWN; 36606f5b778SMarcel Holtmann 36706f5b778SMarcel Holtmann hci_req_lock(hdev); 36806f5b778SMarcel Holtmann mode = val; 36906f5b778SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode), 37006f5b778SMarcel Holtmann &mode, HCI_CMD_TIMEOUT); 37106f5b778SMarcel Holtmann hci_req_unlock(hdev); 37206f5b778SMarcel Holtmann 37306f5b778SMarcel Holtmann if (IS_ERR(skb)) 37406f5b778SMarcel Holtmann return PTR_ERR(skb); 37506f5b778SMarcel Holtmann 37606f5b778SMarcel Holtmann err = -bt_to_errno(skb->data[0]); 37706f5b778SMarcel Holtmann kfree_skb(skb); 37806f5b778SMarcel Holtmann 37906f5b778SMarcel Holtmann if (err < 0) 38006f5b778SMarcel Holtmann return err; 38106f5b778SMarcel Holtmann 38206f5b778SMarcel Holtmann hci_dev_lock(hdev); 38306f5b778SMarcel Holtmann hdev->ssp_debug_mode = val; 38406f5b778SMarcel Holtmann hci_dev_unlock(hdev); 38506f5b778SMarcel Holtmann 38606f5b778SMarcel Holtmann return 0; 38706f5b778SMarcel Holtmann } 38806f5b778SMarcel Holtmann 38906f5b778SMarcel Holtmann static int ssp_debug_mode_get(void *data, u64 *val) 39006f5b778SMarcel Holtmann { 39106f5b778SMarcel Holtmann struct hci_dev *hdev = data; 39206f5b778SMarcel Holtmann 39306f5b778SMarcel Holtmann hci_dev_lock(hdev); 39406f5b778SMarcel Holtmann *val = hdev->ssp_debug_mode; 39506f5b778SMarcel Holtmann hci_dev_unlock(hdev); 39606f5b778SMarcel Holtmann 39706f5b778SMarcel Holtmann return 0; 39806f5b778SMarcel Holtmann } 39906f5b778SMarcel Holtmann 40006f5b778SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get, 40106f5b778SMarcel Holtmann ssp_debug_mode_set, "%llu\n"); 40206f5b778SMarcel Holtmann 4035afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf, 4045afeac14SMarcel Holtmann size_t count, loff_t *ppos) 4055afeac14SMarcel Holtmann { 4065afeac14SMarcel Holtmann struct hci_dev *hdev = file->private_data; 4075afeac14SMarcel Holtmann char buf[3]; 4085afeac14SMarcel Holtmann 4095afeac14SMarcel Holtmann buf[0] = test_bit(HCI_FORCE_SC, &hdev->dev_flags) ? 'Y': 'N'; 4105afeac14SMarcel Holtmann buf[1] = '\n'; 4115afeac14SMarcel Holtmann buf[2] = '\0'; 4125afeac14SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 4135afeac14SMarcel Holtmann } 4145afeac14SMarcel Holtmann 4155afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file, 4165afeac14SMarcel Holtmann const char __user *user_buf, 4175afeac14SMarcel Holtmann size_t count, loff_t *ppos) 4185afeac14SMarcel Holtmann { 4195afeac14SMarcel Holtmann struct hci_dev *hdev = file->private_data; 4205afeac14SMarcel Holtmann char buf[32]; 4215afeac14SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 4225afeac14SMarcel Holtmann bool enable; 4235afeac14SMarcel Holtmann 4245afeac14SMarcel Holtmann if (test_bit(HCI_UP, &hdev->flags)) 4255afeac14SMarcel Holtmann return -EBUSY; 4265afeac14SMarcel Holtmann 4275afeac14SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 4285afeac14SMarcel Holtmann return -EFAULT; 4295afeac14SMarcel Holtmann 4305afeac14SMarcel Holtmann buf[buf_size] = '\0'; 4315afeac14SMarcel Holtmann if (strtobool(buf, &enable)) 4325afeac14SMarcel Holtmann return -EINVAL; 4335afeac14SMarcel Holtmann 4345afeac14SMarcel Holtmann if (enable == test_bit(HCI_FORCE_SC, &hdev->dev_flags)) 4355afeac14SMarcel Holtmann return -EALREADY; 4365afeac14SMarcel Holtmann 4375afeac14SMarcel Holtmann change_bit(HCI_FORCE_SC, &hdev->dev_flags); 4385afeac14SMarcel Holtmann 4395afeac14SMarcel Holtmann return count; 4405afeac14SMarcel Holtmann } 4415afeac14SMarcel Holtmann 4425afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = { 4435afeac14SMarcel Holtmann .open = simple_open, 4445afeac14SMarcel Holtmann .read = force_sc_support_read, 4455afeac14SMarcel Holtmann .write = force_sc_support_write, 4465afeac14SMarcel Holtmann .llseek = default_llseek, 4475afeac14SMarcel Holtmann }; 4485afeac14SMarcel Holtmann 449134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf, 450134c2a89SMarcel Holtmann size_t count, loff_t *ppos) 451134c2a89SMarcel Holtmann { 452134c2a89SMarcel Holtmann struct hci_dev *hdev = file->private_data; 453134c2a89SMarcel Holtmann char buf[3]; 454134c2a89SMarcel Holtmann 455134c2a89SMarcel Holtmann buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N'; 456134c2a89SMarcel Holtmann buf[1] = '\n'; 457134c2a89SMarcel Holtmann buf[2] = '\0'; 458134c2a89SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 459134c2a89SMarcel Holtmann } 460134c2a89SMarcel Holtmann 461134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = { 462134c2a89SMarcel Holtmann .open = simple_open, 463134c2a89SMarcel Holtmann .read = sc_only_mode_read, 464134c2a89SMarcel Holtmann .llseek = default_llseek, 465134c2a89SMarcel Holtmann }; 466134c2a89SMarcel Holtmann 4672bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val) 4682bfa3531SMarcel Holtmann { 4692bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4702bfa3531SMarcel Holtmann 4712bfa3531SMarcel Holtmann if (val != 0 && (val < 500 || val > 3600000)) 4722bfa3531SMarcel Holtmann return -EINVAL; 4732bfa3531SMarcel Holtmann 4742bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4752bfa3531SMarcel Holtmann hdev->idle_timeout = val; 4762bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4772bfa3531SMarcel Holtmann 4782bfa3531SMarcel Holtmann return 0; 4792bfa3531SMarcel Holtmann } 4802bfa3531SMarcel Holtmann 4812bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val) 4822bfa3531SMarcel Holtmann { 4832bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4842bfa3531SMarcel Holtmann 4852bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4862bfa3531SMarcel Holtmann *val = hdev->idle_timeout; 4872bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4882bfa3531SMarcel Holtmann 4892bfa3531SMarcel Holtmann return 0; 4902bfa3531SMarcel Holtmann } 4912bfa3531SMarcel Holtmann 4922bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get, 4932bfa3531SMarcel Holtmann idle_timeout_set, "%llu\n"); 4942bfa3531SMarcel Holtmann 495c982b2eaSJohan Hedberg static int rpa_timeout_set(void *data, u64 val) 496c982b2eaSJohan Hedberg { 497c982b2eaSJohan Hedberg struct hci_dev *hdev = data; 498c982b2eaSJohan Hedberg 499c982b2eaSJohan Hedberg /* Require the RPA timeout to be at least 30 seconds and at most 500c982b2eaSJohan Hedberg * 24 hours. 501c982b2eaSJohan Hedberg */ 502c982b2eaSJohan Hedberg if (val < 30 || val > (60 * 60 * 24)) 503c982b2eaSJohan Hedberg return -EINVAL; 504c982b2eaSJohan Hedberg 505c982b2eaSJohan Hedberg hci_dev_lock(hdev); 506c982b2eaSJohan Hedberg hdev->rpa_timeout = val; 507c982b2eaSJohan Hedberg hci_dev_unlock(hdev); 508c982b2eaSJohan Hedberg 509c982b2eaSJohan Hedberg return 0; 510c982b2eaSJohan Hedberg } 511c982b2eaSJohan Hedberg 512c982b2eaSJohan Hedberg static int rpa_timeout_get(void *data, u64 *val) 513c982b2eaSJohan Hedberg { 514c982b2eaSJohan Hedberg struct hci_dev *hdev = data; 515c982b2eaSJohan Hedberg 516c982b2eaSJohan Hedberg hci_dev_lock(hdev); 517c982b2eaSJohan Hedberg *val = hdev->rpa_timeout; 518c982b2eaSJohan Hedberg hci_dev_unlock(hdev); 519c982b2eaSJohan Hedberg 520c982b2eaSJohan Hedberg return 0; 521c982b2eaSJohan Hedberg } 522c982b2eaSJohan Hedberg 523c982b2eaSJohan Hedberg DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get, 524c982b2eaSJohan Hedberg rpa_timeout_set, "%llu\n"); 525c982b2eaSJohan Hedberg 5262bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val) 5272bfa3531SMarcel Holtmann { 5282bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5292bfa3531SMarcel Holtmann 5302bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val > hdev->sniff_max_interval) 5312bfa3531SMarcel Holtmann return -EINVAL; 5322bfa3531SMarcel Holtmann 5332bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5342bfa3531SMarcel Holtmann hdev->sniff_min_interval = val; 5352bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5362bfa3531SMarcel Holtmann 5372bfa3531SMarcel Holtmann return 0; 5382bfa3531SMarcel Holtmann } 5392bfa3531SMarcel Holtmann 5402bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val) 5412bfa3531SMarcel Holtmann { 5422bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5432bfa3531SMarcel Holtmann 5442bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5452bfa3531SMarcel Holtmann *val = hdev->sniff_min_interval; 5462bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5472bfa3531SMarcel Holtmann 5482bfa3531SMarcel Holtmann return 0; 5492bfa3531SMarcel Holtmann } 5502bfa3531SMarcel Holtmann 5512bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get, 5522bfa3531SMarcel Holtmann sniff_min_interval_set, "%llu\n"); 5532bfa3531SMarcel Holtmann 5542bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val) 5552bfa3531SMarcel Holtmann { 5562bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5572bfa3531SMarcel Holtmann 5582bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val < hdev->sniff_min_interval) 5592bfa3531SMarcel Holtmann return -EINVAL; 5602bfa3531SMarcel Holtmann 5612bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5622bfa3531SMarcel Holtmann hdev->sniff_max_interval = val; 5632bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5642bfa3531SMarcel Holtmann 5652bfa3531SMarcel Holtmann return 0; 5662bfa3531SMarcel Holtmann } 5672bfa3531SMarcel Holtmann 5682bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val) 5692bfa3531SMarcel Holtmann { 5702bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5712bfa3531SMarcel Holtmann 5722bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5732bfa3531SMarcel Holtmann *val = hdev->sniff_max_interval; 5742bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5752bfa3531SMarcel Holtmann 5762bfa3531SMarcel Holtmann return 0; 5772bfa3531SMarcel Holtmann } 5782bfa3531SMarcel Holtmann 5792bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, 5802bfa3531SMarcel Holtmann sniff_max_interval_set, "%llu\n"); 5812bfa3531SMarcel Holtmann 582ac345813SMarcel Holtmann static int identity_show(struct seq_file *f, void *p) 583ac345813SMarcel Holtmann { 584ac345813SMarcel Holtmann struct hci_dev *hdev = f->private; 585a1f4c318SJohan Hedberg bdaddr_t addr; 586ac345813SMarcel Holtmann u8 addr_type; 587ac345813SMarcel Holtmann 588ac345813SMarcel Holtmann hci_dev_lock(hdev); 589ac345813SMarcel Holtmann 590a1f4c318SJohan Hedberg hci_copy_identity_address(hdev, &addr, &addr_type); 591ac345813SMarcel Holtmann 592a1f4c318SJohan Hedberg seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type, 593473deef2SMarcel Holtmann 16, hdev->irk, &hdev->rpa); 594ac345813SMarcel Holtmann 595ac345813SMarcel Holtmann hci_dev_unlock(hdev); 596ac345813SMarcel Holtmann 597ac345813SMarcel Holtmann return 0; 598ac345813SMarcel Holtmann } 599ac345813SMarcel Holtmann 600ac345813SMarcel Holtmann static int identity_open(struct inode *inode, struct file *file) 601ac345813SMarcel Holtmann { 602ac345813SMarcel Holtmann return single_open(file, identity_show, inode->i_private); 603ac345813SMarcel Holtmann } 604ac345813SMarcel Holtmann 605ac345813SMarcel Holtmann static const struct file_operations identity_fops = { 606ac345813SMarcel Holtmann .open = identity_open, 607ac345813SMarcel Holtmann .read = seq_read, 608ac345813SMarcel Holtmann .llseek = seq_lseek, 609ac345813SMarcel Holtmann .release = single_release, 610ac345813SMarcel Holtmann }; 611ac345813SMarcel Holtmann 6127a4cd51dSMarcel Holtmann static int random_address_show(struct seq_file *f, void *p) 6137a4cd51dSMarcel Holtmann { 6147a4cd51dSMarcel Holtmann struct hci_dev *hdev = f->private; 6157a4cd51dSMarcel Holtmann 6167a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 6177a4cd51dSMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->random_addr); 6187a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 6197a4cd51dSMarcel Holtmann 6207a4cd51dSMarcel Holtmann return 0; 6217a4cd51dSMarcel Holtmann } 6227a4cd51dSMarcel Holtmann 6237a4cd51dSMarcel Holtmann static int random_address_open(struct inode *inode, struct file *file) 6247a4cd51dSMarcel Holtmann { 6257a4cd51dSMarcel Holtmann return single_open(file, random_address_show, inode->i_private); 6267a4cd51dSMarcel Holtmann } 6277a4cd51dSMarcel Holtmann 6287a4cd51dSMarcel Holtmann static const struct file_operations random_address_fops = { 6297a4cd51dSMarcel Holtmann .open = random_address_open, 6307a4cd51dSMarcel Holtmann .read = seq_read, 6317a4cd51dSMarcel Holtmann .llseek = seq_lseek, 6327a4cd51dSMarcel Holtmann .release = single_release, 6337a4cd51dSMarcel Holtmann }; 6347a4cd51dSMarcel Holtmann 635e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p) 636e7b8fc92SMarcel Holtmann { 637e7b8fc92SMarcel Holtmann struct hci_dev *hdev = f->private; 638e7b8fc92SMarcel Holtmann 639e7b8fc92SMarcel Holtmann hci_dev_lock(hdev); 640e7b8fc92SMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->static_addr); 641e7b8fc92SMarcel Holtmann hci_dev_unlock(hdev); 642e7b8fc92SMarcel Holtmann 643e7b8fc92SMarcel Holtmann return 0; 644e7b8fc92SMarcel Holtmann } 645e7b8fc92SMarcel Holtmann 646e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file) 647e7b8fc92SMarcel Holtmann { 648e7b8fc92SMarcel Holtmann return single_open(file, static_address_show, inode->i_private); 649e7b8fc92SMarcel Holtmann } 650e7b8fc92SMarcel Holtmann 651e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = { 652e7b8fc92SMarcel Holtmann .open = static_address_open, 653e7b8fc92SMarcel Holtmann .read = seq_read, 654e7b8fc92SMarcel Holtmann .llseek = seq_lseek, 655e7b8fc92SMarcel Holtmann .release = single_release, 656e7b8fc92SMarcel Holtmann }; 657e7b8fc92SMarcel Holtmann 658b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file, 659b32bba6cSMarcel Holtmann char __user *user_buf, 660b32bba6cSMarcel Holtmann size_t count, loff_t *ppos) 66192202185SMarcel Holtmann { 662b32bba6cSMarcel Holtmann struct hci_dev *hdev = file->private_data; 663b32bba6cSMarcel Holtmann char buf[3]; 66492202185SMarcel Holtmann 665b32bba6cSMarcel Holtmann buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ? 'Y': 'N'; 666b32bba6cSMarcel Holtmann buf[1] = '\n'; 667b32bba6cSMarcel Holtmann buf[2] = '\0'; 668b32bba6cSMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 669b32bba6cSMarcel Holtmann } 670b32bba6cSMarcel Holtmann 671b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file, 672b32bba6cSMarcel Holtmann const char __user *user_buf, 673b32bba6cSMarcel Holtmann size_t count, loff_t *ppos) 674b32bba6cSMarcel Holtmann { 675b32bba6cSMarcel Holtmann struct hci_dev *hdev = file->private_data; 676b32bba6cSMarcel Holtmann char buf[32]; 677b32bba6cSMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 678b32bba6cSMarcel Holtmann bool enable; 679b32bba6cSMarcel Holtmann 680b32bba6cSMarcel Holtmann if (test_bit(HCI_UP, &hdev->flags)) 681b32bba6cSMarcel Holtmann return -EBUSY; 682b32bba6cSMarcel Holtmann 683b32bba6cSMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 684b32bba6cSMarcel Holtmann return -EFAULT; 685b32bba6cSMarcel Holtmann 686b32bba6cSMarcel Holtmann buf[buf_size] = '\0'; 687b32bba6cSMarcel Holtmann if (strtobool(buf, &enable)) 68892202185SMarcel Holtmann return -EINVAL; 68992202185SMarcel Holtmann 690b32bba6cSMarcel Holtmann if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags)) 691b32bba6cSMarcel Holtmann return -EALREADY; 69292202185SMarcel Holtmann 693b32bba6cSMarcel Holtmann change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags); 694b32bba6cSMarcel Holtmann 695b32bba6cSMarcel Holtmann return count; 69692202185SMarcel Holtmann } 69792202185SMarcel Holtmann 698b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = { 699b32bba6cSMarcel Holtmann .open = simple_open, 700b32bba6cSMarcel Holtmann .read = force_static_address_read, 701b32bba6cSMarcel Holtmann .write = force_static_address_write, 702b32bba6cSMarcel Holtmann .llseek = default_llseek, 703b32bba6cSMarcel Holtmann }; 70492202185SMarcel Holtmann 705*d2ab0ac1SMarcel Holtmann static int white_list_show(struct seq_file *f, void *ptr) 706*d2ab0ac1SMarcel Holtmann { 707*d2ab0ac1SMarcel Holtmann struct hci_dev *hdev = f->private; 708*d2ab0ac1SMarcel Holtmann struct bdaddr_list *b; 709*d2ab0ac1SMarcel Holtmann 710*d2ab0ac1SMarcel Holtmann hci_dev_lock(hdev); 711*d2ab0ac1SMarcel Holtmann list_for_each_entry(b, &hdev->le_white_list, list) 712*d2ab0ac1SMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 713*d2ab0ac1SMarcel Holtmann hci_dev_unlock(hdev); 714*d2ab0ac1SMarcel Holtmann 715*d2ab0ac1SMarcel Holtmann return 0; 716*d2ab0ac1SMarcel Holtmann } 717*d2ab0ac1SMarcel Holtmann 718*d2ab0ac1SMarcel Holtmann static int white_list_open(struct inode *inode, struct file *file) 719*d2ab0ac1SMarcel Holtmann { 720*d2ab0ac1SMarcel Holtmann return single_open(file, white_list_show, inode->i_private); 721*d2ab0ac1SMarcel Holtmann } 722*d2ab0ac1SMarcel Holtmann 723*d2ab0ac1SMarcel Holtmann static const struct file_operations white_list_fops = { 724*d2ab0ac1SMarcel Holtmann .open = white_list_open, 725*d2ab0ac1SMarcel Holtmann .read = seq_read, 726*d2ab0ac1SMarcel Holtmann .llseek = seq_lseek, 727*d2ab0ac1SMarcel Holtmann .release = single_release, 728*d2ab0ac1SMarcel Holtmann }; 729*d2ab0ac1SMarcel Holtmann 7303698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr) 7313698d704SMarcel Holtmann { 7323698d704SMarcel Holtmann struct hci_dev *hdev = f->private; 7333698d704SMarcel Holtmann struct list_head *p, *n; 7343698d704SMarcel Holtmann 7353698d704SMarcel Holtmann hci_dev_lock(hdev); 7363698d704SMarcel Holtmann list_for_each_safe(p, n, &hdev->identity_resolving_keys) { 7373698d704SMarcel Holtmann struct smp_irk *irk = list_entry(p, struct smp_irk, list); 7383698d704SMarcel Holtmann seq_printf(f, "%pMR (type %u) %*phN %pMR\n", 7393698d704SMarcel Holtmann &irk->bdaddr, irk->addr_type, 7403698d704SMarcel Holtmann 16, irk->val, &irk->rpa); 7413698d704SMarcel Holtmann } 7423698d704SMarcel Holtmann hci_dev_unlock(hdev); 7433698d704SMarcel Holtmann 7443698d704SMarcel Holtmann return 0; 7453698d704SMarcel Holtmann } 7463698d704SMarcel Holtmann 7473698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file) 7483698d704SMarcel Holtmann { 7493698d704SMarcel Holtmann return single_open(file, identity_resolving_keys_show, 7503698d704SMarcel Holtmann inode->i_private); 7513698d704SMarcel Holtmann } 7523698d704SMarcel Holtmann 7533698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = { 7543698d704SMarcel Holtmann .open = identity_resolving_keys_open, 7553698d704SMarcel Holtmann .read = seq_read, 7563698d704SMarcel Holtmann .llseek = seq_lseek, 7573698d704SMarcel Holtmann .release = single_release, 7583698d704SMarcel Holtmann }; 7593698d704SMarcel Holtmann 7608f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr) 7618f8625cdSMarcel Holtmann { 7628f8625cdSMarcel Holtmann struct hci_dev *hdev = f->private; 7638f8625cdSMarcel Holtmann struct list_head *p, *n; 7648f8625cdSMarcel Holtmann 7658f8625cdSMarcel Holtmann hci_dev_lock(hdev); 766f813f1beSJohan Hedberg list_for_each_safe(p, n, &hdev->long_term_keys) { 7678f8625cdSMarcel Holtmann struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list); 768f813f1beSJohan Hedberg seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %*phN %*phN\n", 7698f8625cdSMarcel Holtmann <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, 7708f8625cdSMarcel Holtmann ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), 7718f8625cdSMarcel Holtmann 8, ltk->rand, 16, ltk->val); 7728f8625cdSMarcel Holtmann } 7738f8625cdSMarcel Holtmann hci_dev_unlock(hdev); 7748f8625cdSMarcel Holtmann 7758f8625cdSMarcel Holtmann return 0; 7768f8625cdSMarcel Holtmann } 7778f8625cdSMarcel Holtmann 7788f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file) 7798f8625cdSMarcel Holtmann { 7808f8625cdSMarcel Holtmann return single_open(file, long_term_keys_show, inode->i_private); 7818f8625cdSMarcel Holtmann } 7828f8625cdSMarcel Holtmann 7838f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = { 7848f8625cdSMarcel Holtmann .open = long_term_keys_open, 7858f8625cdSMarcel Holtmann .read = seq_read, 7868f8625cdSMarcel Holtmann .llseek = seq_lseek, 7878f8625cdSMarcel Holtmann .release = single_release, 7888f8625cdSMarcel Holtmann }; 7898f8625cdSMarcel Holtmann 7904e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val) 7914e70c7e7SMarcel Holtmann { 7924e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 7934e70c7e7SMarcel Holtmann 7944e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval) 7954e70c7e7SMarcel Holtmann return -EINVAL; 7964e70c7e7SMarcel Holtmann 7974e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 7984e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = val; 7994e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8004e70c7e7SMarcel Holtmann 8014e70c7e7SMarcel Holtmann return 0; 8024e70c7e7SMarcel Holtmann } 8034e70c7e7SMarcel Holtmann 8044e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val) 8054e70c7e7SMarcel Holtmann { 8064e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 8074e70c7e7SMarcel Holtmann 8084e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 8094e70c7e7SMarcel Holtmann *val = hdev->le_conn_min_interval; 8104e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8114e70c7e7SMarcel Holtmann 8124e70c7e7SMarcel Holtmann return 0; 8134e70c7e7SMarcel Holtmann } 8144e70c7e7SMarcel Holtmann 8154e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get, 8164e70c7e7SMarcel Holtmann conn_min_interval_set, "%llu\n"); 8174e70c7e7SMarcel Holtmann 8184e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val) 8194e70c7e7SMarcel Holtmann { 8204e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 8214e70c7e7SMarcel Holtmann 8224e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval) 8234e70c7e7SMarcel Holtmann return -EINVAL; 8244e70c7e7SMarcel Holtmann 8254e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 8264e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = val; 8274e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8284e70c7e7SMarcel Holtmann 8294e70c7e7SMarcel Holtmann return 0; 8304e70c7e7SMarcel Holtmann } 8314e70c7e7SMarcel Holtmann 8324e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val) 8334e70c7e7SMarcel Holtmann { 8344e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 8354e70c7e7SMarcel Holtmann 8364e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 8374e70c7e7SMarcel Holtmann *val = hdev->le_conn_max_interval; 8384e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8394e70c7e7SMarcel Holtmann 8404e70c7e7SMarcel Holtmann return 0; 8414e70c7e7SMarcel Holtmann } 8424e70c7e7SMarcel Holtmann 8434e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, 8444e70c7e7SMarcel Holtmann conn_max_interval_set, "%llu\n"); 8454e70c7e7SMarcel Holtmann 8463f959d46SMarcel Holtmann static int adv_channel_map_set(void *data, u64 val) 8473f959d46SMarcel Holtmann { 8483f959d46SMarcel Holtmann struct hci_dev *hdev = data; 8493f959d46SMarcel Holtmann 8503f959d46SMarcel Holtmann if (val < 0x01 || val > 0x07) 8513f959d46SMarcel Holtmann return -EINVAL; 8523f959d46SMarcel Holtmann 8533f959d46SMarcel Holtmann hci_dev_lock(hdev); 8543f959d46SMarcel Holtmann hdev->le_adv_channel_map = val; 8553f959d46SMarcel Holtmann hci_dev_unlock(hdev); 8563f959d46SMarcel Holtmann 8573f959d46SMarcel Holtmann return 0; 8583f959d46SMarcel Holtmann } 8593f959d46SMarcel Holtmann 8603f959d46SMarcel Holtmann static int adv_channel_map_get(void *data, u64 *val) 8613f959d46SMarcel Holtmann { 8623f959d46SMarcel Holtmann struct hci_dev *hdev = data; 8633f959d46SMarcel Holtmann 8643f959d46SMarcel Holtmann hci_dev_lock(hdev); 8653f959d46SMarcel Holtmann *val = hdev->le_adv_channel_map; 8663f959d46SMarcel Holtmann hci_dev_unlock(hdev); 8673f959d46SMarcel Holtmann 8683f959d46SMarcel Holtmann return 0; 8693f959d46SMarcel Holtmann } 8703f959d46SMarcel Holtmann 8713f959d46SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get, 8723f959d46SMarcel Holtmann adv_channel_map_set, "%llu\n"); 8733f959d46SMarcel Holtmann 87489863109SJukka Rissanen static ssize_t lowpan_read(struct file *file, char __user *user_buf, 87589863109SJukka Rissanen size_t count, loff_t *ppos) 87689863109SJukka Rissanen { 87789863109SJukka Rissanen struct hci_dev *hdev = file->private_data; 87889863109SJukka Rissanen char buf[3]; 87989863109SJukka Rissanen 88089863109SJukka Rissanen buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N'; 88189863109SJukka Rissanen buf[1] = '\n'; 88289863109SJukka Rissanen buf[2] = '\0'; 88389863109SJukka Rissanen return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 88489863109SJukka Rissanen } 88589863109SJukka Rissanen 88689863109SJukka Rissanen static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer, 88789863109SJukka Rissanen size_t count, loff_t *position) 88889863109SJukka Rissanen { 88989863109SJukka Rissanen struct hci_dev *hdev = fp->private_data; 89089863109SJukka Rissanen bool enable; 89189863109SJukka Rissanen char buf[32]; 89289863109SJukka Rissanen size_t buf_size = min(count, (sizeof(buf)-1)); 89389863109SJukka Rissanen 89489863109SJukka Rissanen if (copy_from_user(buf, user_buffer, buf_size)) 89589863109SJukka Rissanen return -EFAULT; 89689863109SJukka Rissanen 89789863109SJukka Rissanen buf[buf_size] = '\0'; 89889863109SJukka Rissanen 89989863109SJukka Rissanen if (strtobool(buf, &enable) < 0) 90089863109SJukka Rissanen return -EINVAL; 90189863109SJukka Rissanen 90289863109SJukka Rissanen if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags)) 90389863109SJukka Rissanen return -EALREADY; 90489863109SJukka Rissanen 90589863109SJukka Rissanen change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags); 90689863109SJukka Rissanen 90789863109SJukka Rissanen return count; 90889863109SJukka Rissanen } 90989863109SJukka Rissanen 91089863109SJukka Rissanen static const struct file_operations lowpan_debugfs_fops = { 91189863109SJukka Rissanen .open = simple_open, 91289863109SJukka Rissanen .read = lowpan_read, 91389863109SJukka Rissanen .write = lowpan_write, 91489863109SJukka Rissanen .llseek = default_llseek, 91589863109SJukka Rissanen }; 91689863109SJukka Rissanen 9177d474e06SAndre Guedes static int le_auto_conn_show(struct seq_file *sf, void *ptr) 9187d474e06SAndre Guedes { 9197d474e06SAndre Guedes struct hci_dev *hdev = sf->private; 9207d474e06SAndre Guedes struct hci_conn_params *p; 9217d474e06SAndre Guedes 9227d474e06SAndre Guedes hci_dev_lock(hdev); 9237d474e06SAndre Guedes 9247d474e06SAndre Guedes list_for_each_entry(p, &hdev->le_conn_params, list) { 9257d474e06SAndre Guedes seq_printf(sf, "%pMR %u %u\n", &p->addr, p->addr_type, 9267d474e06SAndre Guedes p->auto_connect); 9277d474e06SAndre Guedes } 9287d474e06SAndre Guedes 9297d474e06SAndre Guedes hci_dev_unlock(hdev); 9307d474e06SAndre Guedes 9317d474e06SAndre Guedes return 0; 9327d474e06SAndre Guedes } 9337d474e06SAndre Guedes 9347d474e06SAndre Guedes static int le_auto_conn_open(struct inode *inode, struct file *file) 9357d474e06SAndre Guedes { 9367d474e06SAndre Guedes return single_open(file, le_auto_conn_show, inode->i_private); 9377d474e06SAndre Guedes } 9387d474e06SAndre Guedes 9397d474e06SAndre Guedes static ssize_t le_auto_conn_write(struct file *file, const char __user *data, 9407d474e06SAndre Guedes size_t count, loff_t *offset) 9417d474e06SAndre Guedes { 9427d474e06SAndre Guedes struct seq_file *sf = file->private_data; 9437d474e06SAndre Guedes struct hci_dev *hdev = sf->private; 9447d474e06SAndre Guedes u8 auto_connect = 0; 9457d474e06SAndre Guedes bdaddr_t addr; 9467d474e06SAndre Guedes u8 addr_type; 9477d474e06SAndre Guedes char *buf; 9487d474e06SAndre Guedes int err = 0; 9497d474e06SAndre Guedes int n; 9507d474e06SAndre Guedes 9517d474e06SAndre Guedes /* Don't allow partial write */ 9527d474e06SAndre Guedes if (*offset != 0) 9537d474e06SAndre Guedes return -EINVAL; 9547d474e06SAndre Guedes 9557d474e06SAndre Guedes if (count < 3) 9567d474e06SAndre Guedes return -EINVAL; 9577d474e06SAndre Guedes 9587d474e06SAndre Guedes buf = kzalloc(count, GFP_KERNEL); 9597d474e06SAndre Guedes if (!buf) 9607d474e06SAndre Guedes return -ENOMEM; 9617d474e06SAndre Guedes 9627d474e06SAndre Guedes if (copy_from_user(buf, data, count)) { 9637d474e06SAndre Guedes err = -EFAULT; 9647d474e06SAndre Guedes goto done; 9657d474e06SAndre Guedes } 9667d474e06SAndre Guedes 9677d474e06SAndre Guedes if (memcmp(buf, "add", 3) == 0) { 9687d474e06SAndre Guedes n = sscanf(&buf[4], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu %hhu", 9697d474e06SAndre Guedes &addr.b[5], &addr.b[4], &addr.b[3], &addr.b[2], 9707d474e06SAndre Guedes &addr.b[1], &addr.b[0], &addr_type, 9717d474e06SAndre Guedes &auto_connect); 9727d474e06SAndre Guedes 9737d474e06SAndre Guedes if (n < 7) { 9747d474e06SAndre Guedes err = -EINVAL; 9757d474e06SAndre Guedes goto done; 9767d474e06SAndre Guedes } 9777d474e06SAndre Guedes 9787d474e06SAndre Guedes hci_dev_lock(hdev); 9797d474e06SAndre Guedes err = hci_conn_params_add(hdev, &addr, addr_type, auto_connect, 9807d474e06SAndre Guedes hdev->le_conn_min_interval, 9817d474e06SAndre Guedes hdev->le_conn_max_interval); 9827d474e06SAndre Guedes hci_dev_unlock(hdev); 9837d474e06SAndre Guedes 9847d474e06SAndre Guedes if (err) 9857d474e06SAndre Guedes goto done; 9867d474e06SAndre Guedes } else if (memcmp(buf, "del", 3) == 0) { 9877d474e06SAndre Guedes n = sscanf(&buf[4], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu", 9887d474e06SAndre Guedes &addr.b[5], &addr.b[4], &addr.b[3], &addr.b[2], 9897d474e06SAndre Guedes &addr.b[1], &addr.b[0], &addr_type); 9907d474e06SAndre Guedes 9917d474e06SAndre Guedes if (n < 7) { 9927d474e06SAndre Guedes err = -EINVAL; 9937d474e06SAndre Guedes goto done; 9947d474e06SAndre Guedes } 9957d474e06SAndre Guedes 9967d474e06SAndre Guedes hci_dev_lock(hdev); 9977d474e06SAndre Guedes hci_conn_params_del(hdev, &addr, addr_type); 9987d474e06SAndre Guedes hci_dev_unlock(hdev); 9997d474e06SAndre Guedes } else if (memcmp(buf, "clr", 3) == 0) { 10007d474e06SAndre Guedes hci_dev_lock(hdev); 10017d474e06SAndre Guedes hci_conn_params_clear(hdev); 10027d474e06SAndre Guedes hci_pend_le_conns_clear(hdev); 10037d474e06SAndre Guedes hci_update_background_scan(hdev); 10047d474e06SAndre Guedes hci_dev_unlock(hdev); 10057d474e06SAndre Guedes } else { 10067d474e06SAndre Guedes err = -EINVAL; 10077d474e06SAndre Guedes } 10087d474e06SAndre Guedes 10097d474e06SAndre Guedes done: 10107d474e06SAndre Guedes kfree(buf); 10117d474e06SAndre Guedes 10127d474e06SAndre Guedes if (err) 10137d474e06SAndre Guedes return err; 10147d474e06SAndre Guedes else 10157d474e06SAndre Guedes return count; 10167d474e06SAndre Guedes } 10177d474e06SAndre Guedes 10187d474e06SAndre Guedes static const struct file_operations le_auto_conn_fops = { 10197d474e06SAndre Guedes .open = le_auto_conn_open, 10207d474e06SAndre Guedes .read = seq_read, 10217d474e06SAndre Guedes .write = le_auto_conn_write, 10227d474e06SAndre Guedes .llseek = seq_lseek, 10237d474e06SAndre Guedes .release = single_release, 10247d474e06SAndre Guedes }; 10257d474e06SAndre Guedes 10261da177e4SLinus Torvalds /* ---- HCI requests ---- */ 10271da177e4SLinus Torvalds 102842c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 10291da177e4SLinus Torvalds { 103042c6b129SJohan Hedberg BT_DBG("%s result 0x%2.2x", hdev->name, result); 103175fb0e32SJohan Hedberg 10321da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 10331da177e4SLinus Torvalds hdev->req_result = result; 10341da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 10351da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 10361da177e4SLinus Torvalds } 10371da177e4SLinus Torvalds } 10381da177e4SLinus Torvalds 10391da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 10401da177e4SLinus Torvalds { 10411da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 10421da177e4SLinus Torvalds 10431da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 10441da177e4SLinus Torvalds hdev->req_result = err; 10451da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 10461da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 10471da177e4SLinus Torvalds } 10481da177e4SLinus Torvalds } 10491da177e4SLinus Torvalds 105077a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 105177a63e0aSFengguang Wu u8 event) 105275e84b7cSJohan Hedberg { 105375e84b7cSJohan Hedberg struct hci_ev_cmd_complete *ev; 105475e84b7cSJohan Hedberg struct hci_event_hdr *hdr; 105575e84b7cSJohan Hedberg struct sk_buff *skb; 105675e84b7cSJohan Hedberg 105775e84b7cSJohan Hedberg hci_dev_lock(hdev); 105875e84b7cSJohan Hedberg 105975e84b7cSJohan Hedberg skb = hdev->recv_evt; 106075e84b7cSJohan Hedberg hdev->recv_evt = NULL; 106175e84b7cSJohan Hedberg 106275e84b7cSJohan Hedberg hci_dev_unlock(hdev); 106375e84b7cSJohan Hedberg 106475e84b7cSJohan Hedberg if (!skb) 106575e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 106675e84b7cSJohan Hedberg 106775e84b7cSJohan Hedberg if (skb->len < sizeof(*hdr)) { 106875e84b7cSJohan Hedberg BT_ERR("Too short HCI event"); 106975e84b7cSJohan Hedberg goto failed; 107075e84b7cSJohan Hedberg } 107175e84b7cSJohan Hedberg 107275e84b7cSJohan Hedberg hdr = (void *) skb->data; 107375e84b7cSJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 107475e84b7cSJohan Hedberg 10757b1abbbeSJohan Hedberg if (event) { 10767b1abbbeSJohan Hedberg if (hdr->evt != event) 10777b1abbbeSJohan Hedberg goto failed; 10787b1abbbeSJohan Hedberg return skb; 10797b1abbbeSJohan Hedberg } 10807b1abbbeSJohan Hedberg 108175e84b7cSJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 108275e84b7cSJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 108375e84b7cSJohan Hedberg goto failed; 108475e84b7cSJohan Hedberg } 108575e84b7cSJohan Hedberg 108675e84b7cSJohan Hedberg if (skb->len < sizeof(*ev)) { 108775e84b7cSJohan Hedberg BT_ERR("Too short cmd_complete event"); 108875e84b7cSJohan Hedberg goto failed; 108975e84b7cSJohan Hedberg } 109075e84b7cSJohan Hedberg 109175e84b7cSJohan Hedberg ev = (void *) skb->data; 109275e84b7cSJohan Hedberg skb_pull(skb, sizeof(*ev)); 109375e84b7cSJohan Hedberg 109475e84b7cSJohan Hedberg if (opcode == __le16_to_cpu(ev->opcode)) 109575e84b7cSJohan Hedberg return skb; 109675e84b7cSJohan Hedberg 109775e84b7cSJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 109875e84b7cSJohan Hedberg __le16_to_cpu(ev->opcode)); 109975e84b7cSJohan Hedberg 110075e84b7cSJohan Hedberg failed: 110175e84b7cSJohan Hedberg kfree_skb(skb); 110275e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 110375e84b7cSJohan Hedberg } 110475e84b7cSJohan Hedberg 11057b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 110607dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout) 110775e84b7cSJohan Hedberg { 110875e84b7cSJohan Hedberg DECLARE_WAITQUEUE(wait, current); 110975e84b7cSJohan Hedberg struct hci_request req; 111075e84b7cSJohan Hedberg int err = 0; 111175e84b7cSJohan Hedberg 111275e84b7cSJohan Hedberg BT_DBG("%s", hdev->name); 111375e84b7cSJohan Hedberg 111475e84b7cSJohan Hedberg hci_req_init(&req, hdev); 111575e84b7cSJohan Hedberg 11167b1abbbeSJohan Hedberg hci_req_add_ev(&req, opcode, plen, param, event); 111775e84b7cSJohan Hedberg 111875e84b7cSJohan Hedberg hdev->req_status = HCI_REQ_PEND; 111975e84b7cSJohan Hedberg 112075e84b7cSJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 112175e84b7cSJohan Hedberg if (err < 0) 112275e84b7cSJohan Hedberg return ERR_PTR(err); 112375e84b7cSJohan Hedberg 112475e84b7cSJohan Hedberg add_wait_queue(&hdev->req_wait_q, &wait); 112575e84b7cSJohan Hedberg set_current_state(TASK_INTERRUPTIBLE); 112675e84b7cSJohan Hedberg 112775e84b7cSJohan Hedberg schedule_timeout(timeout); 112875e84b7cSJohan Hedberg 112975e84b7cSJohan Hedberg remove_wait_queue(&hdev->req_wait_q, &wait); 113075e84b7cSJohan Hedberg 113175e84b7cSJohan Hedberg if (signal_pending(current)) 113275e84b7cSJohan Hedberg return ERR_PTR(-EINTR); 113375e84b7cSJohan Hedberg 113475e84b7cSJohan Hedberg switch (hdev->req_status) { 113575e84b7cSJohan Hedberg case HCI_REQ_DONE: 113675e84b7cSJohan Hedberg err = -bt_to_errno(hdev->req_result); 113775e84b7cSJohan Hedberg break; 113875e84b7cSJohan Hedberg 113975e84b7cSJohan Hedberg case HCI_REQ_CANCELED: 114075e84b7cSJohan Hedberg err = -hdev->req_result; 114175e84b7cSJohan Hedberg break; 114275e84b7cSJohan Hedberg 114375e84b7cSJohan Hedberg default: 114475e84b7cSJohan Hedberg err = -ETIMEDOUT; 114575e84b7cSJohan Hedberg break; 114675e84b7cSJohan Hedberg } 114775e84b7cSJohan Hedberg 114875e84b7cSJohan Hedberg hdev->req_status = hdev->req_result = 0; 114975e84b7cSJohan Hedberg 115075e84b7cSJohan Hedberg BT_DBG("%s end: err %d", hdev->name, err); 115175e84b7cSJohan Hedberg 115275e84b7cSJohan Hedberg if (err < 0) 115375e84b7cSJohan Hedberg return ERR_PTR(err); 115475e84b7cSJohan Hedberg 11557b1abbbeSJohan Hedberg return hci_get_cmd_complete(hdev, opcode, event); 11567b1abbbeSJohan Hedberg } 11577b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev); 11587b1abbbeSJohan Hedberg 11597b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 116007dc93ddSJohan Hedberg const void *param, u32 timeout) 11617b1abbbeSJohan Hedberg { 11627b1abbbeSJohan Hedberg return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); 116375e84b7cSJohan Hedberg } 116475e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync); 116575e84b7cSJohan Hedberg 11661da177e4SLinus Torvalds /* Execute request and wait for completion. */ 116701178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev, 116842c6b129SJohan Hedberg void (*func)(struct hci_request *req, 116942c6b129SJohan Hedberg unsigned long opt), 11701da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 11711da177e4SLinus Torvalds { 117242c6b129SJohan Hedberg struct hci_request req; 11731da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 11741da177e4SLinus Torvalds int err = 0; 11751da177e4SLinus Torvalds 11761da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 11771da177e4SLinus Torvalds 117842c6b129SJohan Hedberg hci_req_init(&req, hdev); 117942c6b129SJohan Hedberg 11801da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 11811da177e4SLinus Torvalds 118242c6b129SJohan Hedberg func(&req, opt); 118353cce22dSJohan Hedberg 118442c6b129SJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 118542c6b129SJohan Hedberg if (err < 0) { 118653cce22dSJohan Hedberg hdev->req_status = 0; 1187920c8300SAndre Guedes 1188920c8300SAndre Guedes /* ENODATA means the HCI request command queue is empty. 1189920c8300SAndre Guedes * This can happen when a request with conditionals doesn't 1190920c8300SAndre Guedes * trigger any commands to be sent. This is normal behavior 1191920c8300SAndre Guedes * and should not trigger an error return. 119242c6b129SJohan Hedberg */ 1193920c8300SAndre Guedes if (err == -ENODATA) 119442c6b129SJohan Hedberg return 0; 1195920c8300SAndre Guedes 1196920c8300SAndre Guedes return err; 119753cce22dSJohan Hedberg } 119853cce22dSJohan Hedberg 1199bc4445c7SAndre Guedes add_wait_queue(&hdev->req_wait_q, &wait); 1200bc4445c7SAndre Guedes set_current_state(TASK_INTERRUPTIBLE); 1201bc4445c7SAndre Guedes 12021da177e4SLinus Torvalds schedule_timeout(timeout); 12031da177e4SLinus Torvalds 12041da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 12051da177e4SLinus Torvalds 12061da177e4SLinus Torvalds if (signal_pending(current)) 12071da177e4SLinus Torvalds return -EINTR; 12081da177e4SLinus Torvalds 12091da177e4SLinus Torvalds switch (hdev->req_status) { 12101da177e4SLinus Torvalds case HCI_REQ_DONE: 1211e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 12121da177e4SLinus Torvalds break; 12131da177e4SLinus Torvalds 12141da177e4SLinus Torvalds case HCI_REQ_CANCELED: 12151da177e4SLinus Torvalds err = -hdev->req_result; 12161da177e4SLinus Torvalds break; 12171da177e4SLinus Torvalds 12181da177e4SLinus Torvalds default: 12191da177e4SLinus Torvalds err = -ETIMEDOUT; 12201da177e4SLinus Torvalds break; 12213ff50b79SStephen Hemminger } 12221da177e4SLinus Torvalds 1223a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 12241da177e4SLinus Torvalds 12251da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 12261da177e4SLinus Torvalds 12271da177e4SLinus Torvalds return err; 12281da177e4SLinus Torvalds } 12291da177e4SLinus Torvalds 123001178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev, 123142c6b129SJohan Hedberg void (*req)(struct hci_request *req, 123242c6b129SJohan Hedberg unsigned long opt), 12331da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 12341da177e4SLinus Torvalds { 12351da177e4SLinus Torvalds int ret; 12361da177e4SLinus Torvalds 12377c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 12387c6a329eSMarcel Holtmann return -ENETDOWN; 12397c6a329eSMarcel Holtmann 12401da177e4SLinus Torvalds /* Serialize all requests */ 12411da177e4SLinus Torvalds hci_req_lock(hdev); 124201178cd4SJohan Hedberg ret = __hci_req_sync(hdev, req, opt, timeout); 12431da177e4SLinus Torvalds hci_req_unlock(hdev); 12441da177e4SLinus Torvalds 12451da177e4SLinus Torvalds return ret; 12461da177e4SLinus Torvalds } 12471da177e4SLinus Torvalds 124842c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt) 12491da177e4SLinus Torvalds { 125042c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 12511da177e4SLinus Torvalds 12521da177e4SLinus Torvalds /* Reset device */ 125342c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 125442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 12551da177e4SLinus Torvalds } 12561da177e4SLinus Torvalds 125742c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 12581da177e4SLinus Torvalds { 125942c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 12602455a3eaSAndrei Emeltchenko 12611da177e4SLinus Torvalds /* Read Local Supported Features */ 126242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 12631da177e4SLinus Torvalds 12641143e5a6SMarcel Holtmann /* Read Local Version */ 126542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 12662177bab5SJohan Hedberg 12672177bab5SJohan Hedberg /* Read BD Address */ 126842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 12691da177e4SLinus Torvalds } 12701da177e4SLinus Torvalds 127142c6b129SJohan Hedberg static void amp_init(struct hci_request *req) 1272e61ef499SAndrei Emeltchenko { 127342c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 12742455a3eaSAndrei Emeltchenko 1275e61ef499SAndrei Emeltchenko /* Read Local Version */ 127642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 12776bcbc489SAndrei Emeltchenko 1278f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 1279f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 1280f6996cfeSMarcel Holtmann 1281f6996cfeSMarcel Holtmann /* Read Local Supported Features */ 1282f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 1283f6996cfeSMarcel Holtmann 12846bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 128542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 1286e71dfabaSAndrei Emeltchenko 1287e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 128842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 12897528ca1cSMarcel Holtmann 1290f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 1291f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 1292f38ba941SMarcel Holtmann 12937528ca1cSMarcel Holtmann /* Read Location Data */ 12947528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 1295e61ef499SAndrei Emeltchenko } 1296e61ef499SAndrei Emeltchenko 129742c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 1298e61ef499SAndrei Emeltchenko { 129942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1300e61ef499SAndrei Emeltchenko 1301e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 1302e61ef499SAndrei Emeltchenko 130311778716SAndrei Emeltchenko /* Reset */ 130411778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 130542c6b129SJohan Hedberg hci_reset_req(req, 0); 130611778716SAndrei Emeltchenko 1307e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 1308e61ef499SAndrei Emeltchenko case HCI_BREDR: 130942c6b129SJohan Hedberg bredr_init(req); 1310e61ef499SAndrei Emeltchenko break; 1311e61ef499SAndrei Emeltchenko 1312e61ef499SAndrei Emeltchenko case HCI_AMP: 131342c6b129SJohan Hedberg amp_init(req); 1314e61ef499SAndrei Emeltchenko break; 1315e61ef499SAndrei Emeltchenko 1316e61ef499SAndrei Emeltchenko default: 1317e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 1318e61ef499SAndrei Emeltchenko break; 1319e61ef499SAndrei Emeltchenko } 1320e61ef499SAndrei Emeltchenko } 1321e61ef499SAndrei Emeltchenko 132242c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 13232177bab5SJohan Hedberg { 13244ca048e3SMarcel Holtmann struct hci_dev *hdev = req->hdev; 13254ca048e3SMarcel Holtmann 13262177bab5SJohan Hedberg __le16 param; 13272177bab5SJohan Hedberg __u8 flt_type; 13282177bab5SJohan Hedberg 13292177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 133042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 13312177bab5SJohan Hedberg 13322177bab5SJohan Hedberg /* Read Class of Device */ 133342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 13342177bab5SJohan Hedberg 13352177bab5SJohan Hedberg /* Read Local Name */ 133642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 13372177bab5SJohan Hedberg 13382177bab5SJohan Hedberg /* Read Voice Setting */ 133942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 13402177bab5SJohan Hedberg 1341b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 1342b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 1343b4cb9fb2SMarcel Holtmann 13444b836f39SMarcel Holtmann /* Read Current IAC LAP */ 13454b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 13464b836f39SMarcel Holtmann 13472177bab5SJohan Hedberg /* Clear Event Filters */ 13482177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 134942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 13502177bab5SJohan Hedberg 13512177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 13522177bab5SJohan Hedberg param = __constant_cpu_to_le16(0x7d00); 135342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 13542177bab5SJohan Hedberg 13554ca048e3SMarcel Holtmann /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, 13564ca048e3SMarcel Holtmann * but it does not support page scan related HCI commands. 13574ca048e3SMarcel Holtmann */ 13584ca048e3SMarcel Holtmann if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) { 1359f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 1360f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 1361f332ec66SJohan Hedberg } 13622177bab5SJohan Hedberg } 13632177bab5SJohan Hedberg 136442c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 13652177bab5SJohan Hedberg { 1366c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 1367c73eee91SJohan Hedberg 13682177bab5SJohan Hedberg /* Read LE Buffer Size */ 136942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 13702177bab5SJohan Hedberg 13712177bab5SJohan Hedberg /* Read LE Local Supported Features */ 137242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 13732177bab5SJohan Hedberg 1374747d3f03SMarcel Holtmann /* Read LE Supported States */ 1375747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 1376747d3f03SMarcel Holtmann 13772177bab5SJohan Hedberg /* Read LE Advertising Channel TX Power */ 137842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 13792177bab5SJohan Hedberg 13802177bab5SJohan Hedberg /* Read LE White List Size */ 138142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 13822177bab5SJohan Hedberg 1383747d3f03SMarcel Holtmann /* Clear LE White List */ 1384747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL); 1385c73eee91SJohan Hedberg 1386c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 1387c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1388c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 13892177bab5SJohan Hedberg } 13902177bab5SJohan Hedberg 13912177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 13922177bab5SJohan Hedberg { 13932177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 13942177bab5SJohan Hedberg return 0x02; 13952177bab5SJohan Hedberg 13962177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 13972177bab5SJohan Hedberg return 0x01; 13982177bab5SJohan Hedberg 13992177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 14002177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 14012177bab5SJohan Hedberg return 0x01; 14022177bab5SJohan Hedberg 14032177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 14042177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 14052177bab5SJohan Hedberg return 0x01; 14062177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 14072177bab5SJohan Hedberg return 0x01; 14082177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 14092177bab5SJohan Hedberg return 0x01; 14102177bab5SJohan Hedberg } 14112177bab5SJohan Hedberg 14122177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 14132177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 14142177bab5SJohan Hedberg return 0x01; 14152177bab5SJohan Hedberg 14162177bab5SJohan Hedberg return 0x00; 14172177bab5SJohan Hedberg } 14182177bab5SJohan Hedberg 141942c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 14202177bab5SJohan Hedberg { 14212177bab5SJohan Hedberg u8 mode; 14222177bab5SJohan Hedberg 142342c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 14242177bab5SJohan Hedberg 142542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 14262177bab5SJohan Hedberg } 14272177bab5SJohan Hedberg 142842c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 14292177bab5SJohan Hedberg { 143042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 143142c6b129SJohan Hedberg 14322177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 14332177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 14342177bab5SJohan Hedberg * command otherwise. 14352177bab5SJohan Hedberg */ 14362177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 14372177bab5SJohan Hedberg 14382177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 14392177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 14402177bab5SJohan Hedberg */ 14412177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 14422177bab5SJohan Hedberg return; 14432177bab5SJohan Hedberg 14442177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 14452177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 14462177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 14472177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 14482177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 14492177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 1450c7882cbdSMarcel Holtmann } else { 1451c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 1452c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 1453c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 1454c7882cbdSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 1455c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 1456c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 1457c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 1458c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 1459c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 1460c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 1461c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 14622177bab5SJohan Hedberg } 14632177bab5SJohan Hedberg 14642177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 14652177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 14662177bab5SJohan Hedberg 14672177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 14682177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 14692177bab5SJohan Hedberg 14702177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 14712177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 14722177bab5SJohan Hedberg 14732177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 14742177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 14752177bab5SJohan Hedberg 14762177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 14772177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 14782177bab5SJohan Hedberg 14792177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 14802177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 14812177bab5SJohan Hedberg 14822177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 14832177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 14842177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 14852177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 14862177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 14872177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 14882177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 14892177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 14902177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 14912177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 14922177bab5SJohan Hedberg * Features Notification 14932177bab5SJohan Hedberg */ 14942177bab5SJohan Hedberg } 14952177bab5SJohan Hedberg 14962177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 14972177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 14982177bab5SJohan Hedberg 149942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 15002177bab5SJohan Hedberg 15012177bab5SJohan Hedberg if (lmp_le_capable(hdev)) { 15022177bab5SJohan Hedberg memset(events, 0, sizeof(events)); 15032177bab5SJohan Hedberg events[0] = 0x1f; 150442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, 15052177bab5SJohan Hedberg sizeof(events), events); 15062177bab5SJohan Hedberg } 15072177bab5SJohan Hedberg } 15082177bab5SJohan Hedberg 150942c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 15102177bab5SJohan Hedberg { 151142c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 151242c6b129SJohan Hedberg 15132177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 151442c6b129SJohan Hedberg bredr_setup(req); 151556f87901SJohan Hedberg else 151656f87901SJohan Hedberg clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 15172177bab5SJohan Hedberg 15182177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 151942c6b129SJohan Hedberg le_setup(req); 15202177bab5SJohan Hedberg 152142c6b129SJohan Hedberg hci_setup_event_mask(req); 15222177bab5SJohan Hedberg 15233f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 15243f8e2d75SJohan Hedberg * local supported commands HCI command. 15253f8e2d75SJohan Hedberg */ 15263f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 152742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 15282177bab5SJohan Hedberg 15292177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 153057af75a8SMarcel Holtmann /* When SSP is available, then the host features page 153157af75a8SMarcel Holtmann * should also be available as well. However some 153257af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 153357af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 153457af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 153557af75a8SMarcel Holtmann */ 153657af75a8SMarcel Holtmann hdev->max_page = 0x01; 153757af75a8SMarcel Holtmann 15382177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 15392177bab5SJohan Hedberg u8 mode = 0x01; 154042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 15412177bab5SJohan Hedberg sizeof(mode), &mode); 15422177bab5SJohan Hedberg } else { 15432177bab5SJohan Hedberg struct hci_cp_write_eir cp; 15442177bab5SJohan Hedberg 15452177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 15462177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 15472177bab5SJohan Hedberg 154842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 15492177bab5SJohan Hedberg } 15502177bab5SJohan Hedberg } 15512177bab5SJohan Hedberg 15522177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 155342c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 15542177bab5SJohan Hedberg 15552177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 155642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 15572177bab5SJohan Hedberg 15582177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 15592177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 15602177bab5SJohan Hedberg 15612177bab5SJohan Hedberg cp.page = 0x01; 156242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 156342c6b129SJohan Hedberg sizeof(cp), &cp); 15642177bab5SJohan Hedberg } 15652177bab5SJohan Hedberg 15662177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 15672177bab5SJohan Hedberg u8 enable = 1; 156842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 15692177bab5SJohan Hedberg &enable); 15702177bab5SJohan Hedberg } 15712177bab5SJohan Hedberg } 15722177bab5SJohan Hedberg 157342c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 15742177bab5SJohan Hedberg { 157542c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 15762177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 15772177bab5SJohan Hedberg u16 link_policy = 0; 15782177bab5SJohan Hedberg 15792177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 15802177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 15812177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 15822177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 15832177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 15842177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 15852177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 15862177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 15872177bab5SJohan Hedberg 15882177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 158942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 15902177bab5SJohan Hedberg } 15912177bab5SJohan Hedberg 159242c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 15932177bab5SJohan Hedberg { 159442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 15952177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 15962177bab5SJohan Hedberg 1597c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 1598c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1599c73eee91SJohan Hedberg return; 1600c73eee91SJohan Hedberg 16012177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 16022177bab5SJohan Hedberg 16032177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 16042177bab5SJohan Hedberg cp.le = 0x01; 16052177bab5SJohan Hedberg cp.simul = lmp_le_br_capable(hdev); 16062177bab5SJohan Hedberg } 16072177bab5SJohan Hedberg 16082177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 160942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 16102177bab5SJohan Hedberg &cp); 16112177bab5SJohan Hedberg } 16122177bab5SJohan Hedberg 1613d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 1614d62e6d67SJohan Hedberg { 1615d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 1616d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1617d62e6d67SJohan Hedberg 1618d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 1619d62e6d67SJohan Hedberg * enable all necessary events for it. 1620d62e6d67SJohan Hedberg */ 162153b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 1622d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 1623d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 1624d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 1625d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 1626d62e6d67SJohan Hedberg } 1627d62e6d67SJohan Hedberg 1628d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 1629d62e6d67SJohan Hedberg * enable all necessary events for it. 1630d62e6d67SJohan Hedberg */ 163153b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 1632d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 1633d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 1634d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 1635d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 1636d62e6d67SJohan Hedberg } 1637d62e6d67SJohan Hedberg 163840c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 163940c59fcbSMarcel Holtmann if (lmp_ping_capable(hdev)) 164040c59fcbSMarcel Holtmann events[2] |= 0x80; 164140c59fcbSMarcel Holtmann 1642d62e6d67SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 1643d62e6d67SJohan Hedberg } 1644d62e6d67SJohan Hedberg 164542c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 16462177bab5SJohan Hedberg { 164742c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1648d2c5d77fSJohan Hedberg u8 p; 164942c6b129SJohan Hedberg 1650b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 1651b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 1652b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 1653b8f4e068SGustavo Padovan * 1654b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 1655b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 1656b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 1657b8f4e068SGustavo Padovan * command redundant anyway. 1658f9f462faSMarcel Holtmann * 1659f9f462faSMarcel Holtmann * Some controllers indicate that they support handling deleting 1660f9f462faSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 1661f9f462faSMarcel Holtmann * just disable this command. 1662b8f4e068SGustavo Padovan */ 1663f9f462faSMarcel Holtmann if (hdev->commands[6] & 0x80 && 1664f9f462faSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 166559f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 166659f45d57SJohan Hedberg 166759f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 166859f45d57SJohan Hedberg cp.delete_all = 0x01; 166959f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 167059f45d57SJohan Hedberg sizeof(cp), &cp); 167159f45d57SJohan Hedberg } 167259f45d57SJohan Hedberg 16732177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 167442c6b129SJohan Hedberg hci_setup_link_policy(req); 16752177bab5SJohan Hedberg 16767bf32048SJohan Hedberg if (lmp_le_capable(hdev)) 167742c6b129SJohan Hedberg hci_set_le_support(req); 1678d2c5d77fSJohan Hedberg 1679d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 1680d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 1681d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 1682d2c5d77fSJohan Hedberg 1683d2c5d77fSJohan Hedberg cp.page = p; 1684d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 1685d2c5d77fSJohan Hedberg sizeof(cp), &cp); 1686d2c5d77fSJohan Hedberg } 16872177bab5SJohan Hedberg } 16882177bab5SJohan Hedberg 16895d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt) 16905d4e7e8dSJohan Hedberg { 16915d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 16925d4e7e8dSJohan Hedberg 1693d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 1694d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 1695d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 1696d62e6d67SJohan Hedberg 16975d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 169853b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 16995d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 1700a6d0d690SMarcel Holtmann 1701a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 17025afeac14SMarcel Holtmann if ((lmp_sc_capable(hdev) || 17035afeac14SMarcel Holtmann test_bit(HCI_FORCE_SC, &hdev->dev_flags)) && 1704a6d0d690SMarcel Holtmann test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) { 1705a6d0d690SMarcel Holtmann u8 support = 0x01; 1706a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 1707a6d0d690SMarcel Holtmann sizeof(support), &support); 1708a6d0d690SMarcel Holtmann } 17095d4e7e8dSJohan Hedberg } 17105d4e7e8dSJohan Hedberg 17112177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 17122177bab5SJohan Hedberg { 17132177bab5SJohan Hedberg int err; 17142177bab5SJohan Hedberg 17152177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 17162177bab5SJohan Hedberg if (err < 0) 17172177bab5SJohan Hedberg return err; 17182177bab5SJohan Hedberg 17194b4148e9SMarcel Holtmann /* The Device Under Test (DUT) mode is special and available for 17204b4148e9SMarcel Holtmann * all controller types. So just create it early on. 17214b4148e9SMarcel Holtmann */ 17224b4148e9SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 17234b4148e9SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 17244b4148e9SMarcel Holtmann &dut_mode_fops); 17254b4148e9SMarcel Holtmann } 17264b4148e9SMarcel Holtmann 17272177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 17282177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 17292177bab5SJohan Hedberg * first stage init. 17302177bab5SJohan Hedberg */ 17312177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 17322177bab5SJohan Hedberg return 0; 17332177bab5SJohan Hedberg 17342177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 17352177bab5SJohan Hedberg if (err < 0) 17362177bab5SJohan Hedberg return err; 17372177bab5SJohan Hedberg 17385d4e7e8dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 17395d4e7e8dSJohan Hedberg if (err < 0) 17405d4e7e8dSJohan Hedberg return err; 17415d4e7e8dSJohan Hedberg 1742baf27f6eSMarcel Holtmann err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 1743baf27f6eSMarcel Holtmann if (err < 0) 1744baf27f6eSMarcel Holtmann return err; 1745baf27f6eSMarcel Holtmann 1746baf27f6eSMarcel Holtmann /* Only create debugfs entries during the initial setup 1747baf27f6eSMarcel Holtmann * phase and not every time the controller gets powered on. 1748baf27f6eSMarcel Holtmann */ 1749baf27f6eSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 1750baf27f6eSMarcel Holtmann return 0; 1751baf27f6eSMarcel Holtmann 1752dfb826a8SMarcel Holtmann debugfs_create_file("features", 0444, hdev->debugfs, hdev, 1753dfb826a8SMarcel Holtmann &features_fops); 1754ceeb3bc0SMarcel Holtmann debugfs_create_u16("manufacturer", 0444, hdev->debugfs, 1755ceeb3bc0SMarcel Holtmann &hdev->manufacturer); 1756ceeb3bc0SMarcel Holtmann debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); 1757ceeb3bc0SMarcel Holtmann debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); 175870afe0b8SMarcel Holtmann debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, 175970afe0b8SMarcel Holtmann &blacklist_fops); 176047219839SMarcel Holtmann debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); 176147219839SMarcel Holtmann 1762baf27f6eSMarcel Holtmann if (lmp_bredr_capable(hdev)) { 1763baf27f6eSMarcel Holtmann debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, 1764baf27f6eSMarcel Holtmann hdev, &inquiry_cache_fops); 176502d08d15SMarcel Holtmann debugfs_create_file("link_keys", 0400, hdev->debugfs, 176602d08d15SMarcel Holtmann hdev, &link_keys_fops); 1767babdbb3cSMarcel Holtmann debugfs_create_file("dev_class", 0444, hdev->debugfs, 1768babdbb3cSMarcel Holtmann hdev, &dev_class_fops); 1769041000b9SMarcel Holtmann debugfs_create_file("voice_setting", 0444, hdev->debugfs, 1770041000b9SMarcel Holtmann hdev, &voice_setting_fops); 1771baf27f6eSMarcel Holtmann } 1772baf27f6eSMarcel Holtmann 177306f5b778SMarcel Holtmann if (lmp_ssp_capable(hdev)) { 1774ebd1e33bSMarcel Holtmann debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, 1775ebd1e33bSMarcel Holtmann hdev, &auto_accept_delay_fops); 177606f5b778SMarcel Holtmann debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs, 177706f5b778SMarcel Holtmann hdev, &ssp_debug_mode_fops); 17785afeac14SMarcel Holtmann debugfs_create_file("force_sc_support", 0644, hdev->debugfs, 17795afeac14SMarcel Holtmann hdev, &force_sc_support_fops); 1780134c2a89SMarcel Holtmann debugfs_create_file("sc_only_mode", 0444, hdev->debugfs, 1781134c2a89SMarcel Holtmann hdev, &sc_only_mode_fops); 178206f5b778SMarcel Holtmann } 1783ebd1e33bSMarcel Holtmann 17842bfa3531SMarcel Holtmann if (lmp_sniff_capable(hdev)) { 17852bfa3531SMarcel Holtmann debugfs_create_file("idle_timeout", 0644, hdev->debugfs, 17862bfa3531SMarcel Holtmann hdev, &idle_timeout_fops); 17872bfa3531SMarcel Holtmann debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs, 17882bfa3531SMarcel Holtmann hdev, &sniff_min_interval_fops); 17892bfa3531SMarcel Holtmann debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs, 17902bfa3531SMarcel Holtmann hdev, &sniff_max_interval_fops); 17912bfa3531SMarcel Holtmann } 17922bfa3531SMarcel Holtmann 1793d0f729b8SMarcel Holtmann if (lmp_le_capable(hdev)) { 1794ac345813SMarcel Holtmann debugfs_create_file("identity", 0400, hdev->debugfs, 1795ac345813SMarcel Holtmann hdev, &identity_fops); 1796ac345813SMarcel Holtmann debugfs_create_file("rpa_timeout", 0644, hdev->debugfs, 1797ac345813SMarcel Holtmann hdev, &rpa_timeout_fops); 17987a4cd51dSMarcel Holtmann debugfs_create_file("random_address", 0444, hdev->debugfs, 17997a4cd51dSMarcel Holtmann hdev, &random_address_fops); 1800e7b8fc92SMarcel Holtmann debugfs_create_file("static_address", 0444, hdev->debugfs, 1801e7b8fc92SMarcel Holtmann hdev, &static_address_fops); 1802b32bba6cSMarcel Holtmann 1803b32bba6cSMarcel Holtmann /* For controllers with a public address, provide a debug 1804b32bba6cSMarcel Holtmann * option to force the usage of the configured static 1805b32bba6cSMarcel Holtmann * address. By default the public address is used. 1806b32bba6cSMarcel Holtmann */ 1807b32bba6cSMarcel Holtmann if (bacmp(&hdev->bdaddr, BDADDR_ANY)) 1808b32bba6cSMarcel Holtmann debugfs_create_file("force_static_address", 0644, 1809b32bba6cSMarcel Holtmann hdev->debugfs, hdev, 1810b32bba6cSMarcel Holtmann &force_static_address_fops); 1811b32bba6cSMarcel Holtmann 1812b32bba6cSMarcel Holtmann debugfs_create_u8("white_list_size", 0444, hdev->debugfs, 1813b32bba6cSMarcel Holtmann &hdev->le_white_list_size); 1814*d2ab0ac1SMarcel Holtmann debugfs_create_file("white_list", 0444, hdev->debugfs, hdev, 1815*d2ab0ac1SMarcel Holtmann &white_list_fops); 18163698d704SMarcel Holtmann debugfs_create_file("identity_resolving_keys", 0400, 18173698d704SMarcel Holtmann hdev->debugfs, hdev, 18183698d704SMarcel Holtmann &identity_resolving_keys_fops); 18198f8625cdSMarcel Holtmann debugfs_create_file("long_term_keys", 0400, hdev->debugfs, 18208f8625cdSMarcel Holtmann hdev, &long_term_keys_fops); 18214e70c7e7SMarcel Holtmann debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, 18224e70c7e7SMarcel Holtmann hdev, &conn_min_interval_fops); 18234e70c7e7SMarcel Holtmann debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, 18244e70c7e7SMarcel Holtmann hdev, &conn_max_interval_fops); 18253f959d46SMarcel Holtmann debugfs_create_file("adv_channel_map", 0644, hdev->debugfs, 18263f959d46SMarcel Holtmann hdev, &adv_channel_map_fops); 182789863109SJukka Rissanen debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev, 182889863109SJukka Rissanen &lowpan_debugfs_fops); 18297d474e06SAndre Guedes debugfs_create_file("le_auto_conn", 0644, hdev->debugfs, hdev, 18307d474e06SAndre Guedes &le_auto_conn_fops); 1831d0f729b8SMarcel Holtmann } 1832e7b8fc92SMarcel Holtmann 1833baf27f6eSMarcel Holtmann return 0; 18342177bab5SJohan Hedberg } 18352177bab5SJohan Hedberg 183642c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 18371da177e4SLinus Torvalds { 18381da177e4SLinus Torvalds __u8 scan = opt; 18391da177e4SLinus Torvalds 184042c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 18411da177e4SLinus Torvalds 18421da177e4SLinus Torvalds /* Inquiry and Page scans */ 184342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 18441da177e4SLinus Torvalds } 18451da177e4SLinus Torvalds 184642c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 18471da177e4SLinus Torvalds { 18481da177e4SLinus Torvalds __u8 auth = opt; 18491da177e4SLinus Torvalds 185042c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 18511da177e4SLinus Torvalds 18521da177e4SLinus Torvalds /* Authentication */ 185342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 18541da177e4SLinus Torvalds } 18551da177e4SLinus Torvalds 185642c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 18571da177e4SLinus Torvalds { 18581da177e4SLinus Torvalds __u8 encrypt = opt; 18591da177e4SLinus Torvalds 186042c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 18611da177e4SLinus Torvalds 1862e4e8e37cSMarcel Holtmann /* Encryption */ 186342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 18641da177e4SLinus Torvalds } 18651da177e4SLinus Torvalds 186642c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 1867e4e8e37cSMarcel Holtmann { 1868e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1869e4e8e37cSMarcel Holtmann 187042c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1871e4e8e37cSMarcel Holtmann 1872e4e8e37cSMarcel Holtmann /* Default link policy */ 187342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1874e4e8e37cSMarcel Holtmann } 1875e4e8e37cSMarcel Holtmann 18761da177e4SLinus Torvalds /* Get HCI device by index. 18771da177e4SLinus Torvalds * Device is held on return. */ 18781da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 18791da177e4SLinus Torvalds { 18808035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 18811da177e4SLinus Torvalds 18821da177e4SLinus Torvalds BT_DBG("%d", index); 18831da177e4SLinus Torvalds 18841da177e4SLinus Torvalds if (index < 0) 18851da177e4SLinus Torvalds return NULL; 18861da177e4SLinus Torvalds 18871da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 18888035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 18891da177e4SLinus Torvalds if (d->id == index) { 18901da177e4SLinus Torvalds hdev = hci_dev_hold(d); 18911da177e4SLinus Torvalds break; 18921da177e4SLinus Torvalds } 18931da177e4SLinus Torvalds } 18941da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 18951da177e4SLinus Torvalds return hdev; 18961da177e4SLinus Torvalds } 18971da177e4SLinus Torvalds 18981da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1899ff9ef578SJohan Hedberg 190030dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 190130dc78e1SJohan Hedberg { 190230dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 190330dc78e1SJohan Hedberg 19046fbe195dSAndre Guedes switch (discov->state) { 1905343f935bSAndre Guedes case DISCOVERY_FINDING: 19066fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 190730dc78e1SJohan Hedberg return true; 190830dc78e1SJohan Hedberg 19096fbe195dSAndre Guedes default: 191030dc78e1SJohan Hedberg return false; 191130dc78e1SJohan Hedberg } 19126fbe195dSAndre Guedes } 191330dc78e1SJohan Hedberg 1914ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1915ff9ef578SJohan Hedberg { 1916ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1917ff9ef578SJohan Hedberg 1918ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 1919ff9ef578SJohan Hedberg return; 1920ff9ef578SJohan Hedberg 1921ff9ef578SJohan Hedberg switch (state) { 1922ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 1923c54c3860SAndre Guedes hci_update_background_scan(hdev); 1924c54c3860SAndre Guedes 19257b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 1926ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1927ff9ef578SJohan Hedberg break; 1928ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1929ff9ef578SJohan Hedberg break; 1930343f935bSAndre Guedes case DISCOVERY_FINDING: 1931ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1932ff9ef578SJohan Hedberg break; 193330dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 193430dc78e1SJohan Hedberg break; 1935ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1936ff9ef578SJohan Hedberg break; 1937ff9ef578SJohan Hedberg } 1938ff9ef578SJohan Hedberg 1939ff9ef578SJohan Hedberg hdev->discovery.state = state; 1940ff9ef578SJohan Hedberg } 1941ff9ef578SJohan Hedberg 19421f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 19431da177e4SLinus Torvalds { 194430883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1945b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 19461da177e4SLinus Torvalds 1947561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1948561aafbcSJohan Hedberg list_del(&p->all); 1949b57c1a56SJohan Hedberg kfree(p); 19501da177e4SLinus Torvalds } 1951561aafbcSJohan Hedberg 1952561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1953561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 19541da177e4SLinus Torvalds } 19551da177e4SLinus Torvalds 1956a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1957a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 19581da177e4SLinus Torvalds { 195930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 19601da177e4SLinus Torvalds struct inquiry_entry *e; 19611da177e4SLinus Torvalds 19626ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 19631da177e4SLinus Torvalds 1964561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 19651da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 19661da177e4SLinus Torvalds return e; 19671da177e4SLinus Torvalds } 19681da177e4SLinus Torvalds 1969b57c1a56SJohan Hedberg return NULL; 1970b57c1a56SJohan Hedberg } 1971b57c1a56SJohan Hedberg 1972561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1973561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1974561aafbcSJohan Hedberg { 197530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1976561aafbcSJohan Hedberg struct inquiry_entry *e; 1977561aafbcSJohan Hedberg 19786ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1979561aafbcSJohan Hedberg 1980561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1981561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1982561aafbcSJohan Hedberg return e; 1983561aafbcSJohan Hedberg } 1984561aafbcSJohan Hedberg 1985561aafbcSJohan Hedberg return NULL; 1986561aafbcSJohan Hedberg } 1987561aafbcSJohan Hedberg 198830dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 198930dc78e1SJohan Hedberg bdaddr_t *bdaddr, 199030dc78e1SJohan Hedberg int state) 199130dc78e1SJohan Hedberg { 199230dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 199330dc78e1SJohan Hedberg struct inquiry_entry *e; 199430dc78e1SJohan Hedberg 19956ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 199630dc78e1SJohan Hedberg 199730dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 199830dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 199930dc78e1SJohan Hedberg return e; 200030dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 200130dc78e1SJohan Hedberg return e; 200230dc78e1SJohan Hedberg } 200330dc78e1SJohan Hedberg 200430dc78e1SJohan Hedberg return NULL; 200530dc78e1SJohan Hedberg } 200630dc78e1SJohan Hedberg 2007a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 2008a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 2009a3d4e20aSJohan Hedberg { 2010a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 2011a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 2012a3d4e20aSJohan Hedberg struct inquiry_entry *p; 2013a3d4e20aSJohan Hedberg 2014a3d4e20aSJohan Hedberg list_del(&ie->list); 2015a3d4e20aSJohan Hedberg 2016a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 2017a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 2018a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 2019a3d4e20aSJohan Hedberg break; 2020a3d4e20aSJohan Hedberg pos = &p->list; 2021a3d4e20aSJohan Hedberg } 2022a3d4e20aSJohan Hedberg 2023a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 2024a3d4e20aSJohan Hedberg } 2025a3d4e20aSJohan Hedberg 20263175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 2027388fc8faSJohan Hedberg bool name_known, bool *ssp) 20281da177e4SLinus Torvalds { 202930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 203070f23020SAndrei Emeltchenko struct inquiry_entry *ie; 20311da177e4SLinus Torvalds 20326ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 20331da177e4SLinus Torvalds 20342b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 20352b2fec4dSSzymon Janc 2036388fc8faSJohan Hedberg if (ssp) 2037388fc8faSJohan Hedberg *ssp = data->ssp_mode; 2038388fc8faSJohan Hedberg 203970f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 2040a3d4e20aSJohan Hedberg if (ie) { 2041388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 2042388fc8faSJohan Hedberg *ssp = true; 2043388fc8faSJohan Hedberg 2044a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 2045a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 2046a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 2047a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 2048a3d4e20aSJohan Hedberg } 2049a3d4e20aSJohan Hedberg 2050561aafbcSJohan Hedberg goto update; 2051a3d4e20aSJohan Hedberg } 2052561aafbcSJohan Hedberg 20531da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 205470f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 205570f23020SAndrei Emeltchenko if (!ie) 20563175405bSJohan Hedberg return false; 205770f23020SAndrei Emeltchenko 2058561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 2059561aafbcSJohan Hedberg 2060561aafbcSJohan Hedberg if (name_known) { 2061561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 2062561aafbcSJohan Hedberg } else { 2063561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 2064561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 2065561aafbcSJohan Hedberg } 2066561aafbcSJohan Hedberg 2067561aafbcSJohan Hedberg update: 2068561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 2069561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 2070561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 2071561aafbcSJohan Hedberg list_del(&ie->list); 20721da177e4SLinus Torvalds } 20731da177e4SLinus Torvalds 207470f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 207570f23020SAndrei Emeltchenko ie->timestamp = jiffies; 20761da177e4SLinus Torvalds cache->timestamp = jiffies; 20773175405bSJohan Hedberg 20783175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 20793175405bSJohan Hedberg return false; 20803175405bSJohan Hedberg 20813175405bSJohan Hedberg return true; 20821da177e4SLinus Torvalds } 20831da177e4SLinus Torvalds 20841da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 20851da177e4SLinus Torvalds { 208630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 20871da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 20881da177e4SLinus Torvalds struct inquiry_entry *e; 20891da177e4SLinus Torvalds int copied = 0; 20901da177e4SLinus Torvalds 2091561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 20921da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 2093b57c1a56SJohan Hedberg 2094b57c1a56SJohan Hedberg if (copied >= num) 2095b57c1a56SJohan Hedberg break; 2096b57c1a56SJohan Hedberg 20971da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 20981da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 20991da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 21001da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 21011da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 21021da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 2103b57c1a56SJohan Hedberg 21041da177e4SLinus Torvalds info++; 2105b57c1a56SJohan Hedberg copied++; 21061da177e4SLinus Torvalds } 21071da177e4SLinus Torvalds 21081da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 21091da177e4SLinus Torvalds return copied; 21101da177e4SLinus Torvalds } 21111da177e4SLinus Torvalds 211242c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 21131da177e4SLinus Torvalds { 21141da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 211542c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 21161da177e4SLinus Torvalds struct hci_cp_inquiry cp; 21171da177e4SLinus Torvalds 21181da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 21191da177e4SLinus Torvalds 21201da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 21211da177e4SLinus Torvalds return; 21221da177e4SLinus Torvalds 21231da177e4SLinus Torvalds /* Start Inquiry */ 21241da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 21251da177e4SLinus Torvalds cp.length = ir->length; 21261da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 212742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 21281da177e4SLinus Torvalds } 21291da177e4SLinus Torvalds 21303e13fa1eSAndre Guedes static int wait_inquiry(void *word) 21313e13fa1eSAndre Guedes { 21323e13fa1eSAndre Guedes schedule(); 21333e13fa1eSAndre Guedes return signal_pending(current); 21343e13fa1eSAndre Guedes } 21353e13fa1eSAndre Guedes 21361da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 21371da177e4SLinus Torvalds { 21381da177e4SLinus Torvalds __u8 __user *ptr = arg; 21391da177e4SLinus Torvalds struct hci_inquiry_req ir; 21401da177e4SLinus Torvalds struct hci_dev *hdev; 21411da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 21421da177e4SLinus Torvalds long timeo; 21431da177e4SLinus Torvalds __u8 *buf; 21441da177e4SLinus Torvalds 21451da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 21461da177e4SLinus Torvalds return -EFAULT; 21471da177e4SLinus Torvalds 21485a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 21495a08ecceSAndrei Emeltchenko if (!hdev) 21501da177e4SLinus Torvalds return -ENODEV; 21511da177e4SLinus Torvalds 21520736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 21530736cfa8SMarcel Holtmann err = -EBUSY; 21540736cfa8SMarcel Holtmann goto done; 21550736cfa8SMarcel Holtmann } 21560736cfa8SMarcel Holtmann 21575b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 21585b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 21595b69bef5SMarcel Holtmann goto done; 21605b69bef5SMarcel Holtmann } 21615b69bef5SMarcel Holtmann 216256f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 216356f87901SJohan Hedberg err = -EOPNOTSUPP; 216456f87901SJohan Hedberg goto done; 216556f87901SJohan Hedberg } 216656f87901SJohan Hedberg 216709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 21681da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 2169a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 21701f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 21711da177e4SLinus Torvalds do_inquiry = 1; 21721da177e4SLinus Torvalds } 217309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 21741da177e4SLinus Torvalds 217504837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 217670f23020SAndrei Emeltchenko 217770f23020SAndrei Emeltchenko if (do_inquiry) { 217801178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 217901178cd4SJohan Hedberg timeo); 218070f23020SAndrei Emeltchenko if (err < 0) 21811da177e4SLinus Torvalds goto done; 21823e13fa1eSAndre Guedes 21833e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 21843e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 21853e13fa1eSAndre Guedes */ 21863e13fa1eSAndre Guedes if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, 21873e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 21883e13fa1eSAndre Guedes return -EINTR; 218970f23020SAndrei Emeltchenko } 21901da177e4SLinus Torvalds 21918fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 21928fc9ced3SGustavo Padovan * 255 entries 21938fc9ced3SGustavo Padovan */ 21941da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 21951da177e4SLinus Torvalds 21961da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 21971da177e4SLinus Torvalds * copy it to the user space. 21981da177e4SLinus Torvalds */ 219970f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 220070f23020SAndrei Emeltchenko if (!buf) { 22011da177e4SLinus Torvalds err = -ENOMEM; 22021da177e4SLinus Torvalds goto done; 22031da177e4SLinus Torvalds } 22041da177e4SLinus Torvalds 220509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 22061da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 220709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 22081da177e4SLinus Torvalds 22091da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 22101da177e4SLinus Torvalds 22111da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 22121da177e4SLinus Torvalds ptr += sizeof(ir); 22131da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 22141da177e4SLinus Torvalds ir.num_rsp)) 22151da177e4SLinus Torvalds err = -EFAULT; 22161da177e4SLinus Torvalds } else 22171da177e4SLinus Torvalds err = -EFAULT; 22181da177e4SLinus Torvalds 22191da177e4SLinus Torvalds kfree(buf); 22201da177e4SLinus Torvalds 22211da177e4SLinus Torvalds done: 22221da177e4SLinus Torvalds hci_dev_put(hdev); 22231da177e4SLinus Torvalds return err; 22241da177e4SLinus Torvalds } 22251da177e4SLinus Torvalds 2226cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 22271da177e4SLinus Torvalds { 22281da177e4SLinus Torvalds int ret = 0; 22291da177e4SLinus Torvalds 22301da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 22311da177e4SLinus Torvalds 22321da177e4SLinus Torvalds hci_req_lock(hdev); 22331da177e4SLinus Torvalds 223494324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 223594324962SJohan Hovold ret = -ENODEV; 223694324962SJohan Hovold goto done; 223794324962SJohan Hovold } 223894324962SJohan Hovold 2239a5c8f270SMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 2240a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 2241a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 2242bf543036SJohan Hedberg */ 2243a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 2244611b30f7SMarcel Holtmann ret = -ERFKILL; 2245611b30f7SMarcel Holtmann goto done; 2246611b30f7SMarcel Holtmann } 2247611b30f7SMarcel Holtmann 2248a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 2249a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 2250a5c8f270SMarcel Holtmann * be able to determine if there is a public address 2251a5c8f270SMarcel Holtmann * or not. 2252a5c8f270SMarcel Holtmann * 2253c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 2254c6beca0eSMarcel Holtmann * if a public address or static random address is 2255c6beca0eSMarcel Holtmann * available. 2256c6beca0eSMarcel Holtmann * 2257a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 2258a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 2259a5c8f270SMarcel Holtmann */ 2260c6beca0eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 2261c6beca0eSMarcel Holtmann hdev->dev_type == HCI_BREDR && 2262a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2263a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 2264a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 2265a5c8f270SMarcel Holtmann goto done; 2266a5c8f270SMarcel Holtmann } 2267a5c8f270SMarcel Holtmann } 2268a5c8f270SMarcel Holtmann 22691da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 22701da177e4SLinus Torvalds ret = -EALREADY; 22711da177e4SLinus Torvalds goto done; 22721da177e4SLinus Torvalds } 22731da177e4SLinus Torvalds 22741da177e4SLinus Torvalds if (hdev->open(hdev)) { 22751da177e4SLinus Torvalds ret = -EIO; 22761da177e4SLinus Torvalds goto done; 22771da177e4SLinus Torvalds } 22781da177e4SLinus Torvalds 22791da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 22801da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 2281f41c70c4SMarcel Holtmann 2282f41c70c4SMarcel Holtmann if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags)) 2283f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 2284f41c70c4SMarcel Holtmann 2285f41c70c4SMarcel Holtmann if (!ret) { 2286f41c70c4SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 2287f41c70c4SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 2288f41c70c4SMarcel Holtmann 22890736cfa8SMarcel Holtmann if (!test_bit(HCI_RAW, &hdev->flags) && 22900736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 22912177bab5SJohan Hedberg ret = __hci_init(hdev); 22921da177e4SLinus Torvalds } 22931da177e4SLinus Torvalds 2294f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 2295f41c70c4SMarcel Holtmann 22961da177e4SLinus Torvalds if (!ret) { 22971da177e4SLinus Torvalds hci_dev_hold(hdev); 2298d6bfd59cSJohan Hedberg set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); 22991da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 23001da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 2301bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 23020736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 23031514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 230409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2305744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 230609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 230756e5cb86SJohan Hedberg } 23081da177e4SLinus Torvalds } else { 23091da177e4SLinus Torvalds /* Init failed, cleanup */ 23103eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2311c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 2312b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 23131da177e4SLinus Torvalds 23141da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 23151da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 23161da177e4SLinus Torvalds 23171da177e4SLinus Torvalds if (hdev->flush) 23181da177e4SLinus Torvalds hdev->flush(hdev); 23191da177e4SLinus Torvalds 23201da177e4SLinus Torvalds if (hdev->sent_cmd) { 23211da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 23221da177e4SLinus Torvalds hdev->sent_cmd = NULL; 23231da177e4SLinus Torvalds } 23241da177e4SLinus Torvalds 23251da177e4SLinus Torvalds hdev->close(hdev); 23261da177e4SLinus Torvalds hdev->flags = 0; 23271da177e4SLinus Torvalds } 23281da177e4SLinus Torvalds 23291da177e4SLinus Torvalds done: 23301da177e4SLinus Torvalds hci_req_unlock(hdev); 23311da177e4SLinus Torvalds return ret; 23321da177e4SLinus Torvalds } 23331da177e4SLinus Torvalds 2334cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 2335cbed0ca1SJohan Hedberg 2336cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 2337cbed0ca1SJohan Hedberg { 2338cbed0ca1SJohan Hedberg struct hci_dev *hdev; 2339cbed0ca1SJohan Hedberg int err; 2340cbed0ca1SJohan Hedberg 2341cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 2342cbed0ca1SJohan Hedberg if (!hdev) 2343cbed0ca1SJohan Hedberg return -ENODEV; 2344cbed0ca1SJohan Hedberg 2345e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 2346e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 2347e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 2348e1d08f40SJohan Hedberg * completed. 2349e1d08f40SJohan Hedberg */ 2350e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2351e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 2352e1d08f40SJohan Hedberg 2353a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 2354a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 2355a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 2356a5c8f270SMarcel Holtmann */ 2357e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 2358e1d08f40SJohan Hedberg 2359cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 2360cbed0ca1SJohan Hedberg 2361cbed0ca1SJohan Hedberg hci_dev_put(hdev); 2362cbed0ca1SJohan Hedberg 2363cbed0ca1SJohan Hedberg return err; 2364cbed0ca1SJohan Hedberg } 2365cbed0ca1SJohan Hedberg 23661da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 23671da177e4SLinus Torvalds { 23681da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 23691da177e4SLinus Torvalds 237078c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 237178c04c0bSVinicius Costa Gomes 23721da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 23731da177e4SLinus Torvalds hci_req_lock(hdev); 23741da177e4SLinus Torvalds 23751da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 2376b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 23771da177e4SLinus Torvalds hci_req_unlock(hdev); 23781da177e4SLinus Torvalds return 0; 23791da177e4SLinus Torvalds } 23801da177e4SLinus Torvalds 23813eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 23823eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2383b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 23841da177e4SLinus Torvalds 238516ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 2386e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 238716ab91abSJohan Hedberg hdev->discov_timeout = 0; 23885e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 2389310a3d48SMarcel Holtmann clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 239016ab91abSJohan Hedberg } 239116ab91abSJohan Hedberg 2392a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 23937d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 23947d78525dSJohan Hedberg 23957ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 23964518bb0fSJohan Hedberg 23974518bb0fSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 2398d6bfd59cSJohan Hedberg cancel_delayed_work_sync(&hdev->rpa_expired); 23997ba8b4beSAndre Guedes 240009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 24011f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 24021da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 24036046dc3eSAndre Guedes hci_pend_le_conns_clear(hdev); 240409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 24051da177e4SLinus Torvalds 24061da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 24071da177e4SLinus Torvalds 24081da177e4SLinus Torvalds if (hdev->flush) 24091da177e4SLinus Torvalds hdev->flush(hdev); 24101da177e4SLinus Torvalds 24111da177e4SLinus Torvalds /* Reset device */ 24121da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 24131da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 24148af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 24153a6afbd2SMarcel Holtmann !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 2416a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 24171da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 241801178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 24191da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 24201da177e4SLinus Torvalds } 24211da177e4SLinus Torvalds 2422c347b765SGustavo F. Padovan /* flush cmd work */ 2423c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 24241da177e4SLinus Torvalds 24251da177e4SLinus Torvalds /* Drop queues */ 24261da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 24271da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 24281da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 24291da177e4SLinus Torvalds 24301da177e4SLinus Torvalds /* Drop last sent command */ 24311da177e4SLinus Torvalds if (hdev->sent_cmd) { 2432b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 24331da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 24341da177e4SLinus Torvalds hdev->sent_cmd = NULL; 24351da177e4SLinus Torvalds } 24361da177e4SLinus Torvalds 2437b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 2438b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 2439b6ddb638SJohan Hedberg 24401da177e4SLinus Torvalds /* After this point our queues are empty 24411da177e4SLinus Torvalds * and no tasks are scheduled. */ 24421da177e4SLinus Torvalds hdev->close(hdev); 24431da177e4SLinus Torvalds 244435b973c9SJohan Hedberg /* Clear flags */ 244535b973c9SJohan Hedberg hdev->flags = 0; 244635b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 244735b973c9SJohan Hedberg 244893c311a0SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 244993c311a0SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 245009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2451744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 245209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 24538ee56540SMarcel Holtmann } 245493c311a0SMarcel Holtmann } 24555add6af8SJohan Hedberg 2456ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 2457536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 2458ced5c338SAndrei Emeltchenko 2459e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 246009b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 24617a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, BDADDR_ANY); 2462e59fda8dSJohan Hedberg 24631da177e4SLinus Torvalds hci_req_unlock(hdev); 24641da177e4SLinus Torvalds 24651da177e4SLinus Torvalds hci_dev_put(hdev); 24661da177e4SLinus Torvalds return 0; 24671da177e4SLinus Torvalds } 24681da177e4SLinus Torvalds 24691da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 24701da177e4SLinus Torvalds { 24711da177e4SLinus Torvalds struct hci_dev *hdev; 24721da177e4SLinus Torvalds int err; 24731da177e4SLinus Torvalds 247470f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 247570f23020SAndrei Emeltchenko if (!hdev) 24761da177e4SLinus Torvalds return -ENODEV; 24778ee56540SMarcel Holtmann 24780736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 24790736cfa8SMarcel Holtmann err = -EBUSY; 24800736cfa8SMarcel Holtmann goto done; 24810736cfa8SMarcel Holtmann } 24820736cfa8SMarcel Holtmann 24838ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 24848ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 24858ee56540SMarcel Holtmann 24861da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 24878ee56540SMarcel Holtmann 24880736cfa8SMarcel Holtmann done: 24891da177e4SLinus Torvalds hci_dev_put(hdev); 24901da177e4SLinus Torvalds return err; 24911da177e4SLinus Torvalds } 24921da177e4SLinus Torvalds 24931da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 24941da177e4SLinus Torvalds { 24951da177e4SLinus Torvalds struct hci_dev *hdev; 24961da177e4SLinus Torvalds int ret = 0; 24971da177e4SLinus Torvalds 249870f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 249970f23020SAndrei Emeltchenko if (!hdev) 25001da177e4SLinus Torvalds return -ENODEV; 25011da177e4SLinus Torvalds 25021da177e4SLinus Torvalds hci_req_lock(hdev); 25031da177e4SLinus Torvalds 2504808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 2505808a049eSMarcel Holtmann ret = -ENETDOWN; 25061da177e4SLinus Torvalds goto done; 2507808a049eSMarcel Holtmann } 25081da177e4SLinus Torvalds 25090736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 25100736cfa8SMarcel Holtmann ret = -EBUSY; 25110736cfa8SMarcel Holtmann goto done; 25120736cfa8SMarcel Holtmann } 25130736cfa8SMarcel Holtmann 25141da177e4SLinus Torvalds /* Drop queues */ 25151da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 25161da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 25171da177e4SLinus Torvalds 251809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 25191f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 25201da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 252109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 25221da177e4SLinus Torvalds 25231da177e4SLinus Torvalds if (hdev->flush) 25241da177e4SLinus Torvalds hdev->flush(hdev); 25251da177e4SLinus Torvalds 25261da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 25276ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 25281da177e4SLinus Torvalds 25291da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 253001178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 25311da177e4SLinus Torvalds 25321da177e4SLinus Torvalds done: 25331da177e4SLinus Torvalds hci_req_unlock(hdev); 25341da177e4SLinus Torvalds hci_dev_put(hdev); 25351da177e4SLinus Torvalds return ret; 25361da177e4SLinus Torvalds } 25371da177e4SLinus Torvalds 25381da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 25391da177e4SLinus Torvalds { 25401da177e4SLinus Torvalds struct hci_dev *hdev; 25411da177e4SLinus Torvalds int ret = 0; 25421da177e4SLinus Torvalds 254370f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 254470f23020SAndrei Emeltchenko if (!hdev) 25451da177e4SLinus Torvalds return -ENODEV; 25461da177e4SLinus Torvalds 25470736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 25480736cfa8SMarcel Holtmann ret = -EBUSY; 25490736cfa8SMarcel Holtmann goto done; 25500736cfa8SMarcel Holtmann } 25510736cfa8SMarcel Holtmann 25521da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 25531da177e4SLinus Torvalds 25540736cfa8SMarcel Holtmann done: 25551da177e4SLinus Torvalds hci_dev_put(hdev); 25561da177e4SLinus Torvalds return ret; 25571da177e4SLinus Torvalds } 25581da177e4SLinus Torvalds 25591da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 25601da177e4SLinus Torvalds { 25611da177e4SLinus Torvalds struct hci_dev *hdev; 25621da177e4SLinus Torvalds struct hci_dev_req dr; 25631da177e4SLinus Torvalds int err = 0; 25641da177e4SLinus Torvalds 25651da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 25661da177e4SLinus Torvalds return -EFAULT; 25671da177e4SLinus Torvalds 256870f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 256970f23020SAndrei Emeltchenko if (!hdev) 25701da177e4SLinus Torvalds return -ENODEV; 25711da177e4SLinus Torvalds 25720736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 25730736cfa8SMarcel Holtmann err = -EBUSY; 25740736cfa8SMarcel Holtmann goto done; 25750736cfa8SMarcel Holtmann } 25760736cfa8SMarcel Holtmann 25775b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 25785b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 25795b69bef5SMarcel Holtmann goto done; 25805b69bef5SMarcel Holtmann } 25815b69bef5SMarcel Holtmann 258256f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 258356f87901SJohan Hedberg err = -EOPNOTSUPP; 258456f87901SJohan Hedberg goto done; 258556f87901SJohan Hedberg } 258656f87901SJohan Hedberg 25871da177e4SLinus Torvalds switch (cmd) { 25881da177e4SLinus Torvalds case HCISETAUTH: 258901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 25905f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 25911da177e4SLinus Torvalds break; 25921da177e4SLinus Torvalds 25931da177e4SLinus Torvalds case HCISETENCRYPT: 25941da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 25951da177e4SLinus Torvalds err = -EOPNOTSUPP; 25961da177e4SLinus Torvalds break; 25971da177e4SLinus Torvalds } 25981da177e4SLinus Torvalds 25991da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 26001da177e4SLinus Torvalds /* Auth must be enabled first */ 260101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 26025f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26031da177e4SLinus Torvalds if (err) 26041da177e4SLinus Torvalds break; 26051da177e4SLinus Torvalds } 26061da177e4SLinus Torvalds 260701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 26085f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26091da177e4SLinus Torvalds break; 26101da177e4SLinus Torvalds 26111da177e4SLinus Torvalds case HCISETSCAN: 261201178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 26135f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26141da177e4SLinus Torvalds break; 26151da177e4SLinus Torvalds 26161da177e4SLinus Torvalds case HCISETLINKPOL: 261701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 26185f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 26191da177e4SLinus Torvalds break; 26201da177e4SLinus Torvalds 26211da177e4SLinus Torvalds case HCISETLINKMODE: 2622e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2623e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2624e4e8e37cSMarcel Holtmann break; 2625e4e8e37cSMarcel Holtmann 2626e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2627e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 26281da177e4SLinus Torvalds break; 26291da177e4SLinus Torvalds 26301da177e4SLinus Torvalds case HCISETACLMTU: 26311da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 26321da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 26331da177e4SLinus Torvalds break; 26341da177e4SLinus Torvalds 26351da177e4SLinus Torvalds case HCISETSCOMTU: 26361da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 26371da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 26381da177e4SLinus Torvalds break; 26391da177e4SLinus Torvalds 26401da177e4SLinus Torvalds default: 26411da177e4SLinus Torvalds err = -EINVAL; 26421da177e4SLinus Torvalds break; 26431da177e4SLinus Torvalds } 2644e4e8e37cSMarcel Holtmann 26450736cfa8SMarcel Holtmann done: 26461da177e4SLinus Torvalds hci_dev_put(hdev); 26471da177e4SLinus Torvalds return err; 26481da177e4SLinus Torvalds } 26491da177e4SLinus Torvalds 26501da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 26511da177e4SLinus Torvalds { 26528035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 26531da177e4SLinus Torvalds struct hci_dev_list_req *dl; 26541da177e4SLinus Torvalds struct hci_dev_req *dr; 26551da177e4SLinus Torvalds int n = 0, size, err; 26561da177e4SLinus Torvalds __u16 dev_num; 26571da177e4SLinus Torvalds 26581da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 26591da177e4SLinus Torvalds return -EFAULT; 26601da177e4SLinus Torvalds 26611da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 26621da177e4SLinus Torvalds return -EINVAL; 26631da177e4SLinus Torvalds 26641da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 26651da177e4SLinus Torvalds 266670f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 266770f23020SAndrei Emeltchenko if (!dl) 26681da177e4SLinus Torvalds return -ENOMEM; 26691da177e4SLinus Torvalds 26701da177e4SLinus Torvalds dr = dl->dev_req; 26711da177e4SLinus Torvalds 2672f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 26738035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 2674a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2675e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 2676c542a06cSJohan Hedberg 2677a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2678a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2679c542a06cSJohan Hedberg 26801da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 26811da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 2682c542a06cSJohan Hedberg 26831da177e4SLinus Torvalds if (++n >= dev_num) 26841da177e4SLinus Torvalds break; 26851da177e4SLinus Torvalds } 2686f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 26871da177e4SLinus Torvalds 26881da177e4SLinus Torvalds dl->dev_num = n; 26891da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 26901da177e4SLinus Torvalds 26911da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 26921da177e4SLinus Torvalds kfree(dl); 26931da177e4SLinus Torvalds 26941da177e4SLinus Torvalds return err ? -EFAULT : 0; 26951da177e4SLinus Torvalds } 26961da177e4SLinus Torvalds 26971da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 26981da177e4SLinus Torvalds { 26991da177e4SLinus Torvalds struct hci_dev *hdev; 27001da177e4SLinus Torvalds struct hci_dev_info di; 27011da177e4SLinus Torvalds int err = 0; 27021da177e4SLinus Torvalds 27031da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 27041da177e4SLinus Torvalds return -EFAULT; 27051da177e4SLinus Torvalds 270670f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 270770f23020SAndrei Emeltchenko if (!hdev) 27081da177e4SLinus Torvalds return -ENODEV; 27091da177e4SLinus Torvalds 2710a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 27113243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 2712ab81cbf9SJohan Hedberg 2713a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2714a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2715c542a06cSJohan Hedberg 27161da177e4SLinus Torvalds strcpy(di.name, hdev->name); 27171da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 271860f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 27191da177e4SLinus Torvalds di.flags = hdev->flags; 27201da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2721572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 27221da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 27231da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 27241da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 27251da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2726572c7f84SJohan Hedberg } else { 2727572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2728572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2729572c7f84SJohan Hedberg di.sco_mtu = 0; 2730572c7f84SJohan Hedberg di.sco_pkts = 0; 2731572c7f84SJohan Hedberg } 27321da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 27331da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 27341da177e4SLinus Torvalds 27351da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 27361da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 27371da177e4SLinus Torvalds 27381da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 27391da177e4SLinus Torvalds err = -EFAULT; 27401da177e4SLinus Torvalds 27411da177e4SLinus Torvalds hci_dev_put(hdev); 27421da177e4SLinus Torvalds 27431da177e4SLinus Torvalds return err; 27441da177e4SLinus Torvalds } 27451da177e4SLinus Torvalds 27461da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 27471da177e4SLinus Torvalds 2748611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2749611b30f7SMarcel Holtmann { 2750611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2751611b30f7SMarcel Holtmann 2752611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2753611b30f7SMarcel Holtmann 27540736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 27550736cfa8SMarcel Holtmann return -EBUSY; 27560736cfa8SMarcel Holtmann 27575e130367SJohan Hedberg if (blocked) { 27585e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 2759bf543036SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 2760611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 27615e130367SJohan Hedberg } else { 27625e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 27635e130367SJohan Hedberg } 2764611b30f7SMarcel Holtmann 2765611b30f7SMarcel Holtmann return 0; 2766611b30f7SMarcel Holtmann } 2767611b30f7SMarcel Holtmann 2768611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2769611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2770611b30f7SMarcel Holtmann }; 2771611b30f7SMarcel Holtmann 2772ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2773ab81cbf9SJohan Hedberg { 2774ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 277596570ffcSJohan Hedberg int err; 2776ab81cbf9SJohan Hedberg 2777ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2778ab81cbf9SJohan Hedberg 2779cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 278096570ffcSJohan Hedberg if (err < 0) { 278196570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 2782ab81cbf9SJohan Hedberg return; 278396570ffcSJohan Hedberg } 2784ab81cbf9SJohan Hedberg 2785a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2786a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2787a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2788a5c8f270SMarcel Holtmann */ 2789a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 2790a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 2791a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2792a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2793bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2794bf543036SJohan Hedberg hci_dev_do_close(hdev); 2795bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 279619202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 279719202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2798bf543036SJohan Hedberg } 2799ab81cbf9SJohan Hedberg 2800a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 2801744cf19eSJohan Hedberg mgmt_index_added(hdev); 2802ab81cbf9SJohan Hedberg } 2803ab81cbf9SJohan Hedberg 2804ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2805ab81cbf9SJohan Hedberg { 28063243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 28073243553fSJohan Hedberg power_off.work); 2808ab81cbf9SJohan Hedberg 2809ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2810ab81cbf9SJohan Hedberg 28118ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2812ab81cbf9SJohan Hedberg } 2813ab81cbf9SJohan Hedberg 281416ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 281516ab91abSJohan Hedberg { 281616ab91abSJohan Hedberg struct hci_dev *hdev; 281716ab91abSJohan Hedberg 281816ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 281916ab91abSJohan Hedberg 282016ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 282116ab91abSJohan Hedberg 2822d1967ff8SMarcel Holtmann mgmt_discoverable_timeout(hdev); 282316ab91abSJohan Hedberg } 282416ab91abSJohan Hedberg 282535f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 28262aeb9a1aSJohan Hedberg { 28274821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 28282aeb9a1aSJohan Hedberg 28294821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 28304821002cSJohan Hedberg list_del(&uuid->list); 28312aeb9a1aSJohan Hedberg kfree(uuid); 28322aeb9a1aSJohan Hedberg } 28332aeb9a1aSJohan Hedberg } 28342aeb9a1aSJohan Hedberg 283535f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 283655ed8ca1SJohan Hedberg { 283755ed8ca1SJohan Hedberg struct list_head *p, *n; 283855ed8ca1SJohan Hedberg 283955ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 284055ed8ca1SJohan Hedberg struct link_key *key; 284155ed8ca1SJohan Hedberg 284255ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 284355ed8ca1SJohan Hedberg 284455ed8ca1SJohan Hedberg list_del(p); 284555ed8ca1SJohan Hedberg kfree(key); 284655ed8ca1SJohan Hedberg } 284755ed8ca1SJohan Hedberg } 284855ed8ca1SJohan Hedberg 284935f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2850b899efafSVinicius Costa Gomes { 2851b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2852b899efafSVinicius Costa Gomes 2853b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2854b899efafSVinicius Costa Gomes list_del(&k->list); 2855b899efafSVinicius Costa Gomes kfree(k); 2856b899efafSVinicius Costa Gomes } 2857b899efafSVinicius Costa Gomes } 2858b899efafSVinicius Costa Gomes 2859970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2860970c4e46SJohan Hedberg { 2861970c4e46SJohan Hedberg struct smp_irk *k, *tmp; 2862970c4e46SJohan Hedberg 2863970c4e46SJohan Hedberg list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { 2864970c4e46SJohan Hedberg list_del(&k->list); 2865970c4e46SJohan Hedberg kfree(k); 2866970c4e46SJohan Hedberg } 2867970c4e46SJohan Hedberg } 2868970c4e46SJohan Hedberg 286955ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 287055ed8ca1SJohan Hedberg { 287155ed8ca1SJohan Hedberg struct link_key *k; 287255ed8ca1SJohan Hedberg 28738035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 287455ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 287555ed8ca1SJohan Hedberg return k; 287655ed8ca1SJohan Hedberg 287755ed8ca1SJohan Hedberg return NULL; 287855ed8ca1SJohan Hedberg } 287955ed8ca1SJohan Hedberg 2880745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2881d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2882d25e28abSJohan Hedberg { 2883d25e28abSJohan Hedberg /* Legacy key */ 2884d25e28abSJohan Hedberg if (key_type < 0x03) 2885745c0ce3SVishal Agarwal return true; 2886d25e28abSJohan Hedberg 2887d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2888d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2889745c0ce3SVishal Agarwal return false; 2890d25e28abSJohan Hedberg 2891d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2892d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2893745c0ce3SVishal Agarwal return false; 2894d25e28abSJohan Hedberg 2895d25e28abSJohan Hedberg /* Security mode 3 case */ 2896d25e28abSJohan Hedberg if (!conn) 2897745c0ce3SVishal Agarwal return true; 2898d25e28abSJohan Hedberg 2899d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2900d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2901745c0ce3SVishal Agarwal return true; 2902d25e28abSJohan Hedberg 2903d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2904d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2905745c0ce3SVishal Agarwal return true; 2906d25e28abSJohan Hedberg 2907d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2908d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2909745c0ce3SVishal Agarwal return true; 2910d25e28abSJohan Hedberg 2911d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2912d25e28abSJohan Hedberg * persistently */ 2913745c0ce3SVishal Agarwal return false; 2914d25e28abSJohan Hedberg } 2915d25e28abSJohan Hedberg 291698a0b845SJohan Hedberg static bool ltk_type_master(u8 type) 291798a0b845SJohan Hedberg { 291898a0b845SJohan Hedberg if (type == HCI_SMP_STK || type == HCI_SMP_LTK) 291998a0b845SJohan Hedberg return true; 292098a0b845SJohan Hedberg 292198a0b845SJohan Hedberg return false; 292298a0b845SJohan Hedberg } 292398a0b845SJohan Hedberg 292498a0b845SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8], 292598a0b845SJohan Hedberg bool master) 292675d262c2SVinicius Costa Gomes { 2927c9839a11SVinicius Costa Gomes struct smp_ltk *k; 292875d262c2SVinicius Costa Gomes 2929c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 2930c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 2931c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 293275d262c2SVinicius Costa Gomes continue; 293375d262c2SVinicius Costa Gomes 293498a0b845SJohan Hedberg if (ltk_type_master(k->type) != master) 293598a0b845SJohan Hedberg continue; 293698a0b845SJohan Hedberg 293775d262c2SVinicius Costa Gomes return k; 293875d262c2SVinicius Costa Gomes } 293975d262c2SVinicius Costa Gomes 294075d262c2SVinicius Costa Gomes return NULL; 294175d262c2SVinicius Costa Gomes } 294275d262c2SVinicius Costa Gomes 2943c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 294498a0b845SJohan Hedberg u8 addr_type, bool master) 294575d262c2SVinicius Costa Gomes { 2946c9839a11SVinicius Costa Gomes struct smp_ltk *k; 294775d262c2SVinicius Costa Gomes 2948c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 2949c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 295098a0b845SJohan Hedberg bacmp(bdaddr, &k->bdaddr) == 0 && 295198a0b845SJohan Hedberg ltk_type_master(k->type) == master) 295275d262c2SVinicius Costa Gomes return k; 295375d262c2SVinicius Costa Gomes 295475d262c2SVinicius Costa Gomes return NULL; 295575d262c2SVinicius Costa Gomes } 295675d262c2SVinicius Costa Gomes 2957970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 2958970c4e46SJohan Hedberg { 2959970c4e46SJohan Hedberg struct smp_irk *irk; 2960970c4e46SJohan Hedberg 2961970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2962970c4e46SJohan Hedberg if (!bacmp(&irk->rpa, rpa)) 2963970c4e46SJohan Hedberg return irk; 2964970c4e46SJohan Hedberg } 2965970c4e46SJohan Hedberg 2966970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2967970c4e46SJohan Hedberg if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) { 2968970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2969970c4e46SJohan Hedberg return irk; 2970970c4e46SJohan Hedberg } 2971970c4e46SJohan Hedberg } 2972970c4e46SJohan Hedberg 2973970c4e46SJohan Hedberg return NULL; 2974970c4e46SJohan Hedberg } 2975970c4e46SJohan Hedberg 2976970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2977970c4e46SJohan Hedberg u8 addr_type) 2978970c4e46SJohan Hedberg { 2979970c4e46SJohan Hedberg struct smp_irk *irk; 2980970c4e46SJohan Hedberg 29816cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 29826cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 29836cfc9988SJohan Hedberg return NULL; 29846cfc9988SJohan Hedberg 2985970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2986970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 2987970c4e46SJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) 2988970c4e46SJohan Hedberg return irk; 2989970c4e46SJohan Hedberg } 2990970c4e46SJohan Hedberg 2991970c4e46SJohan Hedberg return NULL; 2992970c4e46SJohan Hedberg } 2993970c4e46SJohan Hedberg 2994d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 2995d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 299655ed8ca1SJohan Hedberg { 299755ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2998745c0ce3SVishal Agarwal u8 old_key_type; 2999745c0ce3SVishal Agarwal bool persistent; 300055ed8ca1SJohan Hedberg 300155ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 300255ed8ca1SJohan Hedberg if (old_key) { 300355ed8ca1SJohan Hedberg old_key_type = old_key->type; 300455ed8ca1SJohan Hedberg key = old_key; 300555ed8ca1SJohan Hedberg } else { 300612adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 30070a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 300855ed8ca1SJohan Hedberg if (!key) 300955ed8ca1SJohan Hedberg return -ENOMEM; 301055ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 301155ed8ca1SJohan Hedberg } 301255ed8ca1SJohan Hedberg 30136ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 301455ed8ca1SJohan Hedberg 3015d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 3016d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 3017d25e28abSJohan Hedberg * previous key */ 3018d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 3019a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 3020d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 3021655fe6ecSJohan Hedberg if (conn) 3022655fe6ecSJohan Hedberg conn->key_type = type; 3023655fe6ecSJohan Hedberg } 3024d25e28abSJohan Hedberg 302555ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 30269b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 302755ed8ca1SJohan Hedberg key->pin_len = pin_len; 302855ed8ca1SJohan Hedberg 3029b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 303055ed8ca1SJohan Hedberg key->type = old_key_type; 30314748fed2SJohan Hedberg else 30324748fed2SJohan Hedberg key->type = type; 30334748fed2SJohan Hedberg 30344df378a1SJohan Hedberg if (!new_key) 30354df378a1SJohan Hedberg return 0; 30364df378a1SJohan Hedberg 30374df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 30384df378a1SJohan Hedberg 3039744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 30404df378a1SJohan Hedberg 30416ec5bcadSVishal Agarwal if (conn) 30426ec5bcadSVishal Agarwal conn->flush_key = !persistent; 304355ed8ca1SJohan Hedberg 304455ed8ca1SJohan Hedberg return 0; 304555ed8ca1SJohan Hedberg } 304655ed8ca1SJohan Hedberg 3047ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 304835d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 304935d70271SJohan Hedberg u8 tk[16], u8 enc_size, __le16 ediv, u8 rand[8]) 305075d262c2SVinicius Costa Gomes { 3051c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 305298a0b845SJohan Hedberg bool master = ltk_type_master(type); 305375d262c2SVinicius Costa Gomes 305498a0b845SJohan Hedberg old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master); 3055c9839a11SVinicius Costa Gomes if (old_key) 305675d262c2SVinicius Costa Gomes key = old_key; 3057c9839a11SVinicius Costa Gomes else { 30580a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 305975d262c2SVinicius Costa Gomes if (!key) 3060ca9142b8SJohan Hedberg return NULL; 3061c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 306275d262c2SVinicius Costa Gomes } 306375d262c2SVinicius Costa Gomes 306475d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 3065c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 3066c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 3067c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 3068c9839a11SVinicius Costa Gomes key->ediv = ediv; 3069c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 3070c9839a11SVinicius Costa Gomes key->type = type; 3071c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 307275d262c2SVinicius Costa Gomes 3073ca9142b8SJohan Hedberg return key; 307475d262c2SVinicius Costa Gomes } 307575d262c2SVinicius Costa Gomes 3076ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 3077ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 3078970c4e46SJohan Hedberg { 3079970c4e46SJohan Hedberg struct smp_irk *irk; 3080970c4e46SJohan Hedberg 3081970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 3082970c4e46SJohan Hedberg if (!irk) { 3083970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 3084970c4e46SJohan Hedberg if (!irk) 3085ca9142b8SJohan Hedberg return NULL; 3086970c4e46SJohan Hedberg 3087970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 3088970c4e46SJohan Hedberg irk->addr_type = addr_type; 3089970c4e46SJohan Hedberg 3090970c4e46SJohan Hedberg list_add(&irk->list, &hdev->identity_resolving_keys); 3091970c4e46SJohan Hedberg } 3092970c4e46SJohan Hedberg 3093970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 3094970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 3095970c4e46SJohan Hedberg 3096ca9142b8SJohan Hedberg return irk; 3097970c4e46SJohan Hedberg } 3098970c4e46SJohan Hedberg 309955ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 310055ed8ca1SJohan Hedberg { 310155ed8ca1SJohan Hedberg struct link_key *key; 310255ed8ca1SJohan Hedberg 310355ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 310455ed8ca1SJohan Hedberg if (!key) 310555ed8ca1SJohan Hedberg return -ENOENT; 310655ed8ca1SJohan Hedberg 31076ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 310855ed8ca1SJohan Hedberg 310955ed8ca1SJohan Hedberg list_del(&key->list); 311055ed8ca1SJohan Hedberg kfree(key); 311155ed8ca1SJohan Hedberg 311255ed8ca1SJohan Hedberg return 0; 311355ed8ca1SJohan Hedberg } 311455ed8ca1SJohan Hedberg 3115e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 3116b899efafSVinicius Costa Gomes { 3117b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 3118c51ffa0bSJohan Hedberg int removed = 0; 3119b899efafSVinicius Costa Gomes 3120b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 3121e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 3122b899efafSVinicius Costa Gomes continue; 3123b899efafSVinicius Costa Gomes 31246ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 3125b899efafSVinicius Costa Gomes 3126b899efafSVinicius Costa Gomes list_del(&k->list); 3127b899efafSVinicius Costa Gomes kfree(k); 3128c51ffa0bSJohan Hedberg removed++; 3129b899efafSVinicius Costa Gomes } 3130b899efafSVinicius Costa Gomes 3131c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 3132b899efafSVinicius Costa Gomes } 3133b899efafSVinicius Costa Gomes 3134a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 3135a7ec7338SJohan Hedberg { 3136a7ec7338SJohan Hedberg struct smp_irk *k, *tmp; 3137a7ec7338SJohan Hedberg 3138668b7b19SJohan Hedberg list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { 3139a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 3140a7ec7338SJohan Hedberg continue; 3141a7ec7338SJohan Hedberg 3142a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 3143a7ec7338SJohan Hedberg 3144a7ec7338SJohan Hedberg list_del(&k->list); 3145a7ec7338SJohan Hedberg kfree(k); 3146a7ec7338SJohan Hedberg } 3147a7ec7338SJohan Hedberg } 3148a7ec7338SJohan Hedberg 31496bd32326SVille Tervo /* HCI command timer function */ 3150bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg) 31516bd32326SVille Tervo { 31526bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 31536bd32326SVille Tervo 3154bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 3155bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 3156bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 3157bda4f23aSAndrei Emeltchenko 3158bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 3159bda4f23aSAndrei Emeltchenko } else { 31606bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 3161bda4f23aSAndrei Emeltchenko } 3162bda4f23aSAndrei Emeltchenko 31636bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 3164c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 31656bd32326SVille Tervo } 31666bd32326SVille Tervo 31672763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 31682763eda6SSzymon Janc bdaddr_t *bdaddr) 31692763eda6SSzymon Janc { 31702763eda6SSzymon Janc struct oob_data *data; 31712763eda6SSzymon Janc 31722763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 31732763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 31742763eda6SSzymon Janc return data; 31752763eda6SSzymon Janc 31762763eda6SSzymon Janc return NULL; 31772763eda6SSzymon Janc } 31782763eda6SSzymon Janc 31792763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 31802763eda6SSzymon Janc { 31812763eda6SSzymon Janc struct oob_data *data; 31822763eda6SSzymon Janc 31832763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 31842763eda6SSzymon Janc if (!data) 31852763eda6SSzymon Janc return -ENOENT; 31862763eda6SSzymon Janc 31876ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 31882763eda6SSzymon Janc 31892763eda6SSzymon Janc list_del(&data->list); 31902763eda6SSzymon Janc kfree(data); 31912763eda6SSzymon Janc 31922763eda6SSzymon Janc return 0; 31932763eda6SSzymon Janc } 31942763eda6SSzymon Janc 319535f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 31962763eda6SSzymon Janc { 31972763eda6SSzymon Janc struct oob_data *data, *n; 31982763eda6SSzymon Janc 31992763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 32002763eda6SSzymon Janc list_del(&data->list); 32012763eda6SSzymon Janc kfree(data); 32022763eda6SSzymon Janc } 32032763eda6SSzymon Janc } 32042763eda6SSzymon Janc 32050798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 32060798872eSMarcel Holtmann u8 *hash, u8 *randomizer) 32072763eda6SSzymon Janc { 32082763eda6SSzymon Janc struct oob_data *data; 32092763eda6SSzymon Janc 32102763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 32112763eda6SSzymon Janc if (!data) { 32120a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 32132763eda6SSzymon Janc if (!data) 32142763eda6SSzymon Janc return -ENOMEM; 32152763eda6SSzymon Janc 32162763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 32172763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 32182763eda6SSzymon Janc } 32192763eda6SSzymon Janc 3220519ca9d0SMarcel Holtmann memcpy(data->hash192, hash, sizeof(data->hash192)); 3221519ca9d0SMarcel Holtmann memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192)); 32222763eda6SSzymon Janc 32230798872eSMarcel Holtmann memset(data->hash256, 0, sizeof(data->hash256)); 32240798872eSMarcel Holtmann memset(data->randomizer256, 0, sizeof(data->randomizer256)); 32250798872eSMarcel Holtmann 32260798872eSMarcel Holtmann BT_DBG("%s for %pMR", hdev->name, bdaddr); 32270798872eSMarcel Holtmann 32280798872eSMarcel Holtmann return 0; 32290798872eSMarcel Holtmann } 32300798872eSMarcel Holtmann 32310798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 32320798872eSMarcel Holtmann u8 *hash192, u8 *randomizer192, 32330798872eSMarcel Holtmann u8 *hash256, u8 *randomizer256) 32340798872eSMarcel Holtmann { 32350798872eSMarcel Holtmann struct oob_data *data; 32360798872eSMarcel Holtmann 32370798872eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, bdaddr); 32380798872eSMarcel Holtmann if (!data) { 32390a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 32400798872eSMarcel Holtmann if (!data) 32410798872eSMarcel Holtmann return -ENOMEM; 32420798872eSMarcel Holtmann 32430798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 32440798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 32450798872eSMarcel Holtmann } 32460798872eSMarcel Holtmann 32470798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 32480798872eSMarcel Holtmann memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192)); 32490798872eSMarcel Holtmann 32500798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 32510798872eSMarcel Holtmann memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256)); 32520798872eSMarcel Holtmann 32536ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 32542763eda6SSzymon Janc 32552763eda6SSzymon Janc return 0; 32562763eda6SSzymon Janc } 32572763eda6SSzymon Janc 3258b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 3259b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 3260b2a66aadSAntti Julku { 3261b2a66aadSAntti Julku struct bdaddr_list *b; 3262b2a66aadSAntti Julku 3263b9ee0a78SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) { 3264b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3265b2a66aadSAntti Julku return b; 3266b9ee0a78SMarcel Holtmann } 3267b2a66aadSAntti Julku 3268b2a66aadSAntti Julku return NULL; 3269b2a66aadSAntti Julku } 3270b2a66aadSAntti Julku 3271c9507490SMarcel Holtmann static void hci_blacklist_clear(struct hci_dev *hdev) 3272b2a66aadSAntti Julku { 3273b2a66aadSAntti Julku struct list_head *p, *n; 3274b2a66aadSAntti Julku 3275b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 3276b9ee0a78SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 3277b2a66aadSAntti Julku 3278b2a66aadSAntti Julku list_del(p); 3279b2a66aadSAntti Julku kfree(b); 3280b2a66aadSAntti Julku } 3281b2a66aadSAntti Julku } 3282b2a66aadSAntti Julku 328388c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3284b2a66aadSAntti Julku { 3285b2a66aadSAntti Julku struct bdaddr_list *entry; 3286b2a66aadSAntti Julku 3287b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3288b2a66aadSAntti Julku return -EBADF; 3289b2a66aadSAntti Julku 3290b9ee0a78SMarcel Holtmann if (hci_blacklist_lookup(hdev, bdaddr, type)) 32915e762444SAntti Julku return -EEXIST; 3292b2a66aadSAntti Julku 3293b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 32945e762444SAntti Julku if (!entry) 32955e762444SAntti Julku return -ENOMEM; 3296b2a66aadSAntti Julku 3297b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 3298b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 3299b2a66aadSAntti Julku 3300b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 3301b2a66aadSAntti Julku 330288c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 3303b2a66aadSAntti Julku } 3304b2a66aadSAntti Julku 330588c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3306b2a66aadSAntti Julku { 3307b2a66aadSAntti Julku struct bdaddr_list *entry; 3308b2a66aadSAntti Julku 330935f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 331035f7498aSJohan Hedberg hci_blacklist_clear(hdev); 331135f7498aSJohan Hedberg return 0; 331235f7498aSJohan Hedberg } 3313b2a66aadSAntti Julku 3314b9ee0a78SMarcel Holtmann entry = hci_blacklist_lookup(hdev, bdaddr, type); 33151ec918ceSSzymon Janc if (!entry) 33165e762444SAntti Julku return -ENOENT; 3317b2a66aadSAntti Julku 3318b2a66aadSAntti Julku list_del(&entry->list); 3319b2a66aadSAntti Julku kfree(entry); 3320b2a66aadSAntti Julku 332188c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 3322b2a66aadSAntti Julku } 3323b2a66aadSAntti Julku 3324*d2ab0ac1SMarcel Holtmann struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev, 3325*d2ab0ac1SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 3326*d2ab0ac1SMarcel Holtmann { 3327*d2ab0ac1SMarcel Holtmann struct bdaddr_list *b; 3328*d2ab0ac1SMarcel Holtmann 3329*d2ab0ac1SMarcel Holtmann list_for_each_entry(b, &hdev->le_white_list, list) { 3330*d2ab0ac1SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3331*d2ab0ac1SMarcel Holtmann return b; 3332*d2ab0ac1SMarcel Holtmann } 3333*d2ab0ac1SMarcel Holtmann 3334*d2ab0ac1SMarcel Holtmann return NULL; 3335*d2ab0ac1SMarcel Holtmann } 3336*d2ab0ac1SMarcel Holtmann 3337*d2ab0ac1SMarcel Holtmann void hci_white_list_clear(struct hci_dev *hdev) 3338*d2ab0ac1SMarcel Holtmann { 3339*d2ab0ac1SMarcel Holtmann struct list_head *p, *n; 3340*d2ab0ac1SMarcel Holtmann 3341*d2ab0ac1SMarcel Holtmann list_for_each_safe(p, n, &hdev->le_white_list) { 3342*d2ab0ac1SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 3343*d2ab0ac1SMarcel Holtmann 3344*d2ab0ac1SMarcel Holtmann list_del(p); 3345*d2ab0ac1SMarcel Holtmann kfree(b); 3346*d2ab0ac1SMarcel Holtmann } 3347*d2ab0ac1SMarcel Holtmann } 3348*d2ab0ac1SMarcel Holtmann 3349*d2ab0ac1SMarcel Holtmann int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3350*d2ab0ac1SMarcel Holtmann { 3351*d2ab0ac1SMarcel Holtmann struct bdaddr_list *entry; 3352*d2ab0ac1SMarcel Holtmann 3353*d2ab0ac1SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3354*d2ab0ac1SMarcel Holtmann return -EBADF; 3355*d2ab0ac1SMarcel Holtmann 3356*d2ab0ac1SMarcel Holtmann entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 3357*d2ab0ac1SMarcel Holtmann if (!entry) 3358*d2ab0ac1SMarcel Holtmann return -ENOMEM; 3359*d2ab0ac1SMarcel Holtmann 3360*d2ab0ac1SMarcel Holtmann bacpy(&entry->bdaddr, bdaddr); 3361*d2ab0ac1SMarcel Holtmann entry->bdaddr_type = type; 3362*d2ab0ac1SMarcel Holtmann 3363*d2ab0ac1SMarcel Holtmann list_add(&entry->list, &hdev->le_white_list); 3364*d2ab0ac1SMarcel Holtmann 3365*d2ab0ac1SMarcel Holtmann return 0; 3366*d2ab0ac1SMarcel Holtmann } 3367*d2ab0ac1SMarcel Holtmann 3368*d2ab0ac1SMarcel Holtmann int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3369*d2ab0ac1SMarcel Holtmann { 3370*d2ab0ac1SMarcel Holtmann struct bdaddr_list *entry; 3371*d2ab0ac1SMarcel Holtmann 3372*d2ab0ac1SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3373*d2ab0ac1SMarcel Holtmann return -EBADF; 3374*d2ab0ac1SMarcel Holtmann 3375*d2ab0ac1SMarcel Holtmann entry = hci_white_list_lookup(hdev, bdaddr, type); 3376*d2ab0ac1SMarcel Holtmann if (!entry) 3377*d2ab0ac1SMarcel Holtmann return -ENOENT; 3378*d2ab0ac1SMarcel Holtmann 3379*d2ab0ac1SMarcel Holtmann list_del(&entry->list); 3380*d2ab0ac1SMarcel Holtmann kfree(entry); 3381*d2ab0ac1SMarcel Holtmann 3382*d2ab0ac1SMarcel Holtmann return 0; 3383*d2ab0ac1SMarcel Holtmann } 3384*d2ab0ac1SMarcel Holtmann 338515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 338615819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 338715819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 338815819a70SAndre Guedes { 338915819a70SAndre Guedes struct hci_conn_params *params; 339015819a70SAndre Guedes 339115819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 339215819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 339315819a70SAndre Guedes params->addr_type == addr_type) { 339415819a70SAndre Guedes return params; 339515819a70SAndre Guedes } 339615819a70SAndre Guedes } 339715819a70SAndre Guedes 339815819a70SAndre Guedes return NULL; 339915819a70SAndre Guedes } 340015819a70SAndre Guedes 3401cef952ceSAndre Guedes static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type) 3402cef952ceSAndre Guedes { 3403cef952ceSAndre Guedes struct hci_conn *conn; 3404cef952ceSAndre Guedes 3405cef952ceSAndre Guedes conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr); 3406cef952ceSAndre Guedes if (!conn) 3407cef952ceSAndre Guedes return false; 3408cef952ceSAndre Guedes 3409cef952ceSAndre Guedes if (conn->dst_type != type) 3410cef952ceSAndre Guedes return false; 3411cef952ceSAndre Guedes 3412cef952ceSAndre Guedes if (conn->state != BT_CONNECTED) 3413cef952ceSAndre Guedes return false; 3414cef952ceSAndre Guedes 3415cef952ceSAndre Guedes return true; 3416cef952ceSAndre Guedes } 3417cef952ceSAndre Guedes 3418a9b0a04cSAndre Guedes static bool is_identity_address(bdaddr_t *addr, u8 addr_type) 3419a9b0a04cSAndre Guedes { 3420a9b0a04cSAndre Guedes if (addr_type == ADDR_LE_DEV_PUBLIC) 3421a9b0a04cSAndre Guedes return true; 3422a9b0a04cSAndre Guedes 3423a9b0a04cSAndre Guedes /* Check for Random Static address type */ 3424a9b0a04cSAndre Guedes if ((addr->b[5] & 0xc0) == 0xc0) 3425a9b0a04cSAndre Guedes return true; 3426a9b0a04cSAndre Guedes 3427a9b0a04cSAndre Guedes return false; 3428a9b0a04cSAndre Guedes } 3429a9b0a04cSAndre Guedes 343015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 3431a9b0a04cSAndre Guedes int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, 34329fcb18efSAndre Guedes u8 auto_connect, u16 conn_min_interval, 34339fcb18efSAndre Guedes u16 conn_max_interval) 343415819a70SAndre Guedes { 343515819a70SAndre Guedes struct hci_conn_params *params; 343615819a70SAndre Guedes 3437a9b0a04cSAndre Guedes if (!is_identity_address(addr, addr_type)) 3438a9b0a04cSAndre Guedes return -EINVAL; 3439a9b0a04cSAndre Guedes 344015819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 3441cef952ceSAndre Guedes if (params) 3442cef952ceSAndre Guedes goto update; 344315819a70SAndre Guedes 344415819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 344515819a70SAndre Guedes if (!params) { 344615819a70SAndre Guedes BT_ERR("Out of memory"); 3447a9b0a04cSAndre Guedes return -ENOMEM; 344815819a70SAndre Guedes } 344915819a70SAndre Guedes 345015819a70SAndre Guedes bacpy(¶ms->addr, addr); 345115819a70SAndre Guedes params->addr_type = addr_type; 3452cef952ceSAndre Guedes 3453cef952ceSAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 3454cef952ceSAndre Guedes 3455cef952ceSAndre Guedes update: 345615819a70SAndre Guedes params->conn_min_interval = conn_min_interval; 345715819a70SAndre Guedes params->conn_max_interval = conn_max_interval; 34589fcb18efSAndre Guedes params->auto_connect = auto_connect; 345915819a70SAndre Guedes 3460cef952ceSAndre Guedes switch (auto_connect) { 3461cef952ceSAndre Guedes case HCI_AUTO_CONN_DISABLED: 3462cef952ceSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 3463cef952ceSAndre Guedes hci_pend_le_conn_del(hdev, addr, addr_type); 3464cef952ceSAndre Guedes break; 3465cef952ceSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 3466cef952ceSAndre Guedes if (!is_connected(hdev, addr, addr_type)) 3467cef952ceSAndre Guedes hci_pend_le_conn_add(hdev, addr, addr_type); 3468cef952ceSAndre Guedes break; 3469cef952ceSAndre Guedes } 347015819a70SAndre Guedes 34719fcb18efSAndre Guedes BT_DBG("addr %pMR (type %u) auto_connect %u conn_min_interval 0x%.4x " 34729fcb18efSAndre Guedes "conn_max_interval 0x%.4x", addr, addr_type, auto_connect, 34739fcb18efSAndre Guedes conn_min_interval, conn_max_interval); 3474a9b0a04cSAndre Guedes 3475a9b0a04cSAndre Guedes return 0; 347615819a70SAndre Guedes } 347715819a70SAndre Guedes 347815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 347915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 348015819a70SAndre Guedes { 348115819a70SAndre Guedes struct hci_conn_params *params; 348215819a70SAndre Guedes 348315819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 348415819a70SAndre Guedes if (!params) 348515819a70SAndre Guedes return; 348615819a70SAndre Guedes 3487cef952ceSAndre Guedes hci_pend_le_conn_del(hdev, addr, addr_type); 3488cef952ceSAndre Guedes 348915819a70SAndre Guedes list_del(¶ms->list); 349015819a70SAndre Guedes kfree(params); 349115819a70SAndre Guedes 349215819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 349315819a70SAndre Guedes } 349415819a70SAndre Guedes 349515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 349615819a70SAndre Guedes void hci_conn_params_clear(struct hci_dev *hdev) 349715819a70SAndre Guedes { 349815819a70SAndre Guedes struct hci_conn_params *params, *tmp; 349915819a70SAndre Guedes 350015819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 350115819a70SAndre Guedes list_del(¶ms->list); 350215819a70SAndre Guedes kfree(params); 350315819a70SAndre Guedes } 350415819a70SAndre Guedes 350515819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 350615819a70SAndre Guedes } 350715819a70SAndre Guedes 350877a77a30SAndre Guedes /* This function requires the caller holds hdev->lock */ 350977a77a30SAndre Guedes struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev, 351077a77a30SAndre Guedes bdaddr_t *addr, u8 addr_type) 351177a77a30SAndre Guedes { 351277a77a30SAndre Guedes struct bdaddr_list *entry; 351377a77a30SAndre Guedes 351477a77a30SAndre Guedes list_for_each_entry(entry, &hdev->pend_le_conns, list) { 351577a77a30SAndre Guedes if (bacmp(&entry->bdaddr, addr) == 0 && 351677a77a30SAndre Guedes entry->bdaddr_type == addr_type) 351777a77a30SAndre Guedes return entry; 351877a77a30SAndre Guedes } 351977a77a30SAndre Guedes 352077a77a30SAndre Guedes return NULL; 352177a77a30SAndre Guedes } 352277a77a30SAndre Guedes 352377a77a30SAndre Guedes /* This function requires the caller holds hdev->lock */ 352477a77a30SAndre Guedes void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 352577a77a30SAndre Guedes { 352677a77a30SAndre Guedes struct bdaddr_list *entry; 352777a77a30SAndre Guedes 352877a77a30SAndre Guedes entry = hci_pend_le_conn_lookup(hdev, addr, addr_type); 352977a77a30SAndre Guedes if (entry) 3530a4790dbdSAndre Guedes goto done; 353177a77a30SAndre Guedes 353277a77a30SAndre Guedes entry = kzalloc(sizeof(*entry), GFP_KERNEL); 353377a77a30SAndre Guedes if (!entry) { 353477a77a30SAndre Guedes BT_ERR("Out of memory"); 353577a77a30SAndre Guedes return; 353677a77a30SAndre Guedes } 353777a77a30SAndre Guedes 353877a77a30SAndre Guedes bacpy(&entry->bdaddr, addr); 353977a77a30SAndre Guedes entry->bdaddr_type = addr_type; 354077a77a30SAndre Guedes 354177a77a30SAndre Guedes list_add(&entry->list, &hdev->pend_le_conns); 354277a77a30SAndre Guedes 354377a77a30SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 3544a4790dbdSAndre Guedes 3545a4790dbdSAndre Guedes done: 3546a4790dbdSAndre Guedes hci_update_background_scan(hdev); 354777a77a30SAndre Guedes } 354877a77a30SAndre Guedes 354977a77a30SAndre Guedes /* This function requires the caller holds hdev->lock */ 355077a77a30SAndre Guedes void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 355177a77a30SAndre Guedes { 355277a77a30SAndre Guedes struct bdaddr_list *entry; 355377a77a30SAndre Guedes 355477a77a30SAndre Guedes entry = hci_pend_le_conn_lookup(hdev, addr, addr_type); 355577a77a30SAndre Guedes if (!entry) 3556a4790dbdSAndre Guedes goto done; 355777a77a30SAndre Guedes 355877a77a30SAndre Guedes list_del(&entry->list); 355977a77a30SAndre Guedes kfree(entry); 356077a77a30SAndre Guedes 356177a77a30SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 3562a4790dbdSAndre Guedes 3563a4790dbdSAndre Guedes done: 3564a4790dbdSAndre Guedes hci_update_background_scan(hdev); 356577a77a30SAndre Guedes } 356677a77a30SAndre Guedes 356777a77a30SAndre Guedes /* This function requires the caller holds hdev->lock */ 356877a77a30SAndre Guedes void hci_pend_le_conns_clear(struct hci_dev *hdev) 356977a77a30SAndre Guedes { 357077a77a30SAndre Guedes struct bdaddr_list *entry, *tmp; 357177a77a30SAndre Guedes 357277a77a30SAndre Guedes list_for_each_entry_safe(entry, tmp, &hdev->pend_le_conns, list) { 357377a77a30SAndre Guedes list_del(&entry->list); 357477a77a30SAndre Guedes kfree(entry); 357577a77a30SAndre Guedes } 357677a77a30SAndre Guedes 357777a77a30SAndre Guedes BT_DBG("All LE pending connections cleared"); 357877a77a30SAndre Guedes } 357977a77a30SAndre Guedes 35804c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 35817ba8b4beSAndre Guedes { 35824c87eaabSAndre Guedes if (status) { 35834c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 35847ba8b4beSAndre Guedes 35854c87eaabSAndre Guedes hci_dev_lock(hdev); 35864c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 35874c87eaabSAndre Guedes hci_dev_unlock(hdev); 35884c87eaabSAndre Guedes return; 35894c87eaabSAndre Guedes } 35907ba8b4beSAndre Guedes } 35917ba8b4beSAndre Guedes 35924c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 35937ba8b4beSAndre Guedes { 35944c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 35954c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 35964c87eaabSAndre Guedes struct hci_request req; 35974c87eaabSAndre Guedes struct hci_cp_inquiry cp; 35987ba8b4beSAndre Guedes int err; 35997ba8b4beSAndre Guedes 36004c87eaabSAndre Guedes if (status) { 36014c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 36024c87eaabSAndre Guedes return; 36037ba8b4beSAndre Guedes } 36047ba8b4beSAndre Guedes 36054c87eaabSAndre Guedes switch (hdev->discovery.type) { 36064c87eaabSAndre Guedes case DISCOV_TYPE_LE: 36074c87eaabSAndre Guedes hci_dev_lock(hdev); 36084c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 36094c87eaabSAndre Guedes hci_dev_unlock(hdev); 36104c87eaabSAndre Guedes break; 36117dbfac1dSAndre Guedes 36124c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 36134c87eaabSAndre Guedes hci_req_init(&req, hdev); 36147dbfac1dSAndre Guedes 36157dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 36164c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 36174c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 36184c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 36194c87eaabSAndre Guedes 36204c87eaabSAndre Guedes hci_dev_lock(hdev); 36214c87eaabSAndre Guedes 36224c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 36234c87eaabSAndre Guedes 36244c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 36254c87eaabSAndre Guedes if (err) { 36264c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 36274c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 36287dbfac1dSAndre Guedes } 36297dbfac1dSAndre Guedes 36304c87eaabSAndre Guedes hci_dev_unlock(hdev); 36314c87eaabSAndre Guedes break; 36324c87eaabSAndre Guedes } 36337dbfac1dSAndre Guedes } 36347dbfac1dSAndre Guedes 36357ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 36367ba8b4beSAndre Guedes { 36377ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 36387ba8b4beSAndre Guedes le_scan_disable.work); 36394c87eaabSAndre Guedes struct hci_request req; 36404c87eaabSAndre Guedes int err; 36417ba8b4beSAndre Guedes 36427ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 36437ba8b4beSAndre Guedes 36444c87eaabSAndre Guedes hci_req_init(&req, hdev); 36457ba8b4beSAndre Guedes 3646b1efcc28SAndre Guedes hci_req_add_le_scan_disable(&req); 36477ba8b4beSAndre Guedes 36484c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 36494c87eaabSAndre Guedes if (err) 36504c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 365128b75a89SAndre Guedes } 365228b75a89SAndre Guedes 365394b1fc92SMarcel Holtmann int hci_update_random_address(struct hci_request *req, bool require_privacy, 365494b1fc92SMarcel Holtmann u8 *own_addr_type) 3655ebd3a747SJohan Hedberg { 3656ebd3a747SJohan Hedberg struct hci_dev *hdev = req->hdev; 3657ebd3a747SJohan Hedberg int err; 3658ebd3a747SJohan Hedberg 3659ebd3a747SJohan Hedberg /* If privacy is enabled use a resolvable private address. If 36602b5224dcSMarcel Holtmann * current RPA has expired or there is something else than 36612b5224dcSMarcel Holtmann * the current RPA in use, then generate a new one. 3662ebd3a747SJohan Hedberg */ 3663ebd3a747SJohan Hedberg if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) { 3664ebd3a747SJohan Hedberg int to; 3665ebd3a747SJohan Hedberg 3666ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_RANDOM; 3667ebd3a747SJohan Hedberg 3668ebd3a747SJohan Hedberg if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) && 36692b5224dcSMarcel Holtmann !bacmp(&hdev->random_addr, &hdev->rpa)) 3670ebd3a747SJohan Hedberg return 0; 3671ebd3a747SJohan Hedberg 36722b5224dcSMarcel Holtmann err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa); 3673ebd3a747SJohan Hedberg if (err < 0) { 3674ebd3a747SJohan Hedberg BT_ERR("%s failed to generate new RPA", hdev->name); 3675ebd3a747SJohan Hedberg return err; 3676ebd3a747SJohan Hedberg } 3677ebd3a747SJohan Hedberg 36782b5224dcSMarcel Holtmann hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, &hdev->rpa); 3679ebd3a747SJohan Hedberg 3680ebd3a747SJohan Hedberg to = msecs_to_jiffies(hdev->rpa_timeout * 1000); 3681ebd3a747SJohan Hedberg queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to); 3682ebd3a747SJohan Hedberg 3683ebd3a747SJohan Hedberg return 0; 3684ebd3a747SJohan Hedberg } 3685ebd3a747SJohan Hedberg 368694b1fc92SMarcel Holtmann /* In case of required privacy without resolvable private address, 368794b1fc92SMarcel Holtmann * use an unresolvable private address. This is useful for active 368894b1fc92SMarcel Holtmann * scanning and non-connectable advertising. 368994b1fc92SMarcel Holtmann */ 369094b1fc92SMarcel Holtmann if (require_privacy) { 369194b1fc92SMarcel Holtmann bdaddr_t urpa; 369294b1fc92SMarcel Holtmann 369394b1fc92SMarcel Holtmann get_random_bytes(&urpa, 6); 369494b1fc92SMarcel Holtmann urpa.b[5] &= 0x3f; /* Clear two most significant bits */ 369594b1fc92SMarcel Holtmann 369694b1fc92SMarcel Holtmann *own_addr_type = ADDR_LE_DEV_RANDOM; 369794b1fc92SMarcel Holtmann hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, &urpa); 369894b1fc92SMarcel Holtmann return 0; 369994b1fc92SMarcel Holtmann } 370094b1fc92SMarcel Holtmann 3701ebd3a747SJohan Hedberg /* If forcing static address is in use or there is no public 3702ebd3a747SJohan Hedberg * address use the static address as random address (but skip 3703ebd3a747SJohan Hedberg * the HCI command if the current random address is already the 3704ebd3a747SJohan Hedberg * static one. 3705ebd3a747SJohan Hedberg */ 3706ebd3a747SJohan Hedberg if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) || 3707ebd3a747SJohan Hedberg !bacmp(&hdev->bdaddr, BDADDR_ANY)) { 3708ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_RANDOM; 3709ebd3a747SJohan Hedberg if (bacmp(&hdev->static_addr, &hdev->random_addr)) 3710ebd3a747SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, 3711ebd3a747SJohan Hedberg &hdev->static_addr); 3712ebd3a747SJohan Hedberg return 0; 3713ebd3a747SJohan Hedberg } 3714ebd3a747SJohan Hedberg 3715ebd3a747SJohan Hedberg /* Neither privacy nor static address is being used so use a 3716ebd3a747SJohan Hedberg * public address. 3717ebd3a747SJohan Hedberg */ 3718ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_PUBLIC; 3719ebd3a747SJohan Hedberg 3720ebd3a747SJohan Hedberg return 0; 3721ebd3a747SJohan Hedberg } 3722ebd3a747SJohan Hedberg 3723a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 3724a1f4c318SJohan Hedberg * 3725a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 3726a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 3727a1f4c318SJohan Hedberg * the static random address. 3728a1f4c318SJohan Hedberg * 3729a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 3730a1f4c318SJohan Hedberg * public address to use the static random address instead. 3731a1f4c318SJohan Hedberg */ 3732a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 3733a1f4c318SJohan Hedberg u8 *bdaddr_type) 3734a1f4c318SJohan Hedberg { 3735a1f4c318SJohan Hedberg if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) || 3736a1f4c318SJohan Hedberg !bacmp(&hdev->bdaddr, BDADDR_ANY)) { 3737a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 3738a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 3739a1f4c318SJohan Hedberg } else { 3740a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 3741a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 3742a1f4c318SJohan Hedberg } 3743a1f4c318SJohan Hedberg } 3744a1f4c318SJohan Hedberg 37459be0dab7SDavid Herrmann /* Alloc HCI device */ 37469be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 37479be0dab7SDavid Herrmann { 37489be0dab7SDavid Herrmann struct hci_dev *hdev; 37499be0dab7SDavid Herrmann 37509be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 37519be0dab7SDavid Herrmann if (!hdev) 37529be0dab7SDavid Herrmann return NULL; 37539be0dab7SDavid Herrmann 3754b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3755b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3756b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3757b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3758b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 3759bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3760bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3761b1b813d4SDavid Herrmann 3762b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3763b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3764b1b813d4SDavid Herrmann 37653f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 3766bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3767bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 37684e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = 0x0028; 37694e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = 0x0038; 3770bef64738SMarcel Holtmann 3771d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 3772d6bfd59cSJohan Hedberg 3773b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3774b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3775b1b813d4SDavid Herrmann 3776b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3777b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 3778b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3779b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3780b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3781970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3782b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 3783*d2ab0ac1SMarcel Holtmann INIT_LIST_HEAD(&hdev->le_white_list); 378415819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 378577a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 37866b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3787b1b813d4SDavid Herrmann 3788b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3789b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3790b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3791b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3792b1b813d4SDavid Herrmann 3793b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3794b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 3795b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 3796b1b813d4SDavid Herrmann 3797b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3798b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3799b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3800b1b813d4SDavid Herrmann 3801b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 3802b1b813d4SDavid Herrmann 3803bda4f23aSAndrei Emeltchenko setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); 3804b1b813d4SDavid Herrmann 3805b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3806b1b813d4SDavid Herrmann discovery_init(hdev); 38079be0dab7SDavid Herrmann 38089be0dab7SDavid Herrmann return hdev; 38099be0dab7SDavid Herrmann } 38109be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 38119be0dab7SDavid Herrmann 38129be0dab7SDavid Herrmann /* Free HCI device */ 38139be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 38149be0dab7SDavid Herrmann { 38159be0dab7SDavid Herrmann /* will free via device release */ 38169be0dab7SDavid Herrmann put_device(&hdev->dev); 38179be0dab7SDavid Herrmann } 38189be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 38199be0dab7SDavid Herrmann 38201da177e4SLinus Torvalds /* Register HCI device */ 38211da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 38221da177e4SLinus Torvalds { 3823b1b813d4SDavid Herrmann int id, error; 38241da177e4SLinus Torvalds 3825010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 38261da177e4SLinus Torvalds return -EINVAL; 38271da177e4SLinus Torvalds 382808add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 382908add513SMat Martineau * so the index can be used as the AMP controller ID. 383008add513SMat Martineau */ 38313df92b31SSasha Levin switch (hdev->dev_type) { 38323df92b31SSasha Levin case HCI_BREDR: 38333df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 38341da177e4SLinus Torvalds break; 38353df92b31SSasha Levin case HCI_AMP: 38363df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 38373df92b31SSasha Levin break; 38383df92b31SSasha Levin default: 38393df92b31SSasha Levin return -EINVAL; 38401da177e4SLinus Torvalds } 38411da177e4SLinus Torvalds 38423df92b31SSasha Levin if (id < 0) 38433df92b31SSasha Levin return id; 38443df92b31SSasha Levin 38451da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 38461da177e4SLinus Torvalds hdev->id = id; 38472d8b3a11SAndrei Emeltchenko 38482d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 38492d8b3a11SAndrei Emeltchenko 3850d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3851d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 385233ca954dSDavid Herrmann if (!hdev->workqueue) { 385333ca954dSDavid Herrmann error = -ENOMEM; 385433ca954dSDavid Herrmann goto err; 385533ca954dSDavid Herrmann } 3856f48fd9c8SMarcel Holtmann 3857d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3858d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 38596ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 38606ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 38616ead1bbcSJohan Hedberg error = -ENOMEM; 38626ead1bbcSJohan Hedberg goto err; 38636ead1bbcSJohan Hedberg } 38646ead1bbcSJohan Hedberg 38650153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 38660153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 38670153e2ecSMarcel Holtmann 3868bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3869bdc3e0f1SMarcel Holtmann 387099780a7bSJohan Hedberg hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 387199780a7bSJohan Hedberg CRYPTO_ALG_ASYNC); 387299780a7bSJohan Hedberg if (IS_ERR(hdev->tfm_aes)) { 387399780a7bSJohan Hedberg BT_ERR("Unable to create crypto context"); 387499780a7bSJohan Hedberg error = PTR_ERR(hdev->tfm_aes); 387599780a7bSJohan Hedberg hdev->tfm_aes = NULL; 387699780a7bSJohan Hedberg goto err_wqueue; 387799780a7bSJohan Hedberg } 387899780a7bSJohan Hedberg 3879bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 388033ca954dSDavid Herrmann if (error < 0) 388199780a7bSJohan Hedberg goto err_tfm; 38821da177e4SLinus Torvalds 3883611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3884a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3885a8c5fb1aSGustavo Padovan hdev); 3886611b30f7SMarcel Holtmann if (hdev->rfkill) { 3887611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3888611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3889611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3890611b30f7SMarcel Holtmann } 3891611b30f7SMarcel Holtmann } 3892611b30f7SMarcel Holtmann 38935e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 38945e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 38955e130367SJohan Hedberg 3896a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 3897004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 3898ce2be9acSAndrei Emeltchenko 389901cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 390056f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 390156f87901SJohan Hedberg * through reading supported features during init. 390256f87901SJohan Hedberg */ 390356f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 390456f87901SJohan Hedberg } 3905ce2be9acSAndrei Emeltchenko 3906fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3907fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3908fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3909fcee3377SGustavo Padovan 39101da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 3911dc946bd8SDavid Herrmann hci_dev_hold(hdev); 39121da177e4SLinus Torvalds 391319202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3914fbe96d6fSMarcel Holtmann 39151da177e4SLinus Torvalds return id; 3916f48fd9c8SMarcel Holtmann 391799780a7bSJohan Hedberg err_tfm: 391899780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 391933ca954dSDavid Herrmann err_wqueue: 392033ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 39216ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 392233ca954dSDavid Herrmann err: 39233df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3924f48fd9c8SMarcel Holtmann 392533ca954dSDavid Herrmann return error; 39261da177e4SLinus Torvalds } 39271da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 39281da177e4SLinus Torvalds 39291da177e4SLinus Torvalds /* Unregister HCI device */ 393059735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 39311da177e4SLinus Torvalds { 39323df92b31SSasha Levin int i, id; 3933ef222013SMarcel Holtmann 3934c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 39351da177e4SLinus Torvalds 393694324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 393794324962SJohan Hovold 39383df92b31SSasha Levin id = hdev->id; 39393df92b31SSasha Levin 3940f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 39411da177e4SLinus Torvalds list_del(&hdev->list); 3942f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 39431da177e4SLinus Torvalds 39441da177e4SLinus Torvalds hci_dev_do_close(hdev); 39451da177e4SLinus Torvalds 3946cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 3947ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 3948ef222013SMarcel Holtmann 3949b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 3950b9b5ef18SGustavo Padovan 3951ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 3952a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 395309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3954744cf19eSJohan Hedberg mgmt_index_removed(hdev); 395509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 395656e5cb86SJohan Hedberg } 3957ab81cbf9SJohan Hedberg 39582e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 39592e58ef3eSJohan Hedberg * pending list */ 39602e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 39612e58ef3eSJohan Hedberg 39621da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 39631da177e4SLinus Torvalds 3964611b30f7SMarcel Holtmann if (hdev->rfkill) { 3965611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 3966611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3967611b30f7SMarcel Holtmann } 3968611b30f7SMarcel Holtmann 396999780a7bSJohan Hedberg if (hdev->tfm_aes) 397099780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 397199780a7bSJohan Hedberg 3972bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 3973147e2d59SDave Young 39740153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 39750153e2ecSMarcel Holtmann 3976f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 39776ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 3978f48fd9c8SMarcel Holtmann 397909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3980e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 39812aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 398255ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 3983b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 3984970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 39852763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 3986*d2ab0ac1SMarcel Holtmann hci_white_list_clear(hdev); 398715819a70SAndre Guedes hci_conn_params_clear(hdev); 398877a77a30SAndre Guedes hci_pend_le_conns_clear(hdev); 398909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 3990e2e0cacbSJohan Hedberg 3991dc946bd8SDavid Herrmann hci_dev_put(hdev); 39923df92b31SSasha Levin 39933df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 39941da177e4SLinus Torvalds } 39951da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 39961da177e4SLinus Torvalds 39971da177e4SLinus Torvalds /* Suspend HCI device */ 39981da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 39991da177e4SLinus Torvalds { 40001da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 40011da177e4SLinus Torvalds return 0; 40021da177e4SLinus Torvalds } 40031da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 40041da177e4SLinus Torvalds 40051da177e4SLinus Torvalds /* Resume HCI device */ 40061da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 40071da177e4SLinus Torvalds { 40081da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 40091da177e4SLinus Torvalds return 0; 40101da177e4SLinus Torvalds } 40111da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 40121da177e4SLinus Torvalds 401376bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 4014e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 401576bca880SMarcel Holtmann { 401676bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 401776bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 401876bca880SMarcel Holtmann kfree_skb(skb); 401976bca880SMarcel Holtmann return -ENXIO; 402076bca880SMarcel Holtmann } 402176bca880SMarcel Holtmann 4022d82603c6SJorrit Schippers /* Incoming skb */ 402376bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 402476bca880SMarcel Holtmann 402576bca880SMarcel Holtmann /* Time stamp */ 402676bca880SMarcel Holtmann __net_timestamp(skb); 402776bca880SMarcel Holtmann 402876bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 4029b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 4030c78ae283SMarcel Holtmann 403176bca880SMarcel Holtmann return 0; 403276bca880SMarcel Holtmann } 403376bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 403476bca880SMarcel Holtmann 403533e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 40361e429f38SGustavo F. Padovan int count, __u8 index) 403733e882a5SSuraj Sumangala { 403833e882a5SSuraj Sumangala int len = 0; 403933e882a5SSuraj Sumangala int hlen = 0; 404033e882a5SSuraj Sumangala int remain = count; 404133e882a5SSuraj Sumangala struct sk_buff *skb; 404233e882a5SSuraj Sumangala struct bt_skb_cb *scb; 404333e882a5SSuraj Sumangala 404433e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 404533e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 404633e882a5SSuraj Sumangala return -EILSEQ; 404733e882a5SSuraj Sumangala 404833e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 404933e882a5SSuraj Sumangala 405033e882a5SSuraj Sumangala if (!skb) { 405133e882a5SSuraj Sumangala switch (type) { 405233e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 405333e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 405433e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 405533e882a5SSuraj Sumangala break; 405633e882a5SSuraj Sumangala case HCI_EVENT_PKT: 405733e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 405833e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 405933e882a5SSuraj Sumangala break; 406033e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 406133e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 406233e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 406333e882a5SSuraj Sumangala break; 406433e882a5SSuraj Sumangala } 406533e882a5SSuraj Sumangala 40661e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 406733e882a5SSuraj Sumangala if (!skb) 406833e882a5SSuraj Sumangala return -ENOMEM; 406933e882a5SSuraj Sumangala 407033e882a5SSuraj Sumangala scb = (void *) skb->cb; 407133e882a5SSuraj Sumangala scb->expect = hlen; 407233e882a5SSuraj Sumangala scb->pkt_type = type; 407333e882a5SSuraj Sumangala 407433e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 407533e882a5SSuraj Sumangala } 407633e882a5SSuraj Sumangala 407733e882a5SSuraj Sumangala while (count) { 407833e882a5SSuraj Sumangala scb = (void *) skb->cb; 407989bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 408033e882a5SSuraj Sumangala 408133e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 408233e882a5SSuraj Sumangala 408333e882a5SSuraj Sumangala count -= len; 408433e882a5SSuraj Sumangala data += len; 408533e882a5SSuraj Sumangala scb->expect -= len; 408633e882a5SSuraj Sumangala remain = count; 408733e882a5SSuraj Sumangala 408833e882a5SSuraj Sumangala switch (type) { 408933e882a5SSuraj Sumangala case HCI_EVENT_PKT: 409033e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 409133e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 409233e882a5SSuraj Sumangala scb->expect = h->plen; 409333e882a5SSuraj Sumangala 409433e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 409533e882a5SSuraj Sumangala kfree_skb(skb); 409633e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 409733e882a5SSuraj Sumangala return -ENOMEM; 409833e882a5SSuraj Sumangala } 409933e882a5SSuraj Sumangala } 410033e882a5SSuraj Sumangala break; 410133e882a5SSuraj Sumangala 410233e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 410333e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 410433e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 410533e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 410633e882a5SSuraj Sumangala 410733e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 410833e882a5SSuraj Sumangala kfree_skb(skb); 410933e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 411033e882a5SSuraj Sumangala return -ENOMEM; 411133e882a5SSuraj Sumangala } 411233e882a5SSuraj Sumangala } 411333e882a5SSuraj Sumangala break; 411433e882a5SSuraj Sumangala 411533e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 411633e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 411733e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 411833e882a5SSuraj Sumangala scb->expect = h->dlen; 411933e882a5SSuraj Sumangala 412033e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 412133e882a5SSuraj Sumangala kfree_skb(skb); 412233e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 412333e882a5SSuraj Sumangala return -ENOMEM; 412433e882a5SSuraj Sumangala } 412533e882a5SSuraj Sumangala } 412633e882a5SSuraj Sumangala break; 412733e882a5SSuraj Sumangala } 412833e882a5SSuraj Sumangala 412933e882a5SSuraj Sumangala if (scb->expect == 0) { 413033e882a5SSuraj Sumangala /* Complete frame */ 413133e882a5SSuraj Sumangala 413233e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 4133e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 413433e882a5SSuraj Sumangala 413533e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 413633e882a5SSuraj Sumangala return remain; 413733e882a5SSuraj Sumangala } 413833e882a5SSuraj Sumangala } 413933e882a5SSuraj Sumangala 414033e882a5SSuraj Sumangala return remain; 414133e882a5SSuraj Sumangala } 414233e882a5SSuraj Sumangala 4143ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 4144ef222013SMarcel Holtmann { 4145f39a3c06SSuraj Sumangala int rem = 0; 4146f39a3c06SSuraj Sumangala 4147ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 4148ef222013SMarcel Holtmann return -EILSEQ; 4149ef222013SMarcel Holtmann 4150da5f6c37SGustavo F. Padovan while (count) { 41511e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 4152f39a3c06SSuraj Sumangala if (rem < 0) 4153f39a3c06SSuraj Sumangala return rem; 4154ef222013SMarcel Holtmann 4155f39a3c06SSuraj Sumangala data += (count - rem); 4156f39a3c06SSuraj Sumangala count = rem; 4157f81c6224SJoe Perches } 4158ef222013SMarcel Holtmann 4159f39a3c06SSuraj Sumangala return rem; 4160ef222013SMarcel Holtmann } 4161ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 4162ef222013SMarcel Holtmann 416399811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 416499811510SSuraj Sumangala 416599811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 416699811510SSuraj Sumangala { 416799811510SSuraj Sumangala int type; 416899811510SSuraj Sumangala int rem = 0; 416999811510SSuraj Sumangala 4170da5f6c37SGustavo F. Padovan while (count) { 417199811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 417299811510SSuraj Sumangala 417399811510SSuraj Sumangala if (!skb) { 417499811510SSuraj Sumangala struct { char type; } *pkt; 417599811510SSuraj Sumangala 417699811510SSuraj Sumangala /* Start of the frame */ 417799811510SSuraj Sumangala pkt = data; 417899811510SSuraj Sumangala type = pkt->type; 417999811510SSuraj Sumangala 418099811510SSuraj Sumangala data++; 418199811510SSuraj Sumangala count--; 418299811510SSuraj Sumangala } else 418399811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 418499811510SSuraj Sumangala 41851e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 41861e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 418799811510SSuraj Sumangala if (rem < 0) 418899811510SSuraj Sumangala return rem; 418999811510SSuraj Sumangala 419099811510SSuraj Sumangala data += (count - rem); 419199811510SSuraj Sumangala count = rem; 4192f81c6224SJoe Perches } 419399811510SSuraj Sumangala 419499811510SSuraj Sumangala return rem; 419599811510SSuraj Sumangala } 419699811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 419799811510SSuraj Sumangala 41981da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 41991da177e4SLinus Torvalds 42001da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 42011da177e4SLinus Torvalds { 42021da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 42031da177e4SLinus Torvalds 4204f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 42051da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 4206f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 42071da177e4SLinus Torvalds 42081da177e4SLinus Torvalds return 0; 42091da177e4SLinus Torvalds } 42101da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 42111da177e4SLinus Torvalds 42121da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 42131da177e4SLinus Torvalds { 42141da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 42151da177e4SLinus Torvalds 4216f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 42171da177e4SLinus Torvalds list_del(&cb->list); 4218f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 42191da177e4SLinus Torvalds 42201da177e4SLinus Torvalds return 0; 42211da177e4SLinus Torvalds } 42221da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 42231da177e4SLinus Torvalds 422451086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 42251da177e4SLinus Torvalds { 42260d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 42271da177e4SLinus Torvalds 42281da177e4SLinus Torvalds /* Time stamp */ 4229a61bbcf2SPatrick McHardy __net_timestamp(skb); 42301da177e4SLinus Torvalds 4231cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4232cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4233cd82e61cSMarcel Holtmann 4234cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 4235cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 4236470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 42371da177e4SLinus Torvalds } 42381da177e4SLinus Torvalds 42391da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 42401da177e4SLinus Torvalds skb_orphan(skb); 42411da177e4SLinus Torvalds 42427bd8f09fSMarcel Holtmann if (hdev->send(hdev, skb) < 0) 424351086991SMarcel Holtmann BT_ERR("%s sending frame failed", hdev->name); 42441da177e4SLinus Torvalds } 42451da177e4SLinus Torvalds 42463119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 42473119ae95SJohan Hedberg { 42483119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 42493119ae95SJohan Hedberg req->hdev = hdev; 42505d73e034SAndre Guedes req->err = 0; 42513119ae95SJohan Hedberg } 42523119ae95SJohan Hedberg 42533119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 42543119ae95SJohan Hedberg { 42553119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 42563119ae95SJohan Hedberg struct sk_buff *skb; 42573119ae95SJohan Hedberg unsigned long flags; 42583119ae95SJohan Hedberg 42593119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 42603119ae95SJohan Hedberg 42615d73e034SAndre Guedes /* If an error occured during request building, remove all HCI 42625d73e034SAndre Guedes * commands queued on the HCI request queue. 42635d73e034SAndre Guedes */ 42645d73e034SAndre Guedes if (req->err) { 42655d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 42665d73e034SAndre Guedes return req->err; 42675d73e034SAndre Guedes } 42685d73e034SAndre Guedes 42693119ae95SJohan Hedberg /* Do not allow empty requests */ 42703119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 4271382b0c39SAndre Guedes return -ENODATA; 42723119ae95SJohan Hedberg 42733119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 42743119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 42753119ae95SJohan Hedberg 42763119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 42773119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 42783119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 42793119ae95SJohan Hedberg 42803119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 42813119ae95SJohan Hedberg 42823119ae95SJohan Hedberg return 0; 42833119ae95SJohan Hedberg } 42843119ae95SJohan Hedberg 42851ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 428607dc93ddSJohan Hedberg u32 plen, const void *param) 42871da177e4SLinus Torvalds { 42881da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 42891da177e4SLinus Torvalds struct hci_command_hdr *hdr; 42901da177e4SLinus Torvalds struct sk_buff *skb; 42911da177e4SLinus Torvalds 42921da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 42931ca3a9d0SJohan Hedberg if (!skb) 42941ca3a9d0SJohan Hedberg return NULL; 42951da177e4SLinus Torvalds 42961da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 4297a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 42981da177e4SLinus Torvalds hdr->plen = plen; 42991da177e4SLinus Torvalds 43001da177e4SLinus Torvalds if (plen) 43011da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 43021da177e4SLinus Torvalds 43031da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 43041da177e4SLinus Torvalds 43050d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 4306c78ae283SMarcel Holtmann 43071ca3a9d0SJohan Hedberg return skb; 43081ca3a9d0SJohan Hedberg } 43091ca3a9d0SJohan Hedberg 43101ca3a9d0SJohan Hedberg /* Send HCI command */ 431107dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 431207dc93ddSJohan Hedberg const void *param) 43131ca3a9d0SJohan Hedberg { 43141ca3a9d0SJohan Hedberg struct sk_buff *skb; 43151ca3a9d0SJohan Hedberg 43161ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 43171ca3a9d0SJohan Hedberg 43181ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 43191ca3a9d0SJohan Hedberg if (!skb) { 43201ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 43211ca3a9d0SJohan Hedberg return -ENOMEM; 43221ca3a9d0SJohan Hedberg } 43231ca3a9d0SJohan Hedberg 432411714b3dSJohan Hedberg /* Stand-alone HCI commands must be flaged as 432511714b3dSJohan Hedberg * single-command requests. 432611714b3dSJohan Hedberg */ 432711714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 432811714b3dSJohan Hedberg 43291da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 4330c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 43311da177e4SLinus Torvalds 43321da177e4SLinus Torvalds return 0; 43331da177e4SLinus Torvalds } 43341da177e4SLinus Torvalds 433571c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 433607dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 433707dc93ddSJohan Hedberg const void *param, u8 event) 433871c76a17SJohan Hedberg { 433971c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 434071c76a17SJohan Hedberg struct sk_buff *skb; 434171c76a17SJohan Hedberg 434271c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 434371c76a17SJohan Hedberg 434434739c1eSAndre Guedes /* If an error occured during request building, there is no point in 434534739c1eSAndre Guedes * queueing the HCI command. We can simply return. 434634739c1eSAndre Guedes */ 434734739c1eSAndre Guedes if (req->err) 434834739c1eSAndre Guedes return; 434934739c1eSAndre Guedes 435071c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 435171c76a17SJohan Hedberg if (!skb) { 43525d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 43535d73e034SAndre Guedes hdev->name, opcode); 43545d73e034SAndre Guedes req->err = -ENOMEM; 4355e348fe6bSAndre Guedes return; 435671c76a17SJohan Hedberg } 435771c76a17SJohan Hedberg 435871c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 435971c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 436071c76a17SJohan Hedberg 436102350a72SJohan Hedberg bt_cb(skb)->req.event = event; 436202350a72SJohan Hedberg 436371c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 436471c76a17SJohan Hedberg } 436571c76a17SJohan Hedberg 436607dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 436707dc93ddSJohan Hedberg const void *param) 436802350a72SJohan Hedberg { 436902350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 437002350a72SJohan Hedberg } 437102350a72SJohan Hedberg 43721da177e4SLinus Torvalds /* Get data from the previously sent command */ 4373a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 43741da177e4SLinus Torvalds { 43751da177e4SLinus Torvalds struct hci_command_hdr *hdr; 43761da177e4SLinus Torvalds 43771da177e4SLinus Torvalds if (!hdev->sent_cmd) 43781da177e4SLinus Torvalds return NULL; 43791da177e4SLinus Torvalds 43801da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 43811da177e4SLinus Torvalds 4382a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 43831da177e4SLinus Torvalds return NULL; 43841da177e4SLinus Torvalds 4385f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 43861da177e4SLinus Torvalds 43871da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 43881da177e4SLinus Torvalds } 43891da177e4SLinus Torvalds 43901da177e4SLinus Torvalds /* Send ACL data */ 43911da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 43921da177e4SLinus Torvalds { 43931da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 43941da177e4SLinus Torvalds int len = skb->len; 43951da177e4SLinus Torvalds 4396badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 4397badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 43989c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 4399aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 4400aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 44011da177e4SLinus Torvalds } 44021da177e4SLinus Torvalds 4403ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 440473d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 44051da177e4SLinus Torvalds { 4406ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 44071da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 44081da177e4SLinus Torvalds struct sk_buff *list; 44091da177e4SLinus Torvalds 4410087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 4411087bfd99SGustavo Padovan skb->data_len = 0; 4412087bfd99SGustavo Padovan 4413087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 4414204a6e54SAndrei Emeltchenko 4415204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 4416204a6e54SAndrei Emeltchenko case HCI_BREDR: 4417087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 4418204a6e54SAndrei Emeltchenko break; 4419204a6e54SAndrei Emeltchenko case HCI_AMP: 4420204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 4421204a6e54SAndrei Emeltchenko break; 4422204a6e54SAndrei Emeltchenko default: 4423204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 4424204a6e54SAndrei Emeltchenko return; 4425204a6e54SAndrei Emeltchenko } 4426087bfd99SGustavo Padovan 442770f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 442870f23020SAndrei Emeltchenko if (!list) { 44291da177e4SLinus Torvalds /* Non fragmented */ 44301da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 44311da177e4SLinus Torvalds 443273d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 44331da177e4SLinus Torvalds } else { 44341da177e4SLinus Torvalds /* Fragmented */ 44351da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 44361da177e4SLinus Torvalds 44371da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 44381da177e4SLinus Torvalds 44391da177e4SLinus Torvalds /* Queue all fragments atomically */ 4440af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 44411da177e4SLinus Torvalds 444273d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 4443e702112fSAndrei Emeltchenko 4444e702112fSAndrei Emeltchenko flags &= ~ACL_START; 4445e702112fSAndrei Emeltchenko flags |= ACL_CONT; 44461da177e4SLinus Torvalds do { 44471da177e4SLinus Torvalds skb = list; list = list->next; 44481da177e4SLinus Torvalds 44490d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 4450e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 44511da177e4SLinus Torvalds 44521da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 44531da177e4SLinus Torvalds 445473d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 44551da177e4SLinus Torvalds } while (list); 44561da177e4SLinus Torvalds 4457af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 44581da177e4SLinus Torvalds } 445973d80debSLuiz Augusto von Dentz } 446073d80debSLuiz Augusto von Dentz 446173d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 446273d80debSLuiz Augusto von Dentz { 4463ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 446473d80debSLuiz Augusto von Dentz 4465f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 446673d80debSLuiz Augusto von Dentz 4467ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 44681da177e4SLinus Torvalds 44693eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 44701da177e4SLinus Torvalds } 44711da177e4SLinus Torvalds 44721da177e4SLinus Torvalds /* Send SCO data */ 44730d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 44741da177e4SLinus Torvalds { 44751da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 44761da177e4SLinus Torvalds struct hci_sco_hdr hdr; 44771da177e4SLinus Torvalds 44781da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 44791da177e4SLinus Torvalds 4480aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 44811da177e4SLinus Torvalds hdr.dlen = skb->len; 44821da177e4SLinus Torvalds 4483badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 4484badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 44859c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 44861da177e4SLinus Torvalds 44870d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 4488c78ae283SMarcel Holtmann 44891da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 44903eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 44911da177e4SLinus Torvalds } 44921da177e4SLinus Torvalds 44931da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 44941da177e4SLinus Torvalds 44951da177e4SLinus Torvalds /* HCI Connection scheduler */ 44966039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 4497a8c5fb1aSGustavo Padovan int *quote) 44981da177e4SLinus Torvalds { 44991da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 45008035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 4501abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 45021da177e4SLinus Torvalds 45031da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 45041da177e4SLinus Torvalds * added and removed with TX task disabled. */ 4505bf4c6325SGustavo F. Padovan 4506bf4c6325SGustavo F. Padovan rcu_read_lock(); 4507bf4c6325SGustavo F. Padovan 4508bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4509769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 45101da177e4SLinus Torvalds continue; 4511769be974SMarcel Holtmann 4512769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 4513769be974SMarcel Holtmann continue; 4514769be974SMarcel Holtmann 45151da177e4SLinus Torvalds num++; 45161da177e4SLinus Torvalds 45171da177e4SLinus Torvalds if (c->sent < min) { 45181da177e4SLinus Torvalds min = c->sent; 45191da177e4SLinus Torvalds conn = c; 45201da177e4SLinus Torvalds } 452152087a79SLuiz Augusto von Dentz 452252087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 452352087a79SLuiz Augusto von Dentz break; 45241da177e4SLinus Torvalds } 45251da177e4SLinus Torvalds 4526bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4527bf4c6325SGustavo F. Padovan 45281da177e4SLinus Torvalds if (conn) { 45296ed58ec5SVille Tervo int cnt, q; 45306ed58ec5SVille Tervo 45316ed58ec5SVille Tervo switch (conn->type) { 45326ed58ec5SVille Tervo case ACL_LINK: 45336ed58ec5SVille Tervo cnt = hdev->acl_cnt; 45346ed58ec5SVille Tervo break; 45356ed58ec5SVille Tervo case SCO_LINK: 45366ed58ec5SVille Tervo case ESCO_LINK: 45376ed58ec5SVille Tervo cnt = hdev->sco_cnt; 45386ed58ec5SVille Tervo break; 45396ed58ec5SVille Tervo case LE_LINK: 45406ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 45416ed58ec5SVille Tervo break; 45426ed58ec5SVille Tervo default: 45436ed58ec5SVille Tervo cnt = 0; 45446ed58ec5SVille Tervo BT_ERR("Unknown link type"); 45456ed58ec5SVille Tervo } 45466ed58ec5SVille Tervo 45476ed58ec5SVille Tervo q = cnt / num; 45481da177e4SLinus Torvalds *quote = q ? q : 1; 45491da177e4SLinus Torvalds } else 45501da177e4SLinus Torvalds *quote = 0; 45511da177e4SLinus Torvalds 45521da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 45531da177e4SLinus Torvalds return conn; 45541da177e4SLinus Torvalds } 45551da177e4SLinus Torvalds 45566039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 45571da177e4SLinus Torvalds { 45581da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 45591da177e4SLinus Torvalds struct hci_conn *c; 45601da177e4SLinus Torvalds 4561bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 45621da177e4SLinus Torvalds 4563bf4c6325SGustavo F. Padovan rcu_read_lock(); 4564bf4c6325SGustavo F. Padovan 45651da177e4SLinus Torvalds /* Kill stalled connections */ 4566bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4567bae1f5d9SVille Tervo if (c->type == type && c->sent) { 45686ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 45696ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 4570bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 45711da177e4SLinus Torvalds } 45721da177e4SLinus Torvalds } 4573bf4c6325SGustavo F. Padovan 4574bf4c6325SGustavo F. Padovan rcu_read_unlock(); 45751da177e4SLinus Torvalds } 45761da177e4SLinus Torvalds 45776039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 457873d80debSLuiz Augusto von Dentz int *quote) 457973d80debSLuiz Augusto von Dentz { 458073d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 458173d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 4582abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 458373d80debSLuiz Augusto von Dentz struct hci_conn *conn; 458473d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 458573d80debSLuiz Augusto von Dentz 458673d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 458773d80debSLuiz Augusto von Dentz 4588bf4c6325SGustavo F. Padovan rcu_read_lock(); 4589bf4c6325SGustavo F. Padovan 4590bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 459173d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 459273d80debSLuiz Augusto von Dentz 459373d80debSLuiz Augusto von Dentz if (conn->type != type) 459473d80debSLuiz Augusto von Dentz continue; 459573d80debSLuiz Augusto von Dentz 459673d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 459773d80debSLuiz Augusto von Dentz continue; 459873d80debSLuiz Augusto von Dentz 459973d80debSLuiz Augusto von Dentz conn_num++; 460073d80debSLuiz Augusto von Dentz 46018192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 460273d80debSLuiz Augusto von Dentz struct sk_buff *skb; 460373d80debSLuiz Augusto von Dentz 460473d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 460573d80debSLuiz Augusto von Dentz continue; 460673d80debSLuiz Augusto von Dentz 460773d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 460873d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 460973d80debSLuiz Augusto von Dentz continue; 461073d80debSLuiz Augusto von Dentz 461173d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 461273d80debSLuiz Augusto von Dentz num = 0; 461373d80debSLuiz Augusto von Dentz min = ~0; 461473d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 461573d80debSLuiz Augusto von Dentz } 461673d80debSLuiz Augusto von Dentz 461773d80debSLuiz Augusto von Dentz num++; 461873d80debSLuiz Augusto von Dentz 461973d80debSLuiz Augusto von Dentz if (conn->sent < min) { 462073d80debSLuiz Augusto von Dentz min = conn->sent; 462173d80debSLuiz Augusto von Dentz chan = tmp; 462273d80debSLuiz Augusto von Dentz } 462373d80debSLuiz Augusto von Dentz } 462473d80debSLuiz Augusto von Dentz 462573d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 462673d80debSLuiz Augusto von Dentz break; 462773d80debSLuiz Augusto von Dentz } 462873d80debSLuiz Augusto von Dentz 4629bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4630bf4c6325SGustavo F. Padovan 463173d80debSLuiz Augusto von Dentz if (!chan) 463273d80debSLuiz Augusto von Dentz return NULL; 463373d80debSLuiz Augusto von Dentz 463473d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 463573d80debSLuiz Augusto von Dentz case ACL_LINK: 463673d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 463773d80debSLuiz Augusto von Dentz break; 4638bd1eb66bSAndrei Emeltchenko case AMP_LINK: 4639bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 4640bd1eb66bSAndrei Emeltchenko break; 464173d80debSLuiz Augusto von Dentz case SCO_LINK: 464273d80debSLuiz Augusto von Dentz case ESCO_LINK: 464373d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 464473d80debSLuiz Augusto von Dentz break; 464573d80debSLuiz Augusto von Dentz case LE_LINK: 464673d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 464773d80debSLuiz Augusto von Dentz break; 464873d80debSLuiz Augusto von Dentz default: 464973d80debSLuiz Augusto von Dentz cnt = 0; 465073d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 465173d80debSLuiz Augusto von Dentz } 465273d80debSLuiz Augusto von Dentz 465373d80debSLuiz Augusto von Dentz q = cnt / num; 465473d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 465573d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 465673d80debSLuiz Augusto von Dentz return chan; 465773d80debSLuiz Augusto von Dentz } 465873d80debSLuiz Augusto von Dentz 465902b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 466002b20f0bSLuiz Augusto von Dentz { 466102b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 466202b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 466302b20f0bSLuiz Augusto von Dentz int num = 0; 466402b20f0bSLuiz Augusto von Dentz 466502b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 466602b20f0bSLuiz Augusto von Dentz 4667bf4c6325SGustavo F. Padovan rcu_read_lock(); 4668bf4c6325SGustavo F. Padovan 4669bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 467002b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 467102b20f0bSLuiz Augusto von Dentz 467202b20f0bSLuiz Augusto von Dentz if (conn->type != type) 467302b20f0bSLuiz Augusto von Dentz continue; 467402b20f0bSLuiz Augusto von Dentz 467502b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 467602b20f0bSLuiz Augusto von Dentz continue; 467702b20f0bSLuiz Augusto von Dentz 467802b20f0bSLuiz Augusto von Dentz num++; 467902b20f0bSLuiz Augusto von Dentz 46808192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 468102b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 468202b20f0bSLuiz Augusto von Dentz 468302b20f0bSLuiz Augusto von Dentz if (chan->sent) { 468402b20f0bSLuiz Augusto von Dentz chan->sent = 0; 468502b20f0bSLuiz Augusto von Dentz continue; 468602b20f0bSLuiz Augusto von Dentz } 468702b20f0bSLuiz Augusto von Dentz 468802b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 468902b20f0bSLuiz Augusto von Dentz continue; 469002b20f0bSLuiz Augusto von Dentz 469102b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 469202b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 469302b20f0bSLuiz Augusto von Dentz continue; 469402b20f0bSLuiz Augusto von Dentz 469502b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 469602b20f0bSLuiz Augusto von Dentz 469702b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 469802b20f0bSLuiz Augusto von Dentz skb->priority); 469902b20f0bSLuiz Augusto von Dentz } 470002b20f0bSLuiz Augusto von Dentz 470102b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 470202b20f0bSLuiz Augusto von Dentz break; 470302b20f0bSLuiz Augusto von Dentz } 4704bf4c6325SGustavo F. Padovan 4705bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4706bf4c6325SGustavo F. Padovan 470702b20f0bSLuiz Augusto von Dentz } 470802b20f0bSLuiz Augusto von Dentz 4709b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4710b71d385aSAndrei Emeltchenko { 4711b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4712b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4713b71d385aSAndrei Emeltchenko } 4714b71d385aSAndrei Emeltchenko 47156039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 47161da177e4SLinus Torvalds { 47171da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 47181da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 47191da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 472063d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 47215f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 4722bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 47231da177e4SLinus Torvalds } 472463d2bc1bSAndrei Emeltchenko } 47251da177e4SLinus Torvalds 47266039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 472763d2bc1bSAndrei Emeltchenko { 472863d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 472963d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 473063d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 473163d2bc1bSAndrei Emeltchenko int quote; 473263d2bc1bSAndrei Emeltchenko 473363d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 473404837f64SMarcel Holtmann 473573d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 473673d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 4737ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4738ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 473973d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 474073d80debSLuiz Augusto von Dentz skb->len, skb->priority); 474173d80debSLuiz Augusto von Dentz 4742ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4743ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4744ec1cce24SLuiz Augusto von Dentz break; 4745ec1cce24SLuiz Augusto von Dentz 4746ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4747ec1cce24SLuiz Augusto von Dentz 474873d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 474973d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 475004837f64SMarcel Holtmann 475157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 47521da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 47531da177e4SLinus Torvalds 47541da177e4SLinus Torvalds hdev->acl_cnt--; 475573d80debSLuiz Augusto von Dentz chan->sent++; 475673d80debSLuiz Augusto von Dentz chan->conn->sent++; 47571da177e4SLinus Torvalds } 47581da177e4SLinus Torvalds } 475902b20f0bSLuiz Augusto von Dentz 476002b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 476102b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 47621da177e4SLinus Torvalds } 47631da177e4SLinus Torvalds 47646039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4765b71d385aSAndrei Emeltchenko { 476663d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4767b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4768b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4769b71d385aSAndrei Emeltchenko int quote; 4770bd1eb66bSAndrei Emeltchenko u8 type; 4771b71d385aSAndrei Emeltchenko 477263d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4773b71d385aSAndrei Emeltchenko 4774bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4775bd1eb66bSAndrei Emeltchenko 4776bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4777bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4778bd1eb66bSAndrei Emeltchenko else 4779bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4780bd1eb66bSAndrei Emeltchenko 4781b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4782bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4783b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4784b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4785b71d385aSAndrei Emeltchenko int blocks; 4786b71d385aSAndrei Emeltchenko 4787b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4788b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4789b71d385aSAndrei Emeltchenko 4790b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4791b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4792b71d385aSAndrei Emeltchenko break; 4793b71d385aSAndrei Emeltchenko 4794b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4795b71d385aSAndrei Emeltchenko 4796b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4797b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4798b71d385aSAndrei Emeltchenko return; 4799b71d385aSAndrei Emeltchenko 4800b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4801b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4802b71d385aSAndrei Emeltchenko 480357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4804b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4805b71d385aSAndrei Emeltchenko 4806b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4807b71d385aSAndrei Emeltchenko quote -= blocks; 4808b71d385aSAndrei Emeltchenko 4809b71d385aSAndrei Emeltchenko chan->sent += blocks; 4810b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4811b71d385aSAndrei Emeltchenko } 4812b71d385aSAndrei Emeltchenko } 4813b71d385aSAndrei Emeltchenko 4814b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4815bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4816b71d385aSAndrei Emeltchenko } 4817b71d385aSAndrei Emeltchenko 48186039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4819b71d385aSAndrei Emeltchenko { 4820b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4821b71d385aSAndrei Emeltchenko 4822bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4823bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 4824bd1eb66bSAndrei Emeltchenko return; 4825bd1eb66bSAndrei Emeltchenko 4826bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4827bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4828b71d385aSAndrei Emeltchenko return; 4829b71d385aSAndrei Emeltchenko 4830b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4831b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4832b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4833b71d385aSAndrei Emeltchenko break; 4834b71d385aSAndrei Emeltchenko 4835b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4836b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4837b71d385aSAndrei Emeltchenko break; 4838b71d385aSAndrei Emeltchenko } 4839b71d385aSAndrei Emeltchenko } 4840b71d385aSAndrei Emeltchenko 48411da177e4SLinus Torvalds /* Schedule SCO */ 48426039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 48431da177e4SLinus Torvalds { 48441da177e4SLinus Torvalds struct hci_conn *conn; 48451da177e4SLinus Torvalds struct sk_buff *skb; 48461da177e4SLinus Torvalds int quote; 48471da177e4SLinus Torvalds 48481da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 48491da177e4SLinus Torvalds 485052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 485152087a79SLuiz Augusto von Dentz return; 485252087a79SLuiz Augusto von Dentz 48531da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 48541da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 48551da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 485657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 48571da177e4SLinus Torvalds 48581da177e4SLinus Torvalds conn->sent++; 48591da177e4SLinus Torvalds if (conn->sent == ~0) 48601da177e4SLinus Torvalds conn->sent = 0; 48611da177e4SLinus Torvalds } 48621da177e4SLinus Torvalds } 48631da177e4SLinus Torvalds } 48641da177e4SLinus Torvalds 48656039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 4866b6a0dc82SMarcel Holtmann { 4867b6a0dc82SMarcel Holtmann struct hci_conn *conn; 4868b6a0dc82SMarcel Holtmann struct sk_buff *skb; 4869b6a0dc82SMarcel Holtmann int quote; 4870b6a0dc82SMarcel Holtmann 4871b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 4872b6a0dc82SMarcel Holtmann 487352087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 487452087a79SLuiz Augusto von Dentz return; 487552087a79SLuiz Augusto von Dentz 48768fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 48778fc9ced3SGustavo Padovan "e))) { 4878b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 4879b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 488057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4881b6a0dc82SMarcel Holtmann 4882b6a0dc82SMarcel Holtmann conn->sent++; 4883b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 4884b6a0dc82SMarcel Holtmann conn->sent = 0; 4885b6a0dc82SMarcel Holtmann } 4886b6a0dc82SMarcel Holtmann } 4887b6a0dc82SMarcel Holtmann } 4888b6a0dc82SMarcel Holtmann 48896039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 48906ed58ec5SVille Tervo { 489173d80debSLuiz Augusto von Dentz struct hci_chan *chan; 48926ed58ec5SVille Tervo struct sk_buff *skb; 489302b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 48946ed58ec5SVille Tervo 48956ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 48966ed58ec5SVille Tervo 489752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 489852087a79SLuiz Augusto von Dentz return; 489952087a79SLuiz Augusto von Dentz 49006ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 49016ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 49026ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 4903bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 49046ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 4905bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 49066ed58ec5SVille Tervo } 49076ed58ec5SVille Tervo 49086ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 490902b20f0bSLuiz Augusto von Dentz tmp = cnt; 491073d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 4911ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4912ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 491373d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 491473d80debSLuiz Augusto von Dentz skb->len, skb->priority); 49156ed58ec5SVille Tervo 4916ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4917ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4918ec1cce24SLuiz Augusto von Dentz break; 4919ec1cce24SLuiz Augusto von Dentz 4920ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4921ec1cce24SLuiz Augusto von Dentz 492257d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 49236ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 49246ed58ec5SVille Tervo 49256ed58ec5SVille Tervo cnt--; 492673d80debSLuiz Augusto von Dentz chan->sent++; 492773d80debSLuiz Augusto von Dentz chan->conn->sent++; 49286ed58ec5SVille Tervo } 49296ed58ec5SVille Tervo } 493073d80debSLuiz Augusto von Dentz 49316ed58ec5SVille Tervo if (hdev->le_pkts) 49326ed58ec5SVille Tervo hdev->le_cnt = cnt; 49336ed58ec5SVille Tervo else 49346ed58ec5SVille Tervo hdev->acl_cnt = cnt; 493502b20f0bSLuiz Augusto von Dentz 493602b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 493702b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 49386ed58ec5SVille Tervo } 49396ed58ec5SVille Tervo 49403eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 49411da177e4SLinus Torvalds { 49423eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 49431da177e4SLinus Torvalds struct sk_buff *skb; 49441da177e4SLinus Torvalds 49456ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 49466ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 49471da177e4SLinus Torvalds 494852de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 49491da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 49501da177e4SLinus Torvalds hci_sched_acl(hdev); 49511da177e4SLinus Torvalds hci_sched_sco(hdev); 4952b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 49536ed58ec5SVille Tervo hci_sched_le(hdev); 495452de599eSMarcel Holtmann } 49556ed58ec5SVille Tervo 49561da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 49571da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 495857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 49591da177e4SLinus Torvalds } 49601da177e4SLinus Torvalds 496125985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 49621da177e4SLinus Torvalds 49631da177e4SLinus Torvalds /* ACL data packet */ 49646039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 49651da177e4SLinus Torvalds { 49661da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 49671da177e4SLinus Torvalds struct hci_conn *conn; 49681da177e4SLinus Torvalds __u16 handle, flags; 49691da177e4SLinus Torvalds 49701da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 49711da177e4SLinus Torvalds 49721da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 49731da177e4SLinus Torvalds flags = hci_flags(handle); 49741da177e4SLinus Torvalds handle = hci_handle(handle); 49751da177e4SLinus Torvalds 4976f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4977a8c5fb1aSGustavo Padovan handle, flags); 49781da177e4SLinus Torvalds 49791da177e4SLinus Torvalds hdev->stat.acl_rx++; 49801da177e4SLinus Torvalds 49811da177e4SLinus Torvalds hci_dev_lock(hdev); 49821da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 49831da177e4SLinus Torvalds hci_dev_unlock(hdev); 49841da177e4SLinus Torvalds 49851da177e4SLinus Torvalds if (conn) { 498665983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 498704837f64SMarcel Holtmann 49881da177e4SLinus Torvalds /* Send to upper protocol */ 4989686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 49901da177e4SLinus Torvalds return; 49911da177e4SLinus Torvalds } else { 49921da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 49931da177e4SLinus Torvalds hdev->name, handle); 49941da177e4SLinus Torvalds } 49951da177e4SLinus Torvalds 49961da177e4SLinus Torvalds kfree_skb(skb); 49971da177e4SLinus Torvalds } 49981da177e4SLinus Torvalds 49991da177e4SLinus Torvalds /* SCO data packet */ 50006039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 50011da177e4SLinus Torvalds { 50021da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 50031da177e4SLinus Torvalds struct hci_conn *conn; 50041da177e4SLinus Torvalds __u16 handle; 50051da177e4SLinus Torvalds 50061da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 50071da177e4SLinus Torvalds 50081da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 50091da177e4SLinus Torvalds 5010f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 50111da177e4SLinus Torvalds 50121da177e4SLinus Torvalds hdev->stat.sco_rx++; 50131da177e4SLinus Torvalds 50141da177e4SLinus Torvalds hci_dev_lock(hdev); 50151da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 50161da177e4SLinus Torvalds hci_dev_unlock(hdev); 50171da177e4SLinus Torvalds 50181da177e4SLinus Torvalds if (conn) { 50191da177e4SLinus Torvalds /* Send to upper protocol */ 5020686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 50211da177e4SLinus Torvalds return; 50221da177e4SLinus Torvalds } else { 50231da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 50241da177e4SLinus Torvalds hdev->name, handle); 50251da177e4SLinus Torvalds } 50261da177e4SLinus Torvalds 50271da177e4SLinus Torvalds kfree_skb(skb); 50281da177e4SLinus Torvalds } 50291da177e4SLinus Torvalds 50309238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 50319238f36aSJohan Hedberg { 50329238f36aSJohan Hedberg struct sk_buff *skb; 50339238f36aSJohan Hedberg 50349238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 50359238f36aSJohan Hedberg if (!skb) 50369238f36aSJohan Hedberg return true; 50379238f36aSJohan Hedberg 50389238f36aSJohan Hedberg return bt_cb(skb)->req.start; 50399238f36aSJohan Hedberg } 50409238f36aSJohan Hedberg 504142c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 504242c6b129SJohan Hedberg { 504342c6b129SJohan Hedberg struct hci_command_hdr *sent; 504442c6b129SJohan Hedberg struct sk_buff *skb; 504542c6b129SJohan Hedberg u16 opcode; 504642c6b129SJohan Hedberg 504742c6b129SJohan Hedberg if (!hdev->sent_cmd) 504842c6b129SJohan Hedberg return; 504942c6b129SJohan Hedberg 505042c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 505142c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 505242c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 505342c6b129SJohan Hedberg return; 505442c6b129SJohan Hedberg 505542c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 505642c6b129SJohan Hedberg if (!skb) 505742c6b129SJohan Hedberg return; 505842c6b129SJohan Hedberg 505942c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 506042c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 506142c6b129SJohan Hedberg } 506242c6b129SJohan Hedberg 50639238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 50649238f36aSJohan Hedberg { 50659238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 50669238f36aSJohan Hedberg struct sk_buff *skb; 50679238f36aSJohan Hedberg unsigned long flags; 50689238f36aSJohan Hedberg 50699238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 50709238f36aSJohan Hedberg 507142c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 507242c6b129SJohan Hedberg * sent we need to do special handling of it. 50739238f36aSJohan Hedberg */ 507442c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 507542c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 507642c6b129SJohan Hedberg * reset complete event during init and any pending 507742c6b129SJohan Hedberg * command will never be completed. In such a case we 507842c6b129SJohan Hedberg * need to resend whatever was the last sent 507942c6b129SJohan Hedberg * command. 508042c6b129SJohan Hedberg */ 508142c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 508242c6b129SJohan Hedberg hci_resend_last(hdev); 508342c6b129SJohan Hedberg 50849238f36aSJohan Hedberg return; 508542c6b129SJohan Hedberg } 50869238f36aSJohan Hedberg 50879238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 50889238f36aSJohan Hedberg * this request the request is not yet complete. 50899238f36aSJohan Hedberg */ 50909238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 50919238f36aSJohan Hedberg return; 50929238f36aSJohan Hedberg 50939238f36aSJohan Hedberg /* If this was the last command in a request the complete 50949238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 50959238f36aSJohan Hedberg * command queue (hdev->cmd_q). 50969238f36aSJohan Hedberg */ 50979238f36aSJohan Hedberg if (hdev->sent_cmd) { 50989238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 509953e21fbcSJohan Hedberg 510053e21fbcSJohan Hedberg if (req_complete) { 510153e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 510253e21fbcSJohan Hedberg * avoid calling the callback more than once if 510353e21fbcSJohan Hedberg * this function gets called again. 510453e21fbcSJohan Hedberg */ 510553e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 510653e21fbcSJohan Hedberg 51079238f36aSJohan Hedberg goto call_complete; 51089238f36aSJohan Hedberg } 510953e21fbcSJohan Hedberg } 51109238f36aSJohan Hedberg 51119238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 51129238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 51139238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 51149238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 51159238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 51169238f36aSJohan Hedberg break; 51179238f36aSJohan Hedberg } 51189238f36aSJohan Hedberg 51199238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 51209238f36aSJohan Hedberg kfree_skb(skb); 51219238f36aSJohan Hedberg } 51229238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 51239238f36aSJohan Hedberg 51249238f36aSJohan Hedberg call_complete: 51259238f36aSJohan Hedberg if (req_complete) 51269238f36aSJohan Hedberg req_complete(hdev, status); 51279238f36aSJohan Hedberg } 51289238f36aSJohan Hedberg 5129b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 51301da177e4SLinus Torvalds { 5131b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 51321da177e4SLinus Torvalds struct sk_buff *skb; 51331da177e4SLinus Torvalds 51341da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 51351da177e4SLinus Torvalds 51361da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 5137cd82e61cSMarcel Holtmann /* Send copy to monitor */ 5138cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 5139cd82e61cSMarcel Holtmann 51401da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 51411da177e4SLinus Torvalds /* Send copy to the sockets */ 5142470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 51431da177e4SLinus Torvalds } 51441da177e4SLinus Torvalds 51450736cfa8SMarcel Holtmann if (test_bit(HCI_RAW, &hdev->flags) || 51460736cfa8SMarcel Holtmann test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 51471da177e4SLinus Torvalds kfree_skb(skb); 51481da177e4SLinus Torvalds continue; 51491da177e4SLinus Torvalds } 51501da177e4SLinus Torvalds 51511da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 51521da177e4SLinus Torvalds /* Don't process data packets in this states. */ 51530d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 51541da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 51551da177e4SLinus Torvalds case HCI_SCODATA_PKT: 51561da177e4SLinus Torvalds kfree_skb(skb); 51571da177e4SLinus Torvalds continue; 51583ff50b79SStephen Hemminger } 51591da177e4SLinus Torvalds } 51601da177e4SLinus Torvalds 51611da177e4SLinus Torvalds /* Process frame */ 51620d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 51631da177e4SLinus Torvalds case HCI_EVENT_PKT: 5164b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 51651da177e4SLinus Torvalds hci_event_packet(hdev, skb); 51661da177e4SLinus Torvalds break; 51671da177e4SLinus Torvalds 51681da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 51691da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 51701da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 51711da177e4SLinus Torvalds break; 51721da177e4SLinus Torvalds 51731da177e4SLinus Torvalds case HCI_SCODATA_PKT: 51741da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 51751da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 51761da177e4SLinus Torvalds break; 51771da177e4SLinus Torvalds 51781da177e4SLinus Torvalds default: 51791da177e4SLinus Torvalds kfree_skb(skb); 51801da177e4SLinus Torvalds break; 51811da177e4SLinus Torvalds } 51821da177e4SLinus Torvalds } 51831da177e4SLinus Torvalds } 51841da177e4SLinus Torvalds 5185c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 51861da177e4SLinus Torvalds { 5187c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 51881da177e4SLinus Torvalds struct sk_buff *skb; 51891da177e4SLinus Torvalds 51902104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 51912104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 51921da177e4SLinus Torvalds 51931da177e4SLinus Torvalds /* Send queued commands */ 51945a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 51955a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 51965a08ecceSAndrei Emeltchenko if (!skb) 51975a08ecceSAndrei Emeltchenko return; 51985a08ecceSAndrei Emeltchenko 51991da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 52001da177e4SLinus Torvalds 5201a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 520270f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 52031da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 520457d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 52057bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 52067bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 52077bdb8a5cSSzymon Janc else 52086bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 52095f246e89SAndrei Emeltchenko jiffies + HCI_CMD_TIMEOUT); 52101da177e4SLinus Torvalds } else { 52111da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 5212c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 52131da177e4SLinus Torvalds } 52141da177e4SLinus Torvalds } 52151da177e4SLinus Torvalds } 5216b1efcc28SAndre Guedes 5217b1efcc28SAndre Guedes void hci_req_add_le_scan_disable(struct hci_request *req) 5218b1efcc28SAndre Guedes { 5219b1efcc28SAndre Guedes struct hci_cp_le_set_scan_enable cp; 5220b1efcc28SAndre Guedes 5221b1efcc28SAndre Guedes memset(&cp, 0, sizeof(cp)); 5222b1efcc28SAndre Guedes cp.enable = LE_SCAN_DISABLE; 5223b1efcc28SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 5224b1efcc28SAndre Guedes } 5225a4790dbdSAndre Guedes 52268ef30fd3SAndre Guedes void hci_req_add_le_passive_scan(struct hci_request *req) 52278ef30fd3SAndre Guedes { 52288ef30fd3SAndre Guedes struct hci_cp_le_set_scan_param param_cp; 52298ef30fd3SAndre Guedes struct hci_cp_le_set_scan_enable enable_cp; 52308ef30fd3SAndre Guedes struct hci_dev *hdev = req->hdev; 52318ef30fd3SAndre Guedes u8 own_addr_type; 52328ef30fd3SAndre Guedes 52338ef30fd3SAndre Guedes /* Set require_privacy to true to avoid identification from 52348ef30fd3SAndre Guedes * unknown peer devices. Since this is passive scanning, no 52358ef30fd3SAndre Guedes * SCAN_REQ using the local identity should be sent. Mandating 52368ef30fd3SAndre Guedes * privacy is just an extra precaution. 52378ef30fd3SAndre Guedes */ 52388ef30fd3SAndre Guedes if (hci_update_random_address(req, true, &own_addr_type)) 52398ef30fd3SAndre Guedes return; 52408ef30fd3SAndre Guedes 52418ef30fd3SAndre Guedes memset(¶m_cp, 0, sizeof(param_cp)); 52428ef30fd3SAndre Guedes param_cp.type = LE_SCAN_PASSIVE; 52438ef30fd3SAndre Guedes param_cp.interval = cpu_to_le16(hdev->le_scan_interval); 52448ef30fd3SAndre Guedes param_cp.window = cpu_to_le16(hdev->le_scan_window); 52458ef30fd3SAndre Guedes param_cp.own_address_type = own_addr_type; 52468ef30fd3SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), 52478ef30fd3SAndre Guedes ¶m_cp); 52488ef30fd3SAndre Guedes 52498ef30fd3SAndre Guedes memset(&enable_cp, 0, sizeof(enable_cp)); 52508ef30fd3SAndre Guedes enable_cp.enable = LE_SCAN_ENABLE; 52518ef30fd3SAndre Guedes enable_cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE; 52528ef30fd3SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), 52538ef30fd3SAndre Guedes &enable_cp); 52548ef30fd3SAndre Guedes } 52558ef30fd3SAndre Guedes 5256a4790dbdSAndre Guedes static void update_background_scan_complete(struct hci_dev *hdev, u8 status) 5257a4790dbdSAndre Guedes { 5258a4790dbdSAndre Guedes if (status) 5259a4790dbdSAndre Guedes BT_DBG("HCI request failed to update background scanning: " 5260a4790dbdSAndre Guedes "status 0x%2.2x", status); 5261a4790dbdSAndre Guedes } 5262a4790dbdSAndre Guedes 5263a4790dbdSAndre Guedes /* This function controls the background scanning based on hdev->pend_le_conns 5264a4790dbdSAndre Guedes * list. If there are pending LE connection we start the background scanning, 5265a4790dbdSAndre Guedes * otherwise we stop it. 5266a4790dbdSAndre Guedes * 5267a4790dbdSAndre Guedes * This function requires the caller holds hdev->lock. 5268a4790dbdSAndre Guedes */ 5269a4790dbdSAndre Guedes void hci_update_background_scan(struct hci_dev *hdev) 5270a4790dbdSAndre Guedes { 5271a4790dbdSAndre Guedes struct hci_request req; 5272a4790dbdSAndre Guedes struct hci_conn *conn; 5273a4790dbdSAndre Guedes int err; 5274a4790dbdSAndre Guedes 5275a4790dbdSAndre Guedes hci_req_init(&req, hdev); 5276a4790dbdSAndre Guedes 5277a4790dbdSAndre Guedes if (list_empty(&hdev->pend_le_conns)) { 5278a4790dbdSAndre Guedes /* If there is no pending LE connections, we should stop 5279a4790dbdSAndre Guedes * the background scanning. 5280a4790dbdSAndre Guedes */ 5281a4790dbdSAndre Guedes 5282a4790dbdSAndre Guedes /* If controller is not scanning we are done. */ 5283a4790dbdSAndre Guedes if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 5284a4790dbdSAndre Guedes return; 5285a4790dbdSAndre Guedes 5286a4790dbdSAndre Guedes hci_req_add_le_scan_disable(&req); 5287a4790dbdSAndre Guedes 5288a4790dbdSAndre Guedes BT_DBG("%s stopping background scanning", hdev->name); 5289a4790dbdSAndre Guedes } else { 5290a4790dbdSAndre Guedes /* If there is at least one pending LE connection, we should 5291a4790dbdSAndre Guedes * keep the background scan running. 5292a4790dbdSAndre Guedes */ 5293a4790dbdSAndre Guedes 5294a4790dbdSAndre Guedes /* If controller is already scanning we are done. */ 5295a4790dbdSAndre Guedes if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 5296a4790dbdSAndre Guedes return; 5297a4790dbdSAndre Guedes 5298a4790dbdSAndre Guedes /* If controller is connecting, we should not start scanning 5299a4790dbdSAndre Guedes * since some controllers are not able to scan and connect at 5300a4790dbdSAndre Guedes * the same time. 5301a4790dbdSAndre Guedes */ 5302a4790dbdSAndre Guedes conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 5303a4790dbdSAndre Guedes if (conn) 5304a4790dbdSAndre Guedes return; 5305a4790dbdSAndre Guedes 53068ef30fd3SAndre Guedes hci_req_add_le_passive_scan(&req); 5307a4790dbdSAndre Guedes 5308a4790dbdSAndre Guedes BT_DBG("%s starting background scanning", hdev->name); 5309a4790dbdSAndre Guedes } 5310a4790dbdSAndre Guedes 5311a4790dbdSAndre Guedes err = hci_req_run(&req, update_background_scan_complete); 5312a4790dbdSAndre Guedes if (err) 5313a4790dbdSAndre Guedes BT_ERR("Failed to run HCI request: err %d", err); 5314a4790dbdSAndre Guedes } 5315