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> 3247219839SMarcel Holtmann #include <asm/unaligned.h> 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 351da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 361da177e4SLinus Torvalds 37b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 38c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 393eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds /* HCI device list */ 421da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 431da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds /* HCI callback list */ 461da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 471da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 481da177e4SLinus Torvalds 493df92b31SSasha Levin /* HCI ID Numbering */ 503df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 513df92b31SSasha Levin 521da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 531da177e4SLinus Torvalds 546516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 551da177e4SLinus Torvalds { 56040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 571da177e4SLinus Torvalds } 581da177e4SLinus Torvalds 59baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */ 60baf27f6eSMarcel Holtmann 614b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf, 624b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 634b4148e9SMarcel Holtmann { 644b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 654b4148e9SMarcel Holtmann char buf[3]; 664b4148e9SMarcel Holtmann 674b4148e9SMarcel Holtmann buf[0] = test_bit(HCI_DUT_MODE, &hdev->dev_flags) ? 'Y': 'N'; 684b4148e9SMarcel Holtmann buf[1] = '\n'; 694b4148e9SMarcel Holtmann buf[2] = '\0'; 704b4148e9SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 714b4148e9SMarcel Holtmann } 724b4148e9SMarcel Holtmann 734b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf, 744b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 754b4148e9SMarcel Holtmann { 764b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 774b4148e9SMarcel Holtmann struct sk_buff *skb; 784b4148e9SMarcel Holtmann char buf[32]; 794b4148e9SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 804b4148e9SMarcel Holtmann bool enable; 814b4148e9SMarcel Holtmann int err; 824b4148e9SMarcel Holtmann 834b4148e9SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 844b4148e9SMarcel Holtmann return -ENETDOWN; 854b4148e9SMarcel Holtmann 864b4148e9SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 874b4148e9SMarcel Holtmann return -EFAULT; 884b4148e9SMarcel Holtmann 894b4148e9SMarcel Holtmann buf[buf_size] = '\0'; 904b4148e9SMarcel Holtmann if (strtobool(buf, &enable)) 914b4148e9SMarcel Holtmann return -EINVAL; 924b4148e9SMarcel Holtmann 934b4148e9SMarcel Holtmann if (enable == test_bit(HCI_DUT_MODE, &hdev->dev_flags)) 944b4148e9SMarcel Holtmann return -EALREADY; 954b4148e9SMarcel Holtmann 964b4148e9SMarcel Holtmann hci_req_lock(hdev); 974b4148e9SMarcel Holtmann if (enable) 984b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL, 994b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1004b4148e9SMarcel Holtmann else 1014b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, 1024b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1034b4148e9SMarcel Holtmann hci_req_unlock(hdev); 1044b4148e9SMarcel Holtmann 1054b4148e9SMarcel Holtmann if (IS_ERR(skb)) 1064b4148e9SMarcel Holtmann return PTR_ERR(skb); 1074b4148e9SMarcel Holtmann 1084b4148e9SMarcel Holtmann err = -bt_to_errno(skb->data[0]); 1094b4148e9SMarcel Holtmann kfree_skb(skb); 1104b4148e9SMarcel Holtmann 1114b4148e9SMarcel Holtmann if (err < 0) 1124b4148e9SMarcel Holtmann return err; 1134b4148e9SMarcel Holtmann 1144b4148e9SMarcel Holtmann change_bit(HCI_DUT_MODE, &hdev->dev_flags); 1154b4148e9SMarcel Holtmann 1164b4148e9SMarcel Holtmann return count; 1174b4148e9SMarcel Holtmann } 1184b4148e9SMarcel Holtmann 1194b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = { 1204b4148e9SMarcel Holtmann .open = simple_open, 1214b4148e9SMarcel Holtmann .read = dut_mode_read, 1224b4148e9SMarcel Holtmann .write = dut_mode_write, 1234b4148e9SMarcel Holtmann .llseek = default_llseek, 1244b4148e9SMarcel Holtmann }; 1254b4148e9SMarcel Holtmann 126dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr) 127dfb826a8SMarcel Holtmann { 128dfb826a8SMarcel Holtmann struct hci_dev *hdev = f->private; 129dfb826a8SMarcel Holtmann u8 p; 130dfb826a8SMarcel Holtmann 131dfb826a8SMarcel Holtmann hci_dev_lock(hdev); 132dfb826a8SMarcel Holtmann for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 133cfbb2b5bSMarcel Holtmann seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 134dfb826a8SMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p, 135dfb826a8SMarcel Holtmann hdev->features[p][0], hdev->features[p][1], 136dfb826a8SMarcel Holtmann hdev->features[p][2], hdev->features[p][3], 137dfb826a8SMarcel Holtmann hdev->features[p][4], hdev->features[p][5], 138dfb826a8SMarcel Holtmann hdev->features[p][6], hdev->features[p][7]); 139dfb826a8SMarcel Holtmann } 140cfbb2b5bSMarcel Holtmann if (lmp_le_capable(hdev)) 141cfbb2b5bSMarcel Holtmann seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 142cfbb2b5bSMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", 143cfbb2b5bSMarcel Holtmann hdev->le_features[0], hdev->le_features[1], 144cfbb2b5bSMarcel Holtmann hdev->le_features[2], hdev->le_features[3], 145cfbb2b5bSMarcel Holtmann hdev->le_features[4], hdev->le_features[5], 146cfbb2b5bSMarcel Holtmann hdev->le_features[6], hdev->le_features[7]); 147dfb826a8SMarcel Holtmann hci_dev_unlock(hdev); 148dfb826a8SMarcel Holtmann 149dfb826a8SMarcel Holtmann return 0; 150dfb826a8SMarcel Holtmann } 151dfb826a8SMarcel Holtmann 152dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file) 153dfb826a8SMarcel Holtmann { 154dfb826a8SMarcel Holtmann return single_open(file, features_show, inode->i_private); 155dfb826a8SMarcel Holtmann } 156dfb826a8SMarcel Holtmann 157dfb826a8SMarcel Holtmann static const struct file_operations features_fops = { 158dfb826a8SMarcel Holtmann .open = features_open, 159dfb826a8SMarcel Holtmann .read = seq_read, 160dfb826a8SMarcel Holtmann .llseek = seq_lseek, 161dfb826a8SMarcel Holtmann .release = single_release, 162dfb826a8SMarcel Holtmann }; 163dfb826a8SMarcel Holtmann 16470afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p) 16570afe0b8SMarcel Holtmann { 16670afe0b8SMarcel Holtmann struct hci_dev *hdev = f->private; 16770afe0b8SMarcel Holtmann struct bdaddr_list *b; 16870afe0b8SMarcel Holtmann 16970afe0b8SMarcel Holtmann hci_dev_lock(hdev); 17070afe0b8SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) 171b25f0785SMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 17270afe0b8SMarcel Holtmann hci_dev_unlock(hdev); 17370afe0b8SMarcel Holtmann 17470afe0b8SMarcel Holtmann return 0; 17570afe0b8SMarcel Holtmann } 17670afe0b8SMarcel Holtmann 17770afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file) 17870afe0b8SMarcel Holtmann { 17970afe0b8SMarcel Holtmann return single_open(file, blacklist_show, inode->i_private); 18070afe0b8SMarcel Holtmann } 18170afe0b8SMarcel Holtmann 18270afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = { 18370afe0b8SMarcel Holtmann .open = blacklist_open, 18470afe0b8SMarcel Holtmann .read = seq_read, 18570afe0b8SMarcel Holtmann .llseek = seq_lseek, 18670afe0b8SMarcel Holtmann .release = single_release, 18770afe0b8SMarcel Holtmann }; 18870afe0b8SMarcel Holtmann 18947219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p) 19047219839SMarcel Holtmann { 19147219839SMarcel Holtmann struct hci_dev *hdev = f->private; 19247219839SMarcel Holtmann struct bt_uuid *uuid; 19347219839SMarcel Holtmann 19447219839SMarcel Holtmann hci_dev_lock(hdev); 19547219839SMarcel Holtmann list_for_each_entry(uuid, &hdev->uuids, list) { 19658f01aa9SMarcel Holtmann u8 i, val[16]; 19747219839SMarcel Holtmann 19858f01aa9SMarcel Holtmann /* The Bluetooth UUID values are stored in big endian, 19958f01aa9SMarcel Holtmann * but with reversed byte order. So convert them into 20058f01aa9SMarcel Holtmann * the right order for the %pUb modifier. 20158f01aa9SMarcel Holtmann */ 20258f01aa9SMarcel Holtmann for (i = 0; i < 16; i++) 20358f01aa9SMarcel Holtmann val[i] = uuid->uuid[15 - i]; 20447219839SMarcel Holtmann 20558f01aa9SMarcel Holtmann seq_printf(f, "%pUb\n", val); 20647219839SMarcel Holtmann } 20747219839SMarcel Holtmann hci_dev_unlock(hdev); 20847219839SMarcel Holtmann 20947219839SMarcel Holtmann return 0; 21047219839SMarcel Holtmann } 21147219839SMarcel Holtmann 21247219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file) 21347219839SMarcel Holtmann { 21447219839SMarcel Holtmann return single_open(file, uuids_show, inode->i_private); 21547219839SMarcel Holtmann } 21647219839SMarcel Holtmann 21747219839SMarcel Holtmann static const struct file_operations uuids_fops = { 21847219839SMarcel Holtmann .open = uuids_open, 21947219839SMarcel Holtmann .read = seq_read, 22047219839SMarcel Holtmann .llseek = seq_lseek, 22147219839SMarcel Holtmann .release = single_release, 22247219839SMarcel Holtmann }; 22347219839SMarcel Holtmann 224baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p) 225baf27f6eSMarcel Holtmann { 226baf27f6eSMarcel Holtmann struct hci_dev *hdev = f->private; 227baf27f6eSMarcel Holtmann struct discovery_state *cache = &hdev->discovery; 228baf27f6eSMarcel Holtmann struct inquiry_entry *e; 229baf27f6eSMarcel Holtmann 230baf27f6eSMarcel Holtmann hci_dev_lock(hdev); 231baf27f6eSMarcel Holtmann 232baf27f6eSMarcel Holtmann list_for_each_entry(e, &cache->all, all) { 233baf27f6eSMarcel Holtmann struct inquiry_data *data = &e->data; 234baf27f6eSMarcel Holtmann seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", 235baf27f6eSMarcel Holtmann &data->bdaddr, 236baf27f6eSMarcel Holtmann data->pscan_rep_mode, data->pscan_period_mode, 237baf27f6eSMarcel Holtmann data->pscan_mode, data->dev_class[2], 238baf27f6eSMarcel Holtmann data->dev_class[1], data->dev_class[0], 239baf27f6eSMarcel Holtmann __le16_to_cpu(data->clock_offset), 240baf27f6eSMarcel Holtmann data->rssi, data->ssp_mode, e->timestamp); 241baf27f6eSMarcel Holtmann } 242baf27f6eSMarcel Holtmann 243baf27f6eSMarcel Holtmann hci_dev_unlock(hdev); 244baf27f6eSMarcel Holtmann 245baf27f6eSMarcel Holtmann return 0; 246baf27f6eSMarcel Holtmann } 247baf27f6eSMarcel Holtmann 248baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file) 249baf27f6eSMarcel Holtmann { 250baf27f6eSMarcel Holtmann return single_open(file, inquiry_cache_show, inode->i_private); 251baf27f6eSMarcel Holtmann } 252baf27f6eSMarcel Holtmann 253baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = { 254baf27f6eSMarcel Holtmann .open = inquiry_cache_open, 255baf27f6eSMarcel Holtmann .read = seq_read, 256baf27f6eSMarcel Holtmann .llseek = seq_lseek, 257baf27f6eSMarcel Holtmann .release = single_release, 258baf27f6eSMarcel Holtmann }; 259baf27f6eSMarcel Holtmann 26002d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr) 26102d08d15SMarcel Holtmann { 26202d08d15SMarcel Holtmann struct hci_dev *hdev = f->private; 26302d08d15SMarcel Holtmann struct list_head *p, *n; 26402d08d15SMarcel Holtmann 26502d08d15SMarcel Holtmann hci_dev_lock(hdev); 26602d08d15SMarcel Holtmann list_for_each_safe(p, n, &hdev->link_keys) { 26702d08d15SMarcel Holtmann struct link_key *key = list_entry(p, struct link_key, list); 26802d08d15SMarcel Holtmann seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type, 26902d08d15SMarcel Holtmann HCI_LINK_KEY_SIZE, key->val, key->pin_len); 27002d08d15SMarcel Holtmann } 27102d08d15SMarcel Holtmann hci_dev_unlock(hdev); 27202d08d15SMarcel Holtmann 27302d08d15SMarcel Holtmann return 0; 27402d08d15SMarcel Holtmann } 27502d08d15SMarcel Holtmann 27602d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file) 27702d08d15SMarcel Holtmann { 27802d08d15SMarcel Holtmann return single_open(file, link_keys_show, inode->i_private); 27902d08d15SMarcel Holtmann } 28002d08d15SMarcel Holtmann 28102d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = { 28202d08d15SMarcel Holtmann .open = link_keys_open, 28302d08d15SMarcel Holtmann .read = seq_read, 28402d08d15SMarcel Holtmann .llseek = seq_lseek, 28502d08d15SMarcel Holtmann .release = single_release, 28602d08d15SMarcel Holtmann }; 28702d08d15SMarcel Holtmann 288babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr) 289babdbb3cSMarcel Holtmann { 290babdbb3cSMarcel Holtmann struct hci_dev *hdev = f->private; 291babdbb3cSMarcel Holtmann 292babdbb3cSMarcel Holtmann hci_dev_lock(hdev); 293babdbb3cSMarcel Holtmann seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], 294babdbb3cSMarcel Holtmann hdev->dev_class[1], hdev->dev_class[0]); 295babdbb3cSMarcel Holtmann hci_dev_unlock(hdev); 296babdbb3cSMarcel Holtmann 297babdbb3cSMarcel Holtmann return 0; 298babdbb3cSMarcel Holtmann } 299babdbb3cSMarcel Holtmann 300babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file) 301babdbb3cSMarcel Holtmann { 302babdbb3cSMarcel Holtmann return single_open(file, dev_class_show, inode->i_private); 303babdbb3cSMarcel Holtmann } 304babdbb3cSMarcel Holtmann 305babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = { 306babdbb3cSMarcel Holtmann .open = dev_class_open, 307babdbb3cSMarcel Holtmann .read = seq_read, 308babdbb3cSMarcel Holtmann .llseek = seq_lseek, 309babdbb3cSMarcel Holtmann .release = single_release, 310babdbb3cSMarcel Holtmann }; 311babdbb3cSMarcel Holtmann 312041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val) 313041000b9SMarcel Holtmann { 314041000b9SMarcel Holtmann struct hci_dev *hdev = data; 315041000b9SMarcel Holtmann 316041000b9SMarcel Holtmann hci_dev_lock(hdev); 317041000b9SMarcel Holtmann *val = hdev->voice_setting; 318041000b9SMarcel Holtmann hci_dev_unlock(hdev); 319041000b9SMarcel Holtmann 320041000b9SMarcel Holtmann return 0; 321041000b9SMarcel Holtmann } 322041000b9SMarcel Holtmann 323041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get, 324041000b9SMarcel Holtmann NULL, "0x%4.4llx\n"); 325041000b9SMarcel Holtmann 326ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val) 327ebd1e33bSMarcel Holtmann { 328ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 329ebd1e33bSMarcel Holtmann 330ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 331ebd1e33bSMarcel Holtmann hdev->auto_accept_delay = val; 332ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 333ebd1e33bSMarcel Holtmann 334ebd1e33bSMarcel Holtmann return 0; 335ebd1e33bSMarcel Holtmann } 336ebd1e33bSMarcel Holtmann 337ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val) 338ebd1e33bSMarcel Holtmann { 339ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 340ebd1e33bSMarcel Holtmann 341ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 342ebd1e33bSMarcel Holtmann *val = hdev->auto_accept_delay; 343ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 344ebd1e33bSMarcel Holtmann 345ebd1e33bSMarcel Holtmann return 0; 346ebd1e33bSMarcel Holtmann } 347ebd1e33bSMarcel Holtmann 348ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, 349ebd1e33bSMarcel Holtmann auto_accept_delay_set, "%llu\n"); 350ebd1e33bSMarcel Holtmann 35106f5b778SMarcel Holtmann static int ssp_debug_mode_set(void *data, u64 val) 35206f5b778SMarcel Holtmann { 35306f5b778SMarcel Holtmann struct hci_dev *hdev = data; 35406f5b778SMarcel Holtmann struct sk_buff *skb; 35506f5b778SMarcel Holtmann __u8 mode; 35606f5b778SMarcel Holtmann int err; 35706f5b778SMarcel Holtmann 35806f5b778SMarcel Holtmann if (val != 0 && val != 1) 35906f5b778SMarcel Holtmann return -EINVAL; 36006f5b778SMarcel Holtmann 36106f5b778SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 36206f5b778SMarcel Holtmann return -ENETDOWN; 36306f5b778SMarcel Holtmann 36406f5b778SMarcel Holtmann hci_req_lock(hdev); 36506f5b778SMarcel Holtmann mode = val; 36606f5b778SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode), 36706f5b778SMarcel Holtmann &mode, HCI_CMD_TIMEOUT); 36806f5b778SMarcel Holtmann hci_req_unlock(hdev); 36906f5b778SMarcel Holtmann 37006f5b778SMarcel Holtmann if (IS_ERR(skb)) 37106f5b778SMarcel Holtmann return PTR_ERR(skb); 37206f5b778SMarcel Holtmann 37306f5b778SMarcel Holtmann err = -bt_to_errno(skb->data[0]); 37406f5b778SMarcel Holtmann kfree_skb(skb); 37506f5b778SMarcel Holtmann 37606f5b778SMarcel Holtmann if (err < 0) 37706f5b778SMarcel Holtmann return err; 37806f5b778SMarcel Holtmann 37906f5b778SMarcel Holtmann hci_dev_lock(hdev); 38006f5b778SMarcel Holtmann hdev->ssp_debug_mode = val; 38106f5b778SMarcel Holtmann hci_dev_unlock(hdev); 38206f5b778SMarcel Holtmann 38306f5b778SMarcel Holtmann return 0; 38406f5b778SMarcel Holtmann } 38506f5b778SMarcel Holtmann 38606f5b778SMarcel Holtmann static int ssp_debug_mode_get(void *data, u64 *val) 38706f5b778SMarcel Holtmann { 38806f5b778SMarcel Holtmann struct hci_dev *hdev = data; 38906f5b778SMarcel Holtmann 39006f5b778SMarcel Holtmann hci_dev_lock(hdev); 39106f5b778SMarcel Holtmann *val = hdev->ssp_debug_mode; 39206f5b778SMarcel Holtmann hci_dev_unlock(hdev); 39306f5b778SMarcel Holtmann 39406f5b778SMarcel Holtmann return 0; 39506f5b778SMarcel Holtmann } 39606f5b778SMarcel Holtmann 39706f5b778SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get, 39806f5b778SMarcel Holtmann ssp_debug_mode_set, "%llu\n"); 39906f5b778SMarcel Holtmann 4005afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf, 4015afeac14SMarcel Holtmann size_t count, loff_t *ppos) 4025afeac14SMarcel Holtmann { 4035afeac14SMarcel Holtmann struct hci_dev *hdev = file->private_data; 4045afeac14SMarcel Holtmann char buf[3]; 4055afeac14SMarcel Holtmann 4065afeac14SMarcel Holtmann buf[0] = test_bit(HCI_FORCE_SC, &hdev->dev_flags) ? 'Y': 'N'; 4075afeac14SMarcel Holtmann buf[1] = '\n'; 4085afeac14SMarcel Holtmann buf[2] = '\0'; 4095afeac14SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 4105afeac14SMarcel Holtmann } 4115afeac14SMarcel Holtmann 4125afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file, 4135afeac14SMarcel Holtmann const char __user *user_buf, 4145afeac14SMarcel Holtmann size_t count, loff_t *ppos) 4155afeac14SMarcel Holtmann { 4165afeac14SMarcel Holtmann struct hci_dev *hdev = file->private_data; 4175afeac14SMarcel Holtmann char buf[32]; 4185afeac14SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 4195afeac14SMarcel Holtmann bool enable; 4205afeac14SMarcel Holtmann 4215afeac14SMarcel Holtmann if (test_bit(HCI_UP, &hdev->flags)) 4225afeac14SMarcel Holtmann return -EBUSY; 4235afeac14SMarcel Holtmann 4245afeac14SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 4255afeac14SMarcel Holtmann return -EFAULT; 4265afeac14SMarcel Holtmann 4275afeac14SMarcel Holtmann buf[buf_size] = '\0'; 4285afeac14SMarcel Holtmann if (strtobool(buf, &enable)) 4295afeac14SMarcel Holtmann return -EINVAL; 4305afeac14SMarcel Holtmann 4315afeac14SMarcel Holtmann if (enable == test_bit(HCI_FORCE_SC, &hdev->dev_flags)) 4325afeac14SMarcel Holtmann return -EALREADY; 4335afeac14SMarcel Holtmann 4345afeac14SMarcel Holtmann change_bit(HCI_FORCE_SC, &hdev->dev_flags); 4355afeac14SMarcel Holtmann 4365afeac14SMarcel Holtmann return count; 4375afeac14SMarcel Holtmann } 4385afeac14SMarcel Holtmann 4395afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = { 4405afeac14SMarcel Holtmann .open = simple_open, 4415afeac14SMarcel Holtmann .read = force_sc_support_read, 4425afeac14SMarcel Holtmann .write = force_sc_support_write, 4435afeac14SMarcel Holtmann .llseek = default_llseek, 4445afeac14SMarcel Holtmann }; 4455afeac14SMarcel Holtmann 446134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf, 447134c2a89SMarcel Holtmann size_t count, loff_t *ppos) 448134c2a89SMarcel Holtmann { 449134c2a89SMarcel Holtmann struct hci_dev *hdev = file->private_data; 450134c2a89SMarcel Holtmann char buf[3]; 451134c2a89SMarcel Holtmann 452134c2a89SMarcel Holtmann buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N'; 453134c2a89SMarcel Holtmann buf[1] = '\n'; 454134c2a89SMarcel Holtmann buf[2] = '\0'; 455134c2a89SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 456134c2a89SMarcel Holtmann } 457134c2a89SMarcel Holtmann 458134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = { 459134c2a89SMarcel Holtmann .open = simple_open, 460134c2a89SMarcel Holtmann .read = sc_only_mode_read, 461134c2a89SMarcel Holtmann .llseek = default_llseek, 462134c2a89SMarcel Holtmann }; 463134c2a89SMarcel Holtmann 4642bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val) 4652bfa3531SMarcel Holtmann { 4662bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4672bfa3531SMarcel Holtmann 4682bfa3531SMarcel Holtmann if (val != 0 && (val < 500 || val > 3600000)) 4692bfa3531SMarcel Holtmann return -EINVAL; 4702bfa3531SMarcel Holtmann 4712bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4722bfa3531SMarcel Holtmann hdev->idle_timeout = val; 4732bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4742bfa3531SMarcel Holtmann 4752bfa3531SMarcel Holtmann return 0; 4762bfa3531SMarcel Holtmann } 4772bfa3531SMarcel Holtmann 4782bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val) 4792bfa3531SMarcel Holtmann { 4802bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4812bfa3531SMarcel Holtmann 4822bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4832bfa3531SMarcel Holtmann *val = hdev->idle_timeout; 4842bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4852bfa3531SMarcel Holtmann 4862bfa3531SMarcel Holtmann return 0; 4872bfa3531SMarcel Holtmann } 4882bfa3531SMarcel Holtmann 4892bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get, 4902bfa3531SMarcel Holtmann idle_timeout_set, "%llu\n"); 4912bfa3531SMarcel Holtmann 4922bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val) 4932bfa3531SMarcel Holtmann { 4942bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4952bfa3531SMarcel Holtmann 4962bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val > hdev->sniff_max_interval) 4972bfa3531SMarcel Holtmann return -EINVAL; 4982bfa3531SMarcel Holtmann 4992bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5002bfa3531SMarcel Holtmann hdev->sniff_min_interval = val; 5012bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5022bfa3531SMarcel Holtmann 5032bfa3531SMarcel Holtmann return 0; 5042bfa3531SMarcel Holtmann } 5052bfa3531SMarcel Holtmann 5062bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val) 5072bfa3531SMarcel Holtmann { 5082bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5092bfa3531SMarcel Holtmann 5102bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5112bfa3531SMarcel Holtmann *val = hdev->sniff_min_interval; 5122bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5132bfa3531SMarcel Holtmann 5142bfa3531SMarcel Holtmann return 0; 5152bfa3531SMarcel Holtmann } 5162bfa3531SMarcel Holtmann 5172bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get, 5182bfa3531SMarcel Holtmann sniff_min_interval_set, "%llu\n"); 5192bfa3531SMarcel Holtmann 5202bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val) 5212bfa3531SMarcel Holtmann { 5222bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5232bfa3531SMarcel Holtmann 5242bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val < hdev->sniff_min_interval) 5252bfa3531SMarcel Holtmann return -EINVAL; 5262bfa3531SMarcel Holtmann 5272bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5282bfa3531SMarcel Holtmann hdev->sniff_max_interval = val; 5292bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5302bfa3531SMarcel Holtmann 5312bfa3531SMarcel Holtmann return 0; 5322bfa3531SMarcel Holtmann } 5332bfa3531SMarcel Holtmann 5342bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val) 5352bfa3531SMarcel Holtmann { 5362bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5372bfa3531SMarcel Holtmann 5382bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5392bfa3531SMarcel Holtmann *val = hdev->sniff_max_interval; 5402bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5412bfa3531SMarcel Holtmann 5422bfa3531SMarcel Holtmann return 0; 5432bfa3531SMarcel Holtmann } 5442bfa3531SMarcel Holtmann 5452bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, 5462bfa3531SMarcel Holtmann sniff_max_interval_set, "%llu\n"); 5472bfa3531SMarcel Holtmann 548e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p) 549e7b8fc92SMarcel Holtmann { 550e7b8fc92SMarcel Holtmann struct hci_dev *hdev = f->private; 551e7b8fc92SMarcel Holtmann 552e7b8fc92SMarcel Holtmann hci_dev_lock(hdev); 553e7b8fc92SMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->static_addr); 554e7b8fc92SMarcel Holtmann hci_dev_unlock(hdev); 555e7b8fc92SMarcel Holtmann 556e7b8fc92SMarcel Holtmann return 0; 557e7b8fc92SMarcel Holtmann } 558e7b8fc92SMarcel Holtmann 559e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file) 560e7b8fc92SMarcel Holtmann { 561e7b8fc92SMarcel Holtmann return single_open(file, static_address_show, inode->i_private); 562e7b8fc92SMarcel Holtmann } 563e7b8fc92SMarcel Holtmann 564e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = { 565e7b8fc92SMarcel Holtmann .open = static_address_open, 566e7b8fc92SMarcel Holtmann .read = seq_read, 567e7b8fc92SMarcel Holtmann .llseek = seq_lseek, 568e7b8fc92SMarcel Holtmann .release = single_release, 569e7b8fc92SMarcel Holtmann }; 570e7b8fc92SMarcel Holtmann 57192202185SMarcel Holtmann static int own_address_type_set(void *data, u64 val) 57292202185SMarcel Holtmann { 57392202185SMarcel Holtmann struct hci_dev *hdev = data; 57492202185SMarcel Holtmann 57592202185SMarcel Holtmann if (val != 0 && val != 1) 57692202185SMarcel Holtmann return -EINVAL; 57792202185SMarcel Holtmann 57892202185SMarcel Holtmann hci_dev_lock(hdev); 57992202185SMarcel Holtmann hdev->own_addr_type = val; 58092202185SMarcel Holtmann hci_dev_unlock(hdev); 58192202185SMarcel Holtmann 58292202185SMarcel Holtmann return 0; 58392202185SMarcel Holtmann } 58492202185SMarcel Holtmann 58592202185SMarcel Holtmann static int own_address_type_get(void *data, u64 *val) 58692202185SMarcel Holtmann { 58792202185SMarcel Holtmann struct hci_dev *hdev = data; 58892202185SMarcel Holtmann 58992202185SMarcel Holtmann hci_dev_lock(hdev); 59092202185SMarcel Holtmann *val = hdev->own_addr_type; 59192202185SMarcel Holtmann hci_dev_unlock(hdev); 59292202185SMarcel Holtmann 59392202185SMarcel Holtmann return 0; 59492202185SMarcel Holtmann } 59592202185SMarcel Holtmann 59692202185SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get, 59792202185SMarcel Holtmann own_address_type_set, "%llu\n"); 59892202185SMarcel Holtmann 5998f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr) 6008f8625cdSMarcel Holtmann { 6018f8625cdSMarcel Holtmann struct hci_dev *hdev = f->private; 6028f8625cdSMarcel Holtmann struct list_head *p, *n; 6038f8625cdSMarcel Holtmann 6048f8625cdSMarcel Holtmann hci_dev_lock(hdev); 605f813f1beSJohan Hedberg list_for_each_safe(p, n, &hdev->long_term_keys) { 6068f8625cdSMarcel Holtmann struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list); 607f813f1beSJohan Hedberg seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %*phN %*phN\n", 6088f8625cdSMarcel Holtmann <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, 6098f8625cdSMarcel Holtmann ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), 6108f8625cdSMarcel Holtmann 8, ltk->rand, 16, ltk->val); 6118f8625cdSMarcel Holtmann } 6128f8625cdSMarcel Holtmann hci_dev_unlock(hdev); 6138f8625cdSMarcel Holtmann 6148f8625cdSMarcel Holtmann return 0; 6158f8625cdSMarcel Holtmann } 6168f8625cdSMarcel Holtmann 6178f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file) 6188f8625cdSMarcel Holtmann { 6198f8625cdSMarcel Holtmann return single_open(file, long_term_keys_show, inode->i_private); 6208f8625cdSMarcel Holtmann } 6218f8625cdSMarcel Holtmann 6228f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = { 6238f8625cdSMarcel Holtmann .open = long_term_keys_open, 6248f8625cdSMarcel Holtmann .read = seq_read, 6258f8625cdSMarcel Holtmann .llseek = seq_lseek, 6268f8625cdSMarcel Holtmann .release = single_release, 6278f8625cdSMarcel Holtmann }; 6288f8625cdSMarcel Holtmann 6294e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val) 6304e70c7e7SMarcel Holtmann { 6314e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6324e70c7e7SMarcel Holtmann 6334e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval) 6344e70c7e7SMarcel Holtmann return -EINVAL; 6354e70c7e7SMarcel Holtmann 6364e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6374e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = val; 6384e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 6394e70c7e7SMarcel Holtmann 6404e70c7e7SMarcel Holtmann return 0; 6414e70c7e7SMarcel Holtmann } 6424e70c7e7SMarcel Holtmann 6434e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val) 6444e70c7e7SMarcel Holtmann { 6454e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6464e70c7e7SMarcel Holtmann 6474e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6484e70c7e7SMarcel Holtmann *val = hdev->le_conn_min_interval; 6494e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 6504e70c7e7SMarcel Holtmann 6514e70c7e7SMarcel Holtmann return 0; 6524e70c7e7SMarcel Holtmann } 6534e70c7e7SMarcel Holtmann 6544e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get, 6554e70c7e7SMarcel Holtmann conn_min_interval_set, "%llu\n"); 6564e70c7e7SMarcel Holtmann 6574e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val) 6584e70c7e7SMarcel Holtmann { 6594e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6604e70c7e7SMarcel Holtmann 6614e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval) 6624e70c7e7SMarcel Holtmann return -EINVAL; 6634e70c7e7SMarcel Holtmann 6644e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6654e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = val; 6664e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 6674e70c7e7SMarcel Holtmann 6684e70c7e7SMarcel Holtmann return 0; 6694e70c7e7SMarcel Holtmann } 6704e70c7e7SMarcel Holtmann 6714e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val) 6724e70c7e7SMarcel Holtmann { 6734e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6744e70c7e7SMarcel Holtmann 6754e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6764e70c7e7SMarcel Holtmann *val = hdev->le_conn_max_interval; 6774e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 6784e70c7e7SMarcel Holtmann 6794e70c7e7SMarcel Holtmann return 0; 6804e70c7e7SMarcel Holtmann } 6814e70c7e7SMarcel Holtmann 6824e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, 6834e70c7e7SMarcel Holtmann conn_max_interval_set, "%llu\n"); 6844e70c7e7SMarcel Holtmann 68589863109SJukka Rissanen static ssize_t lowpan_read(struct file *file, char __user *user_buf, 68689863109SJukka Rissanen size_t count, loff_t *ppos) 68789863109SJukka Rissanen { 68889863109SJukka Rissanen struct hci_dev *hdev = file->private_data; 68989863109SJukka Rissanen char buf[3]; 69089863109SJukka Rissanen 69189863109SJukka Rissanen buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N'; 69289863109SJukka Rissanen buf[1] = '\n'; 69389863109SJukka Rissanen buf[2] = '\0'; 69489863109SJukka Rissanen return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 69589863109SJukka Rissanen } 69689863109SJukka Rissanen 69789863109SJukka Rissanen static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer, 69889863109SJukka Rissanen size_t count, loff_t *position) 69989863109SJukka Rissanen { 70089863109SJukka Rissanen struct hci_dev *hdev = fp->private_data; 70189863109SJukka Rissanen bool enable; 70289863109SJukka Rissanen char buf[32]; 70389863109SJukka Rissanen size_t buf_size = min(count, (sizeof(buf)-1)); 70489863109SJukka Rissanen 70589863109SJukka Rissanen if (copy_from_user(buf, user_buffer, buf_size)) 70689863109SJukka Rissanen return -EFAULT; 70789863109SJukka Rissanen 70889863109SJukka Rissanen buf[buf_size] = '\0'; 70989863109SJukka Rissanen 71089863109SJukka Rissanen if (strtobool(buf, &enable) < 0) 71189863109SJukka Rissanen return -EINVAL; 71289863109SJukka Rissanen 71389863109SJukka Rissanen if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags)) 71489863109SJukka Rissanen return -EALREADY; 71589863109SJukka Rissanen 71689863109SJukka Rissanen change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags); 71789863109SJukka Rissanen 71889863109SJukka Rissanen return count; 71989863109SJukka Rissanen } 72089863109SJukka Rissanen 72189863109SJukka Rissanen static const struct file_operations lowpan_debugfs_fops = { 72289863109SJukka Rissanen .open = simple_open, 72389863109SJukka Rissanen .read = lowpan_read, 72489863109SJukka Rissanen .write = lowpan_write, 72589863109SJukka Rissanen .llseek = default_llseek, 72689863109SJukka Rissanen }; 72789863109SJukka Rissanen 7281da177e4SLinus Torvalds /* ---- HCI requests ---- */ 7291da177e4SLinus Torvalds 73042c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 7311da177e4SLinus Torvalds { 73242c6b129SJohan Hedberg BT_DBG("%s result 0x%2.2x", hdev->name, result); 73375fb0e32SJohan Hedberg 7341da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 7351da177e4SLinus Torvalds hdev->req_result = result; 7361da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 7371da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 7381da177e4SLinus Torvalds } 7391da177e4SLinus Torvalds } 7401da177e4SLinus Torvalds 7411da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 7421da177e4SLinus Torvalds { 7431da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 7441da177e4SLinus Torvalds 7451da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 7461da177e4SLinus Torvalds hdev->req_result = err; 7471da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 7481da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 7491da177e4SLinus Torvalds } 7501da177e4SLinus Torvalds } 7511da177e4SLinus Torvalds 75277a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 75377a63e0aSFengguang Wu u8 event) 75475e84b7cSJohan Hedberg { 75575e84b7cSJohan Hedberg struct hci_ev_cmd_complete *ev; 75675e84b7cSJohan Hedberg struct hci_event_hdr *hdr; 75775e84b7cSJohan Hedberg struct sk_buff *skb; 75875e84b7cSJohan Hedberg 75975e84b7cSJohan Hedberg hci_dev_lock(hdev); 76075e84b7cSJohan Hedberg 76175e84b7cSJohan Hedberg skb = hdev->recv_evt; 76275e84b7cSJohan Hedberg hdev->recv_evt = NULL; 76375e84b7cSJohan Hedberg 76475e84b7cSJohan Hedberg hci_dev_unlock(hdev); 76575e84b7cSJohan Hedberg 76675e84b7cSJohan Hedberg if (!skb) 76775e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 76875e84b7cSJohan Hedberg 76975e84b7cSJohan Hedberg if (skb->len < sizeof(*hdr)) { 77075e84b7cSJohan Hedberg BT_ERR("Too short HCI event"); 77175e84b7cSJohan Hedberg goto failed; 77275e84b7cSJohan Hedberg } 77375e84b7cSJohan Hedberg 77475e84b7cSJohan Hedberg hdr = (void *) skb->data; 77575e84b7cSJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 77675e84b7cSJohan Hedberg 7777b1abbbeSJohan Hedberg if (event) { 7787b1abbbeSJohan Hedberg if (hdr->evt != event) 7797b1abbbeSJohan Hedberg goto failed; 7807b1abbbeSJohan Hedberg return skb; 7817b1abbbeSJohan Hedberg } 7827b1abbbeSJohan Hedberg 78375e84b7cSJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 78475e84b7cSJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 78575e84b7cSJohan Hedberg goto failed; 78675e84b7cSJohan Hedberg } 78775e84b7cSJohan Hedberg 78875e84b7cSJohan Hedberg if (skb->len < sizeof(*ev)) { 78975e84b7cSJohan Hedberg BT_ERR("Too short cmd_complete event"); 79075e84b7cSJohan Hedberg goto failed; 79175e84b7cSJohan Hedberg } 79275e84b7cSJohan Hedberg 79375e84b7cSJohan Hedberg ev = (void *) skb->data; 79475e84b7cSJohan Hedberg skb_pull(skb, sizeof(*ev)); 79575e84b7cSJohan Hedberg 79675e84b7cSJohan Hedberg if (opcode == __le16_to_cpu(ev->opcode)) 79775e84b7cSJohan Hedberg return skb; 79875e84b7cSJohan Hedberg 79975e84b7cSJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 80075e84b7cSJohan Hedberg __le16_to_cpu(ev->opcode)); 80175e84b7cSJohan Hedberg 80275e84b7cSJohan Hedberg failed: 80375e84b7cSJohan Hedberg kfree_skb(skb); 80475e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 80575e84b7cSJohan Hedberg } 80675e84b7cSJohan Hedberg 8077b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 80807dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout) 80975e84b7cSJohan Hedberg { 81075e84b7cSJohan Hedberg DECLARE_WAITQUEUE(wait, current); 81175e84b7cSJohan Hedberg struct hci_request req; 81275e84b7cSJohan Hedberg int err = 0; 81375e84b7cSJohan Hedberg 81475e84b7cSJohan Hedberg BT_DBG("%s", hdev->name); 81575e84b7cSJohan Hedberg 81675e84b7cSJohan Hedberg hci_req_init(&req, hdev); 81775e84b7cSJohan Hedberg 8187b1abbbeSJohan Hedberg hci_req_add_ev(&req, opcode, plen, param, event); 81975e84b7cSJohan Hedberg 82075e84b7cSJohan Hedberg hdev->req_status = HCI_REQ_PEND; 82175e84b7cSJohan Hedberg 82275e84b7cSJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 82375e84b7cSJohan Hedberg if (err < 0) 82475e84b7cSJohan Hedberg return ERR_PTR(err); 82575e84b7cSJohan Hedberg 82675e84b7cSJohan Hedberg add_wait_queue(&hdev->req_wait_q, &wait); 82775e84b7cSJohan Hedberg set_current_state(TASK_INTERRUPTIBLE); 82875e84b7cSJohan Hedberg 82975e84b7cSJohan Hedberg schedule_timeout(timeout); 83075e84b7cSJohan Hedberg 83175e84b7cSJohan Hedberg remove_wait_queue(&hdev->req_wait_q, &wait); 83275e84b7cSJohan Hedberg 83375e84b7cSJohan Hedberg if (signal_pending(current)) 83475e84b7cSJohan Hedberg return ERR_PTR(-EINTR); 83575e84b7cSJohan Hedberg 83675e84b7cSJohan Hedberg switch (hdev->req_status) { 83775e84b7cSJohan Hedberg case HCI_REQ_DONE: 83875e84b7cSJohan Hedberg err = -bt_to_errno(hdev->req_result); 83975e84b7cSJohan Hedberg break; 84075e84b7cSJohan Hedberg 84175e84b7cSJohan Hedberg case HCI_REQ_CANCELED: 84275e84b7cSJohan Hedberg err = -hdev->req_result; 84375e84b7cSJohan Hedberg break; 84475e84b7cSJohan Hedberg 84575e84b7cSJohan Hedberg default: 84675e84b7cSJohan Hedberg err = -ETIMEDOUT; 84775e84b7cSJohan Hedberg break; 84875e84b7cSJohan Hedberg } 84975e84b7cSJohan Hedberg 85075e84b7cSJohan Hedberg hdev->req_status = hdev->req_result = 0; 85175e84b7cSJohan Hedberg 85275e84b7cSJohan Hedberg BT_DBG("%s end: err %d", hdev->name, err); 85375e84b7cSJohan Hedberg 85475e84b7cSJohan Hedberg if (err < 0) 85575e84b7cSJohan Hedberg return ERR_PTR(err); 85675e84b7cSJohan Hedberg 8577b1abbbeSJohan Hedberg return hci_get_cmd_complete(hdev, opcode, event); 8587b1abbbeSJohan Hedberg } 8597b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev); 8607b1abbbeSJohan Hedberg 8617b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 86207dc93ddSJohan Hedberg const void *param, u32 timeout) 8637b1abbbeSJohan Hedberg { 8647b1abbbeSJohan Hedberg return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); 86575e84b7cSJohan Hedberg } 86675e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync); 86775e84b7cSJohan Hedberg 8681da177e4SLinus Torvalds /* Execute request and wait for completion. */ 86901178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev, 87042c6b129SJohan Hedberg void (*func)(struct hci_request *req, 87142c6b129SJohan Hedberg unsigned long opt), 8721da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 8731da177e4SLinus Torvalds { 87442c6b129SJohan Hedberg struct hci_request req; 8751da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 8761da177e4SLinus Torvalds int err = 0; 8771da177e4SLinus Torvalds 8781da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 8791da177e4SLinus Torvalds 88042c6b129SJohan Hedberg hci_req_init(&req, hdev); 88142c6b129SJohan Hedberg 8821da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 8831da177e4SLinus Torvalds 88442c6b129SJohan Hedberg func(&req, opt); 88553cce22dSJohan Hedberg 88642c6b129SJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 88742c6b129SJohan Hedberg if (err < 0) { 88853cce22dSJohan Hedberg hdev->req_status = 0; 889920c8300SAndre Guedes 890920c8300SAndre Guedes /* ENODATA means the HCI request command queue is empty. 891920c8300SAndre Guedes * This can happen when a request with conditionals doesn't 892920c8300SAndre Guedes * trigger any commands to be sent. This is normal behavior 893920c8300SAndre Guedes * and should not trigger an error return. 89442c6b129SJohan Hedberg */ 895920c8300SAndre Guedes if (err == -ENODATA) 89642c6b129SJohan Hedberg return 0; 897920c8300SAndre Guedes 898920c8300SAndre Guedes return err; 89953cce22dSJohan Hedberg } 90053cce22dSJohan Hedberg 901bc4445c7SAndre Guedes add_wait_queue(&hdev->req_wait_q, &wait); 902bc4445c7SAndre Guedes set_current_state(TASK_INTERRUPTIBLE); 903bc4445c7SAndre Guedes 9041da177e4SLinus Torvalds schedule_timeout(timeout); 9051da177e4SLinus Torvalds 9061da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 9071da177e4SLinus Torvalds 9081da177e4SLinus Torvalds if (signal_pending(current)) 9091da177e4SLinus Torvalds return -EINTR; 9101da177e4SLinus Torvalds 9111da177e4SLinus Torvalds switch (hdev->req_status) { 9121da177e4SLinus Torvalds case HCI_REQ_DONE: 913e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 9141da177e4SLinus Torvalds break; 9151da177e4SLinus Torvalds 9161da177e4SLinus Torvalds case HCI_REQ_CANCELED: 9171da177e4SLinus Torvalds err = -hdev->req_result; 9181da177e4SLinus Torvalds break; 9191da177e4SLinus Torvalds 9201da177e4SLinus Torvalds default: 9211da177e4SLinus Torvalds err = -ETIMEDOUT; 9221da177e4SLinus Torvalds break; 9233ff50b79SStephen Hemminger } 9241da177e4SLinus Torvalds 925a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 9261da177e4SLinus Torvalds 9271da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 9281da177e4SLinus Torvalds 9291da177e4SLinus Torvalds return err; 9301da177e4SLinus Torvalds } 9311da177e4SLinus Torvalds 93201178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev, 93342c6b129SJohan Hedberg void (*req)(struct hci_request *req, 93442c6b129SJohan Hedberg unsigned long opt), 9351da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 9361da177e4SLinus Torvalds { 9371da177e4SLinus Torvalds int ret; 9381da177e4SLinus Torvalds 9397c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 9407c6a329eSMarcel Holtmann return -ENETDOWN; 9417c6a329eSMarcel Holtmann 9421da177e4SLinus Torvalds /* Serialize all requests */ 9431da177e4SLinus Torvalds hci_req_lock(hdev); 94401178cd4SJohan Hedberg ret = __hci_req_sync(hdev, req, opt, timeout); 9451da177e4SLinus Torvalds hci_req_unlock(hdev); 9461da177e4SLinus Torvalds 9471da177e4SLinus Torvalds return ret; 9481da177e4SLinus Torvalds } 9491da177e4SLinus Torvalds 95042c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt) 9511da177e4SLinus Torvalds { 95242c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 9531da177e4SLinus Torvalds 9541da177e4SLinus Torvalds /* Reset device */ 95542c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 95642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 9571da177e4SLinus Torvalds } 9581da177e4SLinus Torvalds 95942c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 9601da177e4SLinus Torvalds { 96142c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 9622455a3eaSAndrei Emeltchenko 9631da177e4SLinus Torvalds /* Read Local Supported Features */ 96442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 9651da177e4SLinus Torvalds 9661143e5a6SMarcel Holtmann /* Read Local Version */ 96742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 9682177bab5SJohan Hedberg 9692177bab5SJohan Hedberg /* Read BD Address */ 97042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 9711da177e4SLinus Torvalds } 9721da177e4SLinus Torvalds 97342c6b129SJohan Hedberg static void amp_init(struct hci_request *req) 974e61ef499SAndrei Emeltchenko { 97542c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 9762455a3eaSAndrei Emeltchenko 977e61ef499SAndrei Emeltchenko /* Read Local Version */ 97842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 9796bcbc489SAndrei Emeltchenko 980f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 981f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 982f6996cfeSMarcel Holtmann 983f6996cfeSMarcel Holtmann /* Read Local Supported Features */ 984f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 985f6996cfeSMarcel Holtmann 9866bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 98742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 988e71dfabaSAndrei Emeltchenko 989e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 99042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 9917528ca1cSMarcel Holtmann 992f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 993f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 994f38ba941SMarcel Holtmann 9957528ca1cSMarcel Holtmann /* Read Location Data */ 9967528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 997e61ef499SAndrei Emeltchenko } 998e61ef499SAndrei Emeltchenko 99942c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 1000e61ef499SAndrei Emeltchenko { 100142c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1002e61ef499SAndrei Emeltchenko 1003e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 1004e61ef499SAndrei Emeltchenko 100511778716SAndrei Emeltchenko /* Reset */ 100611778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 100742c6b129SJohan Hedberg hci_reset_req(req, 0); 100811778716SAndrei Emeltchenko 1009e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 1010e61ef499SAndrei Emeltchenko case HCI_BREDR: 101142c6b129SJohan Hedberg bredr_init(req); 1012e61ef499SAndrei Emeltchenko break; 1013e61ef499SAndrei Emeltchenko 1014e61ef499SAndrei Emeltchenko case HCI_AMP: 101542c6b129SJohan Hedberg amp_init(req); 1016e61ef499SAndrei Emeltchenko break; 1017e61ef499SAndrei Emeltchenko 1018e61ef499SAndrei Emeltchenko default: 1019e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 1020e61ef499SAndrei Emeltchenko break; 1021e61ef499SAndrei Emeltchenko } 1022e61ef499SAndrei Emeltchenko } 1023e61ef499SAndrei Emeltchenko 102442c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 10252177bab5SJohan Hedberg { 10264ca048e3SMarcel Holtmann struct hci_dev *hdev = req->hdev; 10274ca048e3SMarcel Holtmann 10282177bab5SJohan Hedberg __le16 param; 10292177bab5SJohan Hedberg __u8 flt_type; 10302177bab5SJohan Hedberg 10312177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 103242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 10332177bab5SJohan Hedberg 10342177bab5SJohan Hedberg /* Read Class of Device */ 103542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 10362177bab5SJohan Hedberg 10372177bab5SJohan Hedberg /* Read Local Name */ 103842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 10392177bab5SJohan Hedberg 10402177bab5SJohan Hedberg /* Read Voice Setting */ 104142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 10422177bab5SJohan Hedberg 1043b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 1044b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 1045b4cb9fb2SMarcel Holtmann 10464b836f39SMarcel Holtmann /* Read Current IAC LAP */ 10474b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 10484b836f39SMarcel Holtmann 10492177bab5SJohan Hedberg /* Clear Event Filters */ 10502177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 105142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 10522177bab5SJohan Hedberg 10532177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 10542177bab5SJohan Hedberg param = __constant_cpu_to_le16(0x7d00); 105542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 10562177bab5SJohan Hedberg 10574ca048e3SMarcel Holtmann /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, 10584ca048e3SMarcel Holtmann * but it does not support page scan related HCI commands. 10594ca048e3SMarcel Holtmann */ 10604ca048e3SMarcel Holtmann if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) { 1061f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 1062f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 1063f332ec66SJohan Hedberg } 10642177bab5SJohan Hedberg } 10652177bab5SJohan Hedberg 106642c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 10672177bab5SJohan Hedberg { 1068c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 1069c73eee91SJohan Hedberg 10702177bab5SJohan Hedberg /* Read LE Buffer Size */ 107142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 10722177bab5SJohan Hedberg 10732177bab5SJohan Hedberg /* Read LE Local Supported Features */ 107442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 10752177bab5SJohan Hedberg 10762177bab5SJohan Hedberg /* Read LE Advertising Channel TX Power */ 107742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 10782177bab5SJohan Hedberg 10792177bab5SJohan Hedberg /* Read LE White List Size */ 108042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 10812177bab5SJohan Hedberg 10822177bab5SJohan Hedberg /* Read LE Supported States */ 108342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 1084c73eee91SJohan Hedberg 1085c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 1086c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1087c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 10882177bab5SJohan Hedberg } 10892177bab5SJohan Hedberg 10902177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 10912177bab5SJohan Hedberg { 10922177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 10932177bab5SJohan Hedberg return 0x02; 10942177bab5SJohan Hedberg 10952177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 10962177bab5SJohan Hedberg return 0x01; 10972177bab5SJohan Hedberg 10982177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 10992177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 11002177bab5SJohan Hedberg return 0x01; 11012177bab5SJohan Hedberg 11022177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 11032177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 11042177bab5SJohan Hedberg return 0x01; 11052177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 11062177bab5SJohan Hedberg return 0x01; 11072177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 11082177bab5SJohan Hedberg return 0x01; 11092177bab5SJohan Hedberg } 11102177bab5SJohan Hedberg 11112177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 11122177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 11132177bab5SJohan Hedberg return 0x01; 11142177bab5SJohan Hedberg 11152177bab5SJohan Hedberg return 0x00; 11162177bab5SJohan Hedberg } 11172177bab5SJohan Hedberg 111842c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 11192177bab5SJohan Hedberg { 11202177bab5SJohan Hedberg u8 mode; 11212177bab5SJohan Hedberg 112242c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 11232177bab5SJohan Hedberg 112442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 11252177bab5SJohan Hedberg } 11262177bab5SJohan Hedberg 112742c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 11282177bab5SJohan Hedberg { 112942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 113042c6b129SJohan Hedberg 11312177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 11322177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 11332177bab5SJohan Hedberg * command otherwise. 11342177bab5SJohan Hedberg */ 11352177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 11362177bab5SJohan Hedberg 11372177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 11382177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 11392177bab5SJohan Hedberg */ 11402177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 11412177bab5SJohan Hedberg return; 11422177bab5SJohan Hedberg 11432177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 11442177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 11452177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 11462177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 11472177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 11482177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 1149c7882cbdSMarcel Holtmann } else { 1150c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 1151c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 1152c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 1153c7882cbdSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 1154c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 1155c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 1156c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 1157c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 1158c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 1159c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 1160c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 11612177bab5SJohan Hedberg } 11622177bab5SJohan Hedberg 11632177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 11642177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 11652177bab5SJohan Hedberg 11662177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 11672177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 11682177bab5SJohan Hedberg 11692177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 11702177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 11712177bab5SJohan Hedberg 11722177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 11732177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 11742177bab5SJohan Hedberg 11752177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 11762177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 11772177bab5SJohan Hedberg 11782177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 11792177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 11802177bab5SJohan Hedberg 11812177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 11822177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 11832177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 11842177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 11852177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 11862177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 11872177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 11882177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 11892177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 11902177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 11912177bab5SJohan Hedberg * Features Notification 11922177bab5SJohan Hedberg */ 11932177bab5SJohan Hedberg } 11942177bab5SJohan Hedberg 11952177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 11962177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 11972177bab5SJohan Hedberg 119842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 11992177bab5SJohan Hedberg 12002177bab5SJohan Hedberg if (lmp_le_capable(hdev)) { 12012177bab5SJohan Hedberg memset(events, 0, sizeof(events)); 12022177bab5SJohan Hedberg events[0] = 0x1f; 120342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, 12042177bab5SJohan Hedberg sizeof(events), events); 12052177bab5SJohan Hedberg } 12062177bab5SJohan Hedberg } 12072177bab5SJohan Hedberg 120842c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 12092177bab5SJohan Hedberg { 121042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 121142c6b129SJohan Hedberg 12122177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 121342c6b129SJohan Hedberg bredr_setup(req); 121456f87901SJohan Hedberg else 121556f87901SJohan Hedberg clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 12162177bab5SJohan Hedberg 12172177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 121842c6b129SJohan Hedberg le_setup(req); 12192177bab5SJohan Hedberg 122042c6b129SJohan Hedberg hci_setup_event_mask(req); 12212177bab5SJohan Hedberg 12223f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 12233f8e2d75SJohan Hedberg * local supported commands HCI command. 12243f8e2d75SJohan Hedberg */ 12253f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 122642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 12272177bab5SJohan Hedberg 12282177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 122957af75a8SMarcel Holtmann /* When SSP is available, then the host features page 123057af75a8SMarcel Holtmann * should also be available as well. However some 123157af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 123257af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 123357af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 123457af75a8SMarcel Holtmann */ 123557af75a8SMarcel Holtmann hdev->max_page = 0x01; 123657af75a8SMarcel Holtmann 12372177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 12382177bab5SJohan Hedberg u8 mode = 0x01; 123942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 12402177bab5SJohan Hedberg sizeof(mode), &mode); 12412177bab5SJohan Hedberg } else { 12422177bab5SJohan Hedberg struct hci_cp_write_eir cp; 12432177bab5SJohan Hedberg 12442177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 12452177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 12462177bab5SJohan Hedberg 124742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 12482177bab5SJohan Hedberg } 12492177bab5SJohan Hedberg } 12502177bab5SJohan Hedberg 12512177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 125242c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 12532177bab5SJohan Hedberg 12542177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 125542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 12562177bab5SJohan Hedberg 12572177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 12582177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 12592177bab5SJohan Hedberg 12602177bab5SJohan Hedberg cp.page = 0x01; 126142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 126242c6b129SJohan Hedberg sizeof(cp), &cp); 12632177bab5SJohan Hedberg } 12642177bab5SJohan Hedberg 12652177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 12662177bab5SJohan Hedberg u8 enable = 1; 126742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 12682177bab5SJohan Hedberg &enable); 12692177bab5SJohan Hedberg } 12702177bab5SJohan Hedberg } 12712177bab5SJohan Hedberg 127242c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 12732177bab5SJohan Hedberg { 127442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 12752177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 12762177bab5SJohan Hedberg u16 link_policy = 0; 12772177bab5SJohan Hedberg 12782177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 12792177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 12802177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 12812177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 12822177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 12832177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 12842177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 12852177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 12862177bab5SJohan Hedberg 12872177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 128842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 12892177bab5SJohan Hedberg } 12902177bab5SJohan Hedberg 129142c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 12922177bab5SJohan Hedberg { 129342c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 12942177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 12952177bab5SJohan Hedberg 1296c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 1297c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1298c73eee91SJohan Hedberg return; 1299c73eee91SJohan Hedberg 13002177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 13012177bab5SJohan Hedberg 13022177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 13032177bab5SJohan Hedberg cp.le = 0x01; 13042177bab5SJohan Hedberg cp.simul = lmp_le_br_capable(hdev); 13052177bab5SJohan Hedberg } 13062177bab5SJohan Hedberg 13072177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 130842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 13092177bab5SJohan Hedberg &cp); 13102177bab5SJohan Hedberg } 13112177bab5SJohan Hedberg 1312d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 1313d62e6d67SJohan Hedberg { 1314d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 1315d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1316d62e6d67SJohan Hedberg 1317d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 1318d62e6d67SJohan Hedberg * enable all necessary events for it. 1319d62e6d67SJohan Hedberg */ 132053b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 1321d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 1322d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 1323d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 1324d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 1325d62e6d67SJohan Hedberg } 1326d62e6d67SJohan Hedberg 1327d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 1328d62e6d67SJohan Hedberg * enable all necessary events for it. 1329d62e6d67SJohan Hedberg */ 133053b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 1331d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 1332d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 1333d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 1334d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 1335d62e6d67SJohan Hedberg } 1336d62e6d67SJohan Hedberg 133740c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 133840c59fcbSMarcel Holtmann if (lmp_ping_capable(hdev)) 133940c59fcbSMarcel Holtmann events[2] |= 0x80; 134040c59fcbSMarcel Holtmann 1341d62e6d67SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 1342d62e6d67SJohan Hedberg } 1343d62e6d67SJohan Hedberg 134442c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 13452177bab5SJohan Hedberg { 134642c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1347d2c5d77fSJohan Hedberg u8 p; 134842c6b129SJohan Hedberg 1349b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 1350b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 1351b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 1352b8f4e068SGustavo Padovan * 1353b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 1354b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 1355b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 1356b8f4e068SGustavo Padovan * command redundant anyway. 1357f9f462faSMarcel Holtmann * 1358f9f462faSMarcel Holtmann * Some controllers indicate that they support handling deleting 1359f9f462faSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 1360f9f462faSMarcel Holtmann * just disable this command. 1361b8f4e068SGustavo Padovan */ 1362f9f462faSMarcel Holtmann if (hdev->commands[6] & 0x80 && 1363f9f462faSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 136459f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 136559f45d57SJohan Hedberg 136659f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 136759f45d57SJohan Hedberg cp.delete_all = 0x01; 136859f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 136959f45d57SJohan Hedberg sizeof(cp), &cp); 137059f45d57SJohan Hedberg } 137159f45d57SJohan Hedberg 13722177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 137342c6b129SJohan Hedberg hci_setup_link_policy(req); 13742177bab5SJohan Hedberg 137579830f66SMarcel Holtmann if (lmp_le_capable(hdev)) { 1376bef34c0aSMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 1377bef34c0aSMarcel Holtmann /* If the controller has a public BD_ADDR, then 1378bef34c0aSMarcel Holtmann * by default use that one. If this is a LE only 1379bef34c0aSMarcel Holtmann * controller without a public address, default 1380bef34c0aSMarcel Holtmann * to the random address. 138179830f66SMarcel Holtmann */ 138279830f66SMarcel Holtmann if (bacmp(&hdev->bdaddr, BDADDR_ANY)) 138379830f66SMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_PUBLIC; 138479830f66SMarcel Holtmann else 138579830f66SMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_RANDOM; 1386bef34c0aSMarcel Holtmann } 138779830f66SMarcel Holtmann 138842c6b129SJohan Hedberg hci_set_le_support(req); 138979830f66SMarcel Holtmann } 1390d2c5d77fSJohan Hedberg 1391d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 1392d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 1393d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 1394d2c5d77fSJohan Hedberg 1395d2c5d77fSJohan Hedberg cp.page = p; 1396d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 1397d2c5d77fSJohan Hedberg sizeof(cp), &cp); 1398d2c5d77fSJohan Hedberg } 13992177bab5SJohan Hedberg } 14002177bab5SJohan Hedberg 14015d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt) 14025d4e7e8dSJohan Hedberg { 14035d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 14045d4e7e8dSJohan Hedberg 1405d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 1406d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 1407d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 1408d62e6d67SJohan Hedberg 14095d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 141053b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 14115d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 1412a6d0d690SMarcel Holtmann 1413a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 14145afeac14SMarcel Holtmann if ((lmp_sc_capable(hdev) || 14155afeac14SMarcel Holtmann test_bit(HCI_FORCE_SC, &hdev->dev_flags)) && 1416a6d0d690SMarcel Holtmann test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) { 1417a6d0d690SMarcel Holtmann u8 support = 0x01; 1418a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 1419a6d0d690SMarcel Holtmann sizeof(support), &support); 1420a6d0d690SMarcel Holtmann } 14215d4e7e8dSJohan Hedberg } 14225d4e7e8dSJohan Hedberg 14232177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 14242177bab5SJohan Hedberg { 14252177bab5SJohan Hedberg int err; 14262177bab5SJohan Hedberg 14272177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 14282177bab5SJohan Hedberg if (err < 0) 14292177bab5SJohan Hedberg return err; 14302177bab5SJohan Hedberg 14314b4148e9SMarcel Holtmann /* The Device Under Test (DUT) mode is special and available for 14324b4148e9SMarcel Holtmann * all controller types. So just create it early on. 14334b4148e9SMarcel Holtmann */ 14344b4148e9SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 14354b4148e9SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 14364b4148e9SMarcel Holtmann &dut_mode_fops); 14374b4148e9SMarcel Holtmann } 14384b4148e9SMarcel Holtmann 14392177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 14402177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 14412177bab5SJohan Hedberg * first stage init. 14422177bab5SJohan Hedberg */ 14432177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 14442177bab5SJohan Hedberg return 0; 14452177bab5SJohan Hedberg 14462177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 14472177bab5SJohan Hedberg if (err < 0) 14482177bab5SJohan Hedberg return err; 14492177bab5SJohan Hedberg 14505d4e7e8dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 14515d4e7e8dSJohan Hedberg if (err < 0) 14525d4e7e8dSJohan Hedberg return err; 14535d4e7e8dSJohan Hedberg 1454baf27f6eSMarcel Holtmann err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 1455baf27f6eSMarcel Holtmann if (err < 0) 1456baf27f6eSMarcel Holtmann return err; 1457baf27f6eSMarcel Holtmann 1458baf27f6eSMarcel Holtmann /* Only create debugfs entries during the initial setup 1459baf27f6eSMarcel Holtmann * phase and not every time the controller gets powered on. 1460baf27f6eSMarcel Holtmann */ 1461baf27f6eSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 1462baf27f6eSMarcel Holtmann return 0; 1463baf27f6eSMarcel Holtmann 1464dfb826a8SMarcel Holtmann debugfs_create_file("features", 0444, hdev->debugfs, hdev, 1465dfb826a8SMarcel Holtmann &features_fops); 1466ceeb3bc0SMarcel Holtmann debugfs_create_u16("manufacturer", 0444, hdev->debugfs, 1467ceeb3bc0SMarcel Holtmann &hdev->manufacturer); 1468ceeb3bc0SMarcel Holtmann debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); 1469ceeb3bc0SMarcel Holtmann debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); 147070afe0b8SMarcel Holtmann debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, 147170afe0b8SMarcel Holtmann &blacklist_fops); 147247219839SMarcel Holtmann debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); 147347219839SMarcel Holtmann 1474baf27f6eSMarcel Holtmann if (lmp_bredr_capable(hdev)) { 1475baf27f6eSMarcel Holtmann debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, 1476baf27f6eSMarcel Holtmann hdev, &inquiry_cache_fops); 147702d08d15SMarcel Holtmann debugfs_create_file("link_keys", 0400, hdev->debugfs, 147802d08d15SMarcel Holtmann hdev, &link_keys_fops); 1479babdbb3cSMarcel Holtmann debugfs_create_file("dev_class", 0444, hdev->debugfs, 1480babdbb3cSMarcel Holtmann hdev, &dev_class_fops); 1481041000b9SMarcel Holtmann debugfs_create_file("voice_setting", 0444, hdev->debugfs, 1482041000b9SMarcel Holtmann hdev, &voice_setting_fops); 1483baf27f6eSMarcel Holtmann } 1484baf27f6eSMarcel Holtmann 148506f5b778SMarcel Holtmann if (lmp_ssp_capable(hdev)) { 1486ebd1e33bSMarcel Holtmann debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, 1487ebd1e33bSMarcel Holtmann hdev, &auto_accept_delay_fops); 148806f5b778SMarcel Holtmann debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs, 148906f5b778SMarcel Holtmann hdev, &ssp_debug_mode_fops); 14905afeac14SMarcel Holtmann debugfs_create_file("force_sc_support", 0644, hdev->debugfs, 14915afeac14SMarcel Holtmann hdev, &force_sc_support_fops); 1492134c2a89SMarcel Holtmann debugfs_create_file("sc_only_mode", 0444, hdev->debugfs, 1493134c2a89SMarcel Holtmann hdev, &sc_only_mode_fops); 149406f5b778SMarcel Holtmann } 1495ebd1e33bSMarcel Holtmann 14962bfa3531SMarcel Holtmann if (lmp_sniff_capable(hdev)) { 14972bfa3531SMarcel Holtmann debugfs_create_file("idle_timeout", 0644, hdev->debugfs, 14982bfa3531SMarcel Holtmann hdev, &idle_timeout_fops); 14992bfa3531SMarcel Holtmann debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs, 15002bfa3531SMarcel Holtmann hdev, &sniff_min_interval_fops); 15012bfa3531SMarcel Holtmann debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs, 15022bfa3531SMarcel Holtmann hdev, &sniff_max_interval_fops); 15032bfa3531SMarcel Holtmann } 15042bfa3531SMarcel Holtmann 1505d0f729b8SMarcel Holtmann if (lmp_le_capable(hdev)) { 1506d0f729b8SMarcel Holtmann debugfs_create_u8("white_list_size", 0444, hdev->debugfs, 1507d0f729b8SMarcel Holtmann &hdev->le_white_list_size); 1508e7b8fc92SMarcel Holtmann debugfs_create_file("static_address", 0444, hdev->debugfs, 1509e7b8fc92SMarcel Holtmann hdev, &static_address_fops); 151092202185SMarcel Holtmann debugfs_create_file("own_address_type", 0644, hdev->debugfs, 151192202185SMarcel Holtmann hdev, &own_address_type_fops); 15128f8625cdSMarcel Holtmann debugfs_create_file("long_term_keys", 0400, hdev->debugfs, 15138f8625cdSMarcel Holtmann hdev, &long_term_keys_fops); 15144e70c7e7SMarcel Holtmann debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, 15154e70c7e7SMarcel Holtmann hdev, &conn_min_interval_fops); 15164e70c7e7SMarcel Holtmann debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, 15174e70c7e7SMarcel Holtmann hdev, &conn_max_interval_fops); 151889863109SJukka Rissanen debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev, 151989863109SJukka Rissanen &lowpan_debugfs_fops); 1520d0f729b8SMarcel Holtmann } 1521e7b8fc92SMarcel Holtmann 1522baf27f6eSMarcel Holtmann return 0; 15232177bab5SJohan Hedberg } 15242177bab5SJohan Hedberg 152542c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 15261da177e4SLinus Torvalds { 15271da177e4SLinus Torvalds __u8 scan = opt; 15281da177e4SLinus Torvalds 152942c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 15301da177e4SLinus Torvalds 15311da177e4SLinus Torvalds /* Inquiry and Page scans */ 153242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 15331da177e4SLinus Torvalds } 15341da177e4SLinus Torvalds 153542c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 15361da177e4SLinus Torvalds { 15371da177e4SLinus Torvalds __u8 auth = opt; 15381da177e4SLinus Torvalds 153942c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 15401da177e4SLinus Torvalds 15411da177e4SLinus Torvalds /* Authentication */ 154242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 15431da177e4SLinus Torvalds } 15441da177e4SLinus Torvalds 154542c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 15461da177e4SLinus Torvalds { 15471da177e4SLinus Torvalds __u8 encrypt = opt; 15481da177e4SLinus Torvalds 154942c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 15501da177e4SLinus Torvalds 1551e4e8e37cSMarcel Holtmann /* Encryption */ 155242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 15531da177e4SLinus Torvalds } 15541da177e4SLinus Torvalds 155542c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 1556e4e8e37cSMarcel Holtmann { 1557e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1558e4e8e37cSMarcel Holtmann 155942c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1560e4e8e37cSMarcel Holtmann 1561e4e8e37cSMarcel Holtmann /* Default link policy */ 156242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1563e4e8e37cSMarcel Holtmann } 1564e4e8e37cSMarcel Holtmann 15651da177e4SLinus Torvalds /* Get HCI device by index. 15661da177e4SLinus Torvalds * Device is held on return. */ 15671da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 15681da177e4SLinus Torvalds { 15698035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 15701da177e4SLinus Torvalds 15711da177e4SLinus Torvalds BT_DBG("%d", index); 15721da177e4SLinus Torvalds 15731da177e4SLinus Torvalds if (index < 0) 15741da177e4SLinus Torvalds return NULL; 15751da177e4SLinus Torvalds 15761da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 15778035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 15781da177e4SLinus Torvalds if (d->id == index) { 15791da177e4SLinus Torvalds hdev = hci_dev_hold(d); 15801da177e4SLinus Torvalds break; 15811da177e4SLinus Torvalds } 15821da177e4SLinus Torvalds } 15831da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 15841da177e4SLinus Torvalds return hdev; 15851da177e4SLinus Torvalds } 15861da177e4SLinus Torvalds 15871da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1588ff9ef578SJohan Hedberg 158930dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 159030dc78e1SJohan Hedberg { 159130dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 159230dc78e1SJohan Hedberg 15936fbe195dSAndre Guedes switch (discov->state) { 1594343f935bSAndre Guedes case DISCOVERY_FINDING: 15956fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 159630dc78e1SJohan Hedberg return true; 159730dc78e1SJohan Hedberg 15986fbe195dSAndre Guedes default: 159930dc78e1SJohan Hedberg return false; 160030dc78e1SJohan Hedberg } 16016fbe195dSAndre Guedes } 160230dc78e1SJohan Hedberg 1603ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1604ff9ef578SJohan Hedberg { 1605ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1606ff9ef578SJohan Hedberg 1607ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 1608ff9ef578SJohan Hedberg return; 1609ff9ef578SJohan Hedberg 1610ff9ef578SJohan Hedberg switch (state) { 1611ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 16127b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 1613ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1614ff9ef578SJohan Hedberg break; 1615ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1616ff9ef578SJohan Hedberg break; 1617343f935bSAndre Guedes case DISCOVERY_FINDING: 1618ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1619ff9ef578SJohan Hedberg break; 162030dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 162130dc78e1SJohan Hedberg break; 1622ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1623ff9ef578SJohan Hedberg break; 1624ff9ef578SJohan Hedberg } 1625ff9ef578SJohan Hedberg 1626ff9ef578SJohan Hedberg hdev->discovery.state = state; 1627ff9ef578SJohan Hedberg } 1628ff9ef578SJohan Hedberg 16291f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 16301da177e4SLinus Torvalds { 163130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1632b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 16331da177e4SLinus Torvalds 1634561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1635561aafbcSJohan Hedberg list_del(&p->all); 1636b57c1a56SJohan Hedberg kfree(p); 16371da177e4SLinus Torvalds } 1638561aafbcSJohan Hedberg 1639561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1640561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 16411da177e4SLinus Torvalds } 16421da177e4SLinus Torvalds 1643a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1644a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 16451da177e4SLinus Torvalds { 164630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 16471da177e4SLinus Torvalds struct inquiry_entry *e; 16481da177e4SLinus Torvalds 16496ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 16501da177e4SLinus Torvalds 1651561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 16521da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 16531da177e4SLinus Torvalds return e; 16541da177e4SLinus Torvalds } 16551da177e4SLinus Torvalds 1656b57c1a56SJohan Hedberg return NULL; 1657b57c1a56SJohan Hedberg } 1658b57c1a56SJohan Hedberg 1659561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1660561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1661561aafbcSJohan Hedberg { 166230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1663561aafbcSJohan Hedberg struct inquiry_entry *e; 1664561aafbcSJohan Hedberg 16656ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1666561aafbcSJohan Hedberg 1667561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1668561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1669561aafbcSJohan Hedberg return e; 1670561aafbcSJohan Hedberg } 1671561aafbcSJohan Hedberg 1672561aafbcSJohan Hedberg return NULL; 1673561aafbcSJohan Hedberg } 1674561aafbcSJohan Hedberg 167530dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 167630dc78e1SJohan Hedberg bdaddr_t *bdaddr, 167730dc78e1SJohan Hedberg int state) 167830dc78e1SJohan Hedberg { 167930dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 168030dc78e1SJohan Hedberg struct inquiry_entry *e; 168130dc78e1SJohan Hedberg 16826ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 168330dc78e1SJohan Hedberg 168430dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 168530dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 168630dc78e1SJohan Hedberg return e; 168730dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 168830dc78e1SJohan Hedberg return e; 168930dc78e1SJohan Hedberg } 169030dc78e1SJohan Hedberg 169130dc78e1SJohan Hedberg return NULL; 169230dc78e1SJohan Hedberg } 169330dc78e1SJohan Hedberg 1694a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1695a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1696a3d4e20aSJohan Hedberg { 1697a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1698a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1699a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1700a3d4e20aSJohan Hedberg 1701a3d4e20aSJohan Hedberg list_del(&ie->list); 1702a3d4e20aSJohan Hedberg 1703a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1704a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1705a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1706a3d4e20aSJohan Hedberg break; 1707a3d4e20aSJohan Hedberg pos = &p->list; 1708a3d4e20aSJohan Hedberg } 1709a3d4e20aSJohan Hedberg 1710a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1711a3d4e20aSJohan Hedberg } 1712a3d4e20aSJohan Hedberg 17133175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1714388fc8faSJohan Hedberg bool name_known, bool *ssp) 17151da177e4SLinus Torvalds { 171630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 171770f23020SAndrei Emeltchenko struct inquiry_entry *ie; 17181da177e4SLinus Torvalds 17196ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 17201da177e4SLinus Torvalds 17212b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 17222b2fec4dSSzymon Janc 1723388fc8faSJohan Hedberg if (ssp) 1724388fc8faSJohan Hedberg *ssp = data->ssp_mode; 1725388fc8faSJohan Hedberg 172670f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1727a3d4e20aSJohan Hedberg if (ie) { 1728388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 1729388fc8faSJohan Hedberg *ssp = true; 1730388fc8faSJohan Hedberg 1731a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1732a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1733a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1734a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1735a3d4e20aSJohan Hedberg } 1736a3d4e20aSJohan Hedberg 1737561aafbcSJohan Hedberg goto update; 1738a3d4e20aSJohan Hedberg } 1739561aafbcSJohan Hedberg 17401da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 174170f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 174270f23020SAndrei Emeltchenko if (!ie) 17433175405bSJohan Hedberg return false; 174470f23020SAndrei Emeltchenko 1745561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1746561aafbcSJohan Hedberg 1747561aafbcSJohan Hedberg if (name_known) { 1748561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1749561aafbcSJohan Hedberg } else { 1750561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1751561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1752561aafbcSJohan Hedberg } 1753561aafbcSJohan Hedberg 1754561aafbcSJohan Hedberg update: 1755561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1756561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1757561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1758561aafbcSJohan Hedberg list_del(&ie->list); 17591da177e4SLinus Torvalds } 17601da177e4SLinus Torvalds 176170f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 176270f23020SAndrei Emeltchenko ie->timestamp = jiffies; 17631da177e4SLinus Torvalds cache->timestamp = jiffies; 17643175405bSJohan Hedberg 17653175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 17663175405bSJohan Hedberg return false; 17673175405bSJohan Hedberg 17683175405bSJohan Hedberg return true; 17691da177e4SLinus Torvalds } 17701da177e4SLinus Torvalds 17711da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 17721da177e4SLinus Torvalds { 177330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 17741da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 17751da177e4SLinus Torvalds struct inquiry_entry *e; 17761da177e4SLinus Torvalds int copied = 0; 17771da177e4SLinus Torvalds 1778561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 17791da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1780b57c1a56SJohan Hedberg 1781b57c1a56SJohan Hedberg if (copied >= num) 1782b57c1a56SJohan Hedberg break; 1783b57c1a56SJohan Hedberg 17841da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 17851da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 17861da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 17871da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 17881da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 17891da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1790b57c1a56SJohan Hedberg 17911da177e4SLinus Torvalds info++; 1792b57c1a56SJohan Hedberg copied++; 17931da177e4SLinus Torvalds } 17941da177e4SLinus Torvalds 17951da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 17961da177e4SLinus Torvalds return copied; 17971da177e4SLinus Torvalds } 17981da177e4SLinus Torvalds 179942c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 18001da177e4SLinus Torvalds { 18011da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 180242c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 18031da177e4SLinus Torvalds struct hci_cp_inquiry cp; 18041da177e4SLinus Torvalds 18051da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 18061da177e4SLinus Torvalds 18071da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 18081da177e4SLinus Torvalds return; 18091da177e4SLinus Torvalds 18101da177e4SLinus Torvalds /* Start Inquiry */ 18111da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 18121da177e4SLinus Torvalds cp.length = ir->length; 18131da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 181442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 18151da177e4SLinus Torvalds } 18161da177e4SLinus Torvalds 18173e13fa1eSAndre Guedes static int wait_inquiry(void *word) 18183e13fa1eSAndre Guedes { 18193e13fa1eSAndre Guedes schedule(); 18203e13fa1eSAndre Guedes return signal_pending(current); 18213e13fa1eSAndre Guedes } 18223e13fa1eSAndre Guedes 18231da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 18241da177e4SLinus Torvalds { 18251da177e4SLinus Torvalds __u8 __user *ptr = arg; 18261da177e4SLinus Torvalds struct hci_inquiry_req ir; 18271da177e4SLinus Torvalds struct hci_dev *hdev; 18281da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 18291da177e4SLinus Torvalds long timeo; 18301da177e4SLinus Torvalds __u8 *buf; 18311da177e4SLinus Torvalds 18321da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 18331da177e4SLinus Torvalds return -EFAULT; 18341da177e4SLinus Torvalds 18355a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 18365a08ecceSAndrei Emeltchenko if (!hdev) 18371da177e4SLinus Torvalds return -ENODEV; 18381da177e4SLinus Torvalds 18390736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 18400736cfa8SMarcel Holtmann err = -EBUSY; 18410736cfa8SMarcel Holtmann goto done; 18420736cfa8SMarcel Holtmann } 18430736cfa8SMarcel Holtmann 18445b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 18455b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 18465b69bef5SMarcel Holtmann goto done; 18475b69bef5SMarcel Holtmann } 18485b69bef5SMarcel Holtmann 184956f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 185056f87901SJohan Hedberg err = -EOPNOTSUPP; 185156f87901SJohan Hedberg goto done; 185256f87901SJohan Hedberg } 185356f87901SJohan Hedberg 185409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 18551da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1856a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 18571f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 18581da177e4SLinus Torvalds do_inquiry = 1; 18591da177e4SLinus Torvalds } 186009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18611da177e4SLinus Torvalds 186204837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 186370f23020SAndrei Emeltchenko 186470f23020SAndrei Emeltchenko if (do_inquiry) { 186501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 186601178cd4SJohan Hedberg timeo); 186770f23020SAndrei Emeltchenko if (err < 0) 18681da177e4SLinus Torvalds goto done; 18693e13fa1eSAndre Guedes 18703e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 18713e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 18723e13fa1eSAndre Guedes */ 18733e13fa1eSAndre Guedes if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, 18743e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 18753e13fa1eSAndre Guedes return -EINTR; 187670f23020SAndrei Emeltchenko } 18771da177e4SLinus Torvalds 18788fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 18798fc9ced3SGustavo Padovan * 255 entries 18808fc9ced3SGustavo Padovan */ 18811da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 18821da177e4SLinus Torvalds 18831da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 18841da177e4SLinus Torvalds * copy it to the user space. 18851da177e4SLinus Torvalds */ 188670f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 188770f23020SAndrei Emeltchenko if (!buf) { 18881da177e4SLinus Torvalds err = -ENOMEM; 18891da177e4SLinus Torvalds goto done; 18901da177e4SLinus Torvalds } 18911da177e4SLinus Torvalds 189209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 18931da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 189409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18951da177e4SLinus Torvalds 18961da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 18971da177e4SLinus Torvalds 18981da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 18991da177e4SLinus Torvalds ptr += sizeof(ir); 19001da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 19011da177e4SLinus Torvalds ir.num_rsp)) 19021da177e4SLinus Torvalds err = -EFAULT; 19031da177e4SLinus Torvalds } else 19041da177e4SLinus Torvalds err = -EFAULT; 19051da177e4SLinus Torvalds 19061da177e4SLinus Torvalds kfree(buf); 19071da177e4SLinus Torvalds 19081da177e4SLinus Torvalds done: 19091da177e4SLinus Torvalds hci_dev_put(hdev); 19101da177e4SLinus Torvalds return err; 19111da177e4SLinus Torvalds } 19121da177e4SLinus Torvalds 1913cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 19141da177e4SLinus Torvalds { 19151da177e4SLinus Torvalds int ret = 0; 19161da177e4SLinus Torvalds 19171da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 19181da177e4SLinus Torvalds 19191da177e4SLinus Torvalds hci_req_lock(hdev); 19201da177e4SLinus Torvalds 192194324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 192294324962SJohan Hovold ret = -ENODEV; 192394324962SJohan Hovold goto done; 192494324962SJohan Hovold } 192594324962SJohan Hovold 1926a5c8f270SMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 1927a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1928a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1929bf543036SJohan Hedberg */ 1930a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 1931611b30f7SMarcel Holtmann ret = -ERFKILL; 1932611b30f7SMarcel Holtmann goto done; 1933611b30f7SMarcel Holtmann } 1934611b30f7SMarcel Holtmann 1935a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 1936a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 1937a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1938a5c8f270SMarcel Holtmann * or not. 1939a5c8f270SMarcel Holtmann * 1940a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1941a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1942a5c8f270SMarcel Holtmann */ 1943a5c8f270SMarcel Holtmann if (hdev->dev_type == HCI_BREDR && 1944a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1945a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1946a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1947a5c8f270SMarcel Holtmann goto done; 1948a5c8f270SMarcel Holtmann } 1949a5c8f270SMarcel Holtmann } 1950a5c8f270SMarcel Holtmann 19511da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 19521da177e4SLinus Torvalds ret = -EALREADY; 19531da177e4SLinus Torvalds goto done; 19541da177e4SLinus Torvalds } 19551da177e4SLinus Torvalds 19561da177e4SLinus Torvalds if (hdev->open(hdev)) { 19571da177e4SLinus Torvalds ret = -EIO; 19581da177e4SLinus Torvalds goto done; 19591da177e4SLinus Torvalds } 19601da177e4SLinus Torvalds 19611da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 19621da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1963f41c70c4SMarcel Holtmann 1964f41c70c4SMarcel Holtmann if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags)) 1965f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1966f41c70c4SMarcel Holtmann 1967f41c70c4SMarcel Holtmann if (!ret) { 1968f41c70c4SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 1969f41c70c4SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 1970f41c70c4SMarcel Holtmann 19710736cfa8SMarcel Holtmann if (!test_bit(HCI_RAW, &hdev->flags) && 19720736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 19732177bab5SJohan Hedberg ret = __hci_init(hdev); 19741da177e4SLinus Torvalds } 19751da177e4SLinus Torvalds 1976f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1977f41c70c4SMarcel Holtmann 19781da177e4SLinus Torvalds if (!ret) { 19791da177e4SLinus Torvalds hci_dev_hold(hdev); 19801da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 19811da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 1982bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 19830736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 19841514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 198509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1986744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 198709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 198856e5cb86SJohan Hedberg } 19891da177e4SLinus Torvalds } else { 19901da177e4SLinus Torvalds /* Init failed, cleanup */ 19913eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1992c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 1993b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 19941da177e4SLinus Torvalds 19951da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 19961da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 19971da177e4SLinus Torvalds 19981da177e4SLinus Torvalds if (hdev->flush) 19991da177e4SLinus Torvalds hdev->flush(hdev); 20001da177e4SLinus Torvalds 20011da177e4SLinus Torvalds if (hdev->sent_cmd) { 20021da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 20031da177e4SLinus Torvalds hdev->sent_cmd = NULL; 20041da177e4SLinus Torvalds } 20051da177e4SLinus Torvalds 20061da177e4SLinus Torvalds hdev->close(hdev); 20071da177e4SLinus Torvalds hdev->flags = 0; 20081da177e4SLinus Torvalds } 20091da177e4SLinus Torvalds 20101da177e4SLinus Torvalds done: 20111da177e4SLinus Torvalds hci_req_unlock(hdev); 20121da177e4SLinus Torvalds return ret; 20131da177e4SLinus Torvalds } 20141da177e4SLinus Torvalds 2015cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 2016cbed0ca1SJohan Hedberg 2017cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 2018cbed0ca1SJohan Hedberg { 2019cbed0ca1SJohan Hedberg struct hci_dev *hdev; 2020cbed0ca1SJohan Hedberg int err; 2021cbed0ca1SJohan Hedberg 2022cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 2023cbed0ca1SJohan Hedberg if (!hdev) 2024cbed0ca1SJohan Hedberg return -ENODEV; 2025cbed0ca1SJohan Hedberg 2026e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 2027e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 2028e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 2029e1d08f40SJohan Hedberg * completed. 2030e1d08f40SJohan Hedberg */ 2031e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2032e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 2033e1d08f40SJohan Hedberg 2034a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 2035a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 2036a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 2037a5c8f270SMarcel Holtmann */ 2038e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 2039e1d08f40SJohan Hedberg 2040cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 2041cbed0ca1SJohan Hedberg 2042cbed0ca1SJohan Hedberg hci_dev_put(hdev); 2043cbed0ca1SJohan Hedberg 2044cbed0ca1SJohan Hedberg return err; 2045cbed0ca1SJohan Hedberg } 2046cbed0ca1SJohan Hedberg 20471da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 20481da177e4SLinus Torvalds { 20491da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 20501da177e4SLinus Torvalds 205178c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 205278c04c0bSVinicius Costa Gomes 20531da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 20541da177e4SLinus Torvalds hci_req_lock(hdev); 20551da177e4SLinus Torvalds 20561da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 2057b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 20581da177e4SLinus Torvalds hci_req_unlock(hdev); 20591da177e4SLinus Torvalds return 0; 20601da177e4SLinus Torvalds } 20611da177e4SLinus Torvalds 20623eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 20633eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2064b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 20651da177e4SLinus Torvalds 206616ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 2067e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 206816ab91abSJohan Hedberg hdev->discov_timeout = 0; 20695e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 2070310a3d48SMarcel Holtmann clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 207116ab91abSJohan Hedberg } 207216ab91abSJohan Hedberg 2073a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 20747d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 20757d78525dSJohan Hedberg 20767ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 20777ba8b4beSAndre Guedes 207809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 20791f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 20801da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 208109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 20821da177e4SLinus Torvalds 20831da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 20841da177e4SLinus Torvalds 20851da177e4SLinus Torvalds if (hdev->flush) 20861da177e4SLinus Torvalds hdev->flush(hdev); 20871da177e4SLinus Torvalds 20881da177e4SLinus Torvalds /* Reset device */ 20891da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 20901da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 20918af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 20923a6afbd2SMarcel Holtmann !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 2093a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 20941da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 209501178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 20961da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 20971da177e4SLinus Torvalds } 20981da177e4SLinus Torvalds 2099c347b765SGustavo F. Padovan /* flush cmd work */ 2100c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 21011da177e4SLinus Torvalds 21021da177e4SLinus Torvalds /* Drop queues */ 21031da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 21041da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 21051da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 21061da177e4SLinus Torvalds 21071da177e4SLinus Torvalds /* Drop last sent command */ 21081da177e4SLinus Torvalds if (hdev->sent_cmd) { 2109b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 21101da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 21111da177e4SLinus Torvalds hdev->sent_cmd = NULL; 21121da177e4SLinus Torvalds } 21131da177e4SLinus Torvalds 2114b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 2115b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 2116b6ddb638SJohan Hedberg 21171da177e4SLinus Torvalds /* After this point our queues are empty 21181da177e4SLinus Torvalds * and no tasks are scheduled. */ 21191da177e4SLinus Torvalds hdev->close(hdev); 21201da177e4SLinus Torvalds 212135b973c9SJohan Hedberg /* Clear flags */ 212235b973c9SJohan Hedberg hdev->flags = 0; 212335b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 212435b973c9SJohan Hedberg 212593c311a0SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 212693c311a0SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 212709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2128744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 212909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 21308ee56540SMarcel Holtmann } 213193c311a0SMarcel Holtmann } 21325add6af8SJohan Hedberg 2133ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 2134536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 2135ced5c338SAndrei Emeltchenko 2136e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 213709b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 2138e59fda8dSJohan Hedberg 21391da177e4SLinus Torvalds hci_req_unlock(hdev); 21401da177e4SLinus Torvalds 21411da177e4SLinus Torvalds hci_dev_put(hdev); 21421da177e4SLinus Torvalds return 0; 21431da177e4SLinus Torvalds } 21441da177e4SLinus Torvalds 21451da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 21461da177e4SLinus Torvalds { 21471da177e4SLinus Torvalds struct hci_dev *hdev; 21481da177e4SLinus Torvalds int err; 21491da177e4SLinus Torvalds 215070f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 215170f23020SAndrei Emeltchenko if (!hdev) 21521da177e4SLinus Torvalds return -ENODEV; 21538ee56540SMarcel Holtmann 21540736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 21550736cfa8SMarcel Holtmann err = -EBUSY; 21560736cfa8SMarcel Holtmann goto done; 21570736cfa8SMarcel Holtmann } 21580736cfa8SMarcel Holtmann 21598ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 21608ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 21618ee56540SMarcel Holtmann 21621da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 21638ee56540SMarcel Holtmann 21640736cfa8SMarcel Holtmann done: 21651da177e4SLinus Torvalds hci_dev_put(hdev); 21661da177e4SLinus Torvalds return err; 21671da177e4SLinus Torvalds } 21681da177e4SLinus Torvalds 21691da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 21701da177e4SLinus Torvalds { 21711da177e4SLinus Torvalds struct hci_dev *hdev; 21721da177e4SLinus Torvalds int ret = 0; 21731da177e4SLinus Torvalds 217470f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 217570f23020SAndrei Emeltchenko if (!hdev) 21761da177e4SLinus Torvalds return -ENODEV; 21771da177e4SLinus Torvalds 21781da177e4SLinus Torvalds hci_req_lock(hdev); 21791da177e4SLinus Torvalds 2180808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 2181808a049eSMarcel Holtmann ret = -ENETDOWN; 21821da177e4SLinus Torvalds goto done; 2183808a049eSMarcel Holtmann } 21841da177e4SLinus Torvalds 21850736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 21860736cfa8SMarcel Holtmann ret = -EBUSY; 21870736cfa8SMarcel Holtmann goto done; 21880736cfa8SMarcel Holtmann } 21890736cfa8SMarcel Holtmann 21901da177e4SLinus Torvalds /* Drop queues */ 21911da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 21921da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 21931da177e4SLinus Torvalds 219409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 21951f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 21961da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 219709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 21981da177e4SLinus Torvalds 21991da177e4SLinus Torvalds if (hdev->flush) 22001da177e4SLinus Torvalds hdev->flush(hdev); 22011da177e4SLinus Torvalds 22021da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 22036ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 22041da177e4SLinus Torvalds 22051da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 220601178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 22071da177e4SLinus Torvalds 22081da177e4SLinus Torvalds done: 22091da177e4SLinus Torvalds hci_req_unlock(hdev); 22101da177e4SLinus Torvalds hci_dev_put(hdev); 22111da177e4SLinus Torvalds return ret; 22121da177e4SLinus Torvalds } 22131da177e4SLinus Torvalds 22141da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 22151da177e4SLinus Torvalds { 22161da177e4SLinus Torvalds struct hci_dev *hdev; 22171da177e4SLinus Torvalds int ret = 0; 22181da177e4SLinus Torvalds 221970f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 222070f23020SAndrei Emeltchenko if (!hdev) 22211da177e4SLinus Torvalds return -ENODEV; 22221da177e4SLinus Torvalds 22230736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22240736cfa8SMarcel Holtmann ret = -EBUSY; 22250736cfa8SMarcel Holtmann goto done; 22260736cfa8SMarcel Holtmann } 22270736cfa8SMarcel Holtmann 22281da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 22291da177e4SLinus Torvalds 22300736cfa8SMarcel Holtmann done: 22311da177e4SLinus Torvalds hci_dev_put(hdev); 22321da177e4SLinus Torvalds return ret; 22331da177e4SLinus Torvalds } 22341da177e4SLinus Torvalds 22351da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 22361da177e4SLinus Torvalds { 22371da177e4SLinus Torvalds struct hci_dev *hdev; 22381da177e4SLinus Torvalds struct hci_dev_req dr; 22391da177e4SLinus Torvalds int err = 0; 22401da177e4SLinus Torvalds 22411da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 22421da177e4SLinus Torvalds return -EFAULT; 22431da177e4SLinus Torvalds 224470f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 224570f23020SAndrei Emeltchenko if (!hdev) 22461da177e4SLinus Torvalds return -ENODEV; 22471da177e4SLinus Torvalds 22480736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22490736cfa8SMarcel Holtmann err = -EBUSY; 22500736cfa8SMarcel Holtmann goto done; 22510736cfa8SMarcel Holtmann } 22520736cfa8SMarcel Holtmann 22535b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 22545b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 22555b69bef5SMarcel Holtmann goto done; 22565b69bef5SMarcel Holtmann } 22575b69bef5SMarcel Holtmann 225856f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 225956f87901SJohan Hedberg err = -EOPNOTSUPP; 226056f87901SJohan Hedberg goto done; 226156f87901SJohan Hedberg } 226256f87901SJohan Hedberg 22631da177e4SLinus Torvalds switch (cmd) { 22641da177e4SLinus Torvalds case HCISETAUTH: 226501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 22665f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 22671da177e4SLinus Torvalds break; 22681da177e4SLinus Torvalds 22691da177e4SLinus Torvalds case HCISETENCRYPT: 22701da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 22711da177e4SLinus Torvalds err = -EOPNOTSUPP; 22721da177e4SLinus Torvalds break; 22731da177e4SLinus Torvalds } 22741da177e4SLinus Torvalds 22751da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 22761da177e4SLinus Torvalds /* Auth must be enabled first */ 227701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 22785f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 22791da177e4SLinus Torvalds if (err) 22801da177e4SLinus Torvalds break; 22811da177e4SLinus Torvalds } 22821da177e4SLinus Torvalds 228301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 22845f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 22851da177e4SLinus Torvalds break; 22861da177e4SLinus Torvalds 22871da177e4SLinus Torvalds case HCISETSCAN: 228801178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 22895f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 22901da177e4SLinus Torvalds break; 22911da177e4SLinus Torvalds 22921da177e4SLinus Torvalds case HCISETLINKPOL: 229301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 22945f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 22951da177e4SLinus Torvalds break; 22961da177e4SLinus Torvalds 22971da177e4SLinus Torvalds case HCISETLINKMODE: 2298e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2299e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2300e4e8e37cSMarcel Holtmann break; 2301e4e8e37cSMarcel Holtmann 2302e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2303e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 23041da177e4SLinus Torvalds break; 23051da177e4SLinus Torvalds 23061da177e4SLinus Torvalds case HCISETACLMTU: 23071da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 23081da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 23091da177e4SLinus Torvalds break; 23101da177e4SLinus Torvalds 23111da177e4SLinus Torvalds case HCISETSCOMTU: 23121da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 23131da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 23141da177e4SLinus Torvalds break; 23151da177e4SLinus Torvalds 23161da177e4SLinus Torvalds default: 23171da177e4SLinus Torvalds err = -EINVAL; 23181da177e4SLinus Torvalds break; 23191da177e4SLinus Torvalds } 2320e4e8e37cSMarcel Holtmann 23210736cfa8SMarcel Holtmann done: 23221da177e4SLinus Torvalds hci_dev_put(hdev); 23231da177e4SLinus Torvalds return err; 23241da177e4SLinus Torvalds } 23251da177e4SLinus Torvalds 23261da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 23271da177e4SLinus Torvalds { 23288035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 23291da177e4SLinus Torvalds struct hci_dev_list_req *dl; 23301da177e4SLinus Torvalds struct hci_dev_req *dr; 23311da177e4SLinus Torvalds int n = 0, size, err; 23321da177e4SLinus Torvalds __u16 dev_num; 23331da177e4SLinus Torvalds 23341da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 23351da177e4SLinus Torvalds return -EFAULT; 23361da177e4SLinus Torvalds 23371da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 23381da177e4SLinus Torvalds return -EINVAL; 23391da177e4SLinus Torvalds 23401da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 23411da177e4SLinus Torvalds 234270f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 234370f23020SAndrei Emeltchenko if (!dl) 23441da177e4SLinus Torvalds return -ENOMEM; 23451da177e4SLinus Torvalds 23461da177e4SLinus Torvalds dr = dl->dev_req; 23471da177e4SLinus Torvalds 2348f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 23498035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 2350a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2351e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 2352c542a06cSJohan Hedberg 2353a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2354a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2355c542a06cSJohan Hedberg 23561da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 23571da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 2358c542a06cSJohan Hedberg 23591da177e4SLinus Torvalds if (++n >= dev_num) 23601da177e4SLinus Torvalds break; 23611da177e4SLinus Torvalds } 2362f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 23631da177e4SLinus Torvalds 23641da177e4SLinus Torvalds dl->dev_num = n; 23651da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 23661da177e4SLinus Torvalds 23671da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 23681da177e4SLinus Torvalds kfree(dl); 23691da177e4SLinus Torvalds 23701da177e4SLinus Torvalds return err ? -EFAULT : 0; 23711da177e4SLinus Torvalds } 23721da177e4SLinus Torvalds 23731da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 23741da177e4SLinus Torvalds { 23751da177e4SLinus Torvalds struct hci_dev *hdev; 23761da177e4SLinus Torvalds struct hci_dev_info di; 23771da177e4SLinus Torvalds int err = 0; 23781da177e4SLinus Torvalds 23791da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 23801da177e4SLinus Torvalds return -EFAULT; 23811da177e4SLinus Torvalds 238270f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 238370f23020SAndrei Emeltchenko if (!hdev) 23841da177e4SLinus Torvalds return -ENODEV; 23851da177e4SLinus Torvalds 2386a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 23873243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 2388ab81cbf9SJohan Hedberg 2389a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2390a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2391c542a06cSJohan Hedberg 23921da177e4SLinus Torvalds strcpy(di.name, hdev->name); 23931da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 239460f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 23951da177e4SLinus Torvalds di.flags = hdev->flags; 23961da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2397572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 23981da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 23991da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 24001da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 24011da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2402572c7f84SJohan Hedberg } else { 2403572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2404572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2405572c7f84SJohan Hedberg di.sco_mtu = 0; 2406572c7f84SJohan Hedberg di.sco_pkts = 0; 2407572c7f84SJohan Hedberg } 24081da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 24091da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 24101da177e4SLinus Torvalds 24111da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 24121da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 24131da177e4SLinus Torvalds 24141da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 24151da177e4SLinus Torvalds err = -EFAULT; 24161da177e4SLinus Torvalds 24171da177e4SLinus Torvalds hci_dev_put(hdev); 24181da177e4SLinus Torvalds 24191da177e4SLinus Torvalds return err; 24201da177e4SLinus Torvalds } 24211da177e4SLinus Torvalds 24221da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 24231da177e4SLinus Torvalds 2424611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2425611b30f7SMarcel Holtmann { 2426611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2427611b30f7SMarcel Holtmann 2428611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2429611b30f7SMarcel Holtmann 24300736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 24310736cfa8SMarcel Holtmann return -EBUSY; 24320736cfa8SMarcel Holtmann 24335e130367SJohan Hedberg if (blocked) { 24345e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 2435bf543036SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 2436611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 24375e130367SJohan Hedberg } else { 24385e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 24395e130367SJohan Hedberg } 2440611b30f7SMarcel Holtmann 2441611b30f7SMarcel Holtmann return 0; 2442611b30f7SMarcel Holtmann } 2443611b30f7SMarcel Holtmann 2444611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2445611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2446611b30f7SMarcel Holtmann }; 2447611b30f7SMarcel Holtmann 2448ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2449ab81cbf9SJohan Hedberg { 2450ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 245196570ffcSJohan Hedberg int err; 2452ab81cbf9SJohan Hedberg 2453ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2454ab81cbf9SJohan Hedberg 2455cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 245696570ffcSJohan Hedberg if (err < 0) { 245796570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 2458ab81cbf9SJohan Hedberg return; 245996570ffcSJohan Hedberg } 2460ab81cbf9SJohan Hedberg 2461a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2462a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2463a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2464a5c8f270SMarcel Holtmann */ 2465a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 2466a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 2467a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2468a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2469bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2470bf543036SJohan Hedberg hci_dev_do_close(hdev); 2471bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 247219202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 247319202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2474bf543036SJohan Hedberg } 2475ab81cbf9SJohan Hedberg 2476a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 2477744cf19eSJohan Hedberg mgmt_index_added(hdev); 2478ab81cbf9SJohan Hedberg } 2479ab81cbf9SJohan Hedberg 2480ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2481ab81cbf9SJohan Hedberg { 24823243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 24833243553fSJohan Hedberg power_off.work); 2484ab81cbf9SJohan Hedberg 2485ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2486ab81cbf9SJohan Hedberg 24878ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2488ab81cbf9SJohan Hedberg } 2489ab81cbf9SJohan Hedberg 249016ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 249116ab91abSJohan Hedberg { 249216ab91abSJohan Hedberg struct hci_dev *hdev; 249316ab91abSJohan Hedberg 249416ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 249516ab91abSJohan Hedberg 249616ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 249716ab91abSJohan Hedberg 2498d1967ff8SMarcel Holtmann mgmt_discoverable_timeout(hdev); 249916ab91abSJohan Hedberg } 250016ab91abSJohan Hedberg 25012aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 25022aeb9a1aSJohan Hedberg { 25034821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 25042aeb9a1aSJohan Hedberg 25054821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 25064821002cSJohan Hedberg list_del(&uuid->list); 25072aeb9a1aSJohan Hedberg kfree(uuid); 25082aeb9a1aSJohan Hedberg } 25092aeb9a1aSJohan Hedberg 25102aeb9a1aSJohan Hedberg return 0; 25112aeb9a1aSJohan Hedberg } 25122aeb9a1aSJohan Hedberg 251355ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 251455ed8ca1SJohan Hedberg { 251555ed8ca1SJohan Hedberg struct list_head *p, *n; 251655ed8ca1SJohan Hedberg 251755ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 251855ed8ca1SJohan Hedberg struct link_key *key; 251955ed8ca1SJohan Hedberg 252055ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 252155ed8ca1SJohan Hedberg 252255ed8ca1SJohan Hedberg list_del(p); 252355ed8ca1SJohan Hedberg kfree(key); 252455ed8ca1SJohan Hedberg } 252555ed8ca1SJohan Hedberg 252655ed8ca1SJohan Hedberg return 0; 252755ed8ca1SJohan Hedberg } 252855ed8ca1SJohan Hedberg 2529b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 2530b899efafSVinicius Costa Gomes { 2531b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2532b899efafSVinicius Costa Gomes 2533b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2534b899efafSVinicius Costa Gomes list_del(&k->list); 2535b899efafSVinicius Costa Gomes kfree(k); 2536b899efafSVinicius Costa Gomes } 2537b899efafSVinicius Costa Gomes 2538b899efafSVinicius Costa Gomes return 0; 2539b899efafSVinicius Costa Gomes } 2540b899efafSVinicius Costa Gomes 254155ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 254255ed8ca1SJohan Hedberg { 254355ed8ca1SJohan Hedberg struct link_key *k; 254455ed8ca1SJohan Hedberg 25458035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 254655ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 254755ed8ca1SJohan Hedberg return k; 254855ed8ca1SJohan Hedberg 254955ed8ca1SJohan Hedberg return NULL; 255055ed8ca1SJohan Hedberg } 255155ed8ca1SJohan Hedberg 2552745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2553d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2554d25e28abSJohan Hedberg { 2555d25e28abSJohan Hedberg /* Legacy key */ 2556d25e28abSJohan Hedberg if (key_type < 0x03) 2557745c0ce3SVishal Agarwal return true; 2558d25e28abSJohan Hedberg 2559d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2560d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2561745c0ce3SVishal Agarwal return false; 2562d25e28abSJohan Hedberg 2563d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2564d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2565745c0ce3SVishal Agarwal return false; 2566d25e28abSJohan Hedberg 2567d25e28abSJohan Hedberg /* Security mode 3 case */ 2568d25e28abSJohan Hedberg if (!conn) 2569745c0ce3SVishal Agarwal return true; 2570d25e28abSJohan Hedberg 2571d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2572d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2573745c0ce3SVishal Agarwal return true; 2574d25e28abSJohan Hedberg 2575d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2576d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2577745c0ce3SVishal Agarwal return true; 2578d25e28abSJohan Hedberg 2579d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2580d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2581745c0ce3SVishal Agarwal return true; 2582d25e28abSJohan Hedberg 2583d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2584d25e28abSJohan Hedberg * persistently */ 2585745c0ce3SVishal Agarwal return false; 2586d25e28abSJohan Hedberg } 2587d25e28abSJohan Hedberg 258898a0b845SJohan Hedberg static bool ltk_type_master(u8 type) 258998a0b845SJohan Hedberg { 259098a0b845SJohan Hedberg if (type == HCI_SMP_STK || type == HCI_SMP_LTK) 259198a0b845SJohan Hedberg return true; 259298a0b845SJohan Hedberg 259398a0b845SJohan Hedberg return false; 259498a0b845SJohan Hedberg } 259598a0b845SJohan Hedberg 259698a0b845SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8], 259798a0b845SJohan Hedberg bool master) 259875d262c2SVinicius Costa Gomes { 2599c9839a11SVinicius Costa Gomes struct smp_ltk *k; 260075d262c2SVinicius Costa Gomes 2601c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 2602c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 2603c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 260475d262c2SVinicius Costa Gomes continue; 260575d262c2SVinicius Costa Gomes 260698a0b845SJohan Hedberg if (ltk_type_master(k->type) != master) 260798a0b845SJohan Hedberg continue; 260898a0b845SJohan Hedberg 260975d262c2SVinicius Costa Gomes return k; 261075d262c2SVinicius Costa Gomes } 261175d262c2SVinicius Costa Gomes 261275d262c2SVinicius Costa Gomes return NULL; 261375d262c2SVinicius Costa Gomes } 261475d262c2SVinicius Costa Gomes 2615c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 261698a0b845SJohan Hedberg u8 addr_type, bool master) 261775d262c2SVinicius Costa Gomes { 2618c9839a11SVinicius Costa Gomes struct smp_ltk *k; 261975d262c2SVinicius Costa Gomes 2620c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 2621c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 262298a0b845SJohan Hedberg bacmp(bdaddr, &k->bdaddr) == 0 && 262398a0b845SJohan Hedberg ltk_type_master(k->type) == master) 262475d262c2SVinicius Costa Gomes return k; 262575d262c2SVinicius Costa Gomes 262675d262c2SVinicius Costa Gomes return NULL; 262775d262c2SVinicius Costa Gomes } 262875d262c2SVinicius Costa Gomes 2629d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 2630d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 263155ed8ca1SJohan Hedberg { 263255ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2633745c0ce3SVishal Agarwal u8 old_key_type; 2634745c0ce3SVishal Agarwal bool persistent; 263555ed8ca1SJohan Hedberg 263655ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 263755ed8ca1SJohan Hedberg if (old_key) { 263855ed8ca1SJohan Hedberg old_key_type = old_key->type; 263955ed8ca1SJohan Hedberg key = old_key; 264055ed8ca1SJohan Hedberg } else { 264112adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 264255ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 264355ed8ca1SJohan Hedberg if (!key) 264455ed8ca1SJohan Hedberg return -ENOMEM; 264555ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 264655ed8ca1SJohan Hedberg } 264755ed8ca1SJohan Hedberg 26486ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 264955ed8ca1SJohan Hedberg 2650d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2651d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2652d25e28abSJohan Hedberg * previous key */ 2653d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2654a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2655d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2656655fe6ecSJohan Hedberg if (conn) 2657655fe6ecSJohan Hedberg conn->key_type = type; 2658655fe6ecSJohan Hedberg } 2659d25e28abSJohan Hedberg 266055ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 26619b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 266255ed8ca1SJohan Hedberg key->pin_len = pin_len; 266355ed8ca1SJohan Hedberg 2664b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 266555ed8ca1SJohan Hedberg key->type = old_key_type; 26664748fed2SJohan Hedberg else 26674748fed2SJohan Hedberg key->type = type; 26684748fed2SJohan Hedberg 26694df378a1SJohan Hedberg if (!new_key) 26704df378a1SJohan Hedberg return 0; 26714df378a1SJohan Hedberg 26724df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 26734df378a1SJohan Hedberg 2674744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 26754df378a1SJohan Hedberg 26766ec5bcadSVishal Agarwal if (conn) 26776ec5bcadSVishal Agarwal conn->flush_key = !persistent; 267855ed8ca1SJohan Hedberg 267955ed8ca1SJohan Hedberg return 0; 268055ed8ca1SJohan Hedberg } 268155ed8ca1SJohan Hedberg 2682c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 26839a006657SAndrei Emeltchenko int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 268404124681SGustavo F. Padovan ediv, u8 rand[8]) 268575d262c2SVinicius Costa Gomes { 2686c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 268798a0b845SJohan Hedberg bool master = ltk_type_master(type); 2688*0fe442ffSMarcel Holtmann u8 persistent; 268975d262c2SVinicius Costa Gomes 269098a0b845SJohan Hedberg old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master); 2691c9839a11SVinicius Costa Gomes if (old_key) 269275d262c2SVinicius Costa Gomes key = old_key; 2693c9839a11SVinicius Costa Gomes else { 2694c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 269575d262c2SVinicius Costa Gomes if (!key) 269675d262c2SVinicius Costa Gomes return -ENOMEM; 2697c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 269875d262c2SVinicius Costa Gomes } 269975d262c2SVinicius Costa Gomes 270075d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2701c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2702c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2703c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2704c9839a11SVinicius Costa Gomes key->ediv = ediv; 2705c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2706c9839a11SVinicius Costa Gomes key->type = type; 2707c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 270875d262c2SVinicius Costa Gomes 2709c9839a11SVinicius Costa Gomes if (!new_key) 2710c9839a11SVinicius Costa Gomes return 0; 271175d262c2SVinicius Costa Gomes 2712*0fe442ffSMarcel Holtmann if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 2713*0fe442ffSMarcel Holtmann persistent = 0; 2714*0fe442ffSMarcel Holtmann else 2715*0fe442ffSMarcel Holtmann persistent = 1; 2716*0fe442ffSMarcel Holtmann 271721b93b75SJohan Hedberg if (type == HCI_SMP_LTK || type == HCI_SMP_LTK_SLAVE) 2718*0fe442ffSMarcel Holtmann mgmt_new_ltk(hdev, key, persistent); 2719261cc5aaSVinicius Costa Gomes 272075d262c2SVinicius Costa Gomes return 0; 272175d262c2SVinicius Costa Gomes } 272275d262c2SVinicius Costa Gomes 272355ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 272455ed8ca1SJohan Hedberg { 272555ed8ca1SJohan Hedberg struct link_key *key; 272655ed8ca1SJohan Hedberg 272755ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 272855ed8ca1SJohan Hedberg if (!key) 272955ed8ca1SJohan Hedberg return -ENOENT; 273055ed8ca1SJohan Hedberg 27316ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 273255ed8ca1SJohan Hedberg 273355ed8ca1SJohan Hedberg list_del(&key->list); 273455ed8ca1SJohan Hedberg kfree(key); 273555ed8ca1SJohan Hedberg 273655ed8ca1SJohan Hedberg return 0; 273755ed8ca1SJohan Hedberg } 273855ed8ca1SJohan Hedberg 2739b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 2740b899efafSVinicius Costa Gomes { 2741b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2742b899efafSVinicius Costa Gomes 2743b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2744b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 2745b899efafSVinicius Costa Gomes continue; 2746b899efafSVinicius Costa Gomes 27476ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2748b899efafSVinicius Costa Gomes 2749b899efafSVinicius Costa Gomes list_del(&k->list); 2750b899efafSVinicius Costa Gomes kfree(k); 2751b899efafSVinicius Costa Gomes } 2752b899efafSVinicius Costa Gomes 2753b899efafSVinicius Costa Gomes return 0; 2754b899efafSVinicius Costa Gomes } 2755b899efafSVinicius Costa Gomes 27566bd32326SVille Tervo /* HCI command timer function */ 2757bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg) 27586bd32326SVille Tervo { 27596bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 27606bd32326SVille Tervo 2761bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2762bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2763bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2764bda4f23aSAndrei Emeltchenko 2765bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 2766bda4f23aSAndrei Emeltchenko } else { 27676bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 2768bda4f23aSAndrei Emeltchenko } 2769bda4f23aSAndrei Emeltchenko 27706bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2771c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 27726bd32326SVille Tervo } 27736bd32326SVille Tervo 27742763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 27752763eda6SSzymon Janc bdaddr_t *bdaddr) 27762763eda6SSzymon Janc { 27772763eda6SSzymon Janc struct oob_data *data; 27782763eda6SSzymon Janc 27792763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 27802763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 27812763eda6SSzymon Janc return data; 27822763eda6SSzymon Janc 27832763eda6SSzymon Janc return NULL; 27842763eda6SSzymon Janc } 27852763eda6SSzymon Janc 27862763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 27872763eda6SSzymon Janc { 27882763eda6SSzymon Janc struct oob_data *data; 27892763eda6SSzymon Janc 27902763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 27912763eda6SSzymon Janc if (!data) 27922763eda6SSzymon Janc return -ENOENT; 27932763eda6SSzymon Janc 27946ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 27952763eda6SSzymon Janc 27962763eda6SSzymon Janc list_del(&data->list); 27972763eda6SSzymon Janc kfree(data); 27982763eda6SSzymon Janc 27992763eda6SSzymon Janc return 0; 28002763eda6SSzymon Janc } 28012763eda6SSzymon Janc 28022763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 28032763eda6SSzymon Janc { 28042763eda6SSzymon Janc struct oob_data *data, *n; 28052763eda6SSzymon Janc 28062763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 28072763eda6SSzymon Janc list_del(&data->list); 28082763eda6SSzymon Janc kfree(data); 28092763eda6SSzymon Janc } 28102763eda6SSzymon Janc 28112763eda6SSzymon Janc return 0; 28122763eda6SSzymon Janc } 28132763eda6SSzymon Janc 28140798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 28150798872eSMarcel Holtmann u8 *hash, u8 *randomizer) 28162763eda6SSzymon Janc { 28172763eda6SSzymon Janc struct oob_data *data; 28182763eda6SSzymon Janc 28192763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 28202763eda6SSzymon Janc if (!data) { 28210798872eSMarcel Holtmann data = kmalloc(sizeof(*data), GFP_ATOMIC); 28222763eda6SSzymon Janc if (!data) 28232763eda6SSzymon Janc return -ENOMEM; 28242763eda6SSzymon Janc 28252763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 28262763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 28272763eda6SSzymon Janc } 28282763eda6SSzymon Janc 2829519ca9d0SMarcel Holtmann memcpy(data->hash192, hash, sizeof(data->hash192)); 2830519ca9d0SMarcel Holtmann memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192)); 28312763eda6SSzymon Janc 28320798872eSMarcel Holtmann memset(data->hash256, 0, sizeof(data->hash256)); 28330798872eSMarcel Holtmann memset(data->randomizer256, 0, sizeof(data->randomizer256)); 28340798872eSMarcel Holtmann 28350798872eSMarcel Holtmann BT_DBG("%s for %pMR", hdev->name, bdaddr); 28360798872eSMarcel Holtmann 28370798872eSMarcel Holtmann return 0; 28380798872eSMarcel Holtmann } 28390798872eSMarcel Holtmann 28400798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 28410798872eSMarcel Holtmann u8 *hash192, u8 *randomizer192, 28420798872eSMarcel Holtmann u8 *hash256, u8 *randomizer256) 28430798872eSMarcel Holtmann { 28440798872eSMarcel Holtmann struct oob_data *data; 28450798872eSMarcel Holtmann 28460798872eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, bdaddr); 28470798872eSMarcel Holtmann if (!data) { 28480798872eSMarcel Holtmann data = kmalloc(sizeof(*data), GFP_ATOMIC); 28490798872eSMarcel Holtmann if (!data) 28500798872eSMarcel Holtmann return -ENOMEM; 28510798872eSMarcel Holtmann 28520798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 28530798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 28540798872eSMarcel Holtmann } 28550798872eSMarcel Holtmann 28560798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 28570798872eSMarcel Holtmann memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192)); 28580798872eSMarcel Holtmann 28590798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 28600798872eSMarcel Holtmann memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256)); 28610798872eSMarcel Holtmann 28626ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 28632763eda6SSzymon Janc 28642763eda6SSzymon Janc return 0; 28652763eda6SSzymon Janc } 28662763eda6SSzymon Janc 2867b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 2868b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 2869b2a66aadSAntti Julku { 2870b2a66aadSAntti Julku struct bdaddr_list *b; 2871b2a66aadSAntti Julku 2872b9ee0a78SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) { 2873b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2874b2a66aadSAntti Julku return b; 2875b9ee0a78SMarcel Holtmann } 2876b2a66aadSAntti Julku 2877b2a66aadSAntti Julku return NULL; 2878b2a66aadSAntti Julku } 2879b2a66aadSAntti Julku 2880b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 2881b2a66aadSAntti Julku { 2882b2a66aadSAntti Julku struct list_head *p, *n; 2883b2a66aadSAntti Julku 2884b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 2885b9ee0a78SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 2886b2a66aadSAntti Julku 2887b2a66aadSAntti Julku list_del(p); 2888b2a66aadSAntti Julku kfree(b); 2889b2a66aadSAntti Julku } 2890b2a66aadSAntti Julku 2891b2a66aadSAntti Julku return 0; 2892b2a66aadSAntti Julku } 2893b2a66aadSAntti Julku 289488c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2895b2a66aadSAntti Julku { 2896b2a66aadSAntti Julku struct bdaddr_list *entry; 2897b2a66aadSAntti Julku 2898b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 2899b2a66aadSAntti Julku return -EBADF; 2900b2a66aadSAntti Julku 2901b9ee0a78SMarcel Holtmann if (hci_blacklist_lookup(hdev, bdaddr, type)) 29025e762444SAntti Julku return -EEXIST; 2903b2a66aadSAntti Julku 2904b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 29055e762444SAntti Julku if (!entry) 29065e762444SAntti Julku return -ENOMEM; 2907b2a66aadSAntti Julku 2908b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 2909b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 2910b2a66aadSAntti Julku 2911b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 2912b2a66aadSAntti Julku 291388c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 2914b2a66aadSAntti Julku } 2915b2a66aadSAntti Julku 291688c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2917b2a66aadSAntti Julku { 2918b2a66aadSAntti Julku struct bdaddr_list *entry; 2919b2a66aadSAntti Julku 2920b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 29215e762444SAntti Julku return hci_blacklist_clear(hdev); 2922b2a66aadSAntti Julku 2923b9ee0a78SMarcel Holtmann entry = hci_blacklist_lookup(hdev, bdaddr, type); 29241ec918ceSSzymon Janc if (!entry) 29255e762444SAntti Julku return -ENOENT; 2926b2a66aadSAntti Julku 2927b2a66aadSAntti Julku list_del(&entry->list); 2928b2a66aadSAntti Julku kfree(entry); 2929b2a66aadSAntti Julku 293088c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 2931b2a66aadSAntti Julku } 2932b2a66aadSAntti Julku 293315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 293415819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 293515819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 293615819a70SAndre Guedes { 293715819a70SAndre Guedes struct hci_conn_params *params; 293815819a70SAndre Guedes 293915819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 294015819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 294115819a70SAndre Guedes params->addr_type == addr_type) { 294215819a70SAndre Guedes return params; 294315819a70SAndre Guedes } 294415819a70SAndre Guedes } 294515819a70SAndre Guedes 294615819a70SAndre Guedes return NULL; 294715819a70SAndre Guedes } 294815819a70SAndre Guedes 294915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 295015819a70SAndre Guedes void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, 295115819a70SAndre Guedes u16 conn_min_interval, u16 conn_max_interval) 295215819a70SAndre Guedes { 295315819a70SAndre Guedes struct hci_conn_params *params; 295415819a70SAndre Guedes 295515819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 295615819a70SAndre Guedes if (params) { 295715819a70SAndre Guedes params->conn_min_interval = conn_min_interval; 295815819a70SAndre Guedes params->conn_max_interval = conn_max_interval; 295915819a70SAndre Guedes return; 296015819a70SAndre Guedes } 296115819a70SAndre Guedes 296215819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 296315819a70SAndre Guedes if (!params) { 296415819a70SAndre Guedes BT_ERR("Out of memory"); 296515819a70SAndre Guedes return; 296615819a70SAndre Guedes } 296715819a70SAndre Guedes 296815819a70SAndre Guedes bacpy(¶ms->addr, addr); 296915819a70SAndre Guedes params->addr_type = addr_type; 297015819a70SAndre Guedes params->conn_min_interval = conn_min_interval; 297115819a70SAndre Guedes params->conn_max_interval = conn_max_interval; 297215819a70SAndre Guedes 297315819a70SAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 297415819a70SAndre Guedes 297515819a70SAndre Guedes BT_DBG("addr %pMR (type %u) conn_min_interval 0x%.4x " 297615819a70SAndre Guedes "conn_max_interval 0x%.4x", addr, addr_type, conn_min_interval, 297715819a70SAndre Guedes conn_max_interval); 297815819a70SAndre Guedes } 297915819a70SAndre Guedes 298015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 298115819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 298215819a70SAndre Guedes { 298315819a70SAndre Guedes struct hci_conn_params *params; 298415819a70SAndre Guedes 298515819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 298615819a70SAndre Guedes if (!params) 298715819a70SAndre Guedes return; 298815819a70SAndre Guedes 298915819a70SAndre Guedes list_del(¶ms->list); 299015819a70SAndre Guedes kfree(params); 299115819a70SAndre Guedes 299215819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 299315819a70SAndre Guedes } 299415819a70SAndre Guedes 299515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 299615819a70SAndre Guedes void hci_conn_params_clear(struct hci_dev *hdev) 299715819a70SAndre Guedes { 299815819a70SAndre Guedes struct hci_conn_params *params, *tmp; 299915819a70SAndre Guedes 300015819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 300115819a70SAndre Guedes list_del(¶ms->list); 300215819a70SAndre Guedes kfree(params); 300315819a70SAndre Guedes } 300415819a70SAndre Guedes 300515819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 300615819a70SAndre Guedes } 300715819a70SAndre Guedes 30084c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 30097ba8b4beSAndre Guedes { 30104c87eaabSAndre Guedes if (status) { 30114c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 30127ba8b4beSAndre Guedes 30134c87eaabSAndre Guedes hci_dev_lock(hdev); 30144c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 30154c87eaabSAndre Guedes hci_dev_unlock(hdev); 30164c87eaabSAndre Guedes return; 30174c87eaabSAndre Guedes } 30187ba8b4beSAndre Guedes } 30197ba8b4beSAndre Guedes 30204c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 30217ba8b4beSAndre Guedes { 30224c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 30234c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 30244c87eaabSAndre Guedes struct hci_request req; 30254c87eaabSAndre Guedes struct hci_cp_inquiry cp; 30267ba8b4beSAndre Guedes int err; 30277ba8b4beSAndre Guedes 30284c87eaabSAndre Guedes if (status) { 30294c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 30304c87eaabSAndre Guedes return; 30317ba8b4beSAndre Guedes } 30327ba8b4beSAndre Guedes 30334c87eaabSAndre Guedes switch (hdev->discovery.type) { 30344c87eaabSAndre Guedes case DISCOV_TYPE_LE: 30354c87eaabSAndre Guedes hci_dev_lock(hdev); 30364c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 30374c87eaabSAndre Guedes hci_dev_unlock(hdev); 30384c87eaabSAndre Guedes break; 30397dbfac1dSAndre Guedes 30404c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 30414c87eaabSAndre Guedes hci_req_init(&req, hdev); 30427dbfac1dSAndre Guedes 30437dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 30444c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 30454c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 30464c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 30474c87eaabSAndre Guedes 30484c87eaabSAndre Guedes hci_dev_lock(hdev); 30494c87eaabSAndre Guedes 30504c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 30514c87eaabSAndre Guedes 30524c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 30534c87eaabSAndre Guedes if (err) { 30544c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 30554c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 30567dbfac1dSAndre Guedes } 30577dbfac1dSAndre Guedes 30584c87eaabSAndre Guedes hci_dev_unlock(hdev); 30594c87eaabSAndre Guedes break; 30604c87eaabSAndre Guedes } 30617dbfac1dSAndre Guedes } 30627dbfac1dSAndre Guedes 30637ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 30647ba8b4beSAndre Guedes { 30657ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 30667ba8b4beSAndre Guedes le_scan_disable.work); 30677ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 30684c87eaabSAndre Guedes struct hci_request req; 30694c87eaabSAndre Guedes int err; 30707ba8b4beSAndre Guedes 30717ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 30727ba8b4beSAndre Guedes 30734c87eaabSAndre Guedes hci_req_init(&req, hdev); 30747ba8b4beSAndre Guedes 30757ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 30764c87eaabSAndre Guedes cp.enable = LE_SCAN_DISABLE; 30774c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 30787ba8b4beSAndre Guedes 30794c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 30804c87eaabSAndre Guedes if (err) 30814c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 308228b75a89SAndre Guedes } 308328b75a89SAndre Guedes 30849be0dab7SDavid Herrmann /* Alloc HCI device */ 30859be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 30869be0dab7SDavid Herrmann { 30879be0dab7SDavid Herrmann struct hci_dev *hdev; 30889be0dab7SDavid Herrmann 30899be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 30909be0dab7SDavid Herrmann if (!hdev) 30919be0dab7SDavid Herrmann return NULL; 30929be0dab7SDavid Herrmann 3093b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3094b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3095b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3096b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3097b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 3098bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3099bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3100b1b813d4SDavid Herrmann 3101b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3102b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3103b1b813d4SDavid Herrmann 3104bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3105bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 31064e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = 0x0028; 31074e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = 0x0038; 3108bef64738SMarcel Holtmann 3109b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3110b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3111b1b813d4SDavid Herrmann 3112b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3113b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 3114b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3115b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3116b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3117b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 311815819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 31196b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3120b1b813d4SDavid Herrmann 3121b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3122b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3123b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3124b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3125b1b813d4SDavid Herrmann 3126b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3127b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 3128b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 3129b1b813d4SDavid Herrmann 3130b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3131b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3132b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3133b1b813d4SDavid Herrmann 3134b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 3135b1b813d4SDavid Herrmann 3136bda4f23aSAndrei Emeltchenko setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); 3137b1b813d4SDavid Herrmann 3138b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3139b1b813d4SDavid Herrmann discovery_init(hdev); 31409be0dab7SDavid Herrmann 31419be0dab7SDavid Herrmann return hdev; 31429be0dab7SDavid Herrmann } 31439be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 31449be0dab7SDavid Herrmann 31459be0dab7SDavid Herrmann /* Free HCI device */ 31469be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 31479be0dab7SDavid Herrmann { 31489be0dab7SDavid Herrmann /* will free via device release */ 31499be0dab7SDavid Herrmann put_device(&hdev->dev); 31509be0dab7SDavid Herrmann } 31519be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 31529be0dab7SDavid Herrmann 31531da177e4SLinus Torvalds /* Register HCI device */ 31541da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 31551da177e4SLinus Torvalds { 3156b1b813d4SDavid Herrmann int id, error; 31571da177e4SLinus Torvalds 3158010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 31591da177e4SLinus Torvalds return -EINVAL; 31601da177e4SLinus Torvalds 316108add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 316208add513SMat Martineau * so the index can be used as the AMP controller ID. 316308add513SMat Martineau */ 31643df92b31SSasha Levin switch (hdev->dev_type) { 31653df92b31SSasha Levin case HCI_BREDR: 31663df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 31671da177e4SLinus Torvalds break; 31683df92b31SSasha Levin case HCI_AMP: 31693df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 31703df92b31SSasha Levin break; 31713df92b31SSasha Levin default: 31723df92b31SSasha Levin return -EINVAL; 31731da177e4SLinus Torvalds } 31741da177e4SLinus Torvalds 31753df92b31SSasha Levin if (id < 0) 31763df92b31SSasha Levin return id; 31773df92b31SSasha Levin 31781da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 31791da177e4SLinus Torvalds hdev->id = id; 31802d8b3a11SAndrei Emeltchenko 31812d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 31822d8b3a11SAndrei Emeltchenko 3183d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3184d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 318533ca954dSDavid Herrmann if (!hdev->workqueue) { 318633ca954dSDavid Herrmann error = -ENOMEM; 318733ca954dSDavid Herrmann goto err; 318833ca954dSDavid Herrmann } 3189f48fd9c8SMarcel Holtmann 3190d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3191d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 31926ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 31936ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 31946ead1bbcSJohan Hedberg error = -ENOMEM; 31956ead1bbcSJohan Hedberg goto err; 31966ead1bbcSJohan Hedberg } 31976ead1bbcSJohan Hedberg 31980153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 31990153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 32000153e2ecSMarcel Holtmann 3201bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3202bdc3e0f1SMarcel Holtmann 3203bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 320433ca954dSDavid Herrmann if (error < 0) 320533ca954dSDavid Herrmann goto err_wqueue; 32061da177e4SLinus Torvalds 3207611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3208a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3209a8c5fb1aSGustavo Padovan hdev); 3210611b30f7SMarcel Holtmann if (hdev->rfkill) { 3211611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3212611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3213611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3214611b30f7SMarcel Holtmann } 3215611b30f7SMarcel Holtmann } 3216611b30f7SMarcel Holtmann 32175e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 32185e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 32195e130367SJohan Hedberg 3220a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 3221004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 3222ce2be9acSAndrei Emeltchenko 322301cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 322456f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 322556f87901SJohan Hedberg * through reading supported features during init. 322656f87901SJohan Hedberg */ 322756f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 322856f87901SJohan Hedberg } 3229ce2be9acSAndrei Emeltchenko 3230fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3231fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3232fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3233fcee3377SGustavo Padovan 32341da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 3235dc946bd8SDavid Herrmann hci_dev_hold(hdev); 32361da177e4SLinus Torvalds 323719202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3238fbe96d6fSMarcel Holtmann 32391da177e4SLinus Torvalds return id; 3240f48fd9c8SMarcel Holtmann 324133ca954dSDavid Herrmann err_wqueue: 324233ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 32436ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 324433ca954dSDavid Herrmann err: 32453df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3246f48fd9c8SMarcel Holtmann 324733ca954dSDavid Herrmann return error; 32481da177e4SLinus Torvalds } 32491da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 32501da177e4SLinus Torvalds 32511da177e4SLinus Torvalds /* Unregister HCI device */ 325259735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 32531da177e4SLinus Torvalds { 32543df92b31SSasha Levin int i, id; 3255ef222013SMarcel Holtmann 3256c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 32571da177e4SLinus Torvalds 325894324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 325994324962SJohan Hovold 32603df92b31SSasha Levin id = hdev->id; 32613df92b31SSasha Levin 3262f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 32631da177e4SLinus Torvalds list_del(&hdev->list); 3264f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 32651da177e4SLinus Torvalds 32661da177e4SLinus Torvalds hci_dev_do_close(hdev); 32671da177e4SLinus Torvalds 3268cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 3269ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 3270ef222013SMarcel Holtmann 3271b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 3272b9b5ef18SGustavo Padovan 3273ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 3274a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 327509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3276744cf19eSJohan Hedberg mgmt_index_removed(hdev); 327709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 327856e5cb86SJohan Hedberg } 3279ab81cbf9SJohan Hedberg 32802e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 32812e58ef3eSJohan Hedberg * pending list */ 32822e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 32832e58ef3eSJohan Hedberg 32841da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 32851da177e4SLinus Torvalds 3286611b30f7SMarcel Holtmann if (hdev->rfkill) { 3287611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 3288611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3289611b30f7SMarcel Holtmann } 3290611b30f7SMarcel Holtmann 3291bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 3292147e2d59SDave Young 32930153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 32940153e2ecSMarcel Holtmann 3295f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 32966ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 3297f48fd9c8SMarcel Holtmann 329809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3299e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 33002aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 330155ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 3302b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 33032763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 330415819a70SAndre Guedes hci_conn_params_clear(hdev); 330509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 3306e2e0cacbSJohan Hedberg 3307dc946bd8SDavid Herrmann hci_dev_put(hdev); 33083df92b31SSasha Levin 33093df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 33101da177e4SLinus Torvalds } 33111da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 33121da177e4SLinus Torvalds 33131da177e4SLinus Torvalds /* Suspend HCI device */ 33141da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 33151da177e4SLinus Torvalds { 33161da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 33171da177e4SLinus Torvalds return 0; 33181da177e4SLinus Torvalds } 33191da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 33201da177e4SLinus Torvalds 33211da177e4SLinus Torvalds /* Resume HCI device */ 33221da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 33231da177e4SLinus Torvalds { 33241da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 33251da177e4SLinus Torvalds return 0; 33261da177e4SLinus Torvalds } 33271da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 33281da177e4SLinus Torvalds 332976bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 3330e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 333176bca880SMarcel Holtmann { 333276bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 333376bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 333476bca880SMarcel Holtmann kfree_skb(skb); 333576bca880SMarcel Holtmann return -ENXIO; 333676bca880SMarcel Holtmann } 333776bca880SMarcel Holtmann 3338d82603c6SJorrit Schippers /* Incoming skb */ 333976bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 334076bca880SMarcel Holtmann 334176bca880SMarcel Holtmann /* Time stamp */ 334276bca880SMarcel Holtmann __net_timestamp(skb); 334376bca880SMarcel Holtmann 334476bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3345b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3346c78ae283SMarcel Holtmann 334776bca880SMarcel Holtmann return 0; 334876bca880SMarcel Holtmann } 334976bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 335076bca880SMarcel Holtmann 335133e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 33521e429f38SGustavo F. Padovan int count, __u8 index) 335333e882a5SSuraj Sumangala { 335433e882a5SSuraj Sumangala int len = 0; 335533e882a5SSuraj Sumangala int hlen = 0; 335633e882a5SSuraj Sumangala int remain = count; 335733e882a5SSuraj Sumangala struct sk_buff *skb; 335833e882a5SSuraj Sumangala struct bt_skb_cb *scb; 335933e882a5SSuraj Sumangala 336033e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 336133e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 336233e882a5SSuraj Sumangala return -EILSEQ; 336333e882a5SSuraj Sumangala 336433e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 336533e882a5SSuraj Sumangala 336633e882a5SSuraj Sumangala if (!skb) { 336733e882a5SSuraj Sumangala switch (type) { 336833e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 336933e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 337033e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 337133e882a5SSuraj Sumangala break; 337233e882a5SSuraj Sumangala case HCI_EVENT_PKT: 337333e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 337433e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 337533e882a5SSuraj Sumangala break; 337633e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 337733e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 337833e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 337933e882a5SSuraj Sumangala break; 338033e882a5SSuraj Sumangala } 338133e882a5SSuraj Sumangala 33821e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 338333e882a5SSuraj Sumangala if (!skb) 338433e882a5SSuraj Sumangala return -ENOMEM; 338533e882a5SSuraj Sumangala 338633e882a5SSuraj Sumangala scb = (void *) skb->cb; 338733e882a5SSuraj Sumangala scb->expect = hlen; 338833e882a5SSuraj Sumangala scb->pkt_type = type; 338933e882a5SSuraj Sumangala 339033e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 339133e882a5SSuraj Sumangala } 339233e882a5SSuraj Sumangala 339333e882a5SSuraj Sumangala while (count) { 339433e882a5SSuraj Sumangala scb = (void *) skb->cb; 339589bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 339633e882a5SSuraj Sumangala 339733e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 339833e882a5SSuraj Sumangala 339933e882a5SSuraj Sumangala count -= len; 340033e882a5SSuraj Sumangala data += len; 340133e882a5SSuraj Sumangala scb->expect -= len; 340233e882a5SSuraj Sumangala remain = count; 340333e882a5SSuraj Sumangala 340433e882a5SSuraj Sumangala switch (type) { 340533e882a5SSuraj Sumangala case HCI_EVENT_PKT: 340633e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 340733e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 340833e882a5SSuraj Sumangala scb->expect = h->plen; 340933e882a5SSuraj Sumangala 341033e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 341133e882a5SSuraj Sumangala kfree_skb(skb); 341233e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 341333e882a5SSuraj Sumangala return -ENOMEM; 341433e882a5SSuraj Sumangala } 341533e882a5SSuraj Sumangala } 341633e882a5SSuraj Sumangala break; 341733e882a5SSuraj Sumangala 341833e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 341933e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 342033e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 342133e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 342233e882a5SSuraj Sumangala 342333e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 342433e882a5SSuraj Sumangala kfree_skb(skb); 342533e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 342633e882a5SSuraj Sumangala return -ENOMEM; 342733e882a5SSuraj Sumangala } 342833e882a5SSuraj Sumangala } 342933e882a5SSuraj Sumangala break; 343033e882a5SSuraj Sumangala 343133e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 343233e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 343333e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 343433e882a5SSuraj Sumangala scb->expect = h->dlen; 343533e882a5SSuraj Sumangala 343633e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 343733e882a5SSuraj Sumangala kfree_skb(skb); 343833e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 343933e882a5SSuraj Sumangala return -ENOMEM; 344033e882a5SSuraj Sumangala } 344133e882a5SSuraj Sumangala } 344233e882a5SSuraj Sumangala break; 344333e882a5SSuraj Sumangala } 344433e882a5SSuraj Sumangala 344533e882a5SSuraj Sumangala if (scb->expect == 0) { 344633e882a5SSuraj Sumangala /* Complete frame */ 344733e882a5SSuraj Sumangala 344833e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 3449e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 345033e882a5SSuraj Sumangala 345133e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 345233e882a5SSuraj Sumangala return remain; 345333e882a5SSuraj Sumangala } 345433e882a5SSuraj Sumangala } 345533e882a5SSuraj Sumangala 345633e882a5SSuraj Sumangala return remain; 345733e882a5SSuraj Sumangala } 345833e882a5SSuraj Sumangala 3459ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 3460ef222013SMarcel Holtmann { 3461f39a3c06SSuraj Sumangala int rem = 0; 3462f39a3c06SSuraj Sumangala 3463ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 3464ef222013SMarcel Holtmann return -EILSEQ; 3465ef222013SMarcel Holtmann 3466da5f6c37SGustavo F. Padovan while (count) { 34671e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 3468f39a3c06SSuraj Sumangala if (rem < 0) 3469f39a3c06SSuraj Sumangala return rem; 3470ef222013SMarcel Holtmann 3471f39a3c06SSuraj Sumangala data += (count - rem); 3472f39a3c06SSuraj Sumangala count = rem; 3473f81c6224SJoe Perches } 3474ef222013SMarcel Holtmann 3475f39a3c06SSuraj Sumangala return rem; 3476ef222013SMarcel Holtmann } 3477ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 3478ef222013SMarcel Holtmann 347999811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 348099811510SSuraj Sumangala 348199811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 348299811510SSuraj Sumangala { 348399811510SSuraj Sumangala int type; 348499811510SSuraj Sumangala int rem = 0; 348599811510SSuraj Sumangala 3486da5f6c37SGustavo F. Padovan while (count) { 348799811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 348899811510SSuraj Sumangala 348999811510SSuraj Sumangala if (!skb) { 349099811510SSuraj Sumangala struct { char type; } *pkt; 349199811510SSuraj Sumangala 349299811510SSuraj Sumangala /* Start of the frame */ 349399811510SSuraj Sumangala pkt = data; 349499811510SSuraj Sumangala type = pkt->type; 349599811510SSuraj Sumangala 349699811510SSuraj Sumangala data++; 349799811510SSuraj Sumangala count--; 349899811510SSuraj Sumangala } else 349999811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 350099811510SSuraj Sumangala 35011e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 35021e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 350399811510SSuraj Sumangala if (rem < 0) 350499811510SSuraj Sumangala return rem; 350599811510SSuraj Sumangala 350699811510SSuraj Sumangala data += (count - rem); 350799811510SSuraj Sumangala count = rem; 3508f81c6224SJoe Perches } 350999811510SSuraj Sumangala 351099811510SSuraj Sumangala return rem; 351199811510SSuraj Sumangala } 351299811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 351399811510SSuraj Sumangala 35141da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 35151da177e4SLinus Torvalds 35161da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 35171da177e4SLinus Torvalds { 35181da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 35191da177e4SLinus Torvalds 3520f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 35211da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 3522f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 35231da177e4SLinus Torvalds 35241da177e4SLinus Torvalds return 0; 35251da177e4SLinus Torvalds } 35261da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 35271da177e4SLinus Torvalds 35281da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 35291da177e4SLinus Torvalds { 35301da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 35311da177e4SLinus Torvalds 3532f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 35331da177e4SLinus Torvalds list_del(&cb->list); 3534f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 35351da177e4SLinus Torvalds 35361da177e4SLinus Torvalds return 0; 35371da177e4SLinus Torvalds } 35381da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 35391da177e4SLinus Torvalds 354051086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 35411da177e4SLinus Torvalds { 35420d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 35431da177e4SLinus Torvalds 35441da177e4SLinus Torvalds /* Time stamp */ 3545a61bbcf2SPatrick McHardy __net_timestamp(skb); 35461da177e4SLinus Torvalds 3547cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3548cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3549cd82e61cSMarcel Holtmann 3550cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3551cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3552470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 35531da177e4SLinus Torvalds } 35541da177e4SLinus Torvalds 35551da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 35561da177e4SLinus Torvalds skb_orphan(skb); 35571da177e4SLinus Torvalds 35587bd8f09fSMarcel Holtmann if (hdev->send(hdev, skb) < 0) 355951086991SMarcel Holtmann BT_ERR("%s sending frame failed", hdev->name); 35601da177e4SLinus Torvalds } 35611da177e4SLinus Torvalds 35623119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 35633119ae95SJohan Hedberg { 35643119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 35653119ae95SJohan Hedberg req->hdev = hdev; 35665d73e034SAndre Guedes req->err = 0; 35673119ae95SJohan Hedberg } 35683119ae95SJohan Hedberg 35693119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 35703119ae95SJohan Hedberg { 35713119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 35723119ae95SJohan Hedberg struct sk_buff *skb; 35733119ae95SJohan Hedberg unsigned long flags; 35743119ae95SJohan Hedberg 35753119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 35763119ae95SJohan Hedberg 35775d73e034SAndre Guedes /* If an error occured during request building, remove all HCI 35785d73e034SAndre Guedes * commands queued on the HCI request queue. 35795d73e034SAndre Guedes */ 35805d73e034SAndre Guedes if (req->err) { 35815d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 35825d73e034SAndre Guedes return req->err; 35835d73e034SAndre Guedes } 35845d73e034SAndre Guedes 35853119ae95SJohan Hedberg /* Do not allow empty requests */ 35863119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 3587382b0c39SAndre Guedes return -ENODATA; 35883119ae95SJohan Hedberg 35893119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 35903119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 35913119ae95SJohan Hedberg 35923119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 35933119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 35943119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 35953119ae95SJohan Hedberg 35963119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 35973119ae95SJohan Hedberg 35983119ae95SJohan Hedberg return 0; 35993119ae95SJohan Hedberg } 36003119ae95SJohan Hedberg 36011ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 360207dc93ddSJohan Hedberg u32 plen, const void *param) 36031da177e4SLinus Torvalds { 36041da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 36051da177e4SLinus Torvalds struct hci_command_hdr *hdr; 36061da177e4SLinus Torvalds struct sk_buff *skb; 36071da177e4SLinus Torvalds 36081da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 36091ca3a9d0SJohan Hedberg if (!skb) 36101ca3a9d0SJohan Hedberg return NULL; 36111da177e4SLinus Torvalds 36121da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 3613a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 36141da177e4SLinus Torvalds hdr->plen = plen; 36151da177e4SLinus Torvalds 36161da177e4SLinus Torvalds if (plen) 36171da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 36181da177e4SLinus Torvalds 36191da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 36201da177e4SLinus Torvalds 36210d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 3622c78ae283SMarcel Holtmann 36231ca3a9d0SJohan Hedberg return skb; 36241ca3a9d0SJohan Hedberg } 36251ca3a9d0SJohan Hedberg 36261ca3a9d0SJohan Hedberg /* Send HCI command */ 362707dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 362807dc93ddSJohan Hedberg const void *param) 36291ca3a9d0SJohan Hedberg { 36301ca3a9d0SJohan Hedberg struct sk_buff *skb; 36311ca3a9d0SJohan Hedberg 36321ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 36331ca3a9d0SJohan Hedberg 36341ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 36351ca3a9d0SJohan Hedberg if (!skb) { 36361ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 36371ca3a9d0SJohan Hedberg return -ENOMEM; 36381ca3a9d0SJohan Hedberg } 36391ca3a9d0SJohan Hedberg 364011714b3dSJohan Hedberg /* Stand-alone HCI commands must be flaged as 364111714b3dSJohan Hedberg * single-command requests. 364211714b3dSJohan Hedberg */ 364311714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 364411714b3dSJohan Hedberg 36451da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3646c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 36471da177e4SLinus Torvalds 36481da177e4SLinus Torvalds return 0; 36491da177e4SLinus Torvalds } 36501da177e4SLinus Torvalds 365171c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 365207dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 365307dc93ddSJohan Hedberg const void *param, u8 event) 365471c76a17SJohan Hedberg { 365571c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 365671c76a17SJohan Hedberg struct sk_buff *skb; 365771c76a17SJohan Hedberg 365871c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 365971c76a17SJohan Hedberg 366034739c1eSAndre Guedes /* If an error occured during request building, there is no point in 366134739c1eSAndre Guedes * queueing the HCI command. We can simply return. 366234739c1eSAndre Guedes */ 366334739c1eSAndre Guedes if (req->err) 366434739c1eSAndre Guedes return; 366534739c1eSAndre Guedes 366671c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 366771c76a17SJohan Hedberg if (!skb) { 36685d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 36695d73e034SAndre Guedes hdev->name, opcode); 36705d73e034SAndre Guedes req->err = -ENOMEM; 3671e348fe6bSAndre Guedes return; 367271c76a17SJohan Hedberg } 367371c76a17SJohan Hedberg 367471c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 367571c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 367671c76a17SJohan Hedberg 367702350a72SJohan Hedberg bt_cb(skb)->req.event = event; 367802350a72SJohan Hedberg 367971c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 368071c76a17SJohan Hedberg } 368171c76a17SJohan Hedberg 368207dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 368307dc93ddSJohan Hedberg const void *param) 368402350a72SJohan Hedberg { 368502350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 368602350a72SJohan Hedberg } 368702350a72SJohan Hedberg 36881da177e4SLinus Torvalds /* Get data from the previously sent command */ 3689a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 36901da177e4SLinus Torvalds { 36911da177e4SLinus Torvalds struct hci_command_hdr *hdr; 36921da177e4SLinus Torvalds 36931da177e4SLinus Torvalds if (!hdev->sent_cmd) 36941da177e4SLinus Torvalds return NULL; 36951da177e4SLinus Torvalds 36961da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 36971da177e4SLinus Torvalds 3698a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 36991da177e4SLinus Torvalds return NULL; 37001da177e4SLinus Torvalds 3701f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 37021da177e4SLinus Torvalds 37031da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 37041da177e4SLinus Torvalds } 37051da177e4SLinus Torvalds 37061da177e4SLinus Torvalds /* Send ACL data */ 37071da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 37081da177e4SLinus Torvalds { 37091da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 37101da177e4SLinus Torvalds int len = skb->len; 37111da177e4SLinus Torvalds 3712badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3713badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 37149c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3715aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3716aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 37171da177e4SLinus Torvalds } 37181da177e4SLinus Torvalds 3719ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 372073d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 37211da177e4SLinus Torvalds { 3722ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 37231da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 37241da177e4SLinus Torvalds struct sk_buff *list; 37251da177e4SLinus Torvalds 3726087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3727087bfd99SGustavo Padovan skb->data_len = 0; 3728087bfd99SGustavo Padovan 3729087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3730204a6e54SAndrei Emeltchenko 3731204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3732204a6e54SAndrei Emeltchenko case HCI_BREDR: 3733087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3734204a6e54SAndrei Emeltchenko break; 3735204a6e54SAndrei Emeltchenko case HCI_AMP: 3736204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3737204a6e54SAndrei Emeltchenko break; 3738204a6e54SAndrei Emeltchenko default: 3739204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 3740204a6e54SAndrei Emeltchenko return; 3741204a6e54SAndrei Emeltchenko } 3742087bfd99SGustavo Padovan 374370f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 374470f23020SAndrei Emeltchenko if (!list) { 37451da177e4SLinus Torvalds /* Non fragmented */ 37461da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 37471da177e4SLinus Torvalds 374873d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 37491da177e4SLinus Torvalds } else { 37501da177e4SLinus Torvalds /* Fragmented */ 37511da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 37521da177e4SLinus Torvalds 37531da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 37541da177e4SLinus Torvalds 37551da177e4SLinus Torvalds /* Queue all fragments atomically */ 3756af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 37571da177e4SLinus Torvalds 375873d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3759e702112fSAndrei Emeltchenko 3760e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3761e702112fSAndrei Emeltchenko flags |= ACL_CONT; 37621da177e4SLinus Torvalds do { 37631da177e4SLinus Torvalds skb = list; list = list->next; 37641da177e4SLinus Torvalds 37650d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3766e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 37671da177e4SLinus Torvalds 37681da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 37691da177e4SLinus Torvalds 377073d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 37711da177e4SLinus Torvalds } while (list); 37721da177e4SLinus Torvalds 3773af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 37741da177e4SLinus Torvalds } 377573d80debSLuiz Augusto von Dentz } 377673d80debSLuiz Augusto von Dentz 377773d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 377873d80debSLuiz Augusto von Dentz { 3779ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 378073d80debSLuiz Augusto von Dentz 3781f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 378273d80debSLuiz Augusto von Dentz 3783ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 37841da177e4SLinus Torvalds 37853eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 37861da177e4SLinus Torvalds } 37871da177e4SLinus Torvalds 37881da177e4SLinus Torvalds /* Send SCO data */ 37890d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 37901da177e4SLinus Torvalds { 37911da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 37921da177e4SLinus Torvalds struct hci_sco_hdr hdr; 37931da177e4SLinus Torvalds 37941da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 37951da177e4SLinus Torvalds 3796aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 37971da177e4SLinus Torvalds hdr.dlen = skb->len; 37981da177e4SLinus Torvalds 3799badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 3800badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 38019c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 38021da177e4SLinus Torvalds 38030d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 3804c78ae283SMarcel Holtmann 38051da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 38063eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 38071da177e4SLinus Torvalds } 38081da177e4SLinus Torvalds 38091da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 38101da177e4SLinus Torvalds 38111da177e4SLinus Torvalds /* HCI Connection scheduler */ 38126039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 3813a8c5fb1aSGustavo Padovan int *quote) 38141da177e4SLinus Torvalds { 38151da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 38168035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 3817abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 38181da177e4SLinus Torvalds 38191da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 38201da177e4SLinus Torvalds * added and removed with TX task disabled. */ 3821bf4c6325SGustavo F. Padovan 3822bf4c6325SGustavo F. Padovan rcu_read_lock(); 3823bf4c6325SGustavo F. Padovan 3824bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3825769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 38261da177e4SLinus Torvalds continue; 3827769be974SMarcel Holtmann 3828769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 3829769be974SMarcel Holtmann continue; 3830769be974SMarcel Holtmann 38311da177e4SLinus Torvalds num++; 38321da177e4SLinus Torvalds 38331da177e4SLinus Torvalds if (c->sent < min) { 38341da177e4SLinus Torvalds min = c->sent; 38351da177e4SLinus Torvalds conn = c; 38361da177e4SLinus Torvalds } 383752087a79SLuiz Augusto von Dentz 383852087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 383952087a79SLuiz Augusto von Dentz break; 38401da177e4SLinus Torvalds } 38411da177e4SLinus Torvalds 3842bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3843bf4c6325SGustavo F. Padovan 38441da177e4SLinus Torvalds if (conn) { 38456ed58ec5SVille Tervo int cnt, q; 38466ed58ec5SVille Tervo 38476ed58ec5SVille Tervo switch (conn->type) { 38486ed58ec5SVille Tervo case ACL_LINK: 38496ed58ec5SVille Tervo cnt = hdev->acl_cnt; 38506ed58ec5SVille Tervo break; 38516ed58ec5SVille Tervo case SCO_LINK: 38526ed58ec5SVille Tervo case ESCO_LINK: 38536ed58ec5SVille Tervo cnt = hdev->sco_cnt; 38546ed58ec5SVille Tervo break; 38556ed58ec5SVille Tervo case LE_LINK: 38566ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 38576ed58ec5SVille Tervo break; 38586ed58ec5SVille Tervo default: 38596ed58ec5SVille Tervo cnt = 0; 38606ed58ec5SVille Tervo BT_ERR("Unknown link type"); 38616ed58ec5SVille Tervo } 38626ed58ec5SVille Tervo 38636ed58ec5SVille Tervo q = cnt / num; 38641da177e4SLinus Torvalds *quote = q ? q : 1; 38651da177e4SLinus Torvalds } else 38661da177e4SLinus Torvalds *quote = 0; 38671da177e4SLinus Torvalds 38681da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 38691da177e4SLinus Torvalds return conn; 38701da177e4SLinus Torvalds } 38711da177e4SLinus Torvalds 38726039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 38731da177e4SLinus Torvalds { 38741da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 38751da177e4SLinus Torvalds struct hci_conn *c; 38761da177e4SLinus Torvalds 3877bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 38781da177e4SLinus Torvalds 3879bf4c6325SGustavo F. Padovan rcu_read_lock(); 3880bf4c6325SGustavo F. Padovan 38811da177e4SLinus Torvalds /* Kill stalled connections */ 3882bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3883bae1f5d9SVille Tervo if (c->type == type && c->sent) { 38846ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 38856ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 3886bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 38871da177e4SLinus Torvalds } 38881da177e4SLinus Torvalds } 3889bf4c6325SGustavo F. Padovan 3890bf4c6325SGustavo F. Padovan rcu_read_unlock(); 38911da177e4SLinus Torvalds } 38921da177e4SLinus Torvalds 38936039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 389473d80debSLuiz Augusto von Dentz int *quote) 389573d80debSLuiz Augusto von Dentz { 389673d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 389773d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 3898abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 389973d80debSLuiz Augusto von Dentz struct hci_conn *conn; 390073d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 390173d80debSLuiz Augusto von Dentz 390273d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 390373d80debSLuiz Augusto von Dentz 3904bf4c6325SGustavo F. Padovan rcu_read_lock(); 3905bf4c6325SGustavo F. Padovan 3906bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 390773d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 390873d80debSLuiz Augusto von Dentz 390973d80debSLuiz Augusto von Dentz if (conn->type != type) 391073d80debSLuiz Augusto von Dentz continue; 391173d80debSLuiz Augusto von Dentz 391273d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 391373d80debSLuiz Augusto von Dentz continue; 391473d80debSLuiz Augusto von Dentz 391573d80debSLuiz Augusto von Dentz conn_num++; 391673d80debSLuiz Augusto von Dentz 39178192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 391873d80debSLuiz Augusto von Dentz struct sk_buff *skb; 391973d80debSLuiz Augusto von Dentz 392073d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 392173d80debSLuiz Augusto von Dentz continue; 392273d80debSLuiz Augusto von Dentz 392373d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 392473d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 392573d80debSLuiz Augusto von Dentz continue; 392673d80debSLuiz Augusto von Dentz 392773d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 392873d80debSLuiz Augusto von Dentz num = 0; 392973d80debSLuiz Augusto von Dentz min = ~0; 393073d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 393173d80debSLuiz Augusto von Dentz } 393273d80debSLuiz Augusto von Dentz 393373d80debSLuiz Augusto von Dentz num++; 393473d80debSLuiz Augusto von Dentz 393573d80debSLuiz Augusto von Dentz if (conn->sent < min) { 393673d80debSLuiz Augusto von Dentz min = conn->sent; 393773d80debSLuiz Augusto von Dentz chan = tmp; 393873d80debSLuiz Augusto von Dentz } 393973d80debSLuiz Augusto von Dentz } 394073d80debSLuiz Augusto von Dentz 394173d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 394273d80debSLuiz Augusto von Dentz break; 394373d80debSLuiz Augusto von Dentz } 394473d80debSLuiz Augusto von Dentz 3945bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3946bf4c6325SGustavo F. Padovan 394773d80debSLuiz Augusto von Dentz if (!chan) 394873d80debSLuiz Augusto von Dentz return NULL; 394973d80debSLuiz Augusto von Dentz 395073d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 395173d80debSLuiz Augusto von Dentz case ACL_LINK: 395273d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 395373d80debSLuiz Augusto von Dentz break; 3954bd1eb66bSAndrei Emeltchenko case AMP_LINK: 3955bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 3956bd1eb66bSAndrei Emeltchenko break; 395773d80debSLuiz Augusto von Dentz case SCO_LINK: 395873d80debSLuiz Augusto von Dentz case ESCO_LINK: 395973d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 396073d80debSLuiz Augusto von Dentz break; 396173d80debSLuiz Augusto von Dentz case LE_LINK: 396273d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 396373d80debSLuiz Augusto von Dentz break; 396473d80debSLuiz Augusto von Dentz default: 396573d80debSLuiz Augusto von Dentz cnt = 0; 396673d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 396773d80debSLuiz Augusto von Dentz } 396873d80debSLuiz Augusto von Dentz 396973d80debSLuiz Augusto von Dentz q = cnt / num; 397073d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 397173d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 397273d80debSLuiz Augusto von Dentz return chan; 397373d80debSLuiz Augusto von Dentz } 397473d80debSLuiz Augusto von Dentz 397502b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 397602b20f0bSLuiz Augusto von Dentz { 397702b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 397802b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 397902b20f0bSLuiz Augusto von Dentz int num = 0; 398002b20f0bSLuiz Augusto von Dentz 398102b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 398202b20f0bSLuiz Augusto von Dentz 3983bf4c6325SGustavo F. Padovan rcu_read_lock(); 3984bf4c6325SGustavo F. Padovan 3985bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 398602b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 398702b20f0bSLuiz Augusto von Dentz 398802b20f0bSLuiz Augusto von Dentz if (conn->type != type) 398902b20f0bSLuiz Augusto von Dentz continue; 399002b20f0bSLuiz Augusto von Dentz 399102b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 399202b20f0bSLuiz Augusto von Dentz continue; 399302b20f0bSLuiz Augusto von Dentz 399402b20f0bSLuiz Augusto von Dentz num++; 399502b20f0bSLuiz Augusto von Dentz 39968192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 399702b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 399802b20f0bSLuiz Augusto von Dentz 399902b20f0bSLuiz Augusto von Dentz if (chan->sent) { 400002b20f0bSLuiz Augusto von Dentz chan->sent = 0; 400102b20f0bSLuiz Augusto von Dentz continue; 400202b20f0bSLuiz Augusto von Dentz } 400302b20f0bSLuiz Augusto von Dentz 400402b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 400502b20f0bSLuiz Augusto von Dentz continue; 400602b20f0bSLuiz Augusto von Dentz 400702b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 400802b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 400902b20f0bSLuiz Augusto von Dentz continue; 401002b20f0bSLuiz Augusto von Dentz 401102b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 401202b20f0bSLuiz Augusto von Dentz 401302b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 401402b20f0bSLuiz Augusto von Dentz skb->priority); 401502b20f0bSLuiz Augusto von Dentz } 401602b20f0bSLuiz Augusto von Dentz 401702b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 401802b20f0bSLuiz Augusto von Dentz break; 401902b20f0bSLuiz Augusto von Dentz } 4020bf4c6325SGustavo F. Padovan 4021bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4022bf4c6325SGustavo F. Padovan 402302b20f0bSLuiz Augusto von Dentz } 402402b20f0bSLuiz Augusto von Dentz 4025b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4026b71d385aSAndrei Emeltchenko { 4027b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4028b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4029b71d385aSAndrei Emeltchenko } 4030b71d385aSAndrei Emeltchenko 40316039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 40321da177e4SLinus Torvalds { 40331da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 40341da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 40351da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 403663d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 40375f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 4038bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 40391da177e4SLinus Torvalds } 404063d2bc1bSAndrei Emeltchenko } 40411da177e4SLinus Torvalds 40426039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 404363d2bc1bSAndrei Emeltchenko { 404463d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 404563d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 404663d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 404763d2bc1bSAndrei Emeltchenko int quote; 404863d2bc1bSAndrei Emeltchenko 404963d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 405004837f64SMarcel Holtmann 405173d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 405273d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 4053ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4054ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 405573d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 405673d80debSLuiz Augusto von Dentz skb->len, skb->priority); 405773d80debSLuiz Augusto von Dentz 4058ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4059ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4060ec1cce24SLuiz Augusto von Dentz break; 4061ec1cce24SLuiz Augusto von Dentz 4062ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4063ec1cce24SLuiz Augusto von Dentz 406473d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 406573d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 406604837f64SMarcel Holtmann 406757d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 40681da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 40691da177e4SLinus Torvalds 40701da177e4SLinus Torvalds hdev->acl_cnt--; 407173d80debSLuiz Augusto von Dentz chan->sent++; 407273d80debSLuiz Augusto von Dentz chan->conn->sent++; 40731da177e4SLinus Torvalds } 40741da177e4SLinus Torvalds } 407502b20f0bSLuiz Augusto von Dentz 407602b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 407702b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 40781da177e4SLinus Torvalds } 40791da177e4SLinus Torvalds 40806039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4081b71d385aSAndrei Emeltchenko { 408263d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4083b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4084b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4085b71d385aSAndrei Emeltchenko int quote; 4086bd1eb66bSAndrei Emeltchenko u8 type; 4087b71d385aSAndrei Emeltchenko 408863d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4089b71d385aSAndrei Emeltchenko 4090bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4091bd1eb66bSAndrei Emeltchenko 4092bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4093bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4094bd1eb66bSAndrei Emeltchenko else 4095bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4096bd1eb66bSAndrei Emeltchenko 4097b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4098bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4099b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4100b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4101b71d385aSAndrei Emeltchenko int blocks; 4102b71d385aSAndrei Emeltchenko 4103b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4104b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4105b71d385aSAndrei Emeltchenko 4106b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4107b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4108b71d385aSAndrei Emeltchenko break; 4109b71d385aSAndrei Emeltchenko 4110b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4111b71d385aSAndrei Emeltchenko 4112b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4113b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4114b71d385aSAndrei Emeltchenko return; 4115b71d385aSAndrei Emeltchenko 4116b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4117b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4118b71d385aSAndrei Emeltchenko 411957d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4120b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4121b71d385aSAndrei Emeltchenko 4122b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4123b71d385aSAndrei Emeltchenko quote -= blocks; 4124b71d385aSAndrei Emeltchenko 4125b71d385aSAndrei Emeltchenko chan->sent += blocks; 4126b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4127b71d385aSAndrei Emeltchenko } 4128b71d385aSAndrei Emeltchenko } 4129b71d385aSAndrei Emeltchenko 4130b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4131bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4132b71d385aSAndrei Emeltchenko } 4133b71d385aSAndrei Emeltchenko 41346039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4135b71d385aSAndrei Emeltchenko { 4136b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4137b71d385aSAndrei Emeltchenko 4138bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4139bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 4140bd1eb66bSAndrei Emeltchenko return; 4141bd1eb66bSAndrei Emeltchenko 4142bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4143bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4144b71d385aSAndrei Emeltchenko return; 4145b71d385aSAndrei Emeltchenko 4146b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4147b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4148b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4149b71d385aSAndrei Emeltchenko break; 4150b71d385aSAndrei Emeltchenko 4151b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4152b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4153b71d385aSAndrei Emeltchenko break; 4154b71d385aSAndrei Emeltchenko } 4155b71d385aSAndrei Emeltchenko } 4156b71d385aSAndrei Emeltchenko 41571da177e4SLinus Torvalds /* Schedule SCO */ 41586039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 41591da177e4SLinus Torvalds { 41601da177e4SLinus Torvalds struct hci_conn *conn; 41611da177e4SLinus Torvalds struct sk_buff *skb; 41621da177e4SLinus Torvalds int quote; 41631da177e4SLinus Torvalds 41641da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 41651da177e4SLinus Torvalds 416652087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 416752087a79SLuiz Augusto von Dentz return; 416852087a79SLuiz Augusto von Dentz 41691da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 41701da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 41711da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 417257d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 41731da177e4SLinus Torvalds 41741da177e4SLinus Torvalds conn->sent++; 41751da177e4SLinus Torvalds if (conn->sent == ~0) 41761da177e4SLinus Torvalds conn->sent = 0; 41771da177e4SLinus Torvalds } 41781da177e4SLinus Torvalds } 41791da177e4SLinus Torvalds } 41801da177e4SLinus Torvalds 41816039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 4182b6a0dc82SMarcel Holtmann { 4183b6a0dc82SMarcel Holtmann struct hci_conn *conn; 4184b6a0dc82SMarcel Holtmann struct sk_buff *skb; 4185b6a0dc82SMarcel Holtmann int quote; 4186b6a0dc82SMarcel Holtmann 4187b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 4188b6a0dc82SMarcel Holtmann 418952087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 419052087a79SLuiz Augusto von Dentz return; 419152087a79SLuiz Augusto von Dentz 41928fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 41938fc9ced3SGustavo Padovan "e))) { 4194b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 4195b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 419657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4197b6a0dc82SMarcel Holtmann 4198b6a0dc82SMarcel Holtmann conn->sent++; 4199b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 4200b6a0dc82SMarcel Holtmann conn->sent = 0; 4201b6a0dc82SMarcel Holtmann } 4202b6a0dc82SMarcel Holtmann } 4203b6a0dc82SMarcel Holtmann } 4204b6a0dc82SMarcel Holtmann 42056039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 42066ed58ec5SVille Tervo { 420773d80debSLuiz Augusto von Dentz struct hci_chan *chan; 42086ed58ec5SVille Tervo struct sk_buff *skb; 420902b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 42106ed58ec5SVille Tervo 42116ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 42126ed58ec5SVille Tervo 421352087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 421452087a79SLuiz Augusto von Dentz return; 421552087a79SLuiz Augusto von Dentz 42166ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 42176ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 42186ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 4219bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 42206ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 4221bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 42226ed58ec5SVille Tervo } 42236ed58ec5SVille Tervo 42246ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 422502b20f0bSLuiz Augusto von Dentz tmp = cnt; 422673d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 4227ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4228ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 422973d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 423073d80debSLuiz Augusto von Dentz skb->len, skb->priority); 42316ed58ec5SVille Tervo 4232ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4233ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4234ec1cce24SLuiz Augusto von Dentz break; 4235ec1cce24SLuiz Augusto von Dentz 4236ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4237ec1cce24SLuiz Augusto von Dentz 423857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 42396ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 42406ed58ec5SVille Tervo 42416ed58ec5SVille Tervo cnt--; 424273d80debSLuiz Augusto von Dentz chan->sent++; 424373d80debSLuiz Augusto von Dentz chan->conn->sent++; 42446ed58ec5SVille Tervo } 42456ed58ec5SVille Tervo } 424673d80debSLuiz Augusto von Dentz 42476ed58ec5SVille Tervo if (hdev->le_pkts) 42486ed58ec5SVille Tervo hdev->le_cnt = cnt; 42496ed58ec5SVille Tervo else 42506ed58ec5SVille Tervo hdev->acl_cnt = cnt; 425102b20f0bSLuiz Augusto von Dentz 425202b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 425302b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 42546ed58ec5SVille Tervo } 42556ed58ec5SVille Tervo 42563eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 42571da177e4SLinus Torvalds { 42583eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 42591da177e4SLinus Torvalds struct sk_buff *skb; 42601da177e4SLinus Torvalds 42616ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 42626ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 42631da177e4SLinus Torvalds 426452de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 42651da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 42661da177e4SLinus Torvalds hci_sched_acl(hdev); 42671da177e4SLinus Torvalds hci_sched_sco(hdev); 4268b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 42696ed58ec5SVille Tervo hci_sched_le(hdev); 427052de599eSMarcel Holtmann } 42716ed58ec5SVille Tervo 42721da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 42731da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 427457d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 42751da177e4SLinus Torvalds } 42761da177e4SLinus Torvalds 427725985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 42781da177e4SLinus Torvalds 42791da177e4SLinus Torvalds /* ACL data packet */ 42806039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 42811da177e4SLinus Torvalds { 42821da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 42831da177e4SLinus Torvalds struct hci_conn *conn; 42841da177e4SLinus Torvalds __u16 handle, flags; 42851da177e4SLinus Torvalds 42861da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 42871da177e4SLinus Torvalds 42881da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 42891da177e4SLinus Torvalds flags = hci_flags(handle); 42901da177e4SLinus Torvalds handle = hci_handle(handle); 42911da177e4SLinus Torvalds 4292f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4293a8c5fb1aSGustavo Padovan handle, flags); 42941da177e4SLinus Torvalds 42951da177e4SLinus Torvalds hdev->stat.acl_rx++; 42961da177e4SLinus Torvalds 42971da177e4SLinus Torvalds hci_dev_lock(hdev); 42981da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 42991da177e4SLinus Torvalds hci_dev_unlock(hdev); 43001da177e4SLinus Torvalds 43011da177e4SLinus Torvalds if (conn) { 430265983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 430304837f64SMarcel Holtmann 43041da177e4SLinus Torvalds /* Send to upper protocol */ 4305686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 43061da177e4SLinus Torvalds return; 43071da177e4SLinus Torvalds } else { 43081da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 43091da177e4SLinus Torvalds hdev->name, handle); 43101da177e4SLinus Torvalds } 43111da177e4SLinus Torvalds 43121da177e4SLinus Torvalds kfree_skb(skb); 43131da177e4SLinus Torvalds } 43141da177e4SLinus Torvalds 43151da177e4SLinus Torvalds /* SCO data packet */ 43166039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 43171da177e4SLinus Torvalds { 43181da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 43191da177e4SLinus Torvalds struct hci_conn *conn; 43201da177e4SLinus Torvalds __u16 handle; 43211da177e4SLinus Torvalds 43221da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 43231da177e4SLinus Torvalds 43241da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 43251da177e4SLinus Torvalds 4326f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 43271da177e4SLinus Torvalds 43281da177e4SLinus Torvalds hdev->stat.sco_rx++; 43291da177e4SLinus Torvalds 43301da177e4SLinus Torvalds hci_dev_lock(hdev); 43311da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 43321da177e4SLinus Torvalds hci_dev_unlock(hdev); 43331da177e4SLinus Torvalds 43341da177e4SLinus Torvalds if (conn) { 43351da177e4SLinus Torvalds /* Send to upper protocol */ 4336686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 43371da177e4SLinus Torvalds return; 43381da177e4SLinus Torvalds } else { 43391da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 43401da177e4SLinus Torvalds hdev->name, handle); 43411da177e4SLinus Torvalds } 43421da177e4SLinus Torvalds 43431da177e4SLinus Torvalds kfree_skb(skb); 43441da177e4SLinus Torvalds } 43451da177e4SLinus Torvalds 43469238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 43479238f36aSJohan Hedberg { 43489238f36aSJohan Hedberg struct sk_buff *skb; 43499238f36aSJohan Hedberg 43509238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 43519238f36aSJohan Hedberg if (!skb) 43529238f36aSJohan Hedberg return true; 43539238f36aSJohan Hedberg 43549238f36aSJohan Hedberg return bt_cb(skb)->req.start; 43559238f36aSJohan Hedberg } 43569238f36aSJohan Hedberg 435742c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 435842c6b129SJohan Hedberg { 435942c6b129SJohan Hedberg struct hci_command_hdr *sent; 436042c6b129SJohan Hedberg struct sk_buff *skb; 436142c6b129SJohan Hedberg u16 opcode; 436242c6b129SJohan Hedberg 436342c6b129SJohan Hedberg if (!hdev->sent_cmd) 436442c6b129SJohan Hedberg return; 436542c6b129SJohan Hedberg 436642c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 436742c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 436842c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 436942c6b129SJohan Hedberg return; 437042c6b129SJohan Hedberg 437142c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 437242c6b129SJohan Hedberg if (!skb) 437342c6b129SJohan Hedberg return; 437442c6b129SJohan Hedberg 437542c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 437642c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 437742c6b129SJohan Hedberg } 437842c6b129SJohan Hedberg 43799238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 43809238f36aSJohan Hedberg { 43819238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 43829238f36aSJohan Hedberg struct sk_buff *skb; 43839238f36aSJohan Hedberg unsigned long flags; 43849238f36aSJohan Hedberg 43859238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 43869238f36aSJohan Hedberg 438742c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 438842c6b129SJohan Hedberg * sent we need to do special handling of it. 43899238f36aSJohan Hedberg */ 439042c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 439142c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 439242c6b129SJohan Hedberg * reset complete event during init and any pending 439342c6b129SJohan Hedberg * command will never be completed. In such a case we 439442c6b129SJohan Hedberg * need to resend whatever was the last sent 439542c6b129SJohan Hedberg * command. 439642c6b129SJohan Hedberg */ 439742c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 439842c6b129SJohan Hedberg hci_resend_last(hdev); 439942c6b129SJohan Hedberg 44009238f36aSJohan Hedberg return; 440142c6b129SJohan Hedberg } 44029238f36aSJohan Hedberg 44039238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 44049238f36aSJohan Hedberg * this request the request is not yet complete. 44059238f36aSJohan Hedberg */ 44069238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 44079238f36aSJohan Hedberg return; 44089238f36aSJohan Hedberg 44099238f36aSJohan Hedberg /* If this was the last command in a request the complete 44109238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 44119238f36aSJohan Hedberg * command queue (hdev->cmd_q). 44129238f36aSJohan Hedberg */ 44139238f36aSJohan Hedberg if (hdev->sent_cmd) { 44149238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 441553e21fbcSJohan Hedberg 441653e21fbcSJohan Hedberg if (req_complete) { 441753e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 441853e21fbcSJohan Hedberg * avoid calling the callback more than once if 441953e21fbcSJohan Hedberg * this function gets called again. 442053e21fbcSJohan Hedberg */ 442153e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 442253e21fbcSJohan Hedberg 44239238f36aSJohan Hedberg goto call_complete; 44249238f36aSJohan Hedberg } 442553e21fbcSJohan Hedberg } 44269238f36aSJohan Hedberg 44279238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 44289238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 44299238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 44309238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 44319238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 44329238f36aSJohan Hedberg break; 44339238f36aSJohan Hedberg } 44349238f36aSJohan Hedberg 44359238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 44369238f36aSJohan Hedberg kfree_skb(skb); 44379238f36aSJohan Hedberg } 44389238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 44399238f36aSJohan Hedberg 44409238f36aSJohan Hedberg call_complete: 44419238f36aSJohan Hedberg if (req_complete) 44429238f36aSJohan Hedberg req_complete(hdev, status); 44439238f36aSJohan Hedberg } 44449238f36aSJohan Hedberg 4445b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 44461da177e4SLinus Torvalds { 4447b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 44481da177e4SLinus Torvalds struct sk_buff *skb; 44491da177e4SLinus Torvalds 44501da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 44511da177e4SLinus Torvalds 44521da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 4453cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4454cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4455cd82e61cSMarcel Holtmann 44561da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 44571da177e4SLinus Torvalds /* Send copy to the sockets */ 4458470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 44591da177e4SLinus Torvalds } 44601da177e4SLinus Torvalds 44610736cfa8SMarcel Holtmann if (test_bit(HCI_RAW, &hdev->flags) || 44620736cfa8SMarcel Holtmann test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 44631da177e4SLinus Torvalds kfree_skb(skb); 44641da177e4SLinus Torvalds continue; 44651da177e4SLinus Torvalds } 44661da177e4SLinus Torvalds 44671da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 44681da177e4SLinus Torvalds /* Don't process data packets in this states. */ 44690d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 44701da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 44711da177e4SLinus Torvalds case HCI_SCODATA_PKT: 44721da177e4SLinus Torvalds kfree_skb(skb); 44731da177e4SLinus Torvalds continue; 44743ff50b79SStephen Hemminger } 44751da177e4SLinus Torvalds } 44761da177e4SLinus Torvalds 44771da177e4SLinus Torvalds /* Process frame */ 44780d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 44791da177e4SLinus Torvalds case HCI_EVENT_PKT: 4480b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 44811da177e4SLinus Torvalds hci_event_packet(hdev, skb); 44821da177e4SLinus Torvalds break; 44831da177e4SLinus Torvalds 44841da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 44851da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 44861da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 44871da177e4SLinus Torvalds break; 44881da177e4SLinus Torvalds 44891da177e4SLinus Torvalds case HCI_SCODATA_PKT: 44901da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 44911da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 44921da177e4SLinus Torvalds break; 44931da177e4SLinus Torvalds 44941da177e4SLinus Torvalds default: 44951da177e4SLinus Torvalds kfree_skb(skb); 44961da177e4SLinus Torvalds break; 44971da177e4SLinus Torvalds } 44981da177e4SLinus Torvalds } 44991da177e4SLinus Torvalds } 45001da177e4SLinus Torvalds 4501c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 45021da177e4SLinus Torvalds { 4503c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 45041da177e4SLinus Torvalds struct sk_buff *skb; 45051da177e4SLinus Torvalds 45062104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 45072104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 45081da177e4SLinus Torvalds 45091da177e4SLinus Torvalds /* Send queued commands */ 45105a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 45115a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 45125a08ecceSAndrei Emeltchenko if (!skb) 45135a08ecceSAndrei Emeltchenko return; 45145a08ecceSAndrei Emeltchenko 45151da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 45161da177e4SLinus Torvalds 4517a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 451870f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 45191da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 452057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 45217bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 45227bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 45237bdb8a5cSSzymon Janc else 45246bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 45255f246e89SAndrei Emeltchenko jiffies + HCI_CMD_TIMEOUT); 45261da177e4SLinus Torvalds } else { 45271da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4528c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 45291da177e4SLinus Torvalds } 45301da177e4SLinus Torvalds } 45311da177e4SLinus Torvalds } 4532