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 4952bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val) 4962bfa3531SMarcel Holtmann { 4972bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4982bfa3531SMarcel Holtmann 4992bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val > hdev->sniff_max_interval) 5002bfa3531SMarcel Holtmann return -EINVAL; 5012bfa3531SMarcel Holtmann 5022bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5032bfa3531SMarcel Holtmann hdev->sniff_min_interval = val; 5042bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5052bfa3531SMarcel Holtmann 5062bfa3531SMarcel Holtmann return 0; 5072bfa3531SMarcel Holtmann } 5082bfa3531SMarcel Holtmann 5092bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val) 5102bfa3531SMarcel Holtmann { 5112bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5122bfa3531SMarcel Holtmann 5132bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5142bfa3531SMarcel Holtmann *val = hdev->sniff_min_interval; 5152bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5162bfa3531SMarcel Holtmann 5172bfa3531SMarcel Holtmann return 0; 5182bfa3531SMarcel Holtmann } 5192bfa3531SMarcel Holtmann 5202bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get, 5212bfa3531SMarcel Holtmann sniff_min_interval_set, "%llu\n"); 5222bfa3531SMarcel Holtmann 5232bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val) 5242bfa3531SMarcel Holtmann { 5252bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5262bfa3531SMarcel Holtmann 5272bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val < hdev->sniff_min_interval) 5282bfa3531SMarcel Holtmann return -EINVAL; 5292bfa3531SMarcel Holtmann 5302bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5312bfa3531SMarcel Holtmann hdev->sniff_max_interval = val; 5322bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5332bfa3531SMarcel Holtmann 5342bfa3531SMarcel Holtmann return 0; 5352bfa3531SMarcel Holtmann } 5362bfa3531SMarcel Holtmann 5372bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val) 5382bfa3531SMarcel Holtmann { 5392bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5402bfa3531SMarcel Holtmann 5412bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5422bfa3531SMarcel Holtmann *val = hdev->sniff_max_interval; 5432bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5442bfa3531SMarcel Holtmann 5452bfa3531SMarcel Holtmann return 0; 5462bfa3531SMarcel Holtmann } 5472bfa3531SMarcel Holtmann 5482bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, 5492bfa3531SMarcel Holtmann sniff_max_interval_set, "%llu\n"); 5502bfa3531SMarcel Holtmann 551e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p) 552e7b8fc92SMarcel Holtmann { 553e7b8fc92SMarcel Holtmann struct hci_dev *hdev = f->private; 554e7b8fc92SMarcel Holtmann 555e7b8fc92SMarcel Holtmann hci_dev_lock(hdev); 556e7b8fc92SMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->static_addr); 557e7b8fc92SMarcel Holtmann hci_dev_unlock(hdev); 558e7b8fc92SMarcel Holtmann 559e7b8fc92SMarcel Holtmann return 0; 560e7b8fc92SMarcel Holtmann } 561e7b8fc92SMarcel Holtmann 562e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file) 563e7b8fc92SMarcel Holtmann { 564e7b8fc92SMarcel Holtmann return single_open(file, static_address_show, inode->i_private); 565e7b8fc92SMarcel Holtmann } 566e7b8fc92SMarcel Holtmann 567e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = { 568e7b8fc92SMarcel Holtmann .open = static_address_open, 569e7b8fc92SMarcel Holtmann .read = seq_read, 570e7b8fc92SMarcel Holtmann .llseek = seq_lseek, 571e7b8fc92SMarcel Holtmann .release = single_release, 572e7b8fc92SMarcel Holtmann }; 573e7b8fc92SMarcel Holtmann 574b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file, 575b32bba6cSMarcel Holtmann char __user *user_buf, 576b32bba6cSMarcel Holtmann size_t count, loff_t *ppos) 57792202185SMarcel Holtmann { 578b32bba6cSMarcel Holtmann struct hci_dev *hdev = file->private_data; 579b32bba6cSMarcel Holtmann char buf[3]; 58092202185SMarcel Holtmann 581b32bba6cSMarcel Holtmann buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ? 'Y': 'N'; 582b32bba6cSMarcel Holtmann buf[1] = '\n'; 583b32bba6cSMarcel Holtmann buf[2] = '\0'; 584b32bba6cSMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 585b32bba6cSMarcel Holtmann } 586b32bba6cSMarcel Holtmann 587b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file, 588b32bba6cSMarcel Holtmann const char __user *user_buf, 589b32bba6cSMarcel Holtmann size_t count, loff_t *ppos) 590b32bba6cSMarcel Holtmann { 591b32bba6cSMarcel Holtmann struct hci_dev *hdev = file->private_data; 592b32bba6cSMarcel Holtmann char buf[32]; 593b32bba6cSMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 594b32bba6cSMarcel Holtmann bool enable; 595b32bba6cSMarcel Holtmann 596b32bba6cSMarcel Holtmann if (test_bit(HCI_UP, &hdev->flags)) 597b32bba6cSMarcel Holtmann return -EBUSY; 598b32bba6cSMarcel Holtmann 599b32bba6cSMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 600b32bba6cSMarcel Holtmann return -EFAULT; 601b32bba6cSMarcel Holtmann 602b32bba6cSMarcel Holtmann buf[buf_size] = '\0'; 603b32bba6cSMarcel Holtmann if (strtobool(buf, &enable)) 60492202185SMarcel Holtmann return -EINVAL; 60592202185SMarcel Holtmann 606b32bba6cSMarcel Holtmann if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags)) 607b32bba6cSMarcel Holtmann return -EALREADY; 60892202185SMarcel Holtmann 609b32bba6cSMarcel Holtmann change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags); 610b32bba6cSMarcel Holtmann 611b32bba6cSMarcel Holtmann return count; 61292202185SMarcel Holtmann } 61392202185SMarcel Holtmann 614b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = { 615b32bba6cSMarcel Holtmann .open = simple_open, 616b32bba6cSMarcel Holtmann .read = force_static_address_read, 617b32bba6cSMarcel Holtmann .write = force_static_address_write, 618b32bba6cSMarcel Holtmann .llseek = default_llseek, 619b32bba6cSMarcel Holtmann }; 62092202185SMarcel Holtmann 6213698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr) 6223698d704SMarcel Holtmann { 6233698d704SMarcel Holtmann struct hci_dev *hdev = f->private; 6243698d704SMarcel Holtmann struct list_head *p, *n; 6253698d704SMarcel Holtmann 6263698d704SMarcel Holtmann hci_dev_lock(hdev); 6273698d704SMarcel Holtmann list_for_each_safe(p, n, &hdev->identity_resolving_keys) { 6283698d704SMarcel Holtmann struct smp_irk *irk = list_entry(p, struct smp_irk, list); 6293698d704SMarcel Holtmann seq_printf(f, "%pMR (type %u) %*phN %pMR\n", 6303698d704SMarcel Holtmann &irk->bdaddr, irk->addr_type, 6313698d704SMarcel Holtmann 16, irk->val, &irk->rpa); 6323698d704SMarcel Holtmann } 6333698d704SMarcel Holtmann hci_dev_unlock(hdev); 6343698d704SMarcel Holtmann 6353698d704SMarcel Holtmann return 0; 6363698d704SMarcel Holtmann } 6373698d704SMarcel Holtmann 6383698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file) 6393698d704SMarcel Holtmann { 6403698d704SMarcel Holtmann return single_open(file, identity_resolving_keys_show, 6413698d704SMarcel Holtmann inode->i_private); 6423698d704SMarcel Holtmann } 6433698d704SMarcel Holtmann 6443698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = { 6453698d704SMarcel Holtmann .open = identity_resolving_keys_open, 6463698d704SMarcel Holtmann .read = seq_read, 6473698d704SMarcel Holtmann .llseek = seq_lseek, 6483698d704SMarcel Holtmann .release = single_release, 6493698d704SMarcel Holtmann }; 6503698d704SMarcel Holtmann 6518f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr) 6528f8625cdSMarcel Holtmann { 6538f8625cdSMarcel Holtmann struct hci_dev *hdev = f->private; 6548f8625cdSMarcel Holtmann struct list_head *p, *n; 6558f8625cdSMarcel Holtmann 6568f8625cdSMarcel Holtmann hci_dev_lock(hdev); 657f813f1beSJohan Hedberg list_for_each_safe(p, n, &hdev->long_term_keys) { 6588f8625cdSMarcel Holtmann struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list); 659f813f1beSJohan Hedberg seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %*phN %*phN\n", 6608f8625cdSMarcel Holtmann <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, 6618f8625cdSMarcel Holtmann ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), 6628f8625cdSMarcel Holtmann 8, ltk->rand, 16, ltk->val); 6638f8625cdSMarcel Holtmann } 6648f8625cdSMarcel Holtmann hci_dev_unlock(hdev); 6658f8625cdSMarcel Holtmann 6668f8625cdSMarcel Holtmann return 0; 6678f8625cdSMarcel Holtmann } 6688f8625cdSMarcel Holtmann 6698f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file) 6708f8625cdSMarcel Holtmann { 6718f8625cdSMarcel Holtmann return single_open(file, long_term_keys_show, inode->i_private); 6728f8625cdSMarcel Holtmann } 6738f8625cdSMarcel Holtmann 6748f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = { 6758f8625cdSMarcel Holtmann .open = long_term_keys_open, 6768f8625cdSMarcel Holtmann .read = seq_read, 6778f8625cdSMarcel Holtmann .llseek = seq_lseek, 6788f8625cdSMarcel Holtmann .release = single_release, 6798f8625cdSMarcel Holtmann }; 6808f8625cdSMarcel Holtmann 6814e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val) 6824e70c7e7SMarcel Holtmann { 6834e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6844e70c7e7SMarcel Holtmann 6854e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval) 6864e70c7e7SMarcel Holtmann return -EINVAL; 6874e70c7e7SMarcel Holtmann 6884e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6894e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = val; 6904e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 6914e70c7e7SMarcel Holtmann 6924e70c7e7SMarcel Holtmann return 0; 6934e70c7e7SMarcel Holtmann } 6944e70c7e7SMarcel Holtmann 6954e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val) 6964e70c7e7SMarcel Holtmann { 6974e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6984e70c7e7SMarcel Holtmann 6994e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 7004e70c7e7SMarcel Holtmann *val = hdev->le_conn_min_interval; 7014e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 7024e70c7e7SMarcel Holtmann 7034e70c7e7SMarcel Holtmann return 0; 7044e70c7e7SMarcel Holtmann } 7054e70c7e7SMarcel Holtmann 7064e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get, 7074e70c7e7SMarcel Holtmann conn_min_interval_set, "%llu\n"); 7084e70c7e7SMarcel Holtmann 7094e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val) 7104e70c7e7SMarcel Holtmann { 7114e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 7124e70c7e7SMarcel Holtmann 7134e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval) 7144e70c7e7SMarcel Holtmann return -EINVAL; 7154e70c7e7SMarcel Holtmann 7164e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 7174e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = val; 7184e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 7194e70c7e7SMarcel Holtmann 7204e70c7e7SMarcel Holtmann return 0; 7214e70c7e7SMarcel Holtmann } 7224e70c7e7SMarcel Holtmann 7234e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val) 7244e70c7e7SMarcel Holtmann { 7254e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 7264e70c7e7SMarcel Holtmann 7274e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 7284e70c7e7SMarcel Holtmann *val = hdev->le_conn_max_interval; 7294e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 7304e70c7e7SMarcel Holtmann 7314e70c7e7SMarcel Holtmann return 0; 7324e70c7e7SMarcel Holtmann } 7334e70c7e7SMarcel Holtmann 7344e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, 7354e70c7e7SMarcel Holtmann conn_max_interval_set, "%llu\n"); 7364e70c7e7SMarcel Holtmann 73789863109SJukka Rissanen static ssize_t lowpan_read(struct file *file, char __user *user_buf, 73889863109SJukka Rissanen size_t count, loff_t *ppos) 73989863109SJukka Rissanen { 74089863109SJukka Rissanen struct hci_dev *hdev = file->private_data; 74189863109SJukka Rissanen char buf[3]; 74289863109SJukka Rissanen 74389863109SJukka Rissanen buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N'; 74489863109SJukka Rissanen buf[1] = '\n'; 74589863109SJukka Rissanen buf[2] = '\0'; 74689863109SJukka Rissanen return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 74789863109SJukka Rissanen } 74889863109SJukka Rissanen 74989863109SJukka Rissanen static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer, 75089863109SJukka Rissanen size_t count, loff_t *position) 75189863109SJukka Rissanen { 75289863109SJukka Rissanen struct hci_dev *hdev = fp->private_data; 75389863109SJukka Rissanen bool enable; 75489863109SJukka Rissanen char buf[32]; 75589863109SJukka Rissanen size_t buf_size = min(count, (sizeof(buf)-1)); 75689863109SJukka Rissanen 75789863109SJukka Rissanen if (copy_from_user(buf, user_buffer, buf_size)) 75889863109SJukka Rissanen return -EFAULT; 75989863109SJukka Rissanen 76089863109SJukka Rissanen buf[buf_size] = '\0'; 76189863109SJukka Rissanen 76289863109SJukka Rissanen if (strtobool(buf, &enable) < 0) 76389863109SJukka Rissanen return -EINVAL; 76489863109SJukka Rissanen 76589863109SJukka Rissanen if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags)) 76689863109SJukka Rissanen return -EALREADY; 76789863109SJukka Rissanen 76889863109SJukka Rissanen change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags); 76989863109SJukka Rissanen 77089863109SJukka Rissanen return count; 77189863109SJukka Rissanen } 77289863109SJukka Rissanen 77389863109SJukka Rissanen static const struct file_operations lowpan_debugfs_fops = { 77489863109SJukka Rissanen .open = simple_open, 77589863109SJukka Rissanen .read = lowpan_read, 77689863109SJukka Rissanen .write = lowpan_write, 77789863109SJukka Rissanen .llseek = default_llseek, 77889863109SJukka Rissanen }; 77989863109SJukka Rissanen 7801da177e4SLinus Torvalds /* ---- HCI requests ---- */ 7811da177e4SLinus Torvalds 78242c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 7831da177e4SLinus Torvalds { 78442c6b129SJohan Hedberg BT_DBG("%s result 0x%2.2x", hdev->name, result); 78575fb0e32SJohan Hedberg 7861da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 7871da177e4SLinus Torvalds hdev->req_result = result; 7881da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 7891da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 7901da177e4SLinus Torvalds } 7911da177e4SLinus Torvalds } 7921da177e4SLinus Torvalds 7931da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 7941da177e4SLinus Torvalds { 7951da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 7961da177e4SLinus Torvalds 7971da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 7981da177e4SLinus Torvalds hdev->req_result = err; 7991da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 8001da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 8011da177e4SLinus Torvalds } 8021da177e4SLinus Torvalds } 8031da177e4SLinus Torvalds 80477a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 80577a63e0aSFengguang Wu u8 event) 80675e84b7cSJohan Hedberg { 80775e84b7cSJohan Hedberg struct hci_ev_cmd_complete *ev; 80875e84b7cSJohan Hedberg struct hci_event_hdr *hdr; 80975e84b7cSJohan Hedberg struct sk_buff *skb; 81075e84b7cSJohan Hedberg 81175e84b7cSJohan Hedberg hci_dev_lock(hdev); 81275e84b7cSJohan Hedberg 81375e84b7cSJohan Hedberg skb = hdev->recv_evt; 81475e84b7cSJohan Hedberg hdev->recv_evt = NULL; 81575e84b7cSJohan Hedberg 81675e84b7cSJohan Hedberg hci_dev_unlock(hdev); 81775e84b7cSJohan Hedberg 81875e84b7cSJohan Hedberg if (!skb) 81975e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 82075e84b7cSJohan Hedberg 82175e84b7cSJohan Hedberg if (skb->len < sizeof(*hdr)) { 82275e84b7cSJohan Hedberg BT_ERR("Too short HCI event"); 82375e84b7cSJohan Hedberg goto failed; 82475e84b7cSJohan Hedberg } 82575e84b7cSJohan Hedberg 82675e84b7cSJohan Hedberg hdr = (void *) skb->data; 82775e84b7cSJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 82875e84b7cSJohan Hedberg 8297b1abbbeSJohan Hedberg if (event) { 8307b1abbbeSJohan Hedberg if (hdr->evt != event) 8317b1abbbeSJohan Hedberg goto failed; 8327b1abbbeSJohan Hedberg return skb; 8337b1abbbeSJohan Hedberg } 8347b1abbbeSJohan Hedberg 83575e84b7cSJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 83675e84b7cSJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 83775e84b7cSJohan Hedberg goto failed; 83875e84b7cSJohan Hedberg } 83975e84b7cSJohan Hedberg 84075e84b7cSJohan Hedberg if (skb->len < sizeof(*ev)) { 84175e84b7cSJohan Hedberg BT_ERR("Too short cmd_complete event"); 84275e84b7cSJohan Hedberg goto failed; 84375e84b7cSJohan Hedberg } 84475e84b7cSJohan Hedberg 84575e84b7cSJohan Hedberg ev = (void *) skb->data; 84675e84b7cSJohan Hedberg skb_pull(skb, sizeof(*ev)); 84775e84b7cSJohan Hedberg 84875e84b7cSJohan Hedberg if (opcode == __le16_to_cpu(ev->opcode)) 84975e84b7cSJohan Hedberg return skb; 85075e84b7cSJohan Hedberg 85175e84b7cSJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 85275e84b7cSJohan Hedberg __le16_to_cpu(ev->opcode)); 85375e84b7cSJohan Hedberg 85475e84b7cSJohan Hedberg failed: 85575e84b7cSJohan Hedberg kfree_skb(skb); 85675e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 85775e84b7cSJohan Hedberg } 85875e84b7cSJohan Hedberg 8597b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 86007dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout) 86175e84b7cSJohan Hedberg { 86275e84b7cSJohan Hedberg DECLARE_WAITQUEUE(wait, current); 86375e84b7cSJohan Hedberg struct hci_request req; 86475e84b7cSJohan Hedberg int err = 0; 86575e84b7cSJohan Hedberg 86675e84b7cSJohan Hedberg BT_DBG("%s", hdev->name); 86775e84b7cSJohan Hedberg 86875e84b7cSJohan Hedberg hci_req_init(&req, hdev); 86975e84b7cSJohan Hedberg 8707b1abbbeSJohan Hedberg hci_req_add_ev(&req, opcode, plen, param, event); 87175e84b7cSJohan Hedberg 87275e84b7cSJohan Hedberg hdev->req_status = HCI_REQ_PEND; 87375e84b7cSJohan Hedberg 87475e84b7cSJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 87575e84b7cSJohan Hedberg if (err < 0) 87675e84b7cSJohan Hedberg return ERR_PTR(err); 87775e84b7cSJohan Hedberg 87875e84b7cSJohan Hedberg add_wait_queue(&hdev->req_wait_q, &wait); 87975e84b7cSJohan Hedberg set_current_state(TASK_INTERRUPTIBLE); 88075e84b7cSJohan Hedberg 88175e84b7cSJohan Hedberg schedule_timeout(timeout); 88275e84b7cSJohan Hedberg 88375e84b7cSJohan Hedberg remove_wait_queue(&hdev->req_wait_q, &wait); 88475e84b7cSJohan Hedberg 88575e84b7cSJohan Hedberg if (signal_pending(current)) 88675e84b7cSJohan Hedberg return ERR_PTR(-EINTR); 88775e84b7cSJohan Hedberg 88875e84b7cSJohan Hedberg switch (hdev->req_status) { 88975e84b7cSJohan Hedberg case HCI_REQ_DONE: 89075e84b7cSJohan Hedberg err = -bt_to_errno(hdev->req_result); 89175e84b7cSJohan Hedberg break; 89275e84b7cSJohan Hedberg 89375e84b7cSJohan Hedberg case HCI_REQ_CANCELED: 89475e84b7cSJohan Hedberg err = -hdev->req_result; 89575e84b7cSJohan Hedberg break; 89675e84b7cSJohan Hedberg 89775e84b7cSJohan Hedberg default: 89875e84b7cSJohan Hedberg err = -ETIMEDOUT; 89975e84b7cSJohan Hedberg break; 90075e84b7cSJohan Hedberg } 90175e84b7cSJohan Hedberg 90275e84b7cSJohan Hedberg hdev->req_status = hdev->req_result = 0; 90375e84b7cSJohan Hedberg 90475e84b7cSJohan Hedberg BT_DBG("%s end: err %d", hdev->name, err); 90575e84b7cSJohan Hedberg 90675e84b7cSJohan Hedberg if (err < 0) 90775e84b7cSJohan Hedberg return ERR_PTR(err); 90875e84b7cSJohan Hedberg 9097b1abbbeSJohan Hedberg return hci_get_cmd_complete(hdev, opcode, event); 9107b1abbbeSJohan Hedberg } 9117b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev); 9127b1abbbeSJohan Hedberg 9137b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 91407dc93ddSJohan Hedberg const void *param, u32 timeout) 9157b1abbbeSJohan Hedberg { 9167b1abbbeSJohan Hedberg return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); 91775e84b7cSJohan Hedberg } 91875e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync); 91975e84b7cSJohan Hedberg 9201da177e4SLinus Torvalds /* Execute request and wait for completion. */ 92101178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev, 92242c6b129SJohan Hedberg void (*func)(struct hci_request *req, 92342c6b129SJohan Hedberg unsigned long opt), 9241da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 9251da177e4SLinus Torvalds { 92642c6b129SJohan Hedberg struct hci_request req; 9271da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 9281da177e4SLinus Torvalds int err = 0; 9291da177e4SLinus Torvalds 9301da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 9311da177e4SLinus Torvalds 93242c6b129SJohan Hedberg hci_req_init(&req, hdev); 93342c6b129SJohan Hedberg 9341da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 9351da177e4SLinus Torvalds 93642c6b129SJohan Hedberg func(&req, opt); 93753cce22dSJohan Hedberg 93842c6b129SJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 93942c6b129SJohan Hedberg if (err < 0) { 94053cce22dSJohan Hedberg hdev->req_status = 0; 941920c8300SAndre Guedes 942920c8300SAndre Guedes /* ENODATA means the HCI request command queue is empty. 943920c8300SAndre Guedes * This can happen when a request with conditionals doesn't 944920c8300SAndre Guedes * trigger any commands to be sent. This is normal behavior 945920c8300SAndre Guedes * and should not trigger an error return. 94642c6b129SJohan Hedberg */ 947920c8300SAndre Guedes if (err == -ENODATA) 94842c6b129SJohan Hedberg return 0; 949920c8300SAndre Guedes 950920c8300SAndre Guedes return err; 95153cce22dSJohan Hedberg } 95253cce22dSJohan Hedberg 953bc4445c7SAndre Guedes add_wait_queue(&hdev->req_wait_q, &wait); 954bc4445c7SAndre Guedes set_current_state(TASK_INTERRUPTIBLE); 955bc4445c7SAndre Guedes 9561da177e4SLinus Torvalds schedule_timeout(timeout); 9571da177e4SLinus Torvalds 9581da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 9591da177e4SLinus Torvalds 9601da177e4SLinus Torvalds if (signal_pending(current)) 9611da177e4SLinus Torvalds return -EINTR; 9621da177e4SLinus Torvalds 9631da177e4SLinus Torvalds switch (hdev->req_status) { 9641da177e4SLinus Torvalds case HCI_REQ_DONE: 965e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 9661da177e4SLinus Torvalds break; 9671da177e4SLinus Torvalds 9681da177e4SLinus Torvalds case HCI_REQ_CANCELED: 9691da177e4SLinus Torvalds err = -hdev->req_result; 9701da177e4SLinus Torvalds break; 9711da177e4SLinus Torvalds 9721da177e4SLinus Torvalds default: 9731da177e4SLinus Torvalds err = -ETIMEDOUT; 9741da177e4SLinus Torvalds break; 9753ff50b79SStephen Hemminger } 9761da177e4SLinus Torvalds 977a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 9781da177e4SLinus Torvalds 9791da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 9801da177e4SLinus Torvalds 9811da177e4SLinus Torvalds return err; 9821da177e4SLinus Torvalds } 9831da177e4SLinus Torvalds 98401178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev, 98542c6b129SJohan Hedberg void (*req)(struct hci_request *req, 98642c6b129SJohan Hedberg unsigned long opt), 9871da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 9881da177e4SLinus Torvalds { 9891da177e4SLinus Torvalds int ret; 9901da177e4SLinus Torvalds 9917c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 9927c6a329eSMarcel Holtmann return -ENETDOWN; 9937c6a329eSMarcel Holtmann 9941da177e4SLinus Torvalds /* Serialize all requests */ 9951da177e4SLinus Torvalds hci_req_lock(hdev); 99601178cd4SJohan Hedberg ret = __hci_req_sync(hdev, req, opt, timeout); 9971da177e4SLinus Torvalds hci_req_unlock(hdev); 9981da177e4SLinus Torvalds 9991da177e4SLinus Torvalds return ret; 10001da177e4SLinus Torvalds } 10011da177e4SLinus Torvalds 100242c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt) 10031da177e4SLinus Torvalds { 100442c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 10051da177e4SLinus Torvalds 10061da177e4SLinus Torvalds /* Reset device */ 100742c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 100842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 10091da177e4SLinus Torvalds } 10101da177e4SLinus Torvalds 101142c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 10121da177e4SLinus Torvalds { 101342c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 10142455a3eaSAndrei Emeltchenko 10151da177e4SLinus Torvalds /* Read Local Supported Features */ 101642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 10171da177e4SLinus Torvalds 10181143e5a6SMarcel Holtmann /* Read Local Version */ 101942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 10202177bab5SJohan Hedberg 10212177bab5SJohan Hedberg /* Read BD Address */ 102242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 10231da177e4SLinus Torvalds } 10241da177e4SLinus Torvalds 102542c6b129SJohan Hedberg static void amp_init(struct hci_request *req) 1026e61ef499SAndrei Emeltchenko { 102742c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 10282455a3eaSAndrei Emeltchenko 1029e61ef499SAndrei Emeltchenko /* Read Local Version */ 103042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 10316bcbc489SAndrei Emeltchenko 1032f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 1033f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 1034f6996cfeSMarcel Holtmann 1035f6996cfeSMarcel Holtmann /* Read Local Supported Features */ 1036f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 1037f6996cfeSMarcel Holtmann 10386bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 103942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 1040e71dfabaSAndrei Emeltchenko 1041e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 104242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 10437528ca1cSMarcel Holtmann 1044f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 1045f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 1046f38ba941SMarcel Holtmann 10477528ca1cSMarcel Holtmann /* Read Location Data */ 10487528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 1049e61ef499SAndrei Emeltchenko } 1050e61ef499SAndrei Emeltchenko 105142c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 1052e61ef499SAndrei Emeltchenko { 105342c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1054e61ef499SAndrei Emeltchenko 1055e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 1056e61ef499SAndrei Emeltchenko 105711778716SAndrei Emeltchenko /* Reset */ 105811778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 105942c6b129SJohan Hedberg hci_reset_req(req, 0); 106011778716SAndrei Emeltchenko 1061e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 1062e61ef499SAndrei Emeltchenko case HCI_BREDR: 106342c6b129SJohan Hedberg bredr_init(req); 1064e61ef499SAndrei Emeltchenko break; 1065e61ef499SAndrei Emeltchenko 1066e61ef499SAndrei Emeltchenko case HCI_AMP: 106742c6b129SJohan Hedberg amp_init(req); 1068e61ef499SAndrei Emeltchenko break; 1069e61ef499SAndrei Emeltchenko 1070e61ef499SAndrei Emeltchenko default: 1071e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 1072e61ef499SAndrei Emeltchenko break; 1073e61ef499SAndrei Emeltchenko } 1074e61ef499SAndrei Emeltchenko } 1075e61ef499SAndrei Emeltchenko 107642c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 10772177bab5SJohan Hedberg { 10784ca048e3SMarcel Holtmann struct hci_dev *hdev = req->hdev; 10794ca048e3SMarcel Holtmann 10802177bab5SJohan Hedberg __le16 param; 10812177bab5SJohan Hedberg __u8 flt_type; 10822177bab5SJohan Hedberg 10832177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 108442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 10852177bab5SJohan Hedberg 10862177bab5SJohan Hedberg /* Read Class of Device */ 108742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 10882177bab5SJohan Hedberg 10892177bab5SJohan Hedberg /* Read Local Name */ 109042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 10912177bab5SJohan Hedberg 10922177bab5SJohan Hedberg /* Read Voice Setting */ 109342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 10942177bab5SJohan Hedberg 1095b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 1096b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 1097b4cb9fb2SMarcel Holtmann 10984b836f39SMarcel Holtmann /* Read Current IAC LAP */ 10994b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 11004b836f39SMarcel Holtmann 11012177bab5SJohan Hedberg /* Clear Event Filters */ 11022177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 110342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 11042177bab5SJohan Hedberg 11052177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 11062177bab5SJohan Hedberg param = __constant_cpu_to_le16(0x7d00); 110742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 11082177bab5SJohan Hedberg 11094ca048e3SMarcel Holtmann /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, 11104ca048e3SMarcel Holtmann * but it does not support page scan related HCI commands. 11114ca048e3SMarcel Holtmann */ 11124ca048e3SMarcel Holtmann if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) { 1113f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 1114f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 1115f332ec66SJohan Hedberg } 11162177bab5SJohan Hedberg } 11172177bab5SJohan Hedberg 111842c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 11192177bab5SJohan Hedberg { 1120c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 1121c73eee91SJohan Hedberg 11222177bab5SJohan Hedberg /* Read LE Buffer Size */ 112342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 11242177bab5SJohan Hedberg 11252177bab5SJohan Hedberg /* Read LE Local Supported Features */ 112642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 11272177bab5SJohan Hedberg 11282177bab5SJohan Hedberg /* Read LE Advertising Channel TX Power */ 112942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 11302177bab5SJohan Hedberg 11312177bab5SJohan Hedberg /* Read LE White List Size */ 113242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 11332177bab5SJohan Hedberg 11342177bab5SJohan Hedberg /* Read LE Supported States */ 113542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 1136c73eee91SJohan Hedberg 1137c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 1138c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1139c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 11402177bab5SJohan Hedberg } 11412177bab5SJohan Hedberg 11422177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 11432177bab5SJohan Hedberg { 11442177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 11452177bab5SJohan Hedberg return 0x02; 11462177bab5SJohan Hedberg 11472177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 11482177bab5SJohan Hedberg return 0x01; 11492177bab5SJohan Hedberg 11502177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 11512177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 11522177bab5SJohan Hedberg return 0x01; 11532177bab5SJohan Hedberg 11542177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 11552177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 11562177bab5SJohan Hedberg return 0x01; 11572177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 11582177bab5SJohan Hedberg return 0x01; 11592177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 11602177bab5SJohan Hedberg return 0x01; 11612177bab5SJohan Hedberg } 11622177bab5SJohan Hedberg 11632177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 11642177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 11652177bab5SJohan Hedberg return 0x01; 11662177bab5SJohan Hedberg 11672177bab5SJohan Hedberg return 0x00; 11682177bab5SJohan Hedberg } 11692177bab5SJohan Hedberg 117042c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 11712177bab5SJohan Hedberg { 11722177bab5SJohan Hedberg u8 mode; 11732177bab5SJohan Hedberg 117442c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 11752177bab5SJohan Hedberg 117642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 11772177bab5SJohan Hedberg } 11782177bab5SJohan Hedberg 117942c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 11802177bab5SJohan Hedberg { 118142c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 118242c6b129SJohan Hedberg 11832177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 11842177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 11852177bab5SJohan Hedberg * command otherwise. 11862177bab5SJohan Hedberg */ 11872177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 11882177bab5SJohan Hedberg 11892177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 11902177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 11912177bab5SJohan Hedberg */ 11922177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 11932177bab5SJohan Hedberg return; 11942177bab5SJohan Hedberg 11952177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 11962177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 11972177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 11982177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 11992177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 12002177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 1201c7882cbdSMarcel Holtmann } else { 1202c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 1203c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 1204c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 1205c7882cbdSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 1206c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 1207c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 1208c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 1209c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 1210c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 1211c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 1212c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 12132177bab5SJohan Hedberg } 12142177bab5SJohan Hedberg 12152177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 12162177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 12172177bab5SJohan Hedberg 12182177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 12192177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 12202177bab5SJohan Hedberg 12212177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 12222177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 12232177bab5SJohan Hedberg 12242177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 12252177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 12262177bab5SJohan Hedberg 12272177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 12282177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 12292177bab5SJohan Hedberg 12302177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 12312177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 12322177bab5SJohan Hedberg 12332177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 12342177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 12352177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 12362177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 12372177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 12382177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 12392177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 12402177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 12412177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 12422177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 12432177bab5SJohan Hedberg * Features Notification 12442177bab5SJohan Hedberg */ 12452177bab5SJohan Hedberg } 12462177bab5SJohan Hedberg 12472177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 12482177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 12492177bab5SJohan Hedberg 125042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 12512177bab5SJohan Hedberg 12522177bab5SJohan Hedberg if (lmp_le_capable(hdev)) { 12532177bab5SJohan Hedberg memset(events, 0, sizeof(events)); 12542177bab5SJohan Hedberg events[0] = 0x1f; 125542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, 12562177bab5SJohan Hedberg sizeof(events), events); 12572177bab5SJohan Hedberg } 12582177bab5SJohan Hedberg } 12592177bab5SJohan Hedberg 126042c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 12612177bab5SJohan Hedberg { 126242c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 126342c6b129SJohan Hedberg 12642177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 126542c6b129SJohan Hedberg bredr_setup(req); 126656f87901SJohan Hedberg else 126756f87901SJohan Hedberg clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 12682177bab5SJohan Hedberg 12692177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 127042c6b129SJohan Hedberg le_setup(req); 12712177bab5SJohan Hedberg 127242c6b129SJohan Hedberg hci_setup_event_mask(req); 12732177bab5SJohan Hedberg 12743f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 12753f8e2d75SJohan Hedberg * local supported commands HCI command. 12763f8e2d75SJohan Hedberg */ 12773f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 127842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 12792177bab5SJohan Hedberg 12802177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 128157af75a8SMarcel Holtmann /* When SSP is available, then the host features page 128257af75a8SMarcel Holtmann * should also be available as well. However some 128357af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 128457af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 128557af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 128657af75a8SMarcel Holtmann */ 128757af75a8SMarcel Holtmann hdev->max_page = 0x01; 128857af75a8SMarcel Holtmann 12892177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 12902177bab5SJohan Hedberg u8 mode = 0x01; 129142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 12922177bab5SJohan Hedberg sizeof(mode), &mode); 12932177bab5SJohan Hedberg } else { 12942177bab5SJohan Hedberg struct hci_cp_write_eir cp; 12952177bab5SJohan Hedberg 12962177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 12972177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 12982177bab5SJohan Hedberg 129942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 13002177bab5SJohan Hedberg } 13012177bab5SJohan Hedberg } 13022177bab5SJohan Hedberg 13032177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 130442c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 13052177bab5SJohan Hedberg 13062177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 130742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 13082177bab5SJohan Hedberg 13092177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 13102177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 13112177bab5SJohan Hedberg 13122177bab5SJohan Hedberg cp.page = 0x01; 131342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 131442c6b129SJohan Hedberg sizeof(cp), &cp); 13152177bab5SJohan Hedberg } 13162177bab5SJohan Hedberg 13172177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 13182177bab5SJohan Hedberg u8 enable = 1; 131942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 13202177bab5SJohan Hedberg &enable); 13212177bab5SJohan Hedberg } 13222177bab5SJohan Hedberg } 13232177bab5SJohan Hedberg 132442c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 13252177bab5SJohan Hedberg { 132642c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 13272177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 13282177bab5SJohan Hedberg u16 link_policy = 0; 13292177bab5SJohan Hedberg 13302177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 13312177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 13322177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 13332177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 13342177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 13352177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 13362177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 13372177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 13382177bab5SJohan Hedberg 13392177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 134042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 13412177bab5SJohan Hedberg } 13422177bab5SJohan Hedberg 134342c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 13442177bab5SJohan Hedberg { 134542c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 13462177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 13472177bab5SJohan Hedberg 1348c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 1349c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1350c73eee91SJohan Hedberg return; 1351c73eee91SJohan Hedberg 13522177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 13532177bab5SJohan Hedberg 13542177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 13552177bab5SJohan Hedberg cp.le = 0x01; 13562177bab5SJohan Hedberg cp.simul = lmp_le_br_capable(hdev); 13572177bab5SJohan Hedberg } 13582177bab5SJohan Hedberg 13592177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 136042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 13612177bab5SJohan Hedberg &cp); 13622177bab5SJohan Hedberg } 13632177bab5SJohan Hedberg 1364d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 1365d62e6d67SJohan Hedberg { 1366d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 1367d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1368d62e6d67SJohan Hedberg 1369d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 1370d62e6d67SJohan Hedberg * enable all necessary events for it. 1371d62e6d67SJohan Hedberg */ 137253b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 1373d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 1374d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 1375d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 1376d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 1377d62e6d67SJohan Hedberg } 1378d62e6d67SJohan Hedberg 1379d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 1380d62e6d67SJohan Hedberg * enable all necessary events for it. 1381d62e6d67SJohan Hedberg */ 138253b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 1383d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 1384d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 1385d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 1386d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 1387d62e6d67SJohan Hedberg } 1388d62e6d67SJohan Hedberg 138940c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 139040c59fcbSMarcel Holtmann if (lmp_ping_capable(hdev)) 139140c59fcbSMarcel Holtmann events[2] |= 0x80; 139240c59fcbSMarcel Holtmann 1393d62e6d67SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 1394d62e6d67SJohan Hedberg } 1395d62e6d67SJohan Hedberg 139642c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 13972177bab5SJohan Hedberg { 139842c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1399d2c5d77fSJohan Hedberg u8 p; 140042c6b129SJohan Hedberg 1401b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 1402b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 1403b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 1404b8f4e068SGustavo Padovan * 1405b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 1406b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 1407b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 1408b8f4e068SGustavo Padovan * command redundant anyway. 1409f9f462faSMarcel Holtmann * 1410f9f462faSMarcel Holtmann * Some controllers indicate that they support handling deleting 1411f9f462faSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 1412f9f462faSMarcel Holtmann * just disable this command. 1413b8f4e068SGustavo Padovan */ 1414f9f462faSMarcel Holtmann if (hdev->commands[6] & 0x80 && 1415f9f462faSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 141659f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 141759f45d57SJohan Hedberg 141859f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 141959f45d57SJohan Hedberg cp.delete_all = 0x01; 142059f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 142159f45d57SJohan Hedberg sizeof(cp), &cp); 142259f45d57SJohan Hedberg } 142359f45d57SJohan Hedberg 14242177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 142542c6b129SJohan Hedberg hci_setup_link_policy(req); 14262177bab5SJohan Hedberg 142779830f66SMarcel Holtmann if (lmp_le_capable(hdev)) { 1428b32bba6cSMarcel Holtmann /* If the controller has a public BD_ADDR, then by default 1429b32bba6cSMarcel Holtmann * use that one. If this is a LE only controller without 1430b32bba6cSMarcel Holtmann * a public address, default to the random address. 1431b32bba6cSMarcel Holtmann * 1432b32bba6cSMarcel Holtmann * For debugging purposes it is possible to force 1433b32bba6cSMarcel Holtmann * controllers with a public address to use the 1434b32bba6cSMarcel Holtmann * random address instead. 143579830f66SMarcel Holtmann */ 1436b32bba6cSMarcel Holtmann if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) || 1437b32bba6cSMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY)) 143879830f66SMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_RANDOM; 1439b32bba6cSMarcel Holtmann else 1440b32bba6cSMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_PUBLIC; 144179830f66SMarcel Holtmann 144242c6b129SJohan Hedberg hci_set_le_support(req); 144379830f66SMarcel Holtmann } 1444d2c5d77fSJohan Hedberg 1445d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 1446d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 1447d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 1448d2c5d77fSJohan Hedberg 1449d2c5d77fSJohan Hedberg cp.page = p; 1450d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 1451d2c5d77fSJohan Hedberg sizeof(cp), &cp); 1452d2c5d77fSJohan Hedberg } 14532177bab5SJohan Hedberg } 14542177bab5SJohan Hedberg 14555d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt) 14565d4e7e8dSJohan Hedberg { 14575d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 14585d4e7e8dSJohan Hedberg 1459d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 1460d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 1461d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 1462d62e6d67SJohan Hedberg 14635d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 146453b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 14655d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 1466a6d0d690SMarcel Holtmann 1467a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 14685afeac14SMarcel Holtmann if ((lmp_sc_capable(hdev) || 14695afeac14SMarcel Holtmann test_bit(HCI_FORCE_SC, &hdev->dev_flags)) && 1470a6d0d690SMarcel Holtmann test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) { 1471a6d0d690SMarcel Holtmann u8 support = 0x01; 1472a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 1473a6d0d690SMarcel Holtmann sizeof(support), &support); 1474a6d0d690SMarcel Holtmann } 14755d4e7e8dSJohan Hedberg } 14765d4e7e8dSJohan Hedberg 14772177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 14782177bab5SJohan Hedberg { 14792177bab5SJohan Hedberg int err; 14802177bab5SJohan Hedberg 14812177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 14822177bab5SJohan Hedberg if (err < 0) 14832177bab5SJohan Hedberg return err; 14842177bab5SJohan Hedberg 14854b4148e9SMarcel Holtmann /* The Device Under Test (DUT) mode is special and available for 14864b4148e9SMarcel Holtmann * all controller types. So just create it early on. 14874b4148e9SMarcel Holtmann */ 14884b4148e9SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 14894b4148e9SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 14904b4148e9SMarcel Holtmann &dut_mode_fops); 14914b4148e9SMarcel Holtmann } 14924b4148e9SMarcel Holtmann 14932177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 14942177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 14952177bab5SJohan Hedberg * first stage init. 14962177bab5SJohan Hedberg */ 14972177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 14982177bab5SJohan Hedberg return 0; 14992177bab5SJohan Hedberg 15002177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 15012177bab5SJohan Hedberg if (err < 0) 15022177bab5SJohan Hedberg return err; 15032177bab5SJohan Hedberg 15045d4e7e8dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 15055d4e7e8dSJohan Hedberg if (err < 0) 15065d4e7e8dSJohan Hedberg return err; 15075d4e7e8dSJohan Hedberg 1508baf27f6eSMarcel Holtmann err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 1509baf27f6eSMarcel Holtmann if (err < 0) 1510baf27f6eSMarcel Holtmann return err; 1511baf27f6eSMarcel Holtmann 1512baf27f6eSMarcel Holtmann /* Only create debugfs entries during the initial setup 1513baf27f6eSMarcel Holtmann * phase and not every time the controller gets powered on. 1514baf27f6eSMarcel Holtmann */ 1515baf27f6eSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 1516baf27f6eSMarcel Holtmann return 0; 1517baf27f6eSMarcel Holtmann 1518dfb826a8SMarcel Holtmann debugfs_create_file("features", 0444, hdev->debugfs, hdev, 1519dfb826a8SMarcel Holtmann &features_fops); 1520ceeb3bc0SMarcel Holtmann debugfs_create_u16("manufacturer", 0444, hdev->debugfs, 1521ceeb3bc0SMarcel Holtmann &hdev->manufacturer); 1522ceeb3bc0SMarcel Holtmann debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); 1523ceeb3bc0SMarcel Holtmann debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); 152470afe0b8SMarcel Holtmann debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, 152570afe0b8SMarcel Holtmann &blacklist_fops); 152647219839SMarcel Holtmann debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); 152747219839SMarcel Holtmann 1528baf27f6eSMarcel Holtmann if (lmp_bredr_capable(hdev)) { 1529baf27f6eSMarcel Holtmann debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, 1530baf27f6eSMarcel Holtmann hdev, &inquiry_cache_fops); 153102d08d15SMarcel Holtmann debugfs_create_file("link_keys", 0400, hdev->debugfs, 153202d08d15SMarcel Holtmann hdev, &link_keys_fops); 1533babdbb3cSMarcel Holtmann debugfs_create_file("dev_class", 0444, hdev->debugfs, 1534babdbb3cSMarcel Holtmann hdev, &dev_class_fops); 1535041000b9SMarcel Holtmann debugfs_create_file("voice_setting", 0444, hdev->debugfs, 1536041000b9SMarcel Holtmann hdev, &voice_setting_fops); 1537baf27f6eSMarcel Holtmann } 1538baf27f6eSMarcel Holtmann 153906f5b778SMarcel Holtmann if (lmp_ssp_capable(hdev)) { 1540ebd1e33bSMarcel Holtmann debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, 1541ebd1e33bSMarcel Holtmann hdev, &auto_accept_delay_fops); 154206f5b778SMarcel Holtmann debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs, 154306f5b778SMarcel Holtmann hdev, &ssp_debug_mode_fops); 15445afeac14SMarcel Holtmann debugfs_create_file("force_sc_support", 0644, hdev->debugfs, 15455afeac14SMarcel Holtmann hdev, &force_sc_support_fops); 1546134c2a89SMarcel Holtmann debugfs_create_file("sc_only_mode", 0444, hdev->debugfs, 1547134c2a89SMarcel Holtmann hdev, &sc_only_mode_fops); 154806f5b778SMarcel Holtmann } 1549ebd1e33bSMarcel Holtmann 15502bfa3531SMarcel Holtmann if (lmp_sniff_capable(hdev)) { 15512bfa3531SMarcel Holtmann debugfs_create_file("idle_timeout", 0644, hdev->debugfs, 15522bfa3531SMarcel Holtmann hdev, &idle_timeout_fops); 15532bfa3531SMarcel Holtmann debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs, 15542bfa3531SMarcel Holtmann hdev, &sniff_min_interval_fops); 15552bfa3531SMarcel Holtmann debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs, 15562bfa3531SMarcel Holtmann hdev, &sniff_max_interval_fops); 15572bfa3531SMarcel Holtmann } 15582bfa3531SMarcel Holtmann 1559d0f729b8SMarcel Holtmann if (lmp_le_capable(hdev)) { 1560e7b8fc92SMarcel Holtmann debugfs_create_file("static_address", 0444, hdev->debugfs, 1561e7b8fc92SMarcel Holtmann hdev, &static_address_fops); 1562b32bba6cSMarcel Holtmann 1563b32bba6cSMarcel Holtmann /* For controllers with a public address, provide a debug 1564b32bba6cSMarcel Holtmann * option to force the usage of the configured static 1565b32bba6cSMarcel Holtmann * address. By default the public address is used. 1566b32bba6cSMarcel Holtmann */ 1567b32bba6cSMarcel Holtmann if (bacmp(&hdev->bdaddr, BDADDR_ANY)) 1568b32bba6cSMarcel Holtmann debugfs_create_file("force_static_address", 0644, 1569b32bba6cSMarcel Holtmann hdev->debugfs, hdev, 1570b32bba6cSMarcel Holtmann &force_static_address_fops); 1571b32bba6cSMarcel Holtmann 1572b32bba6cSMarcel Holtmann debugfs_create_u8("white_list_size", 0444, hdev->debugfs, 1573b32bba6cSMarcel Holtmann &hdev->le_white_list_size); 15743698d704SMarcel Holtmann debugfs_create_file("identity_resolving_keys", 0400, 15753698d704SMarcel Holtmann hdev->debugfs, hdev, 15763698d704SMarcel Holtmann &identity_resolving_keys_fops); 15778f8625cdSMarcel Holtmann debugfs_create_file("long_term_keys", 0400, hdev->debugfs, 15788f8625cdSMarcel Holtmann hdev, &long_term_keys_fops); 15794e70c7e7SMarcel Holtmann debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, 15804e70c7e7SMarcel Holtmann hdev, &conn_min_interval_fops); 15814e70c7e7SMarcel Holtmann debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, 15824e70c7e7SMarcel Holtmann hdev, &conn_max_interval_fops); 158389863109SJukka Rissanen debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev, 158489863109SJukka Rissanen &lowpan_debugfs_fops); 1585d0f729b8SMarcel Holtmann } 1586e7b8fc92SMarcel Holtmann 1587baf27f6eSMarcel Holtmann return 0; 15882177bab5SJohan Hedberg } 15892177bab5SJohan Hedberg 159042c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 15911da177e4SLinus Torvalds { 15921da177e4SLinus Torvalds __u8 scan = opt; 15931da177e4SLinus Torvalds 159442c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 15951da177e4SLinus Torvalds 15961da177e4SLinus Torvalds /* Inquiry and Page scans */ 159742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 15981da177e4SLinus Torvalds } 15991da177e4SLinus Torvalds 160042c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 16011da177e4SLinus Torvalds { 16021da177e4SLinus Torvalds __u8 auth = opt; 16031da177e4SLinus Torvalds 160442c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 16051da177e4SLinus Torvalds 16061da177e4SLinus Torvalds /* Authentication */ 160742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 16081da177e4SLinus Torvalds } 16091da177e4SLinus Torvalds 161042c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 16111da177e4SLinus Torvalds { 16121da177e4SLinus Torvalds __u8 encrypt = opt; 16131da177e4SLinus Torvalds 161442c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 16151da177e4SLinus Torvalds 1616e4e8e37cSMarcel Holtmann /* Encryption */ 161742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 16181da177e4SLinus Torvalds } 16191da177e4SLinus Torvalds 162042c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 1621e4e8e37cSMarcel Holtmann { 1622e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1623e4e8e37cSMarcel Holtmann 162442c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1625e4e8e37cSMarcel Holtmann 1626e4e8e37cSMarcel Holtmann /* Default link policy */ 162742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1628e4e8e37cSMarcel Holtmann } 1629e4e8e37cSMarcel Holtmann 16301da177e4SLinus Torvalds /* Get HCI device by index. 16311da177e4SLinus Torvalds * Device is held on return. */ 16321da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 16331da177e4SLinus Torvalds { 16348035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 16351da177e4SLinus Torvalds 16361da177e4SLinus Torvalds BT_DBG("%d", index); 16371da177e4SLinus Torvalds 16381da177e4SLinus Torvalds if (index < 0) 16391da177e4SLinus Torvalds return NULL; 16401da177e4SLinus Torvalds 16411da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 16428035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 16431da177e4SLinus Torvalds if (d->id == index) { 16441da177e4SLinus Torvalds hdev = hci_dev_hold(d); 16451da177e4SLinus Torvalds break; 16461da177e4SLinus Torvalds } 16471da177e4SLinus Torvalds } 16481da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 16491da177e4SLinus Torvalds return hdev; 16501da177e4SLinus Torvalds } 16511da177e4SLinus Torvalds 16521da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1653ff9ef578SJohan Hedberg 165430dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 165530dc78e1SJohan Hedberg { 165630dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 165730dc78e1SJohan Hedberg 16586fbe195dSAndre Guedes switch (discov->state) { 1659343f935bSAndre Guedes case DISCOVERY_FINDING: 16606fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 166130dc78e1SJohan Hedberg return true; 166230dc78e1SJohan Hedberg 16636fbe195dSAndre Guedes default: 166430dc78e1SJohan Hedberg return false; 166530dc78e1SJohan Hedberg } 16666fbe195dSAndre Guedes } 166730dc78e1SJohan Hedberg 1668ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1669ff9ef578SJohan Hedberg { 1670ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1671ff9ef578SJohan Hedberg 1672ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 1673ff9ef578SJohan Hedberg return; 1674ff9ef578SJohan Hedberg 1675ff9ef578SJohan Hedberg switch (state) { 1676ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 16777b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 1678ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1679ff9ef578SJohan Hedberg break; 1680ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1681ff9ef578SJohan Hedberg break; 1682343f935bSAndre Guedes case DISCOVERY_FINDING: 1683ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1684ff9ef578SJohan Hedberg break; 168530dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 168630dc78e1SJohan Hedberg break; 1687ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1688ff9ef578SJohan Hedberg break; 1689ff9ef578SJohan Hedberg } 1690ff9ef578SJohan Hedberg 1691ff9ef578SJohan Hedberg hdev->discovery.state = state; 1692ff9ef578SJohan Hedberg } 1693ff9ef578SJohan Hedberg 16941f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 16951da177e4SLinus Torvalds { 169630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1697b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 16981da177e4SLinus Torvalds 1699561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1700561aafbcSJohan Hedberg list_del(&p->all); 1701b57c1a56SJohan Hedberg kfree(p); 17021da177e4SLinus Torvalds } 1703561aafbcSJohan Hedberg 1704561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1705561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 17061da177e4SLinus Torvalds } 17071da177e4SLinus Torvalds 1708a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1709a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 17101da177e4SLinus Torvalds { 171130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 17121da177e4SLinus Torvalds struct inquiry_entry *e; 17131da177e4SLinus Torvalds 17146ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 17151da177e4SLinus Torvalds 1716561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 17171da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 17181da177e4SLinus Torvalds return e; 17191da177e4SLinus Torvalds } 17201da177e4SLinus Torvalds 1721b57c1a56SJohan Hedberg return NULL; 1722b57c1a56SJohan Hedberg } 1723b57c1a56SJohan Hedberg 1724561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1725561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1726561aafbcSJohan Hedberg { 172730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1728561aafbcSJohan Hedberg struct inquiry_entry *e; 1729561aafbcSJohan Hedberg 17306ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1731561aafbcSJohan Hedberg 1732561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1733561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1734561aafbcSJohan Hedberg return e; 1735561aafbcSJohan Hedberg } 1736561aafbcSJohan Hedberg 1737561aafbcSJohan Hedberg return NULL; 1738561aafbcSJohan Hedberg } 1739561aafbcSJohan Hedberg 174030dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 174130dc78e1SJohan Hedberg bdaddr_t *bdaddr, 174230dc78e1SJohan Hedberg int state) 174330dc78e1SJohan Hedberg { 174430dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 174530dc78e1SJohan Hedberg struct inquiry_entry *e; 174630dc78e1SJohan Hedberg 17476ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 174830dc78e1SJohan Hedberg 174930dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 175030dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 175130dc78e1SJohan Hedberg return e; 175230dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 175330dc78e1SJohan Hedberg return e; 175430dc78e1SJohan Hedberg } 175530dc78e1SJohan Hedberg 175630dc78e1SJohan Hedberg return NULL; 175730dc78e1SJohan Hedberg } 175830dc78e1SJohan Hedberg 1759a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1760a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1761a3d4e20aSJohan Hedberg { 1762a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1763a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1764a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1765a3d4e20aSJohan Hedberg 1766a3d4e20aSJohan Hedberg list_del(&ie->list); 1767a3d4e20aSJohan Hedberg 1768a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1769a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1770a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1771a3d4e20aSJohan Hedberg break; 1772a3d4e20aSJohan Hedberg pos = &p->list; 1773a3d4e20aSJohan Hedberg } 1774a3d4e20aSJohan Hedberg 1775a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1776a3d4e20aSJohan Hedberg } 1777a3d4e20aSJohan Hedberg 17783175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1779388fc8faSJohan Hedberg bool name_known, bool *ssp) 17801da177e4SLinus Torvalds { 178130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 178270f23020SAndrei Emeltchenko struct inquiry_entry *ie; 17831da177e4SLinus Torvalds 17846ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 17851da177e4SLinus Torvalds 17862b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 17872b2fec4dSSzymon Janc 1788388fc8faSJohan Hedberg if (ssp) 1789388fc8faSJohan Hedberg *ssp = data->ssp_mode; 1790388fc8faSJohan Hedberg 179170f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1792a3d4e20aSJohan Hedberg if (ie) { 1793388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 1794388fc8faSJohan Hedberg *ssp = true; 1795388fc8faSJohan Hedberg 1796a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1797a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1798a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1799a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1800a3d4e20aSJohan Hedberg } 1801a3d4e20aSJohan Hedberg 1802561aafbcSJohan Hedberg goto update; 1803a3d4e20aSJohan Hedberg } 1804561aafbcSJohan Hedberg 18051da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 180670f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 180770f23020SAndrei Emeltchenko if (!ie) 18083175405bSJohan Hedberg return false; 180970f23020SAndrei Emeltchenko 1810561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1811561aafbcSJohan Hedberg 1812561aafbcSJohan Hedberg if (name_known) { 1813561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1814561aafbcSJohan Hedberg } else { 1815561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1816561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1817561aafbcSJohan Hedberg } 1818561aafbcSJohan Hedberg 1819561aafbcSJohan Hedberg update: 1820561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1821561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1822561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1823561aafbcSJohan Hedberg list_del(&ie->list); 18241da177e4SLinus Torvalds } 18251da177e4SLinus Torvalds 182670f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 182770f23020SAndrei Emeltchenko ie->timestamp = jiffies; 18281da177e4SLinus Torvalds cache->timestamp = jiffies; 18293175405bSJohan Hedberg 18303175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 18313175405bSJohan Hedberg return false; 18323175405bSJohan Hedberg 18333175405bSJohan Hedberg return true; 18341da177e4SLinus Torvalds } 18351da177e4SLinus Torvalds 18361da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 18371da177e4SLinus Torvalds { 183830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 18391da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 18401da177e4SLinus Torvalds struct inquiry_entry *e; 18411da177e4SLinus Torvalds int copied = 0; 18421da177e4SLinus Torvalds 1843561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 18441da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1845b57c1a56SJohan Hedberg 1846b57c1a56SJohan Hedberg if (copied >= num) 1847b57c1a56SJohan Hedberg break; 1848b57c1a56SJohan Hedberg 18491da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 18501da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 18511da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 18521da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 18531da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 18541da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1855b57c1a56SJohan Hedberg 18561da177e4SLinus Torvalds info++; 1857b57c1a56SJohan Hedberg copied++; 18581da177e4SLinus Torvalds } 18591da177e4SLinus Torvalds 18601da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 18611da177e4SLinus Torvalds return copied; 18621da177e4SLinus Torvalds } 18631da177e4SLinus Torvalds 186442c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 18651da177e4SLinus Torvalds { 18661da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 186742c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 18681da177e4SLinus Torvalds struct hci_cp_inquiry cp; 18691da177e4SLinus Torvalds 18701da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 18711da177e4SLinus Torvalds 18721da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 18731da177e4SLinus Torvalds return; 18741da177e4SLinus Torvalds 18751da177e4SLinus Torvalds /* Start Inquiry */ 18761da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 18771da177e4SLinus Torvalds cp.length = ir->length; 18781da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 187942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 18801da177e4SLinus Torvalds } 18811da177e4SLinus Torvalds 18823e13fa1eSAndre Guedes static int wait_inquiry(void *word) 18833e13fa1eSAndre Guedes { 18843e13fa1eSAndre Guedes schedule(); 18853e13fa1eSAndre Guedes return signal_pending(current); 18863e13fa1eSAndre Guedes } 18873e13fa1eSAndre Guedes 18881da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 18891da177e4SLinus Torvalds { 18901da177e4SLinus Torvalds __u8 __user *ptr = arg; 18911da177e4SLinus Torvalds struct hci_inquiry_req ir; 18921da177e4SLinus Torvalds struct hci_dev *hdev; 18931da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 18941da177e4SLinus Torvalds long timeo; 18951da177e4SLinus Torvalds __u8 *buf; 18961da177e4SLinus Torvalds 18971da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 18981da177e4SLinus Torvalds return -EFAULT; 18991da177e4SLinus Torvalds 19005a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 19015a08ecceSAndrei Emeltchenko if (!hdev) 19021da177e4SLinus Torvalds return -ENODEV; 19031da177e4SLinus Torvalds 19040736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 19050736cfa8SMarcel Holtmann err = -EBUSY; 19060736cfa8SMarcel Holtmann goto done; 19070736cfa8SMarcel Holtmann } 19080736cfa8SMarcel Holtmann 19095b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 19105b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 19115b69bef5SMarcel Holtmann goto done; 19125b69bef5SMarcel Holtmann } 19135b69bef5SMarcel Holtmann 191456f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 191556f87901SJohan Hedberg err = -EOPNOTSUPP; 191656f87901SJohan Hedberg goto done; 191756f87901SJohan Hedberg } 191856f87901SJohan Hedberg 191909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 19201da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1921a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 19221f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 19231da177e4SLinus Torvalds do_inquiry = 1; 19241da177e4SLinus Torvalds } 192509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 19261da177e4SLinus Torvalds 192704837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 192870f23020SAndrei Emeltchenko 192970f23020SAndrei Emeltchenko if (do_inquiry) { 193001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 193101178cd4SJohan Hedberg timeo); 193270f23020SAndrei Emeltchenko if (err < 0) 19331da177e4SLinus Torvalds goto done; 19343e13fa1eSAndre Guedes 19353e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 19363e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 19373e13fa1eSAndre Guedes */ 19383e13fa1eSAndre Guedes if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, 19393e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 19403e13fa1eSAndre Guedes return -EINTR; 194170f23020SAndrei Emeltchenko } 19421da177e4SLinus Torvalds 19438fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 19448fc9ced3SGustavo Padovan * 255 entries 19458fc9ced3SGustavo Padovan */ 19461da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 19471da177e4SLinus Torvalds 19481da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 19491da177e4SLinus Torvalds * copy it to the user space. 19501da177e4SLinus Torvalds */ 195170f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 195270f23020SAndrei Emeltchenko if (!buf) { 19531da177e4SLinus Torvalds err = -ENOMEM; 19541da177e4SLinus Torvalds goto done; 19551da177e4SLinus Torvalds } 19561da177e4SLinus Torvalds 195709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 19581da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 195909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 19601da177e4SLinus Torvalds 19611da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 19621da177e4SLinus Torvalds 19631da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 19641da177e4SLinus Torvalds ptr += sizeof(ir); 19651da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 19661da177e4SLinus Torvalds ir.num_rsp)) 19671da177e4SLinus Torvalds err = -EFAULT; 19681da177e4SLinus Torvalds } else 19691da177e4SLinus Torvalds err = -EFAULT; 19701da177e4SLinus Torvalds 19711da177e4SLinus Torvalds kfree(buf); 19721da177e4SLinus Torvalds 19731da177e4SLinus Torvalds done: 19741da177e4SLinus Torvalds hci_dev_put(hdev); 19751da177e4SLinus Torvalds return err; 19761da177e4SLinus Torvalds } 19771da177e4SLinus Torvalds 1978cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 19791da177e4SLinus Torvalds { 19801da177e4SLinus Torvalds int ret = 0; 19811da177e4SLinus Torvalds 19821da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 19831da177e4SLinus Torvalds 19841da177e4SLinus Torvalds hci_req_lock(hdev); 19851da177e4SLinus Torvalds 198694324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 198794324962SJohan Hovold ret = -ENODEV; 198894324962SJohan Hovold goto done; 198994324962SJohan Hovold } 199094324962SJohan Hovold 1991a5c8f270SMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 1992a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1993a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1994bf543036SJohan Hedberg */ 1995a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 1996611b30f7SMarcel Holtmann ret = -ERFKILL; 1997611b30f7SMarcel Holtmann goto done; 1998611b30f7SMarcel Holtmann } 1999611b30f7SMarcel Holtmann 2000a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 2001a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 2002a5c8f270SMarcel Holtmann * be able to determine if there is a public address 2003a5c8f270SMarcel Holtmann * or not. 2004a5c8f270SMarcel Holtmann * 2005c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 2006c6beca0eSMarcel Holtmann * if a public address or static random address is 2007c6beca0eSMarcel Holtmann * available. 2008c6beca0eSMarcel Holtmann * 2009a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 2010a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 2011a5c8f270SMarcel Holtmann */ 2012c6beca0eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 2013c6beca0eSMarcel Holtmann hdev->dev_type == HCI_BREDR && 2014a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2015a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 2016a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 2017a5c8f270SMarcel Holtmann goto done; 2018a5c8f270SMarcel Holtmann } 2019a5c8f270SMarcel Holtmann } 2020a5c8f270SMarcel Holtmann 20211da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 20221da177e4SLinus Torvalds ret = -EALREADY; 20231da177e4SLinus Torvalds goto done; 20241da177e4SLinus Torvalds } 20251da177e4SLinus Torvalds 20261da177e4SLinus Torvalds if (hdev->open(hdev)) { 20271da177e4SLinus Torvalds ret = -EIO; 20281da177e4SLinus Torvalds goto done; 20291da177e4SLinus Torvalds } 20301da177e4SLinus Torvalds 20311da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 20321da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 2033f41c70c4SMarcel Holtmann 2034f41c70c4SMarcel Holtmann if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags)) 2035f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 2036f41c70c4SMarcel Holtmann 2037f41c70c4SMarcel Holtmann if (!ret) { 2038f41c70c4SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 2039f41c70c4SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 2040f41c70c4SMarcel Holtmann 20410736cfa8SMarcel Holtmann if (!test_bit(HCI_RAW, &hdev->flags) && 20420736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 20432177bab5SJohan Hedberg ret = __hci_init(hdev); 20441da177e4SLinus Torvalds } 20451da177e4SLinus Torvalds 2046f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 2047f41c70c4SMarcel Holtmann 20481da177e4SLinus Torvalds if (!ret) { 20491da177e4SLinus Torvalds hci_dev_hold(hdev); 20501da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 20511da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 2052bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 20530736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 20541514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 205509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2056744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 205709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 205856e5cb86SJohan Hedberg } 20591da177e4SLinus Torvalds } else { 20601da177e4SLinus Torvalds /* Init failed, cleanup */ 20613eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2062c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 2063b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 20641da177e4SLinus Torvalds 20651da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 20661da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 20671da177e4SLinus Torvalds 20681da177e4SLinus Torvalds if (hdev->flush) 20691da177e4SLinus Torvalds hdev->flush(hdev); 20701da177e4SLinus Torvalds 20711da177e4SLinus Torvalds if (hdev->sent_cmd) { 20721da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 20731da177e4SLinus Torvalds hdev->sent_cmd = NULL; 20741da177e4SLinus Torvalds } 20751da177e4SLinus Torvalds 20761da177e4SLinus Torvalds hdev->close(hdev); 20771da177e4SLinus Torvalds hdev->flags = 0; 20781da177e4SLinus Torvalds } 20791da177e4SLinus Torvalds 20801da177e4SLinus Torvalds done: 20811da177e4SLinus Torvalds hci_req_unlock(hdev); 20821da177e4SLinus Torvalds return ret; 20831da177e4SLinus Torvalds } 20841da177e4SLinus Torvalds 2085cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 2086cbed0ca1SJohan Hedberg 2087cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 2088cbed0ca1SJohan Hedberg { 2089cbed0ca1SJohan Hedberg struct hci_dev *hdev; 2090cbed0ca1SJohan Hedberg int err; 2091cbed0ca1SJohan Hedberg 2092cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 2093cbed0ca1SJohan Hedberg if (!hdev) 2094cbed0ca1SJohan Hedberg return -ENODEV; 2095cbed0ca1SJohan Hedberg 2096e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 2097e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 2098e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 2099e1d08f40SJohan Hedberg * completed. 2100e1d08f40SJohan Hedberg */ 2101e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2102e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 2103e1d08f40SJohan Hedberg 2104a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 2105a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 2106a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 2107a5c8f270SMarcel Holtmann */ 2108e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 2109e1d08f40SJohan Hedberg 2110cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 2111cbed0ca1SJohan Hedberg 2112cbed0ca1SJohan Hedberg hci_dev_put(hdev); 2113cbed0ca1SJohan Hedberg 2114cbed0ca1SJohan Hedberg return err; 2115cbed0ca1SJohan Hedberg } 2116cbed0ca1SJohan Hedberg 21171da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 21181da177e4SLinus Torvalds { 21191da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 21201da177e4SLinus Torvalds 212178c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 212278c04c0bSVinicius Costa Gomes 21231da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 21241da177e4SLinus Torvalds hci_req_lock(hdev); 21251da177e4SLinus Torvalds 21261da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 2127b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 21281da177e4SLinus Torvalds hci_req_unlock(hdev); 21291da177e4SLinus Torvalds return 0; 21301da177e4SLinus Torvalds } 21311da177e4SLinus Torvalds 21323eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 21333eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2134b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 21351da177e4SLinus Torvalds 213616ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 2137e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 213816ab91abSJohan Hedberg hdev->discov_timeout = 0; 21395e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 2140310a3d48SMarcel Holtmann clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 214116ab91abSJohan Hedberg } 214216ab91abSJohan Hedberg 2143a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 21447d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 21457d78525dSJohan Hedberg 21467ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 21477ba8b4beSAndre Guedes 214809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 21491f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 21501da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 215109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 21521da177e4SLinus Torvalds 21531da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 21541da177e4SLinus Torvalds 21551da177e4SLinus Torvalds if (hdev->flush) 21561da177e4SLinus Torvalds hdev->flush(hdev); 21571da177e4SLinus Torvalds 21581da177e4SLinus Torvalds /* Reset device */ 21591da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 21601da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 21618af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 21623a6afbd2SMarcel Holtmann !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 2163a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 21641da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 216501178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 21661da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 21671da177e4SLinus Torvalds } 21681da177e4SLinus Torvalds 2169c347b765SGustavo F. Padovan /* flush cmd work */ 2170c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 21711da177e4SLinus Torvalds 21721da177e4SLinus Torvalds /* Drop queues */ 21731da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 21741da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 21751da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 21761da177e4SLinus Torvalds 21771da177e4SLinus Torvalds /* Drop last sent command */ 21781da177e4SLinus Torvalds if (hdev->sent_cmd) { 2179b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 21801da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 21811da177e4SLinus Torvalds hdev->sent_cmd = NULL; 21821da177e4SLinus Torvalds } 21831da177e4SLinus Torvalds 2184b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 2185b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 2186b6ddb638SJohan Hedberg 21871da177e4SLinus Torvalds /* After this point our queues are empty 21881da177e4SLinus Torvalds * and no tasks are scheduled. */ 21891da177e4SLinus Torvalds hdev->close(hdev); 21901da177e4SLinus Torvalds 219135b973c9SJohan Hedberg /* Clear flags */ 219235b973c9SJohan Hedberg hdev->flags = 0; 219335b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 219435b973c9SJohan Hedberg 219593c311a0SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 219693c311a0SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 219709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2198744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 219909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 22008ee56540SMarcel Holtmann } 220193c311a0SMarcel Holtmann } 22025add6af8SJohan Hedberg 2203ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 2204536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 2205ced5c338SAndrei Emeltchenko 2206e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 220709b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 2208e59fda8dSJohan Hedberg 22091da177e4SLinus Torvalds hci_req_unlock(hdev); 22101da177e4SLinus Torvalds 22111da177e4SLinus Torvalds hci_dev_put(hdev); 22121da177e4SLinus Torvalds return 0; 22131da177e4SLinus Torvalds } 22141da177e4SLinus Torvalds 22151da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 22161da177e4SLinus Torvalds { 22171da177e4SLinus Torvalds struct hci_dev *hdev; 22181da177e4SLinus Torvalds int err; 22191da177e4SLinus Torvalds 222070f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 222170f23020SAndrei Emeltchenko if (!hdev) 22221da177e4SLinus Torvalds return -ENODEV; 22238ee56540SMarcel Holtmann 22240736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22250736cfa8SMarcel Holtmann err = -EBUSY; 22260736cfa8SMarcel Holtmann goto done; 22270736cfa8SMarcel Holtmann } 22280736cfa8SMarcel Holtmann 22298ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 22308ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 22318ee56540SMarcel Holtmann 22321da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 22338ee56540SMarcel Holtmann 22340736cfa8SMarcel Holtmann done: 22351da177e4SLinus Torvalds hci_dev_put(hdev); 22361da177e4SLinus Torvalds return err; 22371da177e4SLinus Torvalds } 22381da177e4SLinus Torvalds 22391da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 22401da177e4SLinus Torvalds { 22411da177e4SLinus Torvalds struct hci_dev *hdev; 22421da177e4SLinus Torvalds int ret = 0; 22431da177e4SLinus Torvalds 224470f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 224570f23020SAndrei Emeltchenko if (!hdev) 22461da177e4SLinus Torvalds return -ENODEV; 22471da177e4SLinus Torvalds 22481da177e4SLinus Torvalds hci_req_lock(hdev); 22491da177e4SLinus Torvalds 2250808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 2251808a049eSMarcel Holtmann ret = -ENETDOWN; 22521da177e4SLinus Torvalds goto done; 2253808a049eSMarcel Holtmann } 22541da177e4SLinus Torvalds 22550736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22560736cfa8SMarcel Holtmann ret = -EBUSY; 22570736cfa8SMarcel Holtmann goto done; 22580736cfa8SMarcel Holtmann } 22590736cfa8SMarcel Holtmann 22601da177e4SLinus Torvalds /* Drop queues */ 22611da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 22621da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 22631da177e4SLinus Torvalds 226409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 22651f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 22661da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 226709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 22681da177e4SLinus Torvalds 22691da177e4SLinus Torvalds if (hdev->flush) 22701da177e4SLinus Torvalds hdev->flush(hdev); 22711da177e4SLinus Torvalds 22721da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 22736ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 22741da177e4SLinus Torvalds 22751da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 227601178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 22771da177e4SLinus Torvalds 22781da177e4SLinus Torvalds done: 22791da177e4SLinus Torvalds hci_req_unlock(hdev); 22801da177e4SLinus Torvalds hci_dev_put(hdev); 22811da177e4SLinus Torvalds return ret; 22821da177e4SLinus Torvalds } 22831da177e4SLinus Torvalds 22841da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 22851da177e4SLinus Torvalds { 22861da177e4SLinus Torvalds struct hci_dev *hdev; 22871da177e4SLinus Torvalds int ret = 0; 22881da177e4SLinus Torvalds 228970f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 229070f23020SAndrei Emeltchenko if (!hdev) 22911da177e4SLinus Torvalds return -ENODEV; 22921da177e4SLinus Torvalds 22930736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22940736cfa8SMarcel Holtmann ret = -EBUSY; 22950736cfa8SMarcel Holtmann goto done; 22960736cfa8SMarcel Holtmann } 22970736cfa8SMarcel Holtmann 22981da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 22991da177e4SLinus Torvalds 23000736cfa8SMarcel Holtmann done: 23011da177e4SLinus Torvalds hci_dev_put(hdev); 23021da177e4SLinus Torvalds return ret; 23031da177e4SLinus Torvalds } 23041da177e4SLinus Torvalds 23051da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 23061da177e4SLinus Torvalds { 23071da177e4SLinus Torvalds struct hci_dev *hdev; 23081da177e4SLinus Torvalds struct hci_dev_req dr; 23091da177e4SLinus Torvalds int err = 0; 23101da177e4SLinus Torvalds 23111da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 23121da177e4SLinus Torvalds return -EFAULT; 23131da177e4SLinus Torvalds 231470f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 231570f23020SAndrei Emeltchenko if (!hdev) 23161da177e4SLinus Torvalds return -ENODEV; 23171da177e4SLinus Torvalds 23180736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 23190736cfa8SMarcel Holtmann err = -EBUSY; 23200736cfa8SMarcel Holtmann goto done; 23210736cfa8SMarcel Holtmann } 23220736cfa8SMarcel Holtmann 23235b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 23245b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 23255b69bef5SMarcel Holtmann goto done; 23265b69bef5SMarcel Holtmann } 23275b69bef5SMarcel Holtmann 232856f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 232956f87901SJohan Hedberg err = -EOPNOTSUPP; 233056f87901SJohan Hedberg goto done; 233156f87901SJohan Hedberg } 233256f87901SJohan Hedberg 23331da177e4SLinus Torvalds switch (cmd) { 23341da177e4SLinus Torvalds case HCISETAUTH: 233501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 23365f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23371da177e4SLinus Torvalds break; 23381da177e4SLinus Torvalds 23391da177e4SLinus Torvalds case HCISETENCRYPT: 23401da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 23411da177e4SLinus Torvalds err = -EOPNOTSUPP; 23421da177e4SLinus Torvalds break; 23431da177e4SLinus Torvalds } 23441da177e4SLinus Torvalds 23451da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 23461da177e4SLinus Torvalds /* Auth must be enabled first */ 234701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 23485f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23491da177e4SLinus Torvalds if (err) 23501da177e4SLinus Torvalds break; 23511da177e4SLinus Torvalds } 23521da177e4SLinus Torvalds 235301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 23545f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23551da177e4SLinus Torvalds break; 23561da177e4SLinus Torvalds 23571da177e4SLinus Torvalds case HCISETSCAN: 235801178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 23595f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23601da177e4SLinus Torvalds break; 23611da177e4SLinus Torvalds 23621da177e4SLinus Torvalds case HCISETLINKPOL: 236301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 23645f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23651da177e4SLinus Torvalds break; 23661da177e4SLinus Torvalds 23671da177e4SLinus Torvalds case HCISETLINKMODE: 2368e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2369e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2370e4e8e37cSMarcel Holtmann break; 2371e4e8e37cSMarcel Holtmann 2372e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2373e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 23741da177e4SLinus Torvalds break; 23751da177e4SLinus Torvalds 23761da177e4SLinus Torvalds case HCISETACLMTU: 23771da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 23781da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 23791da177e4SLinus Torvalds break; 23801da177e4SLinus Torvalds 23811da177e4SLinus Torvalds case HCISETSCOMTU: 23821da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 23831da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 23841da177e4SLinus Torvalds break; 23851da177e4SLinus Torvalds 23861da177e4SLinus Torvalds default: 23871da177e4SLinus Torvalds err = -EINVAL; 23881da177e4SLinus Torvalds break; 23891da177e4SLinus Torvalds } 2390e4e8e37cSMarcel Holtmann 23910736cfa8SMarcel Holtmann done: 23921da177e4SLinus Torvalds hci_dev_put(hdev); 23931da177e4SLinus Torvalds return err; 23941da177e4SLinus Torvalds } 23951da177e4SLinus Torvalds 23961da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 23971da177e4SLinus Torvalds { 23988035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 23991da177e4SLinus Torvalds struct hci_dev_list_req *dl; 24001da177e4SLinus Torvalds struct hci_dev_req *dr; 24011da177e4SLinus Torvalds int n = 0, size, err; 24021da177e4SLinus Torvalds __u16 dev_num; 24031da177e4SLinus Torvalds 24041da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 24051da177e4SLinus Torvalds return -EFAULT; 24061da177e4SLinus Torvalds 24071da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 24081da177e4SLinus Torvalds return -EINVAL; 24091da177e4SLinus Torvalds 24101da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 24111da177e4SLinus Torvalds 241270f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 241370f23020SAndrei Emeltchenko if (!dl) 24141da177e4SLinus Torvalds return -ENOMEM; 24151da177e4SLinus Torvalds 24161da177e4SLinus Torvalds dr = dl->dev_req; 24171da177e4SLinus Torvalds 2418f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 24198035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 2420a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2421e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 2422c542a06cSJohan Hedberg 2423a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2424a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2425c542a06cSJohan Hedberg 24261da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 24271da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 2428c542a06cSJohan Hedberg 24291da177e4SLinus Torvalds if (++n >= dev_num) 24301da177e4SLinus Torvalds break; 24311da177e4SLinus Torvalds } 2432f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 24331da177e4SLinus Torvalds 24341da177e4SLinus Torvalds dl->dev_num = n; 24351da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 24361da177e4SLinus Torvalds 24371da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 24381da177e4SLinus Torvalds kfree(dl); 24391da177e4SLinus Torvalds 24401da177e4SLinus Torvalds return err ? -EFAULT : 0; 24411da177e4SLinus Torvalds } 24421da177e4SLinus Torvalds 24431da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 24441da177e4SLinus Torvalds { 24451da177e4SLinus Torvalds struct hci_dev *hdev; 24461da177e4SLinus Torvalds struct hci_dev_info di; 24471da177e4SLinus Torvalds int err = 0; 24481da177e4SLinus Torvalds 24491da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 24501da177e4SLinus Torvalds return -EFAULT; 24511da177e4SLinus Torvalds 245270f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 245370f23020SAndrei Emeltchenko if (!hdev) 24541da177e4SLinus Torvalds return -ENODEV; 24551da177e4SLinus Torvalds 2456a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 24573243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 2458ab81cbf9SJohan Hedberg 2459a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2460a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2461c542a06cSJohan Hedberg 24621da177e4SLinus Torvalds strcpy(di.name, hdev->name); 24631da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 246460f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 24651da177e4SLinus Torvalds di.flags = hdev->flags; 24661da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2467572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 24681da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 24691da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 24701da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 24711da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2472572c7f84SJohan Hedberg } else { 2473572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2474572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2475572c7f84SJohan Hedberg di.sco_mtu = 0; 2476572c7f84SJohan Hedberg di.sco_pkts = 0; 2477572c7f84SJohan Hedberg } 24781da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 24791da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 24801da177e4SLinus Torvalds 24811da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 24821da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 24831da177e4SLinus Torvalds 24841da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 24851da177e4SLinus Torvalds err = -EFAULT; 24861da177e4SLinus Torvalds 24871da177e4SLinus Torvalds hci_dev_put(hdev); 24881da177e4SLinus Torvalds 24891da177e4SLinus Torvalds return err; 24901da177e4SLinus Torvalds } 24911da177e4SLinus Torvalds 24921da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 24931da177e4SLinus Torvalds 2494611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2495611b30f7SMarcel Holtmann { 2496611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2497611b30f7SMarcel Holtmann 2498611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2499611b30f7SMarcel Holtmann 25000736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 25010736cfa8SMarcel Holtmann return -EBUSY; 25020736cfa8SMarcel Holtmann 25035e130367SJohan Hedberg if (blocked) { 25045e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 2505bf543036SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 2506611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 25075e130367SJohan Hedberg } else { 25085e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 25095e130367SJohan Hedberg } 2510611b30f7SMarcel Holtmann 2511611b30f7SMarcel Holtmann return 0; 2512611b30f7SMarcel Holtmann } 2513611b30f7SMarcel Holtmann 2514611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2515611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2516611b30f7SMarcel Holtmann }; 2517611b30f7SMarcel Holtmann 2518ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2519ab81cbf9SJohan Hedberg { 2520ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 252196570ffcSJohan Hedberg int err; 2522ab81cbf9SJohan Hedberg 2523ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2524ab81cbf9SJohan Hedberg 2525cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 252696570ffcSJohan Hedberg if (err < 0) { 252796570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 2528ab81cbf9SJohan Hedberg return; 252996570ffcSJohan Hedberg } 2530ab81cbf9SJohan Hedberg 2531a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2532a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2533a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2534a5c8f270SMarcel Holtmann */ 2535a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 2536a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 2537a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2538a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2539bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2540bf543036SJohan Hedberg hci_dev_do_close(hdev); 2541bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 254219202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 254319202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2544bf543036SJohan Hedberg } 2545ab81cbf9SJohan Hedberg 2546a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 2547744cf19eSJohan Hedberg mgmt_index_added(hdev); 2548ab81cbf9SJohan Hedberg } 2549ab81cbf9SJohan Hedberg 2550ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2551ab81cbf9SJohan Hedberg { 25523243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 25533243553fSJohan Hedberg power_off.work); 2554ab81cbf9SJohan Hedberg 2555ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2556ab81cbf9SJohan Hedberg 25578ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2558ab81cbf9SJohan Hedberg } 2559ab81cbf9SJohan Hedberg 256016ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 256116ab91abSJohan Hedberg { 256216ab91abSJohan Hedberg struct hci_dev *hdev; 256316ab91abSJohan Hedberg 256416ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 256516ab91abSJohan Hedberg 256616ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 256716ab91abSJohan Hedberg 2568d1967ff8SMarcel Holtmann mgmt_discoverable_timeout(hdev); 256916ab91abSJohan Hedberg } 257016ab91abSJohan Hedberg 257135f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 25722aeb9a1aSJohan Hedberg { 25734821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 25742aeb9a1aSJohan Hedberg 25754821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 25764821002cSJohan Hedberg list_del(&uuid->list); 25772aeb9a1aSJohan Hedberg kfree(uuid); 25782aeb9a1aSJohan Hedberg } 25792aeb9a1aSJohan Hedberg } 25802aeb9a1aSJohan Hedberg 258135f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 258255ed8ca1SJohan Hedberg { 258355ed8ca1SJohan Hedberg struct list_head *p, *n; 258455ed8ca1SJohan Hedberg 258555ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 258655ed8ca1SJohan Hedberg struct link_key *key; 258755ed8ca1SJohan Hedberg 258855ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 258955ed8ca1SJohan Hedberg 259055ed8ca1SJohan Hedberg list_del(p); 259155ed8ca1SJohan Hedberg kfree(key); 259255ed8ca1SJohan Hedberg } 259355ed8ca1SJohan Hedberg } 259455ed8ca1SJohan Hedberg 259535f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2596b899efafSVinicius Costa Gomes { 2597b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2598b899efafSVinicius Costa Gomes 2599b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2600b899efafSVinicius Costa Gomes list_del(&k->list); 2601b899efafSVinicius Costa Gomes kfree(k); 2602b899efafSVinicius Costa Gomes } 2603b899efafSVinicius Costa Gomes } 2604b899efafSVinicius Costa Gomes 2605970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2606970c4e46SJohan Hedberg { 2607970c4e46SJohan Hedberg struct smp_irk *k, *tmp; 2608970c4e46SJohan Hedberg 2609970c4e46SJohan Hedberg list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { 2610970c4e46SJohan Hedberg list_del(&k->list); 2611970c4e46SJohan Hedberg kfree(k); 2612970c4e46SJohan Hedberg } 2613970c4e46SJohan Hedberg } 2614970c4e46SJohan Hedberg 261555ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 261655ed8ca1SJohan Hedberg { 261755ed8ca1SJohan Hedberg struct link_key *k; 261855ed8ca1SJohan Hedberg 26198035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 262055ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 262155ed8ca1SJohan Hedberg return k; 262255ed8ca1SJohan Hedberg 262355ed8ca1SJohan Hedberg return NULL; 262455ed8ca1SJohan Hedberg } 262555ed8ca1SJohan Hedberg 2626745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2627d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2628d25e28abSJohan Hedberg { 2629d25e28abSJohan Hedberg /* Legacy key */ 2630d25e28abSJohan Hedberg if (key_type < 0x03) 2631745c0ce3SVishal Agarwal return true; 2632d25e28abSJohan Hedberg 2633d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2634d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2635745c0ce3SVishal Agarwal return false; 2636d25e28abSJohan Hedberg 2637d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2638d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2639745c0ce3SVishal Agarwal return false; 2640d25e28abSJohan Hedberg 2641d25e28abSJohan Hedberg /* Security mode 3 case */ 2642d25e28abSJohan Hedberg if (!conn) 2643745c0ce3SVishal Agarwal return true; 2644d25e28abSJohan Hedberg 2645d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2646d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2647745c0ce3SVishal Agarwal return true; 2648d25e28abSJohan Hedberg 2649d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2650d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2651745c0ce3SVishal Agarwal return true; 2652d25e28abSJohan Hedberg 2653d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2654d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2655745c0ce3SVishal Agarwal return true; 2656d25e28abSJohan Hedberg 2657d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2658d25e28abSJohan Hedberg * persistently */ 2659745c0ce3SVishal Agarwal return false; 2660d25e28abSJohan Hedberg } 2661d25e28abSJohan Hedberg 266298a0b845SJohan Hedberg static bool ltk_type_master(u8 type) 266398a0b845SJohan Hedberg { 266498a0b845SJohan Hedberg if (type == HCI_SMP_STK || type == HCI_SMP_LTK) 266598a0b845SJohan Hedberg return true; 266698a0b845SJohan Hedberg 266798a0b845SJohan Hedberg return false; 266898a0b845SJohan Hedberg } 266998a0b845SJohan Hedberg 267098a0b845SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8], 267198a0b845SJohan Hedberg bool master) 267275d262c2SVinicius Costa Gomes { 2673c9839a11SVinicius Costa Gomes struct smp_ltk *k; 267475d262c2SVinicius Costa Gomes 2675c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 2676c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 2677c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 267875d262c2SVinicius Costa Gomes continue; 267975d262c2SVinicius Costa Gomes 268098a0b845SJohan Hedberg if (ltk_type_master(k->type) != master) 268198a0b845SJohan Hedberg continue; 268298a0b845SJohan Hedberg 268375d262c2SVinicius Costa Gomes return k; 268475d262c2SVinicius Costa Gomes } 268575d262c2SVinicius Costa Gomes 268675d262c2SVinicius Costa Gomes return NULL; 268775d262c2SVinicius Costa Gomes } 268875d262c2SVinicius Costa Gomes 2689c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 269098a0b845SJohan Hedberg u8 addr_type, bool master) 269175d262c2SVinicius Costa Gomes { 2692c9839a11SVinicius Costa Gomes struct smp_ltk *k; 269375d262c2SVinicius Costa Gomes 2694c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 2695c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 269698a0b845SJohan Hedberg bacmp(bdaddr, &k->bdaddr) == 0 && 269798a0b845SJohan Hedberg ltk_type_master(k->type) == master) 269875d262c2SVinicius Costa Gomes return k; 269975d262c2SVinicius Costa Gomes 270075d262c2SVinicius Costa Gomes return NULL; 270175d262c2SVinicius Costa Gomes } 270275d262c2SVinicius Costa Gomes 2703970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 2704970c4e46SJohan Hedberg { 2705970c4e46SJohan Hedberg struct smp_irk *irk; 2706970c4e46SJohan Hedberg 2707970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2708970c4e46SJohan Hedberg if (!bacmp(&irk->rpa, rpa)) 2709970c4e46SJohan Hedberg return irk; 2710970c4e46SJohan Hedberg } 2711970c4e46SJohan Hedberg 2712970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2713970c4e46SJohan Hedberg if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) { 2714970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2715970c4e46SJohan Hedberg return irk; 2716970c4e46SJohan Hedberg } 2717970c4e46SJohan Hedberg } 2718970c4e46SJohan Hedberg 2719970c4e46SJohan Hedberg return NULL; 2720970c4e46SJohan Hedberg } 2721970c4e46SJohan Hedberg 2722970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2723970c4e46SJohan Hedberg u8 addr_type) 2724970c4e46SJohan Hedberg { 2725970c4e46SJohan Hedberg struct smp_irk *irk; 2726970c4e46SJohan Hedberg 27276cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 27286cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 27296cfc9988SJohan Hedberg return NULL; 27306cfc9988SJohan Hedberg 2731970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2732970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 2733970c4e46SJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) 2734970c4e46SJohan Hedberg return irk; 2735970c4e46SJohan Hedberg } 2736970c4e46SJohan Hedberg 2737970c4e46SJohan Hedberg return NULL; 2738970c4e46SJohan Hedberg } 2739970c4e46SJohan Hedberg 2740d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 2741d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 274255ed8ca1SJohan Hedberg { 274355ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2744745c0ce3SVishal Agarwal u8 old_key_type; 2745745c0ce3SVishal Agarwal bool persistent; 274655ed8ca1SJohan Hedberg 274755ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 274855ed8ca1SJohan Hedberg if (old_key) { 274955ed8ca1SJohan Hedberg old_key_type = old_key->type; 275055ed8ca1SJohan Hedberg key = old_key; 275155ed8ca1SJohan Hedberg } else { 275212adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 27530a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 275455ed8ca1SJohan Hedberg if (!key) 275555ed8ca1SJohan Hedberg return -ENOMEM; 275655ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 275755ed8ca1SJohan Hedberg } 275855ed8ca1SJohan Hedberg 27596ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 276055ed8ca1SJohan Hedberg 2761d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2762d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2763d25e28abSJohan Hedberg * previous key */ 2764d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2765a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2766d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2767655fe6ecSJohan Hedberg if (conn) 2768655fe6ecSJohan Hedberg conn->key_type = type; 2769655fe6ecSJohan Hedberg } 2770d25e28abSJohan Hedberg 277155ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 27729b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 277355ed8ca1SJohan Hedberg key->pin_len = pin_len; 277455ed8ca1SJohan Hedberg 2775b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 277655ed8ca1SJohan Hedberg key->type = old_key_type; 27774748fed2SJohan Hedberg else 27784748fed2SJohan Hedberg key->type = type; 27794748fed2SJohan Hedberg 27804df378a1SJohan Hedberg if (!new_key) 27814df378a1SJohan Hedberg return 0; 27824df378a1SJohan Hedberg 27834df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 27844df378a1SJohan Hedberg 2785744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 27864df378a1SJohan Hedberg 27876ec5bcadSVishal Agarwal if (conn) 27886ec5bcadSVishal Agarwal conn->flush_key = !persistent; 278955ed8ca1SJohan Hedberg 279055ed8ca1SJohan Hedberg return 0; 279155ed8ca1SJohan Hedberg } 279255ed8ca1SJohan Hedberg 2793ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 279435d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 279535d70271SJohan Hedberg u8 tk[16], u8 enc_size, __le16 ediv, u8 rand[8]) 279675d262c2SVinicius Costa Gomes { 2797c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 279898a0b845SJohan Hedberg bool master = ltk_type_master(type); 279975d262c2SVinicius Costa Gomes 280098a0b845SJohan Hedberg old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master); 2801c9839a11SVinicius Costa Gomes if (old_key) 280275d262c2SVinicius Costa Gomes key = old_key; 2803c9839a11SVinicius Costa Gomes else { 28040a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 280575d262c2SVinicius Costa Gomes if (!key) 2806ca9142b8SJohan Hedberg return NULL; 2807c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 280875d262c2SVinicius Costa Gomes } 280975d262c2SVinicius Costa Gomes 281075d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2811c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2812c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2813c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2814c9839a11SVinicius Costa Gomes key->ediv = ediv; 2815c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2816c9839a11SVinicius Costa Gomes key->type = type; 2817c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 281875d262c2SVinicius Costa Gomes 2819ca9142b8SJohan Hedberg return key; 282075d262c2SVinicius Costa Gomes } 282175d262c2SVinicius Costa Gomes 2822ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2823ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 2824970c4e46SJohan Hedberg { 2825970c4e46SJohan Hedberg struct smp_irk *irk; 2826970c4e46SJohan Hedberg 2827970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 2828970c4e46SJohan Hedberg if (!irk) { 2829970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 2830970c4e46SJohan Hedberg if (!irk) 2831ca9142b8SJohan Hedberg return NULL; 2832970c4e46SJohan Hedberg 2833970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 2834970c4e46SJohan Hedberg irk->addr_type = addr_type; 2835970c4e46SJohan Hedberg 2836970c4e46SJohan Hedberg list_add(&irk->list, &hdev->identity_resolving_keys); 2837970c4e46SJohan Hedberg } 2838970c4e46SJohan Hedberg 2839970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 2840970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2841970c4e46SJohan Hedberg 2842ca9142b8SJohan Hedberg return irk; 2843970c4e46SJohan Hedberg } 2844970c4e46SJohan Hedberg 284555ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 284655ed8ca1SJohan Hedberg { 284755ed8ca1SJohan Hedberg struct link_key *key; 284855ed8ca1SJohan Hedberg 284955ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 285055ed8ca1SJohan Hedberg if (!key) 285155ed8ca1SJohan Hedberg return -ENOENT; 285255ed8ca1SJohan Hedberg 28536ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 285455ed8ca1SJohan Hedberg 285555ed8ca1SJohan Hedberg list_del(&key->list); 285655ed8ca1SJohan Hedberg kfree(key); 285755ed8ca1SJohan Hedberg 285855ed8ca1SJohan Hedberg return 0; 285955ed8ca1SJohan Hedberg } 286055ed8ca1SJohan Hedberg 2861e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 2862b899efafSVinicius Costa Gomes { 2863b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2864c51ffa0bSJohan Hedberg int removed = 0; 2865b899efafSVinicius Costa Gomes 2866b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2867e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 2868b899efafSVinicius Costa Gomes continue; 2869b899efafSVinicius Costa Gomes 28706ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2871b899efafSVinicius Costa Gomes 2872b899efafSVinicius Costa Gomes list_del(&k->list); 2873b899efafSVinicius Costa Gomes kfree(k); 2874c51ffa0bSJohan Hedberg removed++; 2875b899efafSVinicius Costa Gomes } 2876b899efafSVinicius Costa Gomes 2877c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 2878b899efafSVinicius Costa Gomes } 2879b899efafSVinicius Costa Gomes 2880a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 2881a7ec7338SJohan Hedberg { 2882a7ec7338SJohan Hedberg struct smp_irk *k, *tmp; 2883a7ec7338SJohan Hedberg 2884a7ec7338SJohan Hedberg list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2885a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 2886a7ec7338SJohan Hedberg continue; 2887a7ec7338SJohan Hedberg 2888a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2889a7ec7338SJohan Hedberg 2890a7ec7338SJohan Hedberg list_del(&k->list); 2891a7ec7338SJohan Hedberg kfree(k); 2892a7ec7338SJohan Hedberg } 2893a7ec7338SJohan Hedberg } 2894a7ec7338SJohan Hedberg 28956bd32326SVille Tervo /* HCI command timer function */ 2896bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg) 28976bd32326SVille Tervo { 28986bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 28996bd32326SVille Tervo 2900bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2901bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2902bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2903bda4f23aSAndrei Emeltchenko 2904bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 2905bda4f23aSAndrei Emeltchenko } else { 29066bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 2907bda4f23aSAndrei Emeltchenko } 2908bda4f23aSAndrei Emeltchenko 29096bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2910c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 29116bd32326SVille Tervo } 29126bd32326SVille Tervo 29132763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 29142763eda6SSzymon Janc bdaddr_t *bdaddr) 29152763eda6SSzymon Janc { 29162763eda6SSzymon Janc struct oob_data *data; 29172763eda6SSzymon Janc 29182763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 29192763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 29202763eda6SSzymon Janc return data; 29212763eda6SSzymon Janc 29222763eda6SSzymon Janc return NULL; 29232763eda6SSzymon Janc } 29242763eda6SSzymon Janc 29252763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 29262763eda6SSzymon Janc { 29272763eda6SSzymon Janc struct oob_data *data; 29282763eda6SSzymon Janc 29292763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 29302763eda6SSzymon Janc if (!data) 29312763eda6SSzymon Janc return -ENOENT; 29322763eda6SSzymon Janc 29336ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 29342763eda6SSzymon Janc 29352763eda6SSzymon Janc list_del(&data->list); 29362763eda6SSzymon Janc kfree(data); 29372763eda6SSzymon Janc 29382763eda6SSzymon Janc return 0; 29392763eda6SSzymon Janc } 29402763eda6SSzymon Janc 294135f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 29422763eda6SSzymon Janc { 29432763eda6SSzymon Janc struct oob_data *data, *n; 29442763eda6SSzymon Janc 29452763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 29462763eda6SSzymon Janc list_del(&data->list); 29472763eda6SSzymon Janc kfree(data); 29482763eda6SSzymon Janc } 29492763eda6SSzymon Janc } 29502763eda6SSzymon Janc 29510798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 29520798872eSMarcel Holtmann u8 *hash, u8 *randomizer) 29532763eda6SSzymon Janc { 29542763eda6SSzymon Janc struct oob_data *data; 29552763eda6SSzymon Janc 29562763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 29572763eda6SSzymon Janc if (!data) { 29580a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 29592763eda6SSzymon Janc if (!data) 29602763eda6SSzymon Janc return -ENOMEM; 29612763eda6SSzymon Janc 29622763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 29632763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 29642763eda6SSzymon Janc } 29652763eda6SSzymon Janc 2966519ca9d0SMarcel Holtmann memcpy(data->hash192, hash, sizeof(data->hash192)); 2967519ca9d0SMarcel Holtmann memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192)); 29682763eda6SSzymon Janc 29690798872eSMarcel Holtmann memset(data->hash256, 0, sizeof(data->hash256)); 29700798872eSMarcel Holtmann memset(data->randomizer256, 0, sizeof(data->randomizer256)); 29710798872eSMarcel Holtmann 29720798872eSMarcel Holtmann BT_DBG("%s for %pMR", hdev->name, bdaddr); 29730798872eSMarcel Holtmann 29740798872eSMarcel Holtmann return 0; 29750798872eSMarcel Holtmann } 29760798872eSMarcel Holtmann 29770798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 29780798872eSMarcel Holtmann u8 *hash192, u8 *randomizer192, 29790798872eSMarcel Holtmann u8 *hash256, u8 *randomizer256) 29800798872eSMarcel Holtmann { 29810798872eSMarcel Holtmann struct oob_data *data; 29820798872eSMarcel Holtmann 29830798872eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, bdaddr); 29840798872eSMarcel Holtmann if (!data) { 29850a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 29860798872eSMarcel Holtmann if (!data) 29870798872eSMarcel Holtmann return -ENOMEM; 29880798872eSMarcel Holtmann 29890798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 29900798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 29910798872eSMarcel Holtmann } 29920798872eSMarcel Holtmann 29930798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 29940798872eSMarcel Holtmann memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192)); 29950798872eSMarcel Holtmann 29960798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 29970798872eSMarcel Holtmann memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256)); 29980798872eSMarcel Holtmann 29996ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 30002763eda6SSzymon Janc 30012763eda6SSzymon Janc return 0; 30022763eda6SSzymon Janc } 30032763eda6SSzymon Janc 3004b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 3005b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 3006b2a66aadSAntti Julku { 3007b2a66aadSAntti Julku struct bdaddr_list *b; 3008b2a66aadSAntti Julku 3009b9ee0a78SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) { 3010b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3011b2a66aadSAntti Julku return b; 3012b9ee0a78SMarcel Holtmann } 3013b2a66aadSAntti Julku 3014b2a66aadSAntti Julku return NULL; 3015b2a66aadSAntti Julku } 3016b2a66aadSAntti Julku 301735f7498aSJohan Hedberg void hci_blacklist_clear(struct hci_dev *hdev) 3018b2a66aadSAntti Julku { 3019b2a66aadSAntti Julku struct list_head *p, *n; 3020b2a66aadSAntti Julku 3021b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 3022b9ee0a78SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 3023b2a66aadSAntti Julku 3024b2a66aadSAntti Julku list_del(p); 3025b2a66aadSAntti Julku kfree(b); 3026b2a66aadSAntti Julku } 3027b2a66aadSAntti Julku } 3028b2a66aadSAntti Julku 302988c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3030b2a66aadSAntti Julku { 3031b2a66aadSAntti Julku struct bdaddr_list *entry; 3032b2a66aadSAntti Julku 3033b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3034b2a66aadSAntti Julku return -EBADF; 3035b2a66aadSAntti Julku 3036b9ee0a78SMarcel Holtmann if (hci_blacklist_lookup(hdev, bdaddr, type)) 30375e762444SAntti Julku return -EEXIST; 3038b2a66aadSAntti Julku 3039b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 30405e762444SAntti Julku if (!entry) 30415e762444SAntti Julku return -ENOMEM; 3042b2a66aadSAntti Julku 3043b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 3044b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 3045b2a66aadSAntti Julku 3046b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 3047b2a66aadSAntti Julku 304888c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 3049b2a66aadSAntti Julku } 3050b2a66aadSAntti Julku 305188c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3052b2a66aadSAntti Julku { 3053b2a66aadSAntti Julku struct bdaddr_list *entry; 3054b2a66aadSAntti Julku 305535f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 305635f7498aSJohan Hedberg hci_blacklist_clear(hdev); 305735f7498aSJohan Hedberg return 0; 305835f7498aSJohan Hedberg } 3059b2a66aadSAntti Julku 3060b9ee0a78SMarcel Holtmann entry = hci_blacklist_lookup(hdev, bdaddr, type); 30611ec918ceSSzymon Janc if (!entry) 30625e762444SAntti Julku return -ENOENT; 3063b2a66aadSAntti Julku 3064b2a66aadSAntti Julku list_del(&entry->list); 3065b2a66aadSAntti Julku kfree(entry); 3066b2a66aadSAntti Julku 306788c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 3068b2a66aadSAntti Julku } 3069b2a66aadSAntti Julku 307015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 307115819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 307215819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 307315819a70SAndre Guedes { 307415819a70SAndre Guedes struct hci_conn_params *params; 307515819a70SAndre Guedes 307615819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 307715819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 307815819a70SAndre Guedes params->addr_type == addr_type) { 307915819a70SAndre Guedes return params; 308015819a70SAndre Guedes } 308115819a70SAndre Guedes } 308215819a70SAndre Guedes 308315819a70SAndre Guedes return NULL; 308415819a70SAndre Guedes } 308515819a70SAndre Guedes 308615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 308715819a70SAndre Guedes void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, 308815819a70SAndre Guedes u16 conn_min_interval, u16 conn_max_interval) 308915819a70SAndre Guedes { 309015819a70SAndre Guedes struct hci_conn_params *params; 309115819a70SAndre Guedes 309215819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 309315819a70SAndre Guedes if (params) { 309415819a70SAndre Guedes params->conn_min_interval = conn_min_interval; 309515819a70SAndre Guedes params->conn_max_interval = conn_max_interval; 309615819a70SAndre Guedes return; 309715819a70SAndre Guedes } 309815819a70SAndre Guedes 309915819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 310015819a70SAndre Guedes if (!params) { 310115819a70SAndre Guedes BT_ERR("Out of memory"); 310215819a70SAndre Guedes return; 310315819a70SAndre Guedes } 310415819a70SAndre Guedes 310515819a70SAndre Guedes bacpy(¶ms->addr, addr); 310615819a70SAndre Guedes params->addr_type = addr_type; 310715819a70SAndre Guedes params->conn_min_interval = conn_min_interval; 310815819a70SAndre Guedes params->conn_max_interval = conn_max_interval; 310915819a70SAndre Guedes 311015819a70SAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 311115819a70SAndre Guedes 311215819a70SAndre Guedes BT_DBG("addr %pMR (type %u) conn_min_interval 0x%.4x " 311315819a70SAndre Guedes "conn_max_interval 0x%.4x", addr, addr_type, conn_min_interval, 311415819a70SAndre Guedes conn_max_interval); 311515819a70SAndre Guedes } 311615819a70SAndre Guedes 311715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 311815819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 311915819a70SAndre Guedes { 312015819a70SAndre Guedes struct hci_conn_params *params; 312115819a70SAndre Guedes 312215819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 312315819a70SAndre Guedes if (!params) 312415819a70SAndre Guedes return; 312515819a70SAndre Guedes 312615819a70SAndre Guedes list_del(¶ms->list); 312715819a70SAndre Guedes kfree(params); 312815819a70SAndre Guedes 312915819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 313015819a70SAndre Guedes } 313115819a70SAndre Guedes 313215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 313315819a70SAndre Guedes void hci_conn_params_clear(struct hci_dev *hdev) 313415819a70SAndre Guedes { 313515819a70SAndre Guedes struct hci_conn_params *params, *tmp; 313615819a70SAndre Guedes 313715819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 313815819a70SAndre Guedes list_del(¶ms->list); 313915819a70SAndre Guedes kfree(params); 314015819a70SAndre Guedes } 314115819a70SAndre Guedes 314215819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 314315819a70SAndre Guedes } 314415819a70SAndre Guedes 31454c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 31467ba8b4beSAndre Guedes { 31474c87eaabSAndre Guedes if (status) { 31484c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 31497ba8b4beSAndre Guedes 31504c87eaabSAndre Guedes hci_dev_lock(hdev); 31514c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 31524c87eaabSAndre Guedes hci_dev_unlock(hdev); 31534c87eaabSAndre Guedes return; 31544c87eaabSAndre Guedes } 31557ba8b4beSAndre Guedes } 31567ba8b4beSAndre Guedes 31574c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 31587ba8b4beSAndre Guedes { 31594c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 31604c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 31614c87eaabSAndre Guedes struct hci_request req; 31624c87eaabSAndre Guedes struct hci_cp_inquiry cp; 31637ba8b4beSAndre Guedes int err; 31647ba8b4beSAndre Guedes 31654c87eaabSAndre Guedes if (status) { 31664c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 31674c87eaabSAndre Guedes return; 31687ba8b4beSAndre Guedes } 31697ba8b4beSAndre Guedes 31704c87eaabSAndre Guedes switch (hdev->discovery.type) { 31714c87eaabSAndre Guedes case DISCOV_TYPE_LE: 31724c87eaabSAndre Guedes hci_dev_lock(hdev); 31734c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 31744c87eaabSAndre Guedes hci_dev_unlock(hdev); 31754c87eaabSAndre Guedes break; 31767dbfac1dSAndre Guedes 31774c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 31784c87eaabSAndre Guedes hci_req_init(&req, hdev); 31797dbfac1dSAndre Guedes 31807dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 31814c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 31824c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 31834c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 31844c87eaabSAndre Guedes 31854c87eaabSAndre Guedes hci_dev_lock(hdev); 31864c87eaabSAndre Guedes 31874c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 31884c87eaabSAndre Guedes 31894c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 31904c87eaabSAndre Guedes if (err) { 31914c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 31924c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 31937dbfac1dSAndre Guedes } 31947dbfac1dSAndre Guedes 31954c87eaabSAndre Guedes hci_dev_unlock(hdev); 31964c87eaabSAndre Guedes break; 31974c87eaabSAndre Guedes } 31987dbfac1dSAndre Guedes } 31997dbfac1dSAndre Guedes 32007ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 32017ba8b4beSAndre Guedes { 32027ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 32037ba8b4beSAndre Guedes le_scan_disable.work); 32047ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 32054c87eaabSAndre Guedes struct hci_request req; 32064c87eaabSAndre Guedes int err; 32077ba8b4beSAndre Guedes 32087ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 32097ba8b4beSAndre Guedes 32104c87eaabSAndre Guedes hci_req_init(&req, hdev); 32117ba8b4beSAndre Guedes 32127ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 32134c87eaabSAndre Guedes cp.enable = LE_SCAN_DISABLE; 32144c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 32157ba8b4beSAndre Guedes 32164c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 32174c87eaabSAndre Guedes if (err) 32184c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 321928b75a89SAndre Guedes } 322028b75a89SAndre Guedes 32219be0dab7SDavid Herrmann /* Alloc HCI device */ 32229be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 32239be0dab7SDavid Herrmann { 32249be0dab7SDavid Herrmann struct hci_dev *hdev; 32259be0dab7SDavid Herrmann 32269be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 32279be0dab7SDavid Herrmann if (!hdev) 32289be0dab7SDavid Herrmann return NULL; 32299be0dab7SDavid Herrmann 3230b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3231b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3232b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3233b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3234b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 3235bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3236bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3237b1b813d4SDavid Herrmann 3238b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3239b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3240b1b813d4SDavid Herrmann 3241bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3242bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 32434e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = 0x0028; 32444e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = 0x0038; 3245bef64738SMarcel Holtmann 3246b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3247b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3248b1b813d4SDavid Herrmann 3249b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3250b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 3251b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3252b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3253b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3254970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3255b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 325615819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 32576b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3258b1b813d4SDavid Herrmann 3259b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3260b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3261b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3262b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3263b1b813d4SDavid Herrmann 3264b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3265b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 3266b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 3267b1b813d4SDavid Herrmann 3268b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3269b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3270b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3271b1b813d4SDavid Herrmann 3272b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 3273b1b813d4SDavid Herrmann 3274bda4f23aSAndrei Emeltchenko setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); 3275b1b813d4SDavid Herrmann 3276b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3277b1b813d4SDavid Herrmann discovery_init(hdev); 32789be0dab7SDavid Herrmann 32799be0dab7SDavid Herrmann return hdev; 32809be0dab7SDavid Herrmann } 32819be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 32829be0dab7SDavid Herrmann 32839be0dab7SDavid Herrmann /* Free HCI device */ 32849be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 32859be0dab7SDavid Herrmann { 32869be0dab7SDavid Herrmann /* will free via device release */ 32879be0dab7SDavid Herrmann put_device(&hdev->dev); 32889be0dab7SDavid Herrmann } 32899be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 32909be0dab7SDavid Herrmann 32911da177e4SLinus Torvalds /* Register HCI device */ 32921da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 32931da177e4SLinus Torvalds { 3294b1b813d4SDavid Herrmann int id, error; 32951da177e4SLinus Torvalds 3296010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 32971da177e4SLinus Torvalds return -EINVAL; 32981da177e4SLinus Torvalds 329908add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 330008add513SMat Martineau * so the index can be used as the AMP controller ID. 330108add513SMat Martineau */ 33023df92b31SSasha Levin switch (hdev->dev_type) { 33033df92b31SSasha Levin case HCI_BREDR: 33043df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 33051da177e4SLinus Torvalds break; 33063df92b31SSasha Levin case HCI_AMP: 33073df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 33083df92b31SSasha Levin break; 33093df92b31SSasha Levin default: 33103df92b31SSasha Levin return -EINVAL; 33111da177e4SLinus Torvalds } 33121da177e4SLinus Torvalds 33133df92b31SSasha Levin if (id < 0) 33143df92b31SSasha Levin return id; 33153df92b31SSasha Levin 33161da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 33171da177e4SLinus Torvalds hdev->id = id; 33182d8b3a11SAndrei Emeltchenko 33192d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 33202d8b3a11SAndrei Emeltchenko 3321d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3322d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 332333ca954dSDavid Herrmann if (!hdev->workqueue) { 332433ca954dSDavid Herrmann error = -ENOMEM; 332533ca954dSDavid Herrmann goto err; 332633ca954dSDavid Herrmann } 3327f48fd9c8SMarcel Holtmann 3328d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3329d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 33306ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 33316ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 33326ead1bbcSJohan Hedberg error = -ENOMEM; 33336ead1bbcSJohan Hedberg goto err; 33346ead1bbcSJohan Hedberg } 33356ead1bbcSJohan Hedberg 33360153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 33370153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 33380153e2ecSMarcel Holtmann 3339bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3340bdc3e0f1SMarcel Holtmann 334199780a7bSJohan Hedberg hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 334299780a7bSJohan Hedberg CRYPTO_ALG_ASYNC); 334399780a7bSJohan Hedberg if (IS_ERR(hdev->tfm_aes)) { 334499780a7bSJohan Hedberg BT_ERR("Unable to create crypto context"); 334599780a7bSJohan Hedberg error = PTR_ERR(hdev->tfm_aes); 334699780a7bSJohan Hedberg hdev->tfm_aes = NULL; 334799780a7bSJohan Hedberg goto err_wqueue; 334899780a7bSJohan Hedberg } 334999780a7bSJohan Hedberg 3350bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 335133ca954dSDavid Herrmann if (error < 0) 335299780a7bSJohan Hedberg goto err_tfm; 33531da177e4SLinus Torvalds 3354611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3355a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3356a8c5fb1aSGustavo Padovan hdev); 3357611b30f7SMarcel Holtmann if (hdev->rfkill) { 3358611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3359611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3360611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3361611b30f7SMarcel Holtmann } 3362611b30f7SMarcel Holtmann } 3363611b30f7SMarcel Holtmann 33645e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 33655e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 33665e130367SJohan Hedberg 3367a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 3368004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 3369ce2be9acSAndrei Emeltchenko 337001cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 337156f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 337256f87901SJohan Hedberg * through reading supported features during init. 337356f87901SJohan Hedberg */ 337456f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 337556f87901SJohan Hedberg } 3376ce2be9acSAndrei Emeltchenko 3377fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3378fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3379fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3380fcee3377SGustavo Padovan 33811da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 3382dc946bd8SDavid Herrmann hci_dev_hold(hdev); 33831da177e4SLinus Torvalds 338419202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3385fbe96d6fSMarcel Holtmann 33861da177e4SLinus Torvalds return id; 3387f48fd9c8SMarcel Holtmann 338899780a7bSJohan Hedberg err_tfm: 338999780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 339033ca954dSDavid Herrmann err_wqueue: 339133ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 33926ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 339333ca954dSDavid Herrmann err: 33943df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3395f48fd9c8SMarcel Holtmann 339633ca954dSDavid Herrmann return error; 33971da177e4SLinus Torvalds } 33981da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 33991da177e4SLinus Torvalds 34001da177e4SLinus Torvalds /* Unregister HCI device */ 340159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 34021da177e4SLinus Torvalds { 34033df92b31SSasha Levin int i, id; 3404ef222013SMarcel Holtmann 3405c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 34061da177e4SLinus Torvalds 340794324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 340894324962SJohan Hovold 34093df92b31SSasha Levin id = hdev->id; 34103df92b31SSasha Levin 3411f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 34121da177e4SLinus Torvalds list_del(&hdev->list); 3413f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 34141da177e4SLinus Torvalds 34151da177e4SLinus Torvalds hci_dev_do_close(hdev); 34161da177e4SLinus Torvalds 3417cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 3418ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 3419ef222013SMarcel Holtmann 3420b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 3421b9b5ef18SGustavo Padovan 3422ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 3423a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 342409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3425744cf19eSJohan Hedberg mgmt_index_removed(hdev); 342609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 342756e5cb86SJohan Hedberg } 3428ab81cbf9SJohan Hedberg 34292e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 34302e58ef3eSJohan Hedberg * pending list */ 34312e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 34322e58ef3eSJohan Hedberg 34331da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 34341da177e4SLinus Torvalds 3435611b30f7SMarcel Holtmann if (hdev->rfkill) { 3436611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 3437611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3438611b30f7SMarcel Holtmann } 3439611b30f7SMarcel Holtmann 344099780a7bSJohan Hedberg if (hdev->tfm_aes) 344199780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 344299780a7bSJohan Hedberg 3443bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 3444147e2d59SDave Young 34450153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 34460153e2ecSMarcel Holtmann 3447f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 34486ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 3449f48fd9c8SMarcel Holtmann 345009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3451e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 34522aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 345355ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 3454b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 3455970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 34562763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 345715819a70SAndre Guedes hci_conn_params_clear(hdev); 345809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 3459e2e0cacbSJohan Hedberg 3460dc946bd8SDavid Herrmann hci_dev_put(hdev); 34613df92b31SSasha Levin 34623df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 34631da177e4SLinus Torvalds } 34641da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 34651da177e4SLinus Torvalds 34661da177e4SLinus Torvalds /* Suspend HCI device */ 34671da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 34681da177e4SLinus Torvalds { 34691da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 34701da177e4SLinus Torvalds return 0; 34711da177e4SLinus Torvalds } 34721da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 34731da177e4SLinus Torvalds 34741da177e4SLinus Torvalds /* Resume HCI device */ 34751da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 34761da177e4SLinus Torvalds { 34771da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 34781da177e4SLinus Torvalds return 0; 34791da177e4SLinus Torvalds } 34801da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 34811da177e4SLinus Torvalds 348276bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 3483e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 348476bca880SMarcel Holtmann { 348576bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 348676bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 348776bca880SMarcel Holtmann kfree_skb(skb); 348876bca880SMarcel Holtmann return -ENXIO; 348976bca880SMarcel Holtmann } 349076bca880SMarcel Holtmann 3491d82603c6SJorrit Schippers /* Incoming skb */ 349276bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 349376bca880SMarcel Holtmann 349476bca880SMarcel Holtmann /* Time stamp */ 349576bca880SMarcel Holtmann __net_timestamp(skb); 349676bca880SMarcel Holtmann 349776bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3498b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3499c78ae283SMarcel Holtmann 350076bca880SMarcel Holtmann return 0; 350176bca880SMarcel Holtmann } 350276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 350376bca880SMarcel Holtmann 350433e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 35051e429f38SGustavo F. Padovan int count, __u8 index) 350633e882a5SSuraj Sumangala { 350733e882a5SSuraj Sumangala int len = 0; 350833e882a5SSuraj Sumangala int hlen = 0; 350933e882a5SSuraj Sumangala int remain = count; 351033e882a5SSuraj Sumangala struct sk_buff *skb; 351133e882a5SSuraj Sumangala struct bt_skb_cb *scb; 351233e882a5SSuraj Sumangala 351333e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 351433e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 351533e882a5SSuraj Sumangala return -EILSEQ; 351633e882a5SSuraj Sumangala 351733e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 351833e882a5SSuraj Sumangala 351933e882a5SSuraj Sumangala if (!skb) { 352033e882a5SSuraj Sumangala switch (type) { 352133e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 352233e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 352333e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 352433e882a5SSuraj Sumangala break; 352533e882a5SSuraj Sumangala case HCI_EVENT_PKT: 352633e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 352733e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 352833e882a5SSuraj Sumangala break; 352933e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 353033e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 353133e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 353233e882a5SSuraj Sumangala break; 353333e882a5SSuraj Sumangala } 353433e882a5SSuraj Sumangala 35351e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 353633e882a5SSuraj Sumangala if (!skb) 353733e882a5SSuraj Sumangala return -ENOMEM; 353833e882a5SSuraj Sumangala 353933e882a5SSuraj Sumangala scb = (void *) skb->cb; 354033e882a5SSuraj Sumangala scb->expect = hlen; 354133e882a5SSuraj Sumangala scb->pkt_type = type; 354233e882a5SSuraj Sumangala 354333e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 354433e882a5SSuraj Sumangala } 354533e882a5SSuraj Sumangala 354633e882a5SSuraj Sumangala while (count) { 354733e882a5SSuraj Sumangala scb = (void *) skb->cb; 354889bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 354933e882a5SSuraj Sumangala 355033e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 355133e882a5SSuraj Sumangala 355233e882a5SSuraj Sumangala count -= len; 355333e882a5SSuraj Sumangala data += len; 355433e882a5SSuraj Sumangala scb->expect -= len; 355533e882a5SSuraj Sumangala remain = count; 355633e882a5SSuraj Sumangala 355733e882a5SSuraj Sumangala switch (type) { 355833e882a5SSuraj Sumangala case HCI_EVENT_PKT: 355933e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 356033e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 356133e882a5SSuraj Sumangala scb->expect = h->plen; 356233e882a5SSuraj Sumangala 356333e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 356433e882a5SSuraj Sumangala kfree_skb(skb); 356533e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 356633e882a5SSuraj Sumangala return -ENOMEM; 356733e882a5SSuraj Sumangala } 356833e882a5SSuraj Sumangala } 356933e882a5SSuraj Sumangala break; 357033e882a5SSuraj Sumangala 357133e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 357233e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 357333e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 357433e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 357533e882a5SSuraj Sumangala 357633e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 357733e882a5SSuraj Sumangala kfree_skb(skb); 357833e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 357933e882a5SSuraj Sumangala return -ENOMEM; 358033e882a5SSuraj Sumangala } 358133e882a5SSuraj Sumangala } 358233e882a5SSuraj Sumangala break; 358333e882a5SSuraj Sumangala 358433e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 358533e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 358633e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 358733e882a5SSuraj Sumangala scb->expect = h->dlen; 358833e882a5SSuraj Sumangala 358933e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 359033e882a5SSuraj Sumangala kfree_skb(skb); 359133e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 359233e882a5SSuraj Sumangala return -ENOMEM; 359333e882a5SSuraj Sumangala } 359433e882a5SSuraj Sumangala } 359533e882a5SSuraj Sumangala break; 359633e882a5SSuraj Sumangala } 359733e882a5SSuraj Sumangala 359833e882a5SSuraj Sumangala if (scb->expect == 0) { 359933e882a5SSuraj Sumangala /* Complete frame */ 360033e882a5SSuraj Sumangala 360133e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 3602e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 360333e882a5SSuraj Sumangala 360433e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 360533e882a5SSuraj Sumangala return remain; 360633e882a5SSuraj Sumangala } 360733e882a5SSuraj Sumangala } 360833e882a5SSuraj Sumangala 360933e882a5SSuraj Sumangala return remain; 361033e882a5SSuraj Sumangala } 361133e882a5SSuraj Sumangala 3612ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 3613ef222013SMarcel Holtmann { 3614f39a3c06SSuraj Sumangala int rem = 0; 3615f39a3c06SSuraj Sumangala 3616ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 3617ef222013SMarcel Holtmann return -EILSEQ; 3618ef222013SMarcel Holtmann 3619da5f6c37SGustavo F. Padovan while (count) { 36201e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 3621f39a3c06SSuraj Sumangala if (rem < 0) 3622f39a3c06SSuraj Sumangala return rem; 3623ef222013SMarcel Holtmann 3624f39a3c06SSuraj Sumangala data += (count - rem); 3625f39a3c06SSuraj Sumangala count = rem; 3626f81c6224SJoe Perches } 3627ef222013SMarcel Holtmann 3628f39a3c06SSuraj Sumangala return rem; 3629ef222013SMarcel Holtmann } 3630ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 3631ef222013SMarcel Holtmann 363299811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 363399811510SSuraj Sumangala 363499811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 363599811510SSuraj Sumangala { 363699811510SSuraj Sumangala int type; 363799811510SSuraj Sumangala int rem = 0; 363899811510SSuraj Sumangala 3639da5f6c37SGustavo F. Padovan while (count) { 364099811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 364199811510SSuraj Sumangala 364299811510SSuraj Sumangala if (!skb) { 364399811510SSuraj Sumangala struct { char type; } *pkt; 364499811510SSuraj Sumangala 364599811510SSuraj Sumangala /* Start of the frame */ 364699811510SSuraj Sumangala pkt = data; 364799811510SSuraj Sumangala type = pkt->type; 364899811510SSuraj Sumangala 364999811510SSuraj Sumangala data++; 365099811510SSuraj Sumangala count--; 365199811510SSuraj Sumangala } else 365299811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 365399811510SSuraj Sumangala 36541e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 36551e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 365699811510SSuraj Sumangala if (rem < 0) 365799811510SSuraj Sumangala return rem; 365899811510SSuraj Sumangala 365999811510SSuraj Sumangala data += (count - rem); 366099811510SSuraj Sumangala count = rem; 3661f81c6224SJoe Perches } 366299811510SSuraj Sumangala 366399811510SSuraj Sumangala return rem; 366499811510SSuraj Sumangala } 366599811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 366699811510SSuraj Sumangala 36671da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 36681da177e4SLinus Torvalds 36691da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 36701da177e4SLinus Torvalds { 36711da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 36721da177e4SLinus Torvalds 3673f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 36741da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 3675f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 36761da177e4SLinus Torvalds 36771da177e4SLinus Torvalds return 0; 36781da177e4SLinus Torvalds } 36791da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 36801da177e4SLinus Torvalds 36811da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 36821da177e4SLinus Torvalds { 36831da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 36841da177e4SLinus Torvalds 3685f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 36861da177e4SLinus Torvalds list_del(&cb->list); 3687f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 36881da177e4SLinus Torvalds 36891da177e4SLinus Torvalds return 0; 36901da177e4SLinus Torvalds } 36911da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 36921da177e4SLinus Torvalds 369351086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 36941da177e4SLinus Torvalds { 36950d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 36961da177e4SLinus Torvalds 36971da177e4SLinus Torvalds /* Time stamp */ 3698a61bbcf2SPatrick McHardy __net_timestamp(skb); 36991da177e4SLinus Torvalds 3700cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3701cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3702cd82e61cSMarcel Holtmann 3703cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3704cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3705470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 37061da177e4SLinus Torvalds } 37071da177e4SLinus Torvalds 37081da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 37091da177e4SLinus Torvalds skb_orphan(skb); 37101da177e4SLinus Torvalds 37117bd8f09fSMarcel Holtmann if (hdev->send(hdev, skb) < 0) 371251086991SMarcel Holtmann BT_ERR("%s sending frame failed", hdev->name); 37131da177e4SLinus Torvalds } 37141da177e4SLinus Torvalds 37153119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 37163119ae95SJohan Hedberg { 37173119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 37183119ae95SJohan Hedberg req->hdev = hdev; 37195d73e034SAndre Guedes req->err = 0; 37203119ae95SJohan Hedberg } 37213119ae95SJohan Hedberg 37223119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 37233119ae95SJohan Hedberg { 37243119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 37253119ae95SJohan Hedberg struct sk_buff *skb; 37263119ae95SJohan Hedberg unsigned long flags; 37273119ae95SJohan Hedberg 37283119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 37293119ae95SJohan Hedberg 37305d73e034SAndre Guedes /* If an error occured during request building, remove all HCI 37315d73e034SAndre Guedes * commands queued on the HCI request queue. 37325d73e034SAndre Guedes */ 37335d73e034SAndre Guedes if (req->err) { 37345d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 37355d73e034SAndre Guedes return req->err; 37365d73e034SAndre Guedes } 37375d73e034SAndre Guedes 37383119ae95SJohan Hedberg /* Do not allow empty requests */ 37393119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 3740382b0c39SAndre Guedes return -ENODATA; 37413119ae95SJohan Hedberg 37423119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 37433119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 37443119ae95SJohan Hedberg 37453119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 37463119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 37473119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 37483119ae95SJohan Hedberg 37493119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 37503119ae95SJohan Hedberg 37513119ae95SJohan Hedberg return 0; 37523119ae95SJohan Hedberg } 37533119ae95SJohan Hedberg 37541ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 375507dc93ddSJohan Hedberg u32 plen, const void *param) 37561da177e4SLinus Torvalds { 37571da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 37581da177e4SLinus Torvalds struct hci_command_hdr *hdr; 37591da177e4SLinus Torvalds struct sk_buff *skb; 37601da177e4SLinus Torvalds 37611da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 37621ca3a9d0SJohan Hedberg if (!skb) 37631ca3a9d0SJohan Hedberg return NULL; 37641da177e4SLinus Torvalds 37651da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 3766a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 37671da177e4SLinus Torvalds hdr->plen = plen; 37681da177e4SLinus Torvalds 37691da177e4SLinus Torvalds if (plen) 37701da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 37711da177e4SLinus Torvalds 37721da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 37731da177e4SLinus Torvalds 37740d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 3775c78ae283SMarcel Holtmann 37761ca3a9d0SJohan Hedberg return skb; 37771ca3a9d0SJohan Hedberg } 37781ca3a9d0SJohan Hedberg 37791ca3a9d0SJohan Hedberg /* Send HCI command */ 378007dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 378107dc93ddSJohan Hedberg const void *param) 37821ca3a9d0SJohan Hedberg { 37831ca3a9d0SJohan Hedberg struct sk_buff *skb; 37841ca3a9d0SJohan Hedberg 37851ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 37861ca3a9d0SJohan Hedberg 37871ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 37881ca3a9d0SJohan Hedberg if (!skb) { 37891ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 37901ca3a9d0SJohan Hedberg return -ENOMEM; 37911ca3a9d0SJohan Hedberg } 37921ca3a9d0SJohan Hedberg 379311714b3dSJohan Hedberg /* Stand-alone HCI commands must be flaged as 379411714b3dSJohan Hedberg * single-command requests. 379511714b3dSJohan Hedberg */ 379611714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 379711714b3dSJohan Hedberg 37981da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3799c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 38001da177e4SLinus Torvalds 38011da177e4SLinus Torvalds return 0; 38021da177e4SLinus Torvalds } 38031da177e4SLinus Torvalds 380471c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 380507dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 380607dc93ddSJohan Hedberg const void *param, u8 event) 380771c76a17SJohan Hedberg { 380871c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 380971c76a17SJohan Hedberg struct sk_buff *skb; 381071c76a17SJohan Hedberg 381171c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 381271c76a17SJohan Hedberg 381334739c1eSAndre Guedes /* If an error occured during request building, there is no point in 381434739c1eSAndre Guedes * queueing the HCI command. We can simply return. 381534739c1eSAndre Guedes */ 381634739c1eSAndre Guedes if (req->err) 381734739c1eSAndre Guedes return; 381834739c1eSAndre Guedes 381971c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 382071c76a17SJohan Hedberg if (!skb) { 38215d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 38225d73e034SAndre Guedes hdev->name, opcode); 38235d73e034SAndre Guedes req->err = -ENOMEM; 3824e348fe6bSAndre Guedes return; 382571c76a17SJohan Hedberg } 382671c76a17SJohan Hedberg 382771c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 382871c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 382971c76a17SJohan Hedberg 383002350a72SJohan Hedberg bt_cb(skb)->req.event = event; 383102350a72SJohan Hedberg 383271c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 383371c76a17SJohan Hedberg } 383471c76a17SJohan Hedberg 383507dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 383607dc93ddSJohan Hedberg const void *param) 383702350a72SJohan Hedberg { 383802350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 383902350a72SJohan Hedberg } 384002350a72SJohan Hedberg 38411da177e4SLinus Torvalds /* Get data from the previously sent command */ 3842a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 38431da177e4SLinus Torvalds { 38441da177e4SLinus Torvalds struct hci_command_hdr *hdr; 38451da177e4SLinus Torvalds 38461da177e4SLinus Torvalds if (!hdev->sent_cmd) 38471da177e4SLinus Torvalds return NULL; 38481da177e4SLinus Torvalds 38491da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 38501da177e4SLinus Torvalds 3851a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 38521da177e4SLinus Torvalds return NULL; 38531da177e4SLinus Torvalds 3854f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 38551da177e4SLinus Torvalds 38561da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 38571da177e4SLinus Torvalds } 38581da177e4SLinus Torvalds 38591da177e4SLinus Torvalds /* Send ACL data */ 38601da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 38611da177e4SLinus Torvalds { 38621da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 38631da177e4SLinus Torvalds int len = skb->len; 38641da177e4SLinus Torvalds 3865badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3866badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 38679c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3868aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3869aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 38701da177e4SLinus Torvalds } 38711da177e4SLinus Torvalds 3872ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 387373d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 38741da177e4SLinus Torvalds { 3875ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 38761da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 38771da177e4SLinus Torvalds struct sk_buff *list; 38781da177e4SLinus Torvalds 3879087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3880087bfd99SGustavo Padovan skb->data_len = 0; 3881087bfd99SGustavo Padovan 3882087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3883204a6e54SAndrei Emeltchenko 3884204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3885204a6e54SAndrei Emeltchenko case HCI_BREDR: 3886087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3887204a6e54SAndrei Emeltchenko break; 3888204a6e54SAndrei Emeltchenko case HCI_AMP: 3889204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3890204a6e54SAndrei Emeltchenko break; 3891204a6e54SAndrei Emeltchenko default: 3892204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 3893204a6e54SAndrei Emeltchenko return; 3894204a6e54SAndrei Emeltchenko } 3895087bfd99SGustavo Padovan 389670f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 389770f23020SAndrei Emeltchenko if (!list) { 38981da177e4SLinus Torvalds /* Non fragmented */ 38991da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 39001da177e4SLinus Torvalds 390173d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 39021da177e4SLinus Torvalds } else { 39031da177e4SLinus Torvalds /* Fragmented */ 39041da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 39051da177e4SLinus Torvalds 39061da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 39071da177e4SLinus Torvalds 39081da177e4SLinus Torvalds /* Queue all fragments atomically */ 3909af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 39101da177e4SLinus Torvalds 391173d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3912e702112fSAndrei Emeltchenko 3913e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3914e702112fSAndrei Emeltchenko flags |= ACL_CONT; 39151da177e4SLinus Torvalds do { 39161da177e4SLinus Torvalds skb = list; list = list->next; 39171da177e4SLinus Torvalds 39180d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3919e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 39201da177e4SLinus Torvalds 39211da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 39221da177e4SLinus Torvalds 392373d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 39241da177e4SLinus Torvalds } while (list); 39251da177e4SLinus Torvalds 3926af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 39271da177e4SLinus Torvalds } 392873d80debSLuiz Augusto von Dentz } 392973d80debSLuiz Augusto von Dentz 393073d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 393173d80debSLuiz Augusto von Dentz { 3932ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 393373d80debSLuiz Augusto von Dentz 3934f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 393573d80debSLuiz Augusto von Dentz 3936ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 39371da177e4SLinus Torvalds 39383eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 39391da177e4SLinus Torvalds } 39401da177e4SLinus Torvalds 39411da177e4SLinus Torvalds /* Send SCO data */ 39420d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 39431da177e4SLinus Torvalds { 39441da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 39451da177e4SLinus Torvalds struct hci_sco_hdr hdr; 39461da177e4SLinus Torvalds 39471da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 39481da177e4SLinus Torvalds 3949aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 39501da177e4SLinus Torvalds hdr.dlen = skb->len; 39511da177e4SLinus Torvalds 3952badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 3953badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 39549c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 39551da177e4SLinus Torvalds 39560d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 3957c78ae283SMarcel Holtmann 39581da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 39593eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 39601da177e4SLinus Torvalds } 39611da177e4SLinus Torvalds 39621da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 39631da177e4SLinus Torvalds 39641da177e4SLinus Torvalds /* HCI Connection scheduler */ 39656039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 3966a8c5fb1aSGustavo Padovan int *quote) 39671da177e4SLinus Torvalds { 39681da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 39698035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 3970abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 39711da177e4SLinus Torvalds 39721da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 39731da177e4SLinus Torvalds * added and removed with TX task disabled. */ 3974bf4c6325SGustavo F. Padovan 3975bf4c6325SGustavo F. Padovan rcu_read_lock(); 3976bf4c6325SGustavo F. Padovan 3977bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3978769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 39791da177e4SLinus Torvalds continue; 3980769be974SMarcel Holtmann 3981769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 3982769be974SMarcel Holtmann continue; 3983769be974SMarcel Holtmann 39841da177e4SLinus Torvalds num++; 39851da177e4SLinus Torvalds 39861da177e4SLinus Torvalds if (c->sent < min) { 39871da177e4SLinus Torvalds min = c->sent; 39881da177e4SLinus Torvalds conn = c; 39891da177e4SLinus Torvalds } 399052087a79SLuiz Augusto von Dentz 399152087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 399252087a79SLuiz Augusto von Dentz break; 39931da177e4SLinus Torvalds } 39941da177e4SLinus Torvalds 3995bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3996bf4c6325SGustavo F. Padovan 39971da177e4SLinus Torvalds if (conn) { 39986ed58ec5SVille Tervo int cnt, q; 39996ed58ec5SVille Tervo 40006ed58ec5SVille Tervo switch (conn->type) { 40016ed58ec5SVille Tervo case ACL_LINK: 40026ed58ec5SVille Tervo cnt = hdev->acl_cnt; 40036ed58ec5SVille Tervo break; 40046ed58ec5SVille Tervo case SCO_LINK: 40056ed58ec5SVille Tervo case ESCO_LINK: 40066ed58ec5SVille Tervo cnt = hdev->sco_cnt; 40076ed58ec5SVille Tervo break; 40086ed58ec5SVille Tervo case LE_LINK: 40096ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 40106ed58ec5SVille Tervo break; 40116ed58ec5SVille Tervo default: 40126ed58ec5SVille Tervo cnt = 0; 40136ed58ec5SVille Tervo BT_ERR("Unknown link type"); 40146ed58ec5SVille Tervo } 40156ed58ec5SVille Tervo 40166ed58ec5SVille Tervo q = cnt / num; 40171da177e4SLinus Torvalds *quote = q ? q : 1; 40181da177e4SLinus Torvalds } else 40191da177e4SLinus Torvalds *quote = 0; 40201da177e4SLinus Torvalds 40211da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 40221da177e4SLinus Torvalds return conn; 40231da177e4SLinus Torvalds } 40241da177e4SLinus Torvalds 40256039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 40261da177e4SLinus Torvalds { 40271da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 40281da177e4SLinus Torvalds struct hci_conn *c; 40291da177e4SLinus Torvalds 4030bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 40311da177e4SLinus Torvalds 4032bf4c6325SGustavo F. Padovan rcu_read_lock(); 4033bf4c6325SGustavo F. Padovan 40341da177e4SLinus Torvalds /* Kill stalled connections */ 4035bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4036bae1f5d9SVille Tervo if (c->type == type && c->sent) { 40376ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 40386ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 4039bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 40401da177e4SLinus Torvalds } 40411da177e4SLinus Torvalds } 4042bf4c6325SGustavo F. Padovan 4043bf4c6325SGustavo F. Padovan rcu_read_unlock(); 40441da177e4SLinus Torvalds } 40451da177e4SLinus Torvalds 40466039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 404773d80debSLuiz Augusto von Dentz int *quote) 404873d80debSLuiz Augusto von Dentz { 404973d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 405073d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 4051abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 405273d80debSLuiz Augusto von Dentz struct hci_conn *conn; 405373d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 405473d80debSLuiz Augusto von Dentz 405573d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 405673d80debSLuiz Augusto von Dentz 4057bf4c6325SGustavo F. Padovan rcu_read_lock(); 4058bf4c6325SGustavo F. Padovan 4059bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 406073d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 406173d80debSLuiz Augusto von Dentz 406273d80debSLuiz Augusto von Dentz if (conn->type != type) 406373d80debSLuiz Augusto von Dentz continue; 406473d80debSLuiz Augusto von Dentz 406573d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 406673d80debSLuiz Augusto von Dentz continue; 406773d80debSLuiz Augusto von Dentz 406873d80debSLuiz Augusto von Dentz conn_num++; 406973d80debSLuiz Augusto von Dentz 40708192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 407173d80debSLuiz Augusto von Dentz struct sk_buff *skb; 407273d80debSLuiz Augusto von Dentz 407373d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 407473d80debSLuiz Augusto von Dentz continue; 407573d80debSLuiz Augusto von Dentz 407673d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 407773d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 407873d80debSLuiz Augusto von Dentz continue; 407973d80debSLuiz Augusto von Dentz 408073d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 408173d80debSLuiz Augusto von Dentz num = 0; 408273d80debSLuiz Augusto von Dentz min = ~0; 408373d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 408473d80debSLuiz Augusto von Dentz } 408573d80debSLuiz Augusto von Dentz 408673d80debSLuiz Augusto von Dentz num++; 408773d80debSLuiz Augusto von Dentz 408873d80debSLuiz Augusto von Dentz if (conn->sent < min) { 408973d80debSLuiz Augusto von Dentz min = conn->sent; 409073d80debSLuiz Augusto von Dentz chan = tmp; 409173d80debSLuiz Augusto von Dentz } 409273d80debSLuiz Augusto von Dentz } 409373d80debSLuiz Augusto von Dentz 409473d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 409573d80debSLuiz Augusto von Dentz break; 409673d80debSLuiz Augusto von Dentz } 409773d80debSLuiz Augusto von Dentz 4098bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4099bf4c6325SGustavo F. Padovan 410073d80debSLuiz Augusto von Dentz if (!chan) 410173d80debSLuiz Augusto von Dentz return NULL; 410273d80debSLuiz Augusto von Dentz 410373d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 410473d80debSLuiz Augusto von Dentz case ACL_LINK: 410573d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 410673d80debSLuiz Augusto von Dentz break; 4107bd1eb66bSAndrei Emeltchenko case AMP_LINK: 4108bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 4109bd1eb66bSAndrei Emeltchenko break; 411073d80debSLuiz Augusto von Dentz case SCO_LINK: 411173d80debSLuiz Augusto von Dentz case ESCO_LINK: 411273d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 411373d80debSLuiz Augusto von Dentz break; 411473d80debSLuiz Augusto von Dentz case LE_LINK: 411573d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 411673d80debSLuiz Augusto von Dentz break; 411773d80debSLuiz Augusto von Dentz default: 411873d80debSLuiz Augusto von Dentz cnt = 0; 411973d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 412073d80debSLuiz Augusto von Dentz } 412173d80debSLuiz Augusto von Dentz 412273d80debSLuiz Augusto von Dentz q = cnt / num; 412373d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 412473d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 412573d80debSLuiz Augusto von Dentz return chan; 412673d80debSLuiz Augusto von Dentz } 412773d80debSLuiz Augusto von Dentz 412802b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 412902b20f0bSLuiz Augusto von Dentz { 413002b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 413102b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 413202b20f0bSLuiz Augusto von Dentz int num = 0; 413302b20f0bSLuiz Augusto von Dentz 413402b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 413502b20f0bSLuiz Augusto von Dentz 4136bf4c6325SGustavo F. Padovan rcu_read_lock(); 4137bf4c6325SGustavo F. Padovan 4138bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 413902b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 414002b20f0bSLuiz Augusto von Dentz 414102b20f0bSLuiz Augusto von Dentz if (conn->type != type) 414202b20f0bSLuiz Augusto von Dentz continue; 414302b20f0bSLuiz Augusto von Dentz 414402b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 414502b20f0bSLuiz Augusto von Dentz continue; 414602b20f0bSLuiz Augusto von Dentz 414702b20f0bSLuiz Augusto von Dentz num++; 414802b20f0bSLuiz Augusto von Dentz 41498192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 415002b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 415102b20f0bSLuiz Augusto von Dentz 415202b20f0bSLuiz Augusto von Dentz if (chan->sent) { 415302b20f0bSLuiz Augusto von Dentz chan->sent = 0; 415402b20f0bSLuiz Augusto von Dentz continue; 415502b20f0bSLuiz Augusto von Dentz } 415602b20f0bSLuiz Augusto von Dentz 415702b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 415802b20f0bSLuiz Augusto von Dentz continue; 415902b20f0bSLuiz Augusto von Dentz 416002b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 416102b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 416202b20f0bSLuiz Augusto von Dentz continue; 416302b20f0bSLuiz Augusto von Dentz 416402b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 416502b20f0bSLuiz Augusto von Dentz 416602b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 416702b20f0bSLuiz Augusto von Dentz skb->priority); 416802b20f0bSLuiz Augusto von Dentz } 416902b20f0bSLuiz Augusto von Dentz 417002b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 417102b20f0bSLuiz Augusto von Dentz break; 417202b20f0bSLuiz Augusto von Dentz } 4173bf4c6325SGustavo F. Padovan 4174bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4175bf4c6325SGustavo F. Padovan 417602b20f0bSLuiz Augusto von Dentz } 417702b20f0bSLuiz Augusto von Dentz 4178b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4179b71d385aSAndrei Emeltchenko { 4180b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4181b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4182b71d385aSAndrei Emeltchenko } 4183b71d385aSAndrei Emeltchenko 41846039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 41851da177e4SLinus Torvalds { 41861da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 41871da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 41881da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 418963d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 41905f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 4191bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 41921da177e4SLinus Torvalds } 419363d2bc1bSAndrei Emeltchenko } 41941da177e4SLinus Torvalds 41956039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 419663d2bc1bSAndrei Emeltchenko { 419763d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 419863d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 419963d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 420063d2bc1bSAndrei Emeltchenko int quote; 420163d2bc1bSAndrei Emeltchenko 420263d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 420304837f64SMarcel Holtmann 420473d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 420573d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 4206ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4207ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 420873d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 420973d80debSLuiz Augusto von Dentz skb->len, skb->priority); 421073d80debSLuiz Augusto von Dentz 4211ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4212ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4213ec1cce24SLuiz Augusto von Dentz break; 4214ec1cce24SLuiz Augusto von Dentz 4215ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4216ec1cce24SLuiz Augusto von Dentz 421773d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 421873d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 421904837f64SMarcel Holtmann 422057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 42211da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 42221da177e4SLinus Torvalds 42231da177e4SLinus Torvalds hdev->acl_cnt--; 422473d80debSLuiz Augusto von Dentz chan->sent++; 422573d80debSLuiz Augusto von Dentz chan->conn->sent++; 42261da177e4SLinus Torvalds } 42271da177e4SLinus Torvalds } 422802b20f0bSLuiz Augusto von Dentz 422902b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 423002b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 42311da177e4SLinus Torvalds } 42321da177e4SLinus Torvalds 42336039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4234b71d385aSAndrei Emeltchenko { 423563d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4236b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4237b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4238b71d385aSAndrei Emeltchenko int quote; 4239bd1eb66bSAndrei Emeltchenko u8 type; 4240b71d385aSAndrei Emeltchenko 424163d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4242b71d385aSAndrei Emeltchenko 4243bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4244bd1eb66bSAndrei Emeltchenko 4245bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4246bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4247bd1eb66bSAndrei Emeltchenko else 4248bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4249bd1eb66bSAndrei Emeltchenko 4250b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4251bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4252b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4253b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4254b71d385aSAndrei Emeltchenko int blocks; 4255b71d385aSAndrei Emeltchenko 4256b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4257b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4258b71d385aSAndrei Emeltchenko 4259b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4260b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4261b71d385aSAndrei Emeltchenko break; 4262b71d385aSAndrei Emeltchenko 4263b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4264b71d385aSAndrei Emeltchenko 4265b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4266b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4267b71d385aSAndrei Emeltchenko return; 4268b71d385aSAndrei Emeltchenko 4269b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4270b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4271b71d385aSAndrei Emeltchenko 427257d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4273b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4274b71d385aSAndrei Emeltchenko 4275b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4276b71d385aSAndrei Emeltchenko quote -= blocks; 4277b71d385aSAndrei Emeltchenko 4278b71d385aSAndrei Emeltchenko chan->sent += blocks; 4279b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4280b71d385aSAndrei Emeltchenko } 4281b71d385aSAndrei Emeltchenko } 4282b71d385aSAndrei Emeltchenko 4283b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4284bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4285b71d385aSAndrei Emeltchenko } 4286b71d385aSAndrei Emeltchenko 42876039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4288b71d385aSAndrei Emeltchenko { 4289b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4290b71d385aSAndrei Emeltchenko 4291bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4292bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 4293bd1eb66bSAndrei Emeltchenko return; 4294bd1eb66bSAndrei Emeltchenko 4295bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4296bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4297b71d385aSAndrei Emeltchenko return; 4298b71d385aSAndrei Emeltchenko 4299b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4300b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4301b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4302b71d385aSAndrei Emeltchenko break; 4303b71d385aSAndrei Emeltchenko 4304b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4305b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4306b71d385aSAndrei Emeltchenko break; 4307b71d385aSAndrei Emeltchenko } 4308b71d385aSAndrei Emeltchenko } 4309b71d385aSAndrei Emeltchenko 43101da177e4SLinus Torvalds /* Schedule SCO */ 43116039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 43121da177e4SLinus Torvalds { 43131da177e4SLinus Torvalds struct hci_conn *conn; 43141da177e4SLinus Torvalds struct sk_buff *skb; 43151da177e4SLinus Torvalds int quote; 43161da177e4SLinus Torvalds 43171da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 43181da177e4SLinus Torvalds 431952087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 432052087a79SLuiz Augusto von Dentz return; 432152087a79SLuiz Augusto von Dentz 43221da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 43231da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 43241da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 432557d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 43261da177e4SLinus Torvalds 43271da177e4SLinus Torvalds conn->sent++; 43281da177e4SLinus Torvalds if (conn->sent == ~0) 43291da177e4SLinus Torvalds conn->sent = 0; 43301da177e4SLinus Torvalds } 43311da177e4SLinus Torvalds } 43321da177e4SLinus Torvalds } 43331da177e4SLinus Torvalds 43346039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 4335b6a0dc82SMarcel Holtmann { 4336b6a0dc82SMarcel Holtmann struct hci_conn *conn; 4337b6a0dc82SMarcel Holtmann struct sk_buff *skb; 4338b6a0dc82SMarcel Holtmann int quote; 4339b6a0dc82SMarcel Holtmann 4340b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 4341b6a0dc82SMarcel Holtmann 434252087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 434352087a79SLuiz Augusto von Dentz return; 434452087a79SLuiz Augusto von Dentz 43458fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 43468fc9ced3SGustavo Padovan "e))) { 4347b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 4348b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 434957d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4350b6a0dc82SMarcel Holtmann 4351b6a0dc82SMarcel Holtmann conn->sent++; 4352b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 4353b6a0dc82SMarcel Holtmann conn->sent = 0; 4354b6a0dc82SMarcel Holtmann } 4355b6a0dc82SMarcel Holtmann } 4356b6a0dc82SMarcel Holtmann } 4357b6a0dc82SMarcel Holtmann 43586039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 43596ed58ec5SVille Tervo { 436073d80debSLuiz Augusto von Dentz struct hci_chan *chan; 43616ed58ec5SVille Tervo struct sk_buff *skb; 436202b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 43636ed58ec5SVille Tervo 43646ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 43656ed58ec5SVille Tervo 436652087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 436752087a79SLuiz Augusto von Dentz return; 436852087a79SLuiz Augusto von Dentz 43696ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 43706ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 43716ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 4372bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 43736ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 4374bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 43756ed58ec5SVille Tervo } 43766ed58ec5SVille Tervo 43776ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 437802b20f0bSLuiz Augusto von Dentz tmp = cnt; 437973d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 4380ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4381ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 438273d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 438373d80debSLuiz Augusto von Dentz skb->len, skb->priority); 43846ed58ec5SVille Tervo 4385ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4386ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4387ec1cce24SLuiz Augusto von Dentz break; 4388ec1cce24SLuiz Augusto von Dentz 4389ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4390ec1cce24SLuiz Augusto von Dentz 439157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 43926ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 43936ed58ec5SVille Tervo 43946ed58ec5SVille Tervo cnt--; 439573d80debSLuiz Augusto von Dentz chan->sent++; 439673d80debSLuiz Augusto von Dentz chan->conn->sent++; 43976ed58ec5SVille Tervo } 43986ed58ec5SVille Tervo } 439973d80debSLuiz Augusto von Dentz 44006ed58ec5SVille Tervo if (hdev->le_pkts) 44016ed58ec5SVille Tervo hdev->le_cnt = cnt; 44026ed58ec5SVille Tervo else 44036ed58ec5SVille Tervo hdev->acl_cnt = cnt; 440402b20f0bSLuiz Augusto von Dentz 440502b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 440602b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 44076ed58ec5SVille Tervo } 44086ed58ec5SVille Tervo 44093eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 44101da177e4SLinus Torvalds { 44113eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 44121da177e4SLinus Torvalds struct sk_buff *skb; 44131da177e4SLinus Torvalds 44146ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 44156ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 44161da177e4SLinus Torvalds 441752de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 44181da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 44191da177e4SLinus Torvalds hci_sched_acl(hdev); 44201da177e4SLinus Torvalds hci_sched_sco(hdev); 4421b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 44226ed58ec5SVille Tervo hci_sched_le(hdev); 442352de599eSMarcel Holtmann } 44246ed58ec5SVille Tervo 44251da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 44261da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 442757d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 44281da177e4SLinus Torvalds } 44291da177e4SLinus Torvalds 443025985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 44311da177e4SLinus Torvalds 44321da177e4SLinus Torvalds /* ACL data packet */ 44336039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 44341da177e4SLinus Torvalds { 44351da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 44361da177e4SLinus Torvalds struct hci_conn *conn; 44371da177e4SLinus Torvalds __u16 handle, flags; 44381da177e4SLinus Torvalds 44391da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 44401da177e4SLinus Torvalds 44411da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 44421da177e4SLinus Torvalds flags = hci_flags(handle); 44431da177e4SLinus Torvalds handle = hci_handle(handle); 44441da177e4SLinus Torvalds 4445f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4446a8c5fb1aSGustavo Padovan handle, flags); 44471da177e4SLinus Torvalds 44481da177e4SLinus Torvalds hdev->stat.acl_rx++; 44491da177e4SLinus Torvalds 44501da177e4SLinus Torvalds hci_dev_lock(hdev); 44511da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 44521da177e4SLinus Torvalds hci_dev_unlock(hdev); 44531da177e4SLinus Torvalds 44541da177e4SLinus Torvalds if (conn) { 445565983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 445604837f64SMarcel Holtmann 44571da177e4SLinus Torvalds /* Send to upper protocol */ 4458686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 44591da177e4SLinus Torvalds return; 44601da177e4SLinus Torvalds } else { 44611da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 44621da177e4SLinus Torvalds hdev->name, handle); 44631da177e4SLinus Torvalds } 44641da177e4SLinus Torvalds 44651da177e4SLinus Torvalds kfree_skb(skb); 44661da177e4SLinus Torvalds } 44671da177e4SLinus Torvalds 44681da177e4SLinus Torvalds /* SCO data packet */ 44696039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 44701da177e4SLinus Torvalds { 44711da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 44721da177e4SLinus Torvalds struct hci_conn *conn; 44731da177e4SLinus Torvalds __u16 handle; 44741da177e4SLinus Torvalds 44751da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 44761da177e4SLinus Torvalds 44771da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 44781da177e4SLinus Torvalds 4479f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 44801da177e4SLinus Torvalds 44811da177e4SLinus Torvalds hdev->stat.sco_rx++; 44821da177e4SLinus Torvalds 44831da177e4SLinus Torvalds hci_dev_lock(hdev); 44841da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 44851da177e4SLinus Torvalds hci_dev_unlock(hdev); 44861da177e4SLinus Torvalds 44871da177e4SLinus Torvalds if (conn) { 44881da177e4SLinus Torvalds /* Send to upper protocol */ 4489686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 44901da177e4SLinus Torvalds return; 44911da177e4SLinus Torvalds } else { 44921da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 44931da177e4SLinus Torvalds hdev->name, handle); 44941da177e4SLinus Torvalds } 44951da177e4SLinus Torvalds 44961da177e4SLinus Torvalds kfree_skb(skb); 44971da177e4SLinus Torvalds } 44981da177e4SLinus Torvalds 44999238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 45009238f36aSJohan Hedberg { 45019238f36aSJohan Hedberg struct sk_buff *skb; 45029238f36aSJohan Hedberg 45039238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 45049238f36aSJohan Hedberg if (!skb) 45059238f36aSJohan Hedberg return true; 45069238f36aSJohan Hedberg 45079238f36aSJohan Hedberg return bt_cb(skb)->req.start; 45089238f36aSJohan Hedberg } 45099238f36aSJohan Hedberg 451042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 451142c6b129SJohan Hedberg { 451242c6b129SJohan Hedberg struct hci_command_hdr *sent; 451342c6b129SJohan Hedberg struct sk_buff *skb; 451442c6b129SJohan Hedberg u16 opcode; 451542c6b129SJohan Hedberg 451642c6b129SJohan Hedberg if (!hdev->sent_cmd) 451742c6b129SJohan Hedberg return; 451842c6b129SJohan Hedberg 451942c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 452042c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 452142c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 452242c6b129SJohan Hedberg return; 452342c6b129SJohan Hedberg 452442c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 452542c6b129SJohan Hedberg if (!skb) 452642c6b129SJohan Hedberg return; 452742c6b129SJohan Hedberg 452842c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 452942c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 453042c6b129SJohan Hedberg } 453142c6b129SJohan Hedberg 45329238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 45339238f36aSJohan Hedberg { 45349238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 45359238f36aSJohan Hedberg struct sk_buff *skb; 45369238f36aSJohan Hedberg unsigned long flags; 45379238f36aSJohan Hedberg 45389238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 45399238f36aSJohan Hedberg 454042c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 454142c6b129SJohan Hedberg * sent we need to do special handling of it. 45429238f36aSJohan Hedberg */ 454342c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 454442c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 454542c6b129SJohan Hedberg * reset complete event during init and any pending 454642c6b129SJohan Hedberg * command will never be completed. In such a case we 454742c6b129SJohan Hedberg * need to resend whatever was the last sent 454842c6b129SJohan Hedberg * command. 454942c6b129SJohan Hedberg */ 455042c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 455142c6b129SJohan Hedberg hci_resend_last(hdev); 455242c6b129SJohan Hedberg 45539238f36aSJohan Hedberg return; 455442c6b129SJohan Hedberg } 45559238f36aSJohan Hedberg 45569238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 45579238f36aSJohan Hedberg * this request the request is not yet complete. 45589238f36aSJohan Hedberg */ 45599238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 45609238f36aSJohan Hedberg return; 45619238f36aSJohan Hedberg 45629238f36aSJohan Hedberg /* If this was the last command in a request the complete 45639238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 45649238f36aSJohan Hedberg * command queue (hdev->cmd_q). 45659238f36aSJohan Hedberg */ 45669238f36aSJohan Hedberg if (hdev->sent_cmd) { 45679238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 456853e21fbcSJohan Hedberg 456953e21fbcSJohan Hedberg if (req_complete) { 457053e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 457153e21fbcSJohan Hedberg * avoid calling the callback more than once if 457253e21fbcSJohan Hedberg * this function gets called again. 457353e21fbcSJohan Hedberg */ 457453e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 457553e21fbcSJohan Hedberg 45769238f36aSJohan Hedberg goto call_complete; 45779238f36aSJohan Hedberg } 457853e21fbcSJohan Hedberg } 45799238f36aSJohan Hedberg 45809238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 45819238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 45829238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 45839238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 45849238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 45859238f36aSJohan Hedberg break; 45869238f36aSJohan Hedberg } 45879238f36aSJohan Hedberg 45889238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 45899238f36aSJohan Hedberg kfree_skb(skb); 45909238f36aSJohan Hedberg } 45919238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 45929238f36aSJohan Hedberg 45939238f36aSJohan Hedberg call_complete: 45949238f36aSJohan Hedberg if (req_complete) 45959238f36aSJohan Hedberg req_complete(hdev, status); 45969238f36aSJohan Hedberg } 45979238f36aSJohan Hedberg 4598b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 45991da177e4SLinus Torvalds { 4600b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 46011da177e4SLinus Torvalds struct sk_buff *skb; 46021da177e4SLinus Torvalds 46031da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 46041da177e4SLinus Torvalds 46051da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 4606cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4607cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4608cd82e61cSMarcel Holtmann 46091da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 46101da177e4SLinus Torvalds /* Send copy to the sockets */ 4611470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 46121da177e4SLinus Torvalds } 46131da177e4SLinus Torvalds 46140736cfa8SMarcel Holtmann if (test_bit(HCI_RAW, &hdev->flags) || 46150736cfa8SMarcel Holtmann test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 46161da177e4SLinus Torvalds kfree_skb(skb); 46171da177e4SLinus Torvalds continue; 46181da177e4SLinus Torvalds } 46191da177e4SLinus Torvalds 46201da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 46211da177e4SLinus Torvalds /* Don't process data packets in this states. */ 46220d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 46231da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 46241da177e4SLinus Torvalds case HCI_SCODATA_PKT: 46251da177e4SLinus Torvalds kfree_skb(skb); 46261da177e4SLinus Torvalds continue; 46273ff50b79SStephen Hemminger } 46281da177e4SLinus Torvalds } 46291da177e4SLinus Torvalds 46301da177e4SLinus Torvalds /* Process frame */ 46310d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 46321da177e4SLinus Torvalds case HCI_EVENT_PKT: 4633b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 46341da177e4SLinus Torvalds hci_event_packet(hdev, skb); 46351da177e4SLinus Torvalds break; 46361da177e4SLinus Torvalds 46371da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 46381da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 46391da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 46401da177e4SLinus Torvalds break; 46411da177e4SLinus Torvalds 46421da177e4SLinus Torvalds case HCI_SCODATA_PKT: 46431da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 46441da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 46451da177e4SLinus Torvalds break; 46461da177e4SLinus Torvalds 46471da177e4SLinus Torvalds default: 46481da177e4SLinus Torvalds kfree_skb(skb); 46491da177e4SLinus Torvalds break; 46501da177e4SLinus Torvalds } 46511da177e4SLinus Torvalds } 46521da177e4SLinus Torvalds } 46531da177e4SLinus Torvalds 4654c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 46551da177e4SLinus Torvalds { 4656c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 46571da177e4SLinus Torvalds struct sk_buff *skb; 46581da177e4SLinus Torvalds 46592104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 46602104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 46611da177e4SLinus Torvalds 46621da177e4SLinus Torvalds /* Send queued commands */ 46635a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 46645a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 46655a08ecceSAndrei Emeltchenko if (!skb) 46665a08ecceSAndrei Emeltchenko return; 46675a08ecceSAndrei Emeltchenko 46681da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 46691da177e4SLinus Torvalds 4670a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 467170f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 46721da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 467357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 46747bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 46757bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 46767bdb8a5cSSzymon Janc else 46776bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 46785f246e89SAndrei Emeltchenko jiffies + HCI_CMD_TIMEOUT); 46791da177e4SLinus Torvalds } else { 46801da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4681c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 46821da177e4SLinus Torvalds } 46831da177e4SLinus Torvalds } 46841da177e4SLinus Torvalds } 4685