11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 31da177e4SLinus Torvalds Copyright (C) 2000-2001 Qualcomm Incorporated 4590051deSGustavo F. Padovan Copyright (C) 2011 ProFUSION Embedded Systems 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 91da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 101da177e4SLinus Torvalds published by the Free Software Foundation; 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 131da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 141da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 151da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 161da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 171da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 181da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 191da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 221da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 231da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 241da177e4SLinus Torvalds */ 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds /* Bluetooth HCI core. */ 271da177e4SLinus Torvalds 288c520a59SGustavo Padovan #include <linux/export.h> 293df92b31SSasha Levin #include <linux/idr.h> 30611b30f7SMarcel Holtmann #include <linux/rfkill.h> 31baf27f6eSMarcel Holtmann #include <linux/debugfs.h> 3299780a7bSJohan Hedberg #include <linux/crypto.h> 3347219839SMarcel Holtmann #include <asm/unaligned.h> 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 361da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 371da177e4SLinus Torvalds 38970c4e46SJohan Hedberg #include "smp.h" 39970c4e46SJohan Hedberg 40b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 41c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 423eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds /* HCI device list */ 451da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 461da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds /* HCI callback list */ 491da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 501da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 511da177e4SLinus Torvalds 523df92b31SSasha Levin /* HCI ID Numbering */ 533df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 543df92b31SSasha Levin 551da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 561da177e4SLinus Torvalds 576516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 581da177e4SLinus Torvalds { 59040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 601da177e4SLinus Torvalds } 611da177e4SLinus Torvalds 62baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */ 63baf27f6eSMarcel Holtmann 644b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf, 654b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 664b4148e9SMarcel Holtmann { 674b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 684b4148e9SMarcel Holtmann char buf[3]; 694b4148e9SMarcel Holtmann 704b4148e9SMarcel Holtmann buf[0] = test_bit(HCI_DUT_MODE, &hdev->dev_flags) ? 'Y': 'N'; 714b4148e9SMarcel Holtmann buf[1] = '\n'; 724b4148e9SMarcel Holtmann buf[2] = '\0'; 734b4148e9SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 744b4148e9SMarcel Holtmann } 754b4148e9SMarcel Holtmann 764b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf, 774b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 784b4148e9SMarcel Holtmann { 794b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 804b4148e9SMarcel Holtmann struct sk_buff *skb; 814b4148e9SMarcel Holtmann char buf[32]; 824b4148e9SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 834b4148e9SMarcel Holtmann bool enable; 844b4148e9SMarcel Holtmann int err; 854b4148e9SMarcel Holtmann 864b4148e9SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 874b4148e9SMarcel Holtmann return -ENETDOWN; 884b4148e9SMarcel Holtmann 894b4148e9SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 904b4148e9SMarcel Holtmann return -EFAULT; 914b4148e9SMarcel Holtmann 924b4148e9SMarcel Holtmann buf[buf_size] = '\0'; 934b4148e9SMarcel Holtmann if (strtobool(buf, &enable)) 944b4148e9SMarcel Holtmann return -EINVAL; 954b4148e9SMarcel Holtmann 964b4148e9SMarcel Holtmann if (enable == test_bit(HCI_DUT_MODE, &hdev->dev_flags)) 974b4148e9SMarcel Holtmann return -EALREADY; 984b4148e9SMarcel Holtmann 994b4148e9SMarcel Holtmann hci_req_lock(hdev); 1004b4148e9SMarcel Holtmann if (enable) 1014b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL, 1024b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1034b4148e9SMarcel Holtmann else 1044b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, 1054b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1064b4148e9SMarcel Holtmann hci_req_unlock(hdev); 1074b4148e9SMarcel Holtmann 1084b4148e9SMarcel Holtmann if (IS_ERR(skb)) 1094b4148e9SMarcel Holtmann return PTR_ERR(skb); 1104b4148e9SMarcel Holtmann 1114b4148e9SMarcel Holtmann err = -bt_to_errno(skb->data[0]); 1124b4148e9SMarcel Holtmann kfree_skb(skb); 1134b4148e9SMarcel Holtmann 1144b4148e9SMarcel Holtmann if (err < 0) 1154b4148e9SMarcel Holtmann return err; 1164b4148e9SMarcel Holtmann 1174b4148e9SMarcel Holtmann change_bit(HCI_DUT_MODE, &hdev->dev_flags); 1184b4148e9SMarcel Holtmann 1194b4148e9SMarcel Holtmann return count; 1204b4148e9SMarcel Holtmann } 1214b4148e9SMarcel Holtmann 1224b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = { 1234b4148e9SMarcel Holtmann .open = simple_open, 1244b4148e9SMarcel Holtmann .read = dut_mode_read, 1254b4148e9SMarcel Holtmann .write = dut_mode_write, 1264b4148e9SMarcel Holtmann .llseek = default_llseek, 1274b4148e9SMarcel Holtmann }; 1284b4148e9SMarcel Holtmann 129dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr) 130dfb826a8SMarcel Holtmann { 131dfb826a8SMarcel Holtmann struct hci_dev *hdev = f->private; 132dfb826a8SMarcel Holtmann u8 p; 133dfb826a8SMarcel Holtmann 134dfb826a8SMarcel Holtmann hci_dev_lock(hdev); 135dfb826a8SMarcel Holtmann for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 136cfbb2b5bSMarcel Holtmann seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 137dfb826a8SMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p, 138dfb826a8SMarcel Holtmann hdev->features[p][0], hdev->features[p][1], 139dfb826a8SMarcel Holtmann hdev->features[p][2], hdev->features[p][3], 140dfb826a8SMarcel Holtmann hdev->features[p][4], hdev->features[p][5], 141dfb826a8SMarcel Holtmann hdev->features[p][6], hdev->features[p][7]); 142dfb826a8SMarcel Holtmann } 143cfbb2b5bSMarcel Holtmann if (lmp_le_capable(hdev)) 144cfbb2b5bSMarcel Holtmann seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 145cfbb2b5bSMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", 146cfbb2b5bSMarcel Holtmann hdev->le_features[0], hdev->le_features[1], 147cfbb2b5bSMarcel Holtmann hdev->le_features[2], hdev->le_features[3], 148cfbb2b5bSMarcel Holtmann hdev->le_features[4], hdev->le_features[5], 149cfbb2b5bSMarcel Holtmann hdev->le_features[6], hdev->le_features[7]); 150dfb826a8SMarcel Holtmann hci_dev_unlock(hdev); 151dfb826a8SMarcel Holtmann 152dfb826a8SMarcel Holtmann return 0; 153dfb826a8SMarcel Holtmann } 154dfb826a8SMarcel Holtmann 155dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file) 156dfb826a8SMarcel Holtmann { 157dfb826a8SMarcel Holtmann return single_open(file, features_show, inode->i_private); 158dfb826a8SMarcel Holtmann } 159dfb826a8SMarcel Holtmann 160dfb826a8SMarcel Holtmann static const struct file_operations features_fops = { 161dfb826a8SMarcel Holtmann .open = features_open, 162dfb826a8SMarcel Holtmann .read = seq_read, 163dfb826a8SMarcel Holtmann .llseek = seq_lseek, 164dfb826a8SMarcel Holtmann .release = single_release, 165dfb826a8SMarcel Holtmann }; 166dfb826a8SMarcel Holtmann 16770afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p) 16870afe0b8SMarcel Holtmann { 16970afe0b8SMarcel Holtmann struct hci_dev *hdev = f->private; 17070afe0b8SMarcel Holtmann struct bdaddr_list *b; 17170afe0b8SMarcel Holtmann 17270afe0b8SMarcel Holtmann hci_dev_lock(hdev); 17370afe0b8SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) 174b25f0785SMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 17570afe0b8SMarcel Holtmann hci_dev_unlock(hdev); 17670afe0b8SMarcel Holtmann 17770afe0b8SMarcel Holtmann return 0; 17870afe0b8SMarcel Holtmann } 17970afe0b8SMarcel Holtmann 18070afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file) 18170afe0b8SMarcel Holtmann { 18270afe0b8SMarcel Holtmann return single_open(file, blacklist_show, inode->i_private); 18370afe0b8SMarcel Holtmann } 18470afe0b8SMarcel Holtmann 18570afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = { 18670afe0b8SMarcel Holtmann .open = blacklist_open, 18770afe0b8SMarcel Holtmann .read = seq_read, 18870afe0b8SMarcel Holtmann .llseek = seq_lseek, 18970afe0b8SMarcel Holtmann .release = single_release, 19070afe0b8SMarcel Holtmann }; 19170afe0b8SMarcel Holtmann 19247219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p) 19347219839SMarcel Holtmann { 19447219839SMarcel Holtmann struct hci_dev *hdev = f->private; 19547219839SMarcel Holtmann struct bt_uuid *uuid; 19647219839SMarcel Holtmann 19747219839SMarcel Holtmann hci_dev_lock(hdev); 19847219839SMarcel Holtmann list_for_each_entry(uuid, &hdev->uuids, list) { 19958f01aa9SMarcel Holtmann u8 i, val[16]; 20047219839SMarcel Holtmann 20158f01aa9SMarcel Holtmann /* The Bluetooth UUID values are stored in big endian, 20258f01aa9SMarcel Holtmann * but with reversed byte order. So convert them into 20358f01aa9SMarcel Holtmann * the right order for the %pUb modifier. 20458f01aa9SMarcel Holtmann */ 20558f01aa9SMarcel Holtmann for (i = 0; i < 16; i++) 20658f01aa9SMarcel Holtmann val[i] = uuid->uuid[15 - i]; 20747219839SMarcel Holtmann 20858f01aa9SMarcel Holtmann seq_printf(f, "%pUb\n", val); 20947219839SMarcel Holtmann } 21047219839SMarcel Holtmann hci_dev_unlock(hdev); 21147219839SMarcel Holtmann 21247219839SMarcel Holtmann return 0; 21347219839SMarcel Holtmann } 21447219839SMarcel Holtmann 21547219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file) 21647219839SMarcel Holtmann { 21747219839SMarcel Holtmann return single_open(file, uuids_show, inode->i_private); 21847219839SMarcel Holtmann } 21947219839SMarcel Holtmann 22047219839SMarcel Holtmann static const struct file_operations uuids_fops = { 22147219839SMarcel Holtmann .open = uuids_open, 22247219839SMarcel Holtmann .read = seq_read, 22347219839SMarcel Holtmann .llseek = seq_lseek, 22447219839SMarcel Holtmann .release = single_release, 22547219839SMarcel Holtmann }; 22647219839SMarcel Holtmann 227baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p) 228baf27f6eSMarcel Holtmann { 229baf27f6eSMarcel Holtmann struct hci_dev *hdev = f->private; 230baf27f6eSMarcel Holtmann struct discovery_state *cache = &hdev->discovery; 231baf27f6eSMarcel Holtmann struct inquiry_entry *e; 232baf27f6eSMarcel Holtmann 233baf27f6eSMarcel Holtmann hci_dev_lock(hdev); 234baf27f6eSMarcel Holtmann 235baf27f6eSMarcel Holtmann list_for_each_entry(e, &cache->all, all) { 236baf27f6eSMarcel Holtmann struct inquiry_data *data = &e->data; 237baf27f6eSMarcel Holtmann seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", 238baf27f6eSMarcel Holtmann &data->bdaddr, 239baf27f6eSMarcel Holtmann data->pscan_rep_mode, data->pscan_period_mode, 240baf27f6eSMarcel Holtmann data->pscan_mode, data->dev_class[2], 241baf27f6eSMarcel Holtmann data->dev_class[1], data->dev_class[0], 242baf27f6eSMarcel Holtmann __le16_to_cpu(data->clock_offset), 243baf27f6eSMarcel Holtmann data->rssi, data->ssp_mode, e->timestamp); 244baf27f6eSMarcel Holtmann } 245baf27f6eSMarcel Holtmann 246baf27f6eSMarcel Holtmann hci_dev_unlock(hdev); 247baf27f6eSMarcel Holtmann 248baf27f6eSMarcel Holtmann return 0; 249baf27f6eSMarcel Holtmann } 250baf27f6eSMarcel Holtmann 251baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file) 252baf27f6eSMarcel Holtmann { 253baf27f6eSMarcel Holtmann return single_open(file, inquiry_cache_show, inode->i_private); 254baf27f6eSMarcel Holtmann } 255baf27f6eSMarcel Holtmann 256baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = { 257baf27f6eSMarcel Holtmann .open = inquiry_cache_open, 258baf27f6eSMarcel Holtmann .read = seq_read, 259baf27f6eSMarcel Holtmann .llseek = seq_lseek, 260baf27f6eSMarcel Holtmann .release = single_release, 261baf27f6eSMarcel Holtmann }; 262baf27f6eSMarcel Holtmann 26302d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr) 26402d08d15SMarcel Holtmann { 26502d08d15SMarcel Holtmann struct hci_dev *hdev = f->private; 26602d08d15SMarcel Holtmann struct list_head *p, *n; 26702d08d15SMarcel Holtmann 26802d08d15SMarcel Holtmann hci_dev_lock(hdev); 26902d08d15SMarcel Holtmann list_for_each_safe(p, n, &hdev->link_keys) { 27002d08d15SMarcel Holtmann struct link_key *key = list_entry(p, struct link_key, list); 27102d08d15SMarcel Holtmann seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type, 27202d08d15SMarcel Holtmann HCI_LINK_KEY_SIZE, key->val, key->pin_len); 27302d08d15SMarcel Holtmann } 27402d08d15SMarcel Holtmann hci_dev_unlock(hdev); 27502d08d15SMarcel Holtmann 27602d08d15SMarcel Holtmann return 0; 27702d08d15SMarcel Holtmann } 27802d08d15SMarcel Holtmann 27902d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file) 28002d08d15SMarcel Holtmann { 28102d08d15SMarcel Holtmann return single_open(file, link_keys_show, inode->i_private); 28202d08d15SMarcel Holtmann } 28302d08d15SMarcel Holtmann 28402d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = { 28502d08d15SMarcel Holtmann .open = link_keys_open, 28602d08d15SMarcel Holtmann .read = seq_read, 28702d08d15SMarcel Holtmann .llseek = seq_lseek, 28802d08d15SMarcel Holtmann .release = single_release, 28902d08d15SMarcel Holtmann }; 29002d08d15SMarcel Holtmann 291babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr) 292babdbb3cSMarcel Holtmann { 293babdbb3cSMarcel Holtmann struct hci_dev *hdev = f->private; 294babdbb3cSMarcel Holtmann 295babdbb3cSMarcel Holtmann hci_dev_lock(hdev); 296babdbb3cSMarcel Holtmann seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], 297babdbb3cSMarcel Holtmann hdev->dev_class[1], hdev->dev_class[0]); 298babdbb3cSMarcel Holtmann hci_dev_unlock(hdev); 299babdbb3cSMarcel Holtmann 300babdbb3cSMarcel Holtmann return 0; 301babdbb3cSMarcel Holtmann } 302babdbb3cSMarcel Holtmann 303babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file) 304babdbb3cSMarcel Holtmann { 305babdbb3cSMarcel Holtmann return single_open(file, dev_class_show, inode->i_private); 306babdbb3cSMarcel Holtmann } 307babdbb3cSMarcel Holtmann 308babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = { 309babdbb3cSMarcel Holtmann .open = dev_class_open, 310babdbb3cSMarcel Holtmann .read = seq_read, 311babdbb3cSMarcel Holtmann .llseek = seq_lseek, 312babdbb3cSMarcel Holtmann .release = single_release, 313babdbb3cSMarcel Holtmann }; 314babdbb3cSMarcel Holtmann 315041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val) 316041000b9SMarcel Holtmann { 317041000b9SMarcel Holtmann struct hci_dev *hdev = data; 318041000b9SMarcel Holtmann 319041000b9SMarcel Holtmann hci_dev_lock(hdev); 320041000b9SMarcel Holtmann *val = hdev->voice_setting; 321041000b9SMarcel Holtmann hci_dev_unlock(hdev); 322041000b9SMarcel Holtmann 323041000b9SMarcel Holtmann return 0; 324041000b9SMarcel Holtmann } 325041000b9SMarcel Holtmann 326041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get, 327041000b9SMarcel Holtmann NULL, "0x%4.4llx\n"); 328041000b9SMarcel Holtmann 329ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val) 330ebd1e33bSMarcel Holtmann { 331ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 332ebd1e33bSMarcel Holtmann 333ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 334ebd1e33bSMarcel Holtmann hdev->auto_accept_delay = val; 335ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 336ebd1e33bSMarcel Holtmann 337ebd1e33bSMarcel Holtmann return 0; 338ebd1e33bSMarcel Holtmann } 339ebd1e33bSMarcel Holtmann 340ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val) 341ebd1e33bSMarcel Holtmann { 342ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 343ebd1e33bSMarcel Holtmann 344ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 345ebd1e33bSMarcel Holtmann *val = hdev->auto_accept_delay; 346ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 347ebd1e33bSMarcel Holtmann 348ebd1e33bSMarcel Holtmann return 0; 349ebd1e33bSMarcel Holtmann } 350ebd1e33bSMarcel Holtmann 351ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, 352ebd1e33bSMarcel Holtmann auto_accept_delay_set, "%llu\n"); 353ebd1e33bSMarcel Holtmann 35406f5b778SMarcel Holtmann static int ssp_debug_mode_set(void *data, u64 val) 35506f5b778SMarcel Holtmann { 35606f5b778SMarcel Holtmann struct hci_dev *hdev = data; 35706f5b778SMarcel Holtmann struct sk_buff *skb; 35806f5b778SMarcel Holtmann __u8 mode; 35906f5b778SMarcel Holtmann int err; 36006f5b778SMarcel Holtmann 36106f5b778SMarcel Holtmann if (val != 0 && val != 1) 36206f5b778SMarcel Holtmann return -EINVAL; 36306f5b778SMarcel Holtmann 36406f5b778SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 36506f5b778SMarcel Holtmann return -ENETDOWN; 36606f5b778SMarcel Holtmann 36706f5b778SMarcel Holtmann hci_req_lock(hdev); 36806f5b778SMarcel Holtmann mode = val; 36906f5b778SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode), 37006f5b778SMarcel Holtmann &mode, HCI_CMD_TIMEOUT); 37106f5b778SMarcel Holtmann hci_req_unlock(hdev); 37206f5b778SMarcel Holtmann 37306f5b778SMarcel Holtmann if (IS_ERR(skb)) 37406f5b778SMarcel Holtmann return PTR_ERR(skb); 37506f5b778SMarcel Holtmann 37606f5b778SMarcel Holtmann err = -bt_to_errno(skb->data[0]); 37706f5b778SMarcel Holtmann kfree_skb(skb); 37806f5b778SMarcel Holtmann 37906f5b778SMarcel Holtmann if (err < 0) 38006f5b778SMarcel Holtmann return err; 38106f5b778SMarcel Holtmann 38206f5b778SMarcel Holtmann hci_dev_lock(hdev); 38306f5b778SMarcel Holtmann hdev->ssp_debug_mode = val; 38406f5b778SMarcel Holtmann hci_dev_unlock(hdev); 38506f5b778SMarcel Holtmann 38606f5b778SMarcel Holtmann return 0; 38706f5b778SMarcel Holtmann } 38806f5b778SMarcel Holtmann 38906f5b778SMarcel Holtmann static int ssp_debug_mode_get(void *data, u64 *val) 39006f5b778SMarcel Holtmann { 39106f5b778SMarcel Holtmann struct hci_dev *hdev = data; 39206f5b778SMarcel Holtmann 39306f5b778SMarcel Holtmann hci_dev_lock(hdev); 39406f5b778SMarcel Holtmann *val = hdev->ssp_debug_mode; 39506f5b778SMarcel Holtmann hci_dev_unlock(hdev); 39606f5b778SMarcel Holtmann 39706f5b778SMarcel Holtmann return 0; 39806f5b778SMarcel Holtmann } 39906f5b778SMarcel Holtmann 40006f5b778SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get, 40106f5b778SMarcel Holtmann ssp_debug_mode_set, "%llu\n"); 40206f5b778SMarcel Holtmann 4035afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf, 4045afeac14SMarcel Holtmann size_t count, loff_t *ppos) 4055afeac14SMarcel Holtmann { 4065afeac14SMarcel Holtmann struct hci_dev *hdev = file->private_data; 4075afeac14SMarcel Holtmann char buf[3]; 4085afeac14SMarcel Holtmann 4095afeac14SMarcel Holtmann buf[0] = test_bit(HCI_FORCE_SC, &hdev->dev_flags) ? 'Y': 'N'; 4105afeac14SMarcel Holtmann buf[1] = '\n'; 4115afeac14SMarcel Holtmann buf[2] = '\0'; 4125afeac14SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 4135afeac14SMarcel Holtmann } 4145afeac14SMarcel Holtmann 4155afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file, 4165afeac14SMarcel Holtmann const char __user *user_buf, 4175afeac14SMarcel Holtmann size_t count, loff_t *ppos) 4185afeac14SMarcel Holtmann { 4195afeac14SMarcel Holtmann struct hci_dev *hdev = file->private_data; 4205afeac14SMarcel Holtmann char buf[32]; 4215afeac14SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 4225afeac14SMarcel Holtmann bool enable; 4235afeac14SMarcel Holtmann 4245afeac14SMarcel Holtmann if (test_bit(HCI_UP, &hdev->flags)) 4255afeac14SMarcel Holtmann return -EBUSY; 4265afeac14SMarcel Holtmann 4275afeac14SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 4285afeac14SMarcel Holtmann return -EFAULT; 4295afeac14SMarcel Holtmann 4305afeac14SMarcel Holtmann buf[buf_size] = '\0'; 4315afeac14SMarcel Holtmann if (strtobool(buf, &enable)) 4325afeac14SMarcel Holtmann return -EINVAL; 4335afeac14SMarcel Holtmann 4345afeac14SMarcel Holtmann if (enable == test_bit(HCI_FORCE_SC, &hdev->dev_flags)) 4355afeac14SMarcel Holtmann return -EALREADY; 4365afeac14SMarcel Holtmann 4375afeac14SMarcel Holtmann change_bit(HCI_FORCE_SC, &hdev->dev_flags); 4385afeac14SMarcel Holtmann 4395afeac14SMarcel Holtmann return count; 4405afeac14SMarcel Holtmann } 4415afeac14SMarcel Holtmann 4425afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = { 4435afeac14SMarcel Holtmann .open = simple_open, 4445afeac14SMarcel Holtmann .read = force_sc_support_read, 4455afeac14SMarcel Holtmann .write = force_sc_support_write, 4465afeac14SMarcel Holtmann .llseek = default_llseek, 4475afeac14SMarcel Holtmann }; 4485afeac14SMarcel Holtmann 449134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf, 450134c2a89SMarcel Holtmann size_t count, loff_t *ppos) 451134c2a89SMarcel Holtmann { 452134c2a89SMarcel Holtmann struct hci_dev *hdev = file->private_data; 453134c2a89SMarcel Holtmann char buf[3]; 454134c2a89SMarcel Holtmann 455134c2a89SMarcel Holtmann buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N'; 456134c2a89SMarcel Holtmann buf[1] = '\n'; 457134c2a89SMarcel Holtmann buf[2] = '\0'; 458134c2a89SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 459134c2a89SMarcel Holtmann } 460134c2a89SMarcel Holtmann 461134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = { 462134c2a89SMarcel Holtmann .open = simple_open, 463134c2a89SMarcel Holtmann .read = sc_only_mode_read, 464134c2a89SMarcel Holtmann .llseek = default_llseek, 465134c2a89SMarcel Holtmann }; 466134c2a89SMarcel Holtmann 4672bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val) 4682bfa3531SMarcel Holtmann { 4692bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4702bfa3531SMarcel Holtmann 4712bfa3531SMarcel Holtmann if (val != 0 && (val < 500 || val > 3600000)) 4722bfa3531SMarcel Holtmann return -EINVAL; 4732bfa3531SMarcel Holtmann 4742bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4752bfa3531SMarcel Holtmann hdev->idle_timeout = val; 4762bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4772bfa3531SMarcel Holtmann 4782bfa3531SMarcel Holtmann return 0; 4792bfa3531SMarcel Holtmann } 4802bfa3531SMarcel Holtmann 4812bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val) 4822bfa3531SMarcel Holtmann { 4832bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4842bfa3531SMarcel Holtmann 4852bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4862bfa3531SMarcel Holtmann *val = hdev->idle_timeout; 4872bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4882bfa3531SMarcel Holtmann 4892bfa3531SMarcel Holtmann return 0; 4902bfa3531SMarcel Holtmann } 4912bfa3531SMarcel Holtmann 4922bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get, 4932bfa3531SMarcel Holtmann idle_timeout_set, "%llu\n"); 4942bfa3531SMarcel Holtmann 4952bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val) 4962bfa3531SMarcel Holtmann { 4972bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4982bfa3531SMarcel Holtmann 4992bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val > hdev->sniff_max_interval) 5002bfa3531SMarcel Holtmann return -EINVAL; 5012bfa3531SMarcel Holtmann 5022bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5032bfa3531SMarcel Holtmann hdev->sniff_min_interval = val; 5042bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5052bfa3531SMarcel Holtmann 5062bfa3531SMarcel Holtmann return 0; 5072bfa3531SMarcel Holtmann } 5082bfa3531SMarcel Holtmann 5092bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val) 5102bfa3531SMarcel Holtmann { 5112bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5122bfa3531SMarcel Holtmann 5132bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5142bfa3531SMarcel Holtmann *val = hdev->sniff_min_interval; 5152bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5162bfa3531SMarcel Holtmann 5172bfa3531SMarcel Holtmann return 0; 5182bfa3531SMarcel Holtmann } 5192bfa3531SMarcel Holtmann 5202bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get, 5212bfa3531SMarcel Holtmann sniff_min_interval_set, "%llu\n"); 5222bfa3531SMarcel Holtmann 5232bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val) 5242bfa3531SMarcel Holtmann { 5252bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5262bfa3531SMarcel Holtmann 5272bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val < hdev->sniff_min_interval) 5282bfa3531SMarcel Holtmann return -EINVAL; 5292bfa3531SMarcel Holtmann 5302bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5312bfa3531SMarcel Holtmann hdev->sniff_max_interval = val; 5322bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5332bfa3531SMarcel Holtmann 5342bfa3531SMarcel Holtmann return 0; 5352bfa3531SMarcel Holtmann } 5362bfa3531SMarcel Holtmann 5372bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val) 5382bfa3531SMarcel Holtmann { 5392bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5402bfa3531SMarcel Holtmann 5412bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5422bfa3531SMarcel Holtmann *val = hdev->sniff_max_interval; 5432bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5442bfa3531SMarcel Holtmann 5452bfa3531SMarcel Holtmann return 0; 5462bfa3531SMarcel Holtmann } 5472bfa3531SMarcel Holtmann 5482bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, 5492bfa3531SMarcel Holtmann sniff_max_interval_set, "%llu\n"); 5502bfa3531SMarcel Holtmann 551e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p) 552e7b8fc92SMarcel Holtmann { 553e7b8fc92SMarcel Holtmann struct hci_dev *hdev = f->private; 554e7b8fc92SMarcel Holtmann 555e7b8fc92SMarcel Holtmann hci_dev_lock(hdev); 556e7b8fc92SMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->static_addr); 557e7b8fc92SMarcel Holtmann hci_dev_unlock(hdev); 558e7b8fc92SMarcel Holtmann 559e7b8fc92SMarcel Holtmann return 0; 560e7b8fc92SMarcel Holtmann } 561e7b8fc92SMarcel Holtmann 562e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file) 563e7b8fc92SMarcel Holtmann { 564e7b8fc92SMarcel Holtmann return single_open(file, static_address_show, inode->i_private); 565e7b8fc92SMarcel Holtmann } 566e7b8fc92SMarcel Holtmann 567e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = { 568e7b8fc92SMarcel Holtmann .open = static_address_open, 569e7b8fc92SMarcel Holtmann .read = seq_read, 570e7b8fc92SMarcel Holtmann .llseek = seq_lseek, 571e7b8fc92SMarcel Holtmann .release = single_release, 572e7b8fc92SMarcel Holtmann }; 573e7b8fc92SMarcel Holtmann 57492202185SMarcel Holtmann static int own_address_type_set(void *data, u64 val) 57592202185SMarcel Holtmann { 57692202185SMarcel Holtmann struct hci_dev *hdev = data; 57792202185SMarcel Holtmann 57892202185SMarcel Holtmann if (val != 0 && val != 1) 57992202185SMarcel Holtmann return -EINVAL; 58092202185SMarcel Holtmann 58192202185SMarcel Holtmann hci_dev_lock(hdev); 58292202185SMarcel Holtmann hdev->own_addr_type = val; 58392202185SMarcel Holtmann hci_dev_unlock(hdev); 58492202185SMarcel Holtmann 58592202185SMarcel Holtmann return 0; 58692202185SMarcel Holtmann } 58792202185SMarcel Holtmann 58892202185SMarcel Holtmann static int own_address_type_get(void *data, u64 *val) 58992202185SMarcel Holtmann { 59092202185SMarcel Holtmann struct hci_dev *hdev = data; 59192202185SMarcel Holtmann 59292202185SMarcel Holtmann hci_dev_lock(hdev); 59392202185SMarcel Holtmann *val = hdev->own_addr_type; 59492202185SMarcel Holtmann hci_dev_unlock(hdev); 59592202185SMarcel Holtmann 59692202185SMarcel Holtmann return 0; 59792202185SMarcel Holtmann } 59892202185SMarcel Holtmann 59992202185SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get, 60092202185SMarcel Holtmann own_address_type_set, "%llu\n"); 60192202185SMarcel Holtmann 6023698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr) 6033698d704SMarcel Holtmann { 6043698d704SMarcel Holtmann struct hci_dev *hdev = f->private; 6053698d704SMarcel Holtmann struct list_head *p, *n; 6063698d704SMarcel Holtmann 6073698d704SMarcel Holtmann hci_dev_lock(hdev); 6083698d704SMarcel Holtmann list_for_each_safe(p, n, &hdev->identity_resolving_keys) { 6093698d704SMarcel Holtmann struct smp_irk *irk = list_entry(p, struct smp_irk, list); 6103698d704SMarcel Holtmann seq_printf(f, "%pMR (type %u) %*phN %pMR\n", 6113698d704SMarcel Holtmann &irk->bdaddr, irk->addr_type, 6123698d704SMarcel Holtmann 16, irk->val, &irk->rpa); 6133698d704SMarcel Holtmann } 6143698d704SMarcel Holtmann hci_dev_unlock(hdev); 6153698d704SMarcel Holtmann 6163698d704SMarcel Holtmann return 0; 6173698d704SMarcel Holtmann } 6183698d704SMarcel Holtmann 6193698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file) 6203698d704SMarcel Holtmann { 6213698d704SMarcel Holtmann return single_open(file, identity_resolving_keys_show, 6223698d704SMarcel Holtmann inode->i_private); 6233698d704SMarcel Holtmann } 6243698d704SMarcel Holtmann 6253698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = { 6263698d704SMarcel Holtmann .open = identity_resolving_keys_open, 6273698d704SMarcel Holtmann .read = seq_read, 6283698d704SMarcel Holtmann .llseek = seq_lseek, 6293698d704SMarcel Holtmann .release = single_release, 6303698d704SMarcel Holtmann }; 6313698d704SMarcel Holtmann 6328f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr) 6338f8625cdSMarcel Holtmann { 6348f8625cdSMarcel Holtmann struct hci_dev *hdev = f->private; 6358f8625cdSMarcel Holtmann struct list_head *p, *n; 6368f8625cdSMarcel Holtmann 6378f8625cdSMarcel Holtmann hci_dev_lock(hdev); 638f813f1beSJohan Hedberg list_for_each_safe(p, n, &hdev->long_term_keys) { 6398f8625cdSMarcel Holtmann struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list); 640f813f1beSJohan Hedberg seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %*phN %*phN\n", 6418f8625cdSMarcel Holtmann <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, 6428f8625cdSMarcel Holtmann ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), 6438f8625cdSMarcel Holtmann 8, ltk->rand, 16, ltk->val); 6448f8625cdSMarcel Holtmann } 6458f8625cdSMarcel Holtmann hci_dev_unlock(hdev); 6468f8625cdSMarcel Holtmann 6478f8625cdSMarcel Holtmann return 0; 6488f8625cdSMarcel Holtmann } 6498f8625cdSMarcel Holtmann 6508f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file) 6518f8625cdSMarcel Holtmann { 6528f8625cdSMarcel Holtmann return single_open(file, long_term_keys_show, inode->i_private); 6538f8625cdSMarcel Holtmann } 6548f8625cdSMarcel Holtmann 6558f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = { 6568f8625cdSMarcel Holtmann .open = long_term_keys_open, 6578f8625cdSMarcel Holtmann .read = seq_read, 6588f8625cdSMarcel Holtmann .llseek = seq_lseek, 6598f8625cdSMarcel Holtmann .release = single_release, 6608f8625cdSMarcel Holtmann }; 6618f8625cdSMarcel Holtmann 6624e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val) 6634e70c7e7SMarcel Holtmann { 6644e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6654e70c7e7SMarcel Holtmann 6664e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval) 6674e70c7e7SMarcel Holtmann return -EINVAL; 6684e70c7e7SMarcel Holtmann 6694e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6704e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = val; 6714e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 6724e70c7e7SMarcel Holtmann 6734e70c7e7SMarcel Holtmann return 0; 6744e70c7e7SMarcel Holtmann } 6754e70c7e7SMarcel Holtmann 6764e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val) 6774e70c7e7SMarcel Holtmann { 6784e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6794e70c7e7SMarcel Holtmann 6804e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6814e70c7e7SMarcel Holtmann *val = hdev->le_conn_min_interval; 6824e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 6834e70c7e7SMarcel Holtmann 6844e70c7e7SMarcel Holtmann return 0; 6854e70c7e7SMarcel Holtmann } 6864e70c7e7SMarcel Holtmann 6874e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get, 6884e70c7e7SMarcel Holtmann conn_min_interval_set, "%llu\n"); 6894e70c7e7SMarcel Holtmann 6904e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val) 6914e70c7e7SMarcel Holtmann { 6924e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6934e70c7e7SMarcel Holtmann 6944e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval) 6954e70c7e7SMarcel Holtmann return -EINVAL; 6964e70c7e7SMarcel Holtmann 6974e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6984e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = val; 6994e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 7004e70c7e7SMarcel Holtmann 7014e70c7e7SMarcel Holtmann return 0; 7024e70c7e7SMarcel Holtmann } 7034e70c7e7SMarcel Holtmann 7044e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val) 7054e70c7e7SMarcel Holtmann { 7064e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 7074e70c7e7SMarcel Holtmann 7084e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 7094e70c7e7SMarcel Holtmann *val = hdev->le_conn_max_interval; 7104e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 7114e70c7e7SMarcel Holtmann 7124e70c7e7SMarcel Holtmann return 0; 7134e70c7e7SMarcel Holtmann } 7144e70c7e7SMarcel Holtmann 7154e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, 7164e70c7e7SMarcel Holtmann conn_max_interval_set, "%llu\n"); 7174e70c7e7SMarcel Holtmann 71889863109SJukka Rissanen static ssize_t lowpan_read(struct file *file, char __user *user_buf, 71989863109SJukka Rissanen size_t count, loff_t *ppos) 72089863109SJukka Rissanen { 72189863109SJukka Rissanen struct hci_dev *hdev = file->private_data; 72289863109SJukka Rissanen char buf[3]; 72389863109SJukka Rissanen 72489863109SJukka Rissanen buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N'; 72589863109SJukka Rissanen buf[1] = '\n'; 72689863109SJukka Rissanen buf[2] = '\0'; 72789863109SJukka Rissanen return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 72889863109SJukka Rissanen } 72989863109SJukka Rissanen 73089863109SJukka Rissanen static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer, 73189863109SJukka Rissanen size_t count, loff_t *position) 73289863109SJukka Rissanen { 73389863109SJukka Rissanen struct hci_dev *hdev = fp->private_data; 73489863109SJukka Rissanen bool enable; 73589863109SJukka Rissanen char buf[32]; 73689863109SJukka Rissanen size_t buf_size = min(count, (sizeof(buf)-1)); 73789863109SJukka Rissanen 73889863109SJukka Rissanen if (copy_from_user(buf, user_buffer, buf_size)) 73989863109SJukka Rissanen return -EFAULT; 74089863109SJukka Rissanen 74189863109SJukka Rissanen buf[buf_size] = '\0'; 74289863109SJukka Rissanen 74389863109SJukka Rissanen if (strtobool(buf, &enable) < 0) 74489863109SJukka Rissanen return -EINVAL; 74589863109SJukka Rissanen 74689863109SJukka Rissanen if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags)) 74789863109SJukka Rissanen return -EALREADY; 74889863109SJukka Rissanen 74989863109SJukka Rissanen change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags); 75089863109SJukka Rissanen 75189863109SJukka Rissanen return count; 75289863109SJukka Rissanen } 75389863109SJukka Rissanen 75489863109SJukka Rissanen static const struct file_operations lowpan_debugfs_fops = { 75589863109SJukka Rissanen .open = simple_open, 75689863109SJukka Rissanen .read = lowpan_read, 75789863109SJukka Rissanen .write = lowpan_write, 75889863109SJukka Rissanen .llseek = default_llseek, 75989863109SJukka Rissanen }; 76089863109SJukka Rissanen 7611da177e4SLinus Torvalds /* ---- HCI requests ---- */ 7621da177e4SLinus Torvalds 76342c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 7641da177e4SLinus Torvalds { 76542c6b129SJohan Hedberg BT_DBG("%s result 0x%2.2x", hdev->name, result); 76675fb0e32SJohan Hedberg 7671da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 7681da177e4SLinus Torvalds hdev->req_result = result; 7691da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 7701da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 7711da177e4SLinus Torvalds } 7721da177e4SLinus Torvalds } 7731da177e4SLinus Torvalds 7741da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 7751da177e4SLinus Torvalds { 7761da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 7771da177e4SLinus Torvalds 7781da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 7791da177e4SLinus Torvalds hdev->req_result = err; 7801da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 7811da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 7821da177e4SLinus Torvalds } 7831da177e4SLinus Torvalds } 7841da177e4SLinus Torvalds 78577a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 78677a63e0aSFengguang Wu u8 event) 78775e84b7cSJohan Hedberg { 78875e84b7cSJohan Hedberg struct hci_ev_cmd_complete *ev; 78975e84b7cSJohan Hedberg struct hci_event_hdr *hdr; 79075e84b7cSJohan Hedberg struct sk_buff *skb; 79175e84b7cSJohan Hedberg 79275e84b7cSJohan Hedberg hci_dev_lock(hdev); 79375e84b7cSJohan Hedberg 79475e84b7cSJohan Hedberg skb = hdev->recv_evt; 79575e84b7cSJohan Hedberg hdev->recv_evt = NULL; 79675e84b7cSJohan Hedberg 79775e84b7cSJohan Hedberg hci_dev_unlock(hdev); 79875e84b7cSJohan Hedberg 79975e84b7cSJohan Hedberg if (!skb) 80075e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 80175e84b7cSJohan Hedberg 80275e84b7cSJohan Hedberg if (skb->len < sizeof(*hdr)) { 80375e84b7cSJohan Hedberg BT_ERR("Too short HCI event"); 80475e84b7cSJohan Hedberg goto failed; 80575e84b7cSJohan Hedberg } 80675e84b7cSJohan Hedberg 80775e84b7cSJohan Hedberg hdr = (void *) skb->data; 80875e84b7cSJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 80975e84b7cSJohan Hedberg 8107b1abbbeSJohan Hedberg if (event) { 8117b1abbbeSJohan Hedberg if (hdr->evt != event) 8127b1abbbeSJohan Hedberg goto failed; 8137b1abbbeSJohan Hedberg return skb; 8147b1abbbeSJohan Hedberg } 8157b1abbbeSJohan Hedberg 81675e84b7cSJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 81775e84b7cSJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 81875e84b7cSJohan Hedberg goto failed; 81975e84b7cSJohan Hedberg } 82075e84b7cSJohan Hedberg 82175e84b7cSJohan Hedberg if (skb->len < sizeof(*ev)) { 82275e84b7cSJohan Hedberg BT_ERR("Too short cmd_complete event"); 82375e84b7cSJohan Hedberg goto failed; 82475e84b7cSJohan Hedberg } 82575e84b7cSJohan Hedberg 82675e84b7cSJohan Hedberg ev = (void *) skb->data; 82775e84b7cSJohan Hedberg skb_pull(skb, sizeof(*ev)); 82875e84b7cSJohan Hedberg 82975e84b7cSJohan Hedberg if (opcode == __le16_to_cpu(ev->opcode)) 83075e84b7cSJohan Hedberg return skb; 83175e84b7cSJohan Hedberg 83275e84b7cSJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 83375e84b7cSJohan Hedberg __le16_to_cpu(ev->opcode)); 83475e84b7cSJohan Hedberg 83575e84b7cSJohan Hedberg failed: 83675e84b7cSJohan Hedberg kfree_skb(skb); 83775e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 83875e84b7cSJohan Hedberg } 83975e84b7cSJohan Hedberg 8407b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 84107dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout) 84275e84b7cSJohan Hedberg { 84375e84b7cSJohan Hedberg DECLARE_WAITQUEUE(wait, current); 84475e84b7cSJohan Hedberg struct hci_request req; 84575e84b7cSJohan Hedberg int err = 0; 84675e84b7cSJohan Hedberg 84775e84b7cSJohan Hedberg BT_DBG("%s", hdev->name); 84875e84b7cSJohan Hedberg 84975e84b7cSJohan Hedberg hci_req_init(&req, hdev); 85075e84b7cSJohan Hedberg 8517b1abbbeSJohan Hedberg hci_req_add_ev(&req, opcode, plen, param, event); 85275e84b7cSJohan Hedberg 85375e84b7cSJohan Hedberg hdev->req_status = HCI_REQ_PEND; 85475e84b7cSJohan Hedberg 85575e84b7cSJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 85675e84b7cSJohan Hedberg if (err < 0) 85775e84b7cSJohan Hedberg return ERR_PTR(err); 85875e84b7cSJohan Hedberg 85975e84b7cSJohan Hedberg add_wait_queue(&hdev->req_wait_q, &wait); 86075e84b7cSJohan Hedberg set_current_state(TASK_INTERRUPTIBLE); 86175e84b7cSJohan Hedberg 86275e84b7cSJohan Hedberg schedule_timeout(timeout); 86375e84b7cSJohan Hedberg 86475e84b7cSJohan Hedberg remove_wait_queue(&hdev->req_wait_q, &wait); 86575e84b7cSJohan Hedberg 86675e84b7cSJohan Hedberg if (signal_pending(current)) 86775e84b7cSJohan Hedberg return ERR_PTR(-EINTR); 86875e84b7cSJohan Hedberg 86975e84b7cSJohan Hedberg switch (hdev->req_status) { 87075e84b7cSJohan Hedberg case HCI_REQ_DONE: 87175e84b7cSJohan Hedberg err = -bt_to_errno(hdev->req_result); 87275e84b7cSJohan Hedberg break; 87375e84b7cSJohan Hedberg 87475e84b7cSJohan Hedberg case HCI_REQ_CANCELED: 87575e84b7cSJohan Hedberg err = -hdev->req_result; 87675e84b7cSJohan Hedberg break; 87775e84b7cSJohan Hedberg 87875e84b7cSJohan Hedberg default: 87975e84b7cSJohan Hedberg err = -ETIMEDOUT; 88075e84b7cSJohan Hedberg break; 88175e84b7cSJohan Hedberg } 88275e84b7cSJohan Hedberg 88375e84b7cSJohan Hedberg hdev->req_status = hdev->req_result = 0; 88475e84b7cSJohan Hedberg 88575e84b7cSJohan Hedberg BT_DBG("%s end: err %d", hdev->name, err); 88675e84b7cSJohan Hedberg 88775e84b7cSJohan Hedberg if (err < 0) 88875e84b7cSJohan Hedberg return ERR_PTR(err); 88975e84b7cSJohan Hedberg 8907b1abbbeSJohan Hedberg return hci_get_cmd_complete(hdev, opcode, event); 8917b1abbbeSJohan Hedberg } 8927b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev); 8937b1abbbeSJohan Hedberg 8947b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 89507dc93ddSJohan Hedberg const void *param, u32 timeout) 8967b1abbbeSJohan Hedberg { 8977b1abbbeSJohan Hedberg return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); 89875e84b7cSJohan Hedberg } 89975e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync); 90075e84b7cSJohan Hedberg 9011da177e4SLinus Torvalds /* Execute request and wait for completion. */ 90201178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev, 90342c6b129SJohan Hedberg void (*func)(struct hci_request *req, 90442c6b129SJohan Hedberg unsigned long opt), 9051da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 9061da177e4SLinus Torvalds { 90742c6b129SJohan Hedberg struct hci_request req; 9081da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 9091da177e4SLinus Torvalds int err = 0; 9101da177e4SLinus Torvalds 9111da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 9121da177e4SLinus Torvalds 91342c6b129SJohan Hedberg hci_req_init(&req, hdev); 91442c6b129SJohan Hedberg 9151da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 9161da177e4SLinus Torvalds 91742c6b129SJohan Hedberg func(&req, opt); 91853cce22dSJohan Hedberg 91942c6b129SJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 92042c6b129SJohan Hedberg if (err < 0) { 92153cce22dSJohan Hedberg hdev->req_status = 0; 922920c8300SAndre Guedes 923920c8300SAndre Guedes /* ENODATA means the HCI request command queue is empty. 924920c8300SAndre Guedes * This can happen when a request with conditionals doesn't 925920c8300SAndre Guedes * trigger any commands to be sent. This is normal behavior 926920c8300SAndre Guedes * and should not trigger an error return. 92742c6b129SJohan Hedberg */ 928920c8300SAndre Guedes if (err == -ENODATA) 92942c6b129SJohan Hedberg return 0; 930920c8300SAndre Guedes 931920c8300SAndre Guedes return err; 93253cce22dSJohan Hedberg } 93353cce22dSJohan Hedberg 934bc4445c7SAndre Guedes add_wait_queue(&hdev->req_wait_q, &wait); 935bc4445c7SAndre Guedes set_current_state(TASK_INTERRUPTIBLE); 936bc4445c7SAndre Guedes 9371da177e4SLinus Torvalds schedule_timeout(timeout); 9381da177e4SLinus Torvalds 9391da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 9401da177e4SLinus Torvalds 9411da177e4SLinus Torvalds if (signal_pending(current)) 9421da177e4SLinus Torvalds return -EINTR; 9431da177e4SLinus Torvalds 9441da177e4SLinus Torvalds switch (hdev->req_status) { 9451da177e4SLinus Torvalds case HCI_REQ_DONE: 946e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 9471da177e4SLinus Torvalds break; 9481da177e4SLinus Torvalds 9491da177e4SLinus Torvalds case HCI_REQ_CANCELED: 9501da177e4SLinus Torvalds err = -hdev->req_result; 9511da177e4SLinus Torvalds break; 9521da177e4SLinus Torvalds 9531da177e4SLinus Torvalds default: 9541da177e4SLinus Torvalds err = -ETIMEDOUT; 9551da177e4SLinus Torvalds break; 9563ff50b79SStephen Hemminger } 9571da177e4SLinus Torvalds 958a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 9591da177e4SLinus Torvalds 9601da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 9611da177e4SLinus Torvalds 9621da177e4SLinus Torvalds return err; 9631da177e4SLinus Torvalds } 9641da177e4SLinus Torvalds 96501178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev, 96642c6b129SJohan Hedberg void (*req)(struct hci_request *req, 96742c6b129SJohan Hedberg unsigned long opt), 9681da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 9691da177e4SLinus Torvalds { 9701da177e4SLinus Torvalds int ret; 9711da177e4SLinus Torvalds 9727c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 9737c6a329eSMarcel Holtmann return -ENETDOWN; 9747c6a329eSMarcel Holtmann 9751da177e4SLinus Torvalds /* Serialize all requests */ 9761da177e4SLinus Torvalds hci_req_lock(hdev); 97701178cd4SJohan Hedberg ret = __hci_req_sync(hdev, req, opt, timeout); 9781da177e4SLinus Torvalds hci_req_unlock(hdev); 9791da177e4SLinus Torvalds 9801da177e4SLinus Torvalds return ret; 9811da177e4SLinus Torvalds } 9821da177e4SLinus Torvalds 98342c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt) 9841da177e4SLinus Torvalds { 98542c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 9861da177e4SLinus Torvalds 9871da177e4SLinus Torvalds /* Reset device */ 98842c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 98942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 9901da177e4SLinus Torvalds } 9911da177e4SLinus Torvalds 99242c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 9931da177e4SLinus Torvalds { 99442c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 9952455a3eaSAndrei Emeltchenko 9961da177e4SLinus Torvalds /* Read Local Supported Features */ 99742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 9981da177e4SLinus Torvalds 9991143e5a6SMarcel Holtmann /* Read Local Version */ 100042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 10012177bab5SJohan Hedberg 10022177bab5SJohan Hedberg /* Read BD Address */ 100342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 10041da177e4SLinus Torvalds } 10051da177e4SLinus Torvalds 100642c6b129SJohan Hedberg static void amp_init(struct hci_request *req) 1007e61ef499SAndrei Emeltchenko { 100842c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 10092455a3eaSAndrei Emeltchenko 1010e61ef499SAndrei Emeltchenko /* Read Local Version */ 101142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 10126bcbc489SAndrei Emeltchenko 1013f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 1014f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 1015f6996cfeSMarcel Holtmann 1016f6996cfeSMarcel Holtmann /* Read Local Supported Features */ 1017f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 1018f6996cfeSMarcel Holtmann 10196bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 102042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 1021e71dfabaSAndrei Emeltchenko 1022e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 102342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 10247528ca1cSMarcel Holtmann 1025f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 1026f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 1027f38ba941SMarcel Holtmann 10287528ca1cSMarcel Holtmann /* Read Location Data */ 10297528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 1030e61ef499SAndrei Emeltchenko } 1031e61ef499SAndrei Emeltchenko 103242c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 1033e61ef499SAndrei Emeltchenko { 103442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1035e61ef499SAndrei Emeltchenko 1036e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 1037e61ef499SAndrei Emeltchenko 103811778716SAndrei Emeltchenko /* Reset */ 103911778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 104042c6b129SJohan Hedberg hci_reset_req(req, 0); 104111778716SAndrei Emeltchenko 1042e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 1043e61ef499SAndrei Emeltchenko case HCI_BREDR: 104442c6b129SJohan Hedberg bredr_init(req); 1045e61ef499SAndrei Emeltchenko break; 1046e61ef499SAndrei Emeltchenko 1047e61ef499SAndrei Emeltchenko case HCI_AMP: 104842c6b129SJohan Hedberg amp_init(req); 1049e61ef499SAndrei Emeltchenko break; 1050e61ef499SAndrei Emeltchenko 1051e61ef499SAndrei Emeltchenko default: 1052e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 1053e61ef499SAndrei Emeltchenko break; 1054e61ef499SAndrei Emeltchenko } 1055e61ef499SAndrei Emeltchenko } 1056e61ef499SAndrei Emeltchenko 105742c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 10582177bab5SJohan Hedberg { 10594ca048e3SMarcel Holtmann struct hci_dev *hdev = req->hdev; 10604ca048e3SMarcel Holtmann 10612177bab5SJohan Hedberg __le16 param; 10622177bab5SJohan Hedberg __u8 flt_type; 10632177bab5SJohan Hedberg 10642177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 106542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 10662177bab5SJohan Hedberg 10672177bab5SJohan Hedberg /* Read Class of Device */ 106842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 10692177bab5SJohan Hedberg 10702177bab5SJohan Hedberg /* Read Local Name */ 107142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 10722177bab5SJohan Hedberg 10732177bab5SJohan Hedberg /* Read Voice Setting */ 107442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 10752177bab5SJohan Hedberg 1076b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 1077b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 1078b4cb9fb2SMarcel Holtmann 10794b836f39SMarcel Holtmann /* Read Current IAC LAP */ 10804b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 10814b836f39SMarcel Holtmann 10822177bab5SJohan Hedberg /* Clear Event Filters */ 10832177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 108442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 10852177bab5SJohan Hedberg 10862177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 10872177bab5SJohan Hedberg param = __constant_cpu_to_le16(0x7d00); 108842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 10892177bab5SJohan Hedberg 10904ca048e3SMarcel Holtmann /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, 10914ca048e3SMarcel Holtmann * but it does not support page scan related HCI commands. 10924ca048e3SMarcel Holtmann */ 10934ca048e3SMarcel Holtmann if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) { 1094f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 1095f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 1096f332ec66SJohan Hedberg } 10972177bab5SJohan Hedberg } 10982177bab5SJohan Hedberg 109942c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 11002177bab5SJohan Hedberg { 1101c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 1102c73eee91SJohan Hedberg 11032177bab5SJohan Hedberg /* Read LE Buffer Size */ 110442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 11052177bab5SJohan Hedberg 11062177bab5SJohan Hedberg /* Read LE Local Supported Features */ 110742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 11082177bab5SJohan Hedberg 11092177bab5SJohan Hedberg /* Read LE Advertising Channel TX Power */ 111042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 11112177bab5SJohan Hedberg 11122177bab5SJohan Hedberg /* Read LE White List Size */ 111342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 11142177bab5SJohan Hedberg 11152177bab5SJohan Hedberg /* Read LE Supported States */ 111642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 1117c73eee91SJohan Hedberg 1118c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 1119c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1120c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 11212177bab5SJohan Hedberg } 11222177bab5SJohan Hedberg 11232177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 11242177bab5SJohan Hedberg { 11252177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 11262177bab5SJohan Hedberg return 0x02; 11272177bab5SJohan Hedberg 11282177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 11292177bab5SJohan Hedberg return 0x01; 11302177bab5SJohan Hedberg 11312177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 11322177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 11332177bab5SJohan Hedberg return 0x01; 11342177bab5SJohan Hedberg 11352177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 11362177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 11372177bab5SJohan Hedberg return 0x01; 11382177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 11392177bab5SJohan Hedberg return 0x01; 11402177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 11412177bab5SJohan Hedberg return 0x01; 11422177bab5SJohan Hedberg } 11432177bab5SJohan Hedberg 11442177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 11452177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 11462177bab5SJohan Hedberg return 0x01; 11472177bab5SJohan Hedberg 11482177bab5SJohan Hedberg return 0x00; 11492177bab5SJohan Hedberg } 11502177bab5SJohan Hedberg 115142c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 11522177bab5SJohan Hedberg { 11532177bab5SJohan Hedberg u8 mode; 11542177bab5SJohan Hedberg 115542c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 11562177bab5SJohan Hedberg 115742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 11582177bab5SJohan Hedberg } 11592177bab5SJohan Hedberg 116042c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 11612177bab5SJohan Hedberg { 116242c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 116342c6b129SJohan Hedberg 11642177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 11652177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 11662177bab5SJohan Hedberg * command otherwise. 11672177bab5SJohan Hedberg */ 11682177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 11692177bab5SJohan Hedberg 11702177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 11712177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 11722177bab5SJohan Hedberg */ 11732177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 11742177bab5SJohan Hedberg return; 11752177bab5SJohan Hedberg 11762177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 11772177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 11782177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 11792177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 11802177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 11812177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 1182c7882cbdSMarcel Holtmann } else { 1183c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 1184c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 1185c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 1186c7882cbdSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 1187c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 1188c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 1189c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 1190c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 1191c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 1192c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 1193c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 11942177bab5SJohan Hedberg } 11952177bab5SJohan Hedberg 11962177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 11972177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 11982177bab5SJohan Hedberg 11992177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 12002177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 12012177bab5SJohan Hedberg 12022177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 12032177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 12042177bab5SJohan Hedberg 12052177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 12062177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 12072177bab5SJohan Hedberg 12082177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 12092177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 12102177bab5SJohan Hedberg 12112177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 12122177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 12132177bab5SJohan Hedberg 12142177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 12152177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 12162177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 12172177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 12182177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 12192177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 12202177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 12212177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 12222177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 12232177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 12242177bab5SJohan Hedberg * Features Notification 12252177bab5SJohan Hedberg */ 12262177bab5SJohan Hedberg } 12272177bab5SJohan Hedberg 12282177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 12292177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 12302177bab5SJohan Hedberg 123142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 12322177bab5SJohan Hedberg 12332177bab5SJohan Hedberg if (lmp_le_capable(hdev)) { 12342177bab5SJohan Hedberg memset(events, 0, sizeof(events)); 12352177bab5SJohan Hedberg events[0] = 0x1f; 123642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, 12372177bab5SJohan Hedberg sizeof(events), events); 12382177bab5SJohan Hedberg } 12392177bab5SJohan Hedberg } 12402177bab5SJohan Hedberg 124142c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 12422177bab5SJohan Hedberg { 124342c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 124442c6b129SJohan Hedberg 12452177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 124642c6b129SJohan Hedberg bredr_setup(req); 124756f87901SJohan Hedberg else 124856f87901SJohan Hedberg clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 12492177bab5SJohan Hedberg 12502177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 125142c6b129SJohan Hedberg le_setup(req); 12522177bab5SJohan Hedberg 125342c6b129SJohan Hedberg hci_setup_event_mask(req); 12542177bab5SJohan Hedberg 12553f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 12563f8e2d75SJohan Hedberg * local supported commands HCI command. 12573f8e2d75SJohan Hedberg */ 12583f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 125942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 12602177bab5SJohan Hedberg 12612177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 126257af75a8SMarcel Holtmann /* When SSP is available, then the host features page 126357af75a8SMarcel Holtmann * should also be available as well. However some 126457af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 126557af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 126657af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 126757af75a8SMarcel Holtmann */ 126857af75a8SMarcel Holtmann hdev->max_page = 0x01; 126957af75a8SMarcel Holtmann 12702177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 12712177bab5SJohan Hedberg u8 mode = 0x01; 127242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 12732177bab5SJohan Hedberg sizeof(mode), &mode); 12742177bab5SJohan Hedberg } else { 12752177bab5SJohan Hedberg struct hci_cp_write_eir cp; 12762177bab5SJohan Hedberg 12772177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 12782177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 12792177bab5SJohan Hedberg 128042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 12812177bab5SJohan Hedberg } 12822177bab5SJohan Hedberg } 12832177bab5SJohan Hedberg 12842177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 128542c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 12862177bab5SJohan Hedberg 12872177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 128842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 12892177bab5SJohan Hedberg 12902177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 12912177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 12922177bab5SJohan Hedberg 12932177bab5SJohan Hedberg cp.page = 0x01; 129442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 129542c6b129SJohan Hedberg sizeof(cp), &cp); 12962177bab5SJohan Hedberg } 12972177bab5SJohan Hedberg 12982177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 12992177bab5SJohan Hedberg u8 enable = 1; 130042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 13012177bab5SJohan Hedberg &enable); 13022177bab5SJohan Hedberg } 13032177bab5SJohan Hedberg } 13042177bab5SJohan Hedberg 130542c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 13062177bab5SJohan Hedberg { 130742c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 13082177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 13092177bab5SJohan Hedberg u16 link_policy = 0; 13102177bab5SJohan Hedberg 13112177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 13122177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 13132177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 13142177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 13152177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 13162177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 13172177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 13182177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 13192177bab5SJohan Hedberg 13202177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 132142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 13222177bab5SJohan Hedberg } 13232177bab5SJohan Hedberg 132442c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 13252177bab5SJohan Hedberg { 132642c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 13272177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 13282177bab5SJohan Hedberg 1329c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 1330c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1331c73eee91SJohan Hedberg return; 1332c73eee91SJohan Hedberg 13332177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 13342177bab5SJohan Hedberg 13352177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 13362177bab5SJohan Hedberg cp.le = 0x01; 13372177bab5SJohan Hedberg cp.simul = lmp_le_br_capable(hdev); 13382177bab5SJohan Hedberg } 13392177bab5SJohan Hedberg 13402177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 134142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 13422177bab5SJohan Hedberg &cp); 13432177bab5SJohan Hedberg } 13442177bab5SJohan Hedberg 1345d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 1346d62e6d67SJohan Hedberg { 1347d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 1348d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1349d62e6d67SJohan Hedberg 1350d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 1351d62e6d67SJohan Hedberg * enable all necessary events for it. 1352d62e6d67SJohan Hedberg */ 135353b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 1354d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 1355d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 1356d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 1357d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 1358d62e6d67SJohan Hedberg } 1359d62e6d67SJohan Hedberg 1360d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 1361d62e6d67SJohan Hedberg * enable all necessary events for it. 1362d62e6d67SJohan Hedberg */ 136353b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 1364d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 1365d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 1366d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 1367d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 1368d62e6d67SJohan Hedberg } 1369d62e6d67SJohan Hedberg 137040c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 137140c59fcbSMarcel Holtmann if (lmp_ping_capable(hdev)) 137240c59fcbSMarcel Holtmann events[2] |= 0x80; 137340c59fcbSMarcel Holtmann 1374d62e6d67SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 1375d62e6d67SJohan Hedberg } 1376d62e6d67SJohan Hedberg 137742c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 13782177bab5SJohan Hedberg { 137942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1380d2c5d77fSJohan Hedberg u8 p; 138142c6b129SJohan Hedberg 1382b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 1383b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 1384b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 1385b8f4e068SGustavo Padovan * 1386b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 1387b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 1388b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 1389b8f4e068SGustavo Padovan * command redundant anyway. 1390f9f462faSMarcel Holtmann * 1391f9f462faSMarcel Holtmann * Some controllers indicate that they support handling deleting 1392f9f462faSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 1393f9f462faSMarcel Holtmann * just disable this command. 1394b8f4e068SGustavo Padovan */ 1395f9f462faSMarcel Holtmann if (hdev->commands[6] & 0x80 && 1396f9f462faSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 139759f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 139859f45d57SJohan Hedberg 139959f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 140059f45d57SJohan Hedberg cp.delete_all = 0x01; 140159f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 140259f45d57SJohan Hedberg sizeof(cp), &cp); 140359f45d57SJohan Hedberg } 140459f45d57SJohan Hedberg 14052177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 140642c6b129SJohan Hedberg hci_setup_link_policy(req); 14072177bab5SJohan Hedberg 140879830f66SMarcel Holtmann if (lmp_le_capable(hdev)) { 1409bef34c0aSMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 1410bef34c0aSMarcel Holtmann /* If the controller has a public BD_ADDR, then 1411bef34c0aSMarcel Holtmann * by default use that one. If this is a LE only 1412bef34c0aSMarcel Holtmann * controller without a public address, default 1413bef34c0aSMarcel Holtmann * to the random address. 141479830f66SMarcel Holtmann */ 141579830f66SMarcel Holtmann if (bacmp(&hdev->bdaddr, BDADDR_ANY)) 141679830f66SMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_PUBLIC; 141779830f66SMarcel Holtmann else 141879830f66SMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_RANDOM; 1419bef34c0aSMarcel Holtmann } 142079830f66SMarcel Holtmann 142142c6b129SJohan Hedberg hci_set_le_support(req); 142279830f66SMarcel Holtmann } 1423d2c5d77fSJohan Hedberg 1424d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 1425d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 1426d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 1427d2c5d77fSJohan Hedberg 1428d2c5d77fSJohan Hedberg cp.page = p; 1429d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 1430d2c5d77fSJohan Hedberg sizeof(cp), &cp); 1431d2c5d77fSJohan Hedberg } 14322177bab5SJohan Hedberg } 14332177bab5SJohan Hedberg 14345d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt) 14355d4e7e8dSJohan Hedberg { 14365d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 14375d4e7e8dSJohan Hedberg 1438d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 1439d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 1440d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 1441d62e6d67SJohan Hedberg 14425d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 144353b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 14445d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 1445a6d0d690SMarcel Holtmann 1446a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 14475afeac14SMarcel Holtmann if ((lmp_sc_capable(hdev) || 14485afeac14SMarcel Holtmann test_bit(HCI_FORCE_SC, &hdev->dev_flags)) && 1449a6d0d690SMarcel Holtmann test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) { 1450a6d0d690SMarcel Holtmann u8 support = 0x01; 1451a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 1452a6d0d690SMarcel Holtmann sizeof(support), &support); 1453a6d0d690SMarcel Holtmann } 14545d4e7e8dSJohan Hedberg } 14555d4e7e8dSJohan Hedberg 14562177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 14572177bab5SJohan Hedberg { 14582177bab5SJohan Hedberg int err; 14592177bab5SJohan Hedberg 14602177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 14612177bab5SJohan Hedberg if (err < 0) 14622177bab5SJohan Hedberg return err; 14632177bab5SJohan Hedberg 14644b4148e9SMarcel Holtmann /* The Device Under Test (DUT) mode is special and available for 14654b4148e9SMarcel Holtmann * all controller types. So just create it early on. 14664b4148e9SMarcel Holtmann */ 14674b4148e9SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 14684b4148e9SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 14694b4148e9SMarcel Holtmann &dut_mode_fops); 14704b4148e9SMarcel Holtmann } 14714b4148e9SMarcel Holtmann 14722177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 14732177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 14742177bab5SJohan Hedberg * first stage init. 14752177bab5SJohan Hedberg */ 14762177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 14772177bab5SJohan Hedberg return 0; 14782177bab5SJohan Hedberg 14792177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 14802177bab5SJohan Hedberg if (err < 0) 14812177bab5SJohan Hedberg return err; 14822177bab5SJohan Hedberg 14835d4e7e8dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 14845d4e7e8dSJohan Hedberg if (err < 0) 14855d4e7e8dSJohan Hedberg return err; 14865d4e7e8dSJohan Hedberg 1487baf27f6eSMarcel Holtmann err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 1488baf27f6eSMarcel Holtmann if (err < 0) 1489baf27f6eSMarcel Holtmann return err; 1490baf27f6eSMarcel Holtmann 1491baf27f6eSMarcel Holtmann /* Only create debugfs entries during the initial setup 1492baf27f6eSMarcel Holtmann * phase and not every time the controller gets powered on. 1493baf27f6eSMarcel Holtmann */ 1494baf27f6eSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 1495baf27f6eSMarcel Holtmann return 0; 1496baf27f6eSMarcel Holtmann 1497dfb826a8SMarcel Holtmann debugfs_create_file("features", 0444, hdev->debugfs, hdev, 1498dfb826a8SMarcel Holtmann &features_fops); 1499ceeb3bc0SMarcel Holtmann debugfs_create_u16("manufacturer", 0444, hdev->debugfs, 1500ceeb3bc0SMarcel Holtmann &hdev->manufacturer); 1501ceeb3bc0SMarcel Holtmann debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); 1502ceeb3bc0SMarcel Holtmann debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); 150370afe0b8SMarcel Holtmann debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, 150470afe0b8SMarcel Holtmann &blacklist_fops); 150547219839SMarcel Holtmann debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); 150647219839SMarcel Holtmann 1507baf27f6eSMarcel Holtmann if (lmp_bredr_capable(hdev)) { 1508baf27f6eSMarcel Holtmann debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, 1509baf27f6eSMarcel Holtmann hdev, &inquiry_cache_fops); 151002d08d15SMarcel Holtmann debugfs_create_file("link_keys", 0400, hdev->debugfs, 151102d08d15SMarcel Holtmann hdev, &link_keys_fops); 1512babdbb3cSMarcel Holtmann debugfs_create_file("dev_class", 0444, hdev->debugfs, 1513babdbb3cSMarcel Holtmann hdev, &dev_class_fops); 1514041000b9SMarcel Holtmann debugfs_create_file("voice_setting", 0444, hdev->debugfs, 1515041000b9SMarcel Holtmann hdev, &voice_setting_fops); 1516baf27f6eSMarcel Holtmann } 1517baf27f6eSMarcel Holtmann 151806f5b778SMarcel Holtmann if (lmp_ssp_capable(hdev)) { 1519ebd1e33bSMarcel Holtmann debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, 1520ebd1e33bSMarcel Holtmann hdev, &auto_accept_delay_fops); 152106f5b778SMarcel Holtmann debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs, 152206f5b778SMarcel Holtmann hdev, &ssp_debug_mode_fops); 15235afeac14SMarcel Holtmann debugfs_create_file("force_sc_support", 0644, hdev->debugfs, 15245afeac14SMarcel Holtmann hdev, &force_sc_support_fops); 1525134c2a89SMarcel Holtmann debugfs_create_file("sc_only_mode", 0444, hdev->debugfs, 1526134c2a89SMarcel Holtmann hdev, &sc_only_mode_fops); 152706f5b778SMarcel Holtmann } 1528ebd1e33bSMarcel Holtmann 15292bfa3531SMarcel Holtmann if (lmp_sniff_capable(hdev)) { 15302bfa3531SMarcel Holtmann debugfs_create_file("idle_timeout", 0644, hdev->debugfs, 15312bfa3531SMarcel Holtmann hdev, &idle_timeout_fops); 15322bfa3531SMarcel Holtmann debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs, 15332bfa3531SMarcel Holtmann hdev, &sniff_min_interval_fops); 15342bfa3531SMarcel Holtmann debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs, 15352bfa3531SMarcel Holtmann hdev, &sniff_max_interval_fops); 15362bfa3531SMarcel Holtmann } 15372bfa3531SMarcel Holtmann 1538d0f729b8SMarcel Holtmann if (lmp_le_capable(hdev)) { 1539d0f729b8SMarcel Holtmann debugfs_create_u8("white_list_size", 0444, hdev->debugfs, 1540d0f729b8SMarcel Holtmann &hdev->le_white_list_size); 1541e7b8fc92SMarcel Holtmann debugfs_create_file("static_address", 0444, hdev->debugfs, 1542e7b8fc92SMarcel Holtmann hdev, &static_address_fops); 154392202185SMarcel Holtmann debugfs_create_file("own_address_type", 0644, hdev->debugfs, 154492202185SMarcel Holtmann hdev, &own_address_type_fops); 15453698d704SMarcel Holtmann debugfs_create_file("identity_resolving_keys", 0400, 15463698d704SMarcel Holtmann hdev->debugfs, hdev, 15473698d704SMarcel Holtmann &identity_resolving_keys_fops); 15488f8625cdSMarcel Holtmann debugfs_create_file("long_term_keys", 0400, hdev->debugfs, 15498f8625cdSMarcel Holtmann hdev, &long_term_keys_fops); 15504e70c7e7SMarcel Holtmann debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, 15514e70c7e7SMarcel Holtmann hdev, &conn_min_interval_fops); 15524e70c7e7SMarcel Holtmann debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, 15534e70c7e7SMarcel Holtmann hdev, &conn_max_interval_fops); 155489863109SJukka Rissanen debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev, 155589863109SJukka Rissanen &lowpan_debugfs_fops); 1556d0f729b8SMarcel Holtmann } 1557e7b8fc92SMarcel Holtmann 1558baf27f6eSMarcel Holtmann return 0; 15592177bab5SJohan Hedberg } 15602177bab5SJohan Hedberg 156142c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 15621da177e4SLinus Torvalds { 15631da177e4SLinus Torvalds __u8 scan = opt; 15641da177e4SLinus Torvalds 156542c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 15661da177e4SLinus Torvalds 15671da177e4SLinus Torvalds /* Inquiry and Page scans */ 156842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 15691da177e4SLinus Torvalds } 15701da177e4SLinus Torvalds 157142c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 15721da177e4SLinus Torvalds { 15731da177e4SLinus Torvalds __u8 auth = opt; 15741da177e4SLinus Torvalds 157542c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 15761da177e4SLinus Torvalds 15771da177e4SLinus Torvalds /* Authentication */ 157842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 15791da177e4SLinus Torvalds } 15801da177e4SLinus Torvalds 158142c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 15821da177e4SLinus Torvalds { 15831da177e4SLinus Torvalds __u8 encrypt = opt; 15841da177e4SLinus Torvalds 158542c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 15861da177e4SLinus Torvalds 1587e4e8e37cSMarcel Holtmann /* Encryption */ 158842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 15891da177e4SLinus Torvalds } 15901da177e4SLinus Torvalds 159142c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 1592e4e8e37cSMarcel Holtmann { 1593e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1594e4e8e37cSMarcel Holtmann 159542c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1596e4e8e37cSMarcel Holtmann 1597e4e8e37cSMarcel Holtmann /* Default link policy */ 159842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1599e4e8e37cSMarcel Holtmann } 1600e4e8e37cSMarcel Holtmann 16011da177e4SLinus Torvalds /* Get HCI device by index. 16021da177e4SLinus Torvalds * Device is held on return. */ 16031da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 16041da177e4SLinus Torvalds { 16058035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 16061da177e4SLinus Torvalds 16071da177e4SLinus Torvalds BT_DBG("%d", index); 16081da177e4SLinus Torvalds 16091da177e4SLinus Torvalds if (index < 0) 16101da177e4SLinus Torvalds return NULL; 16111da177e4SLinus Torvalds 16121da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 16138035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 16141da177e4SLinus Torvalds if (d->id == index) { 16151da177e4SLinus Torvalds hdev = hci_dev_hold(d); 16161da177e4SLinus Torvalds break; 16171da177e4SLinus Torvalds } 16181da177e4SLinus Torvalds } 16191da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 16201da177e4SLinus Torvalds return hdev; 16211da177e4SLinus Torvalds } 16221da177e4SLinus Torvalds 16231da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1624ff9ef578SJohan Hedberg 162530dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 162630dc78e1SJohan Hedberg { 162730dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 162830dc78e1SJohan Hedberg 16296fbe195dSAndre Guedes switch (discov->state) { 1630343f935bSAndre Guedes case DISCOVERY_FINDING: 16316fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 163230dc78e1SJohan Hedberg return true; 163330dc78e1SJohan Hedberg 16346fbe195dSAndre Guedes default: 163530dc78e1SJohan Hedberg return false; 163630dc78e1SJohan Hedberg } 16376fbe195dSAndre Guedes } 163830dc78e1SJohan Hedberg 1639ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1640ff9ef578SJohan Hedberg { 1641ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1642ff9ef578SJohan Hedberg 1643ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 1644ff9ef578SJohan Hedberg return; 1645ff9ef578SJohan Hedberg 1646ff9ef578SJohan Hedberg switch (state) { 1647ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 16487b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 1649ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1650ff9ef578SJohan Hedberg break; 1651ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1652ff9ef578SJohan Hedberg break; 1653343f935bSAndre Guedes case DISCOVERY_FINDING: 1654ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1655ff9ef578SJohan Hedberg break; 165630dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 165730dc78e1SJohan Hedberg break; 1658ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1659ff9ef578SJohan Hedberg break; 1660ff9ef578SJohan Hedberg } 1661ff9ef578SJohan Hedberg 1662ff9ef578SJohan Hedberg hdev->discovery.state = state; 1663ff9ef578SJohan Hedberg } 1664ff9ef578SJohan Hedberg 16651f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 16661da177e4SLinus Torvalds { 166730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1668b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 16691da177e4SLinus Torvalds 1670561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1671561aafbcSJohan Hedberg list_del(&p->all); 1672b57c1a56SJohan Hedberg kfree(p); 16731da177e4SLinus Torvalds } 1674561aafbcSJohan Hedberg 1675561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1676561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 16771da177e4SLinus Torvalds } 16781da177e4SLinus Torvalds 1679a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1680a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 16811da177e4SLinus Torvalds { 168230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 16831da177e4SLinus Torvalds struct inquiry_entry *e; 16841da177e4SLinus Torvalds 16856ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 16861da177e4SLinus Torvalds 1687561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 16881da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 16891da177e4SLinus Torvalds return e; 16901da177e4SLinus Torvalds } 16911da177e4SLinus Torvalds 1692b57c1a56SJohan Hedberg return NULL; 1693b57c1a56SJohan Hedberg } 1694b57c1a56SJohan Hedberg 1695561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1696561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1697561aafbcSJohan Hedberg { 169830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1699561aafbcSJohan Hedberg struct inquiry_entry *e; 1700561aafbcSJohan Hedberg 17016ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1702561aafbcSJohan Hedberg 1703561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1704561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1705561aafbcSJohan Hedberg return e; 1706561aafbcSJohan Hedberg } 1707561aafbcSJohan Hedberg 1708561aafbcSJohan Hedberg return NULL; 1709561aafbcSJohan Hedberg } 1710561aafbcSJohan Hedberg 171130dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 171230dc78e1SJohan Hedberg bdaddr_t *bdaddr, 171330dc78e1SJohan Hedberg int state) 171430dc78e1SJohan Hedberg { 171530dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 171630dc78e1SJohan Hedberg struct inquiry_entry *e; 171730dc78e1SJohan Hedberg 17186ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 171930dc78e1SJohan Hedberg 172030dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 172130dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 172230dc78e1SJohan Hedberg return e; 172330dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 172430dc78e1SJohan Hedberg return e; 172530dc78e1SJohan Hedberg } 172630dc78e1SJohan Hedberg 172730dc78e1SJohan Hedberg return NULL; 172830dc78e1SJohan Hedberg } 172930dc78e1SJohan Hedberg 1730a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1731a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1732a3d4e20aSJohan Hedberg { 1733a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1734a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1735a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1736a3d4e20aSJohan Hedberg 1737a3d4e20aSJohan Hedberg list_del(&ie->list); 1738a3d4e20aSJohan Hedberg 1739a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1740a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1741a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1742a3d4e20aSJohan Hedberg break; 1743a3d4e20aSJohan Hedberg pos = &p->list; 1744a3d4e20aSJohan Hedberg } 1745a3d4e20aSJohan Hedberg 1746a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1747a3d4e20aSJohan Hedberg } 1748a3d4e20aSJohan Hedberg 17493175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1750388fc8faSJohan Hedberg bool name_known, bool *ssp) 17511da177e4SLinus Torvalds { 175230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 175370f23020SAndrei Emeltchenko struct inquiry_entry *ie; 17541da177e4SLinus Torvalds 17556ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 17561da177e4SLinus Torvalds 17572b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 17582b2fec4dSSzymon Janc 1759388fc8faSJohan Hedberg if (ssp) 1760388fc8faSJohan Hedberg *ssp = data->ssp_mode; 1761388fc8faSJohan Hedberg 176270f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1763a3d4e20aSJohan Hedberg if (ie) { 1764388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 1765388fc8faSJohan Hedberg *ssp = true; 1766388fc8faSJohan Hedberg 1767a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1768a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1769a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1770a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1771a3d4e20aSJohan Hedberg } 1772a3d4e20aSJohan Hedberg 1773561aafbcSJohan Hedberg goto update; 1774a3d4e20aSJohan Hedberg } 1775561aafbcSJohan Hedberg 17761da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 177770f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 177870f23020SAndrei Emeltchenko if (!ie) 17793175405bSJohan Hedberg return false; 178070f23020SAndrei Emeltchenko 1781561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1782561aafbcSJohan Hedberg 1783561aafbcSJohan Hedberg if (name_known) { 1784561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1785561aafbcSJohan Hedberg } else { 1786561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1787561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1788561aafbcSJohan Hedberg } 1789561aafbcSJohan Hedberg 1790561aafbcSJohan Hedberg update: 1791561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1792561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1793561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1794561aafbcSJohan Hedberg list_del(&ie->list); 17951da177e4SLinus Torvalds } 17961da177e4SLinus Torvalds 179770f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 179870f23020SAndrei Emeltchenko ie->timestamp = jiffies; 17991da177e4SLinus Torvalds cache->timestamp = jiffies; 18003175405bSJohan Hedberg 18013175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 18023175405bSJohan Hedberg return false; 18033175405bSJohan Hedberg 18043175405bSJohan Hedberg return true; 18051da177e4SLinus Torvalds } 18061da177e4SLinus Torvalds 18071da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 18081da177e4SLinus Torvalds { 180930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 18101da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 18111da177e4SLinus Torvalds struct inquiry_entry *e; 18121da177e4SLinus Torvalds int copied = 0; 18131da177e4SLinus Torvalds 1814561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 18151da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1816b57c1a56SJohan Hedberg 1817b57c1a56SJohan Hedberg if (copied >= num) 1818b57c1a56SJohan Hedberg break; 1819b57c1a56SJohan Hedberg 18201da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 18211da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 18221da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 18231da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 18241da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 18251da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1826b57c1a56SJohan Hedberg 18271da177e4SLinus Torvalds info++; 1828b57c1a56SJohan Hedberg copied++; 18291da177e4SLinus Torvalds } 18301da177e4SLinus Torvalds 18311da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 18321da177e4SLinus Torvalds return copied; 18331da177e4SLinus Torvalds } 18341da177e4SLinus Torvalds 183542c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 18361da177e4SLinus Torvalds { 18371da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 183842c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 18391da177e4SLinus Torvalds struct hci_cp_inquiry cp; 18401da177e4SLinus Torvalds 18411da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 18421da177e4SLinus Torvalds 18431da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 18441da177e4SLinus Torvalds return; 18451da177e4SLinus Torvalds 18461da177e4SLinus Torvalds /* Start Inquiry */ 18471da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 18481da177e4SLinus Torvalds cp.length = ir->length; 18491da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 185042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 18511da177e4SLinus Torvalds } 18521da177e4SLinus Torvalds 18533e13fa1eSAndre Guedes static int wait_inquiry(void *word) 18543e13fa1eSAndre Guedes { 18553e13fa1eSAndre Guedes schedule(); 18563e13fa1eSAndre Guedes return signal_pending(current); 18573e13fa1eSAndre Guedes } 18583e13fa1eSAndre Guedes 18591da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 18601da177e4SLinus Torvalds { 18611da177e4SLinus Torvalds __u8 __user *ptr = arg; 18621da177e4SLinus Torvalds struct hci_inquiry_req ir; 18631da177e4SLinus Torvalds struct hci_dev *hdev; 18641da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 18651da177e4SLinus Torvalds long timeo; 18661da177e4SLinus Torvalds __u8 *buf; 18671da177e4SLinus Torvalds 18681da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 18691da177e4SLinus Torvalds return -EFAULT; 18701da177e4SLinus Torvalds 18715a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 18725a08ecceSAndrei Emeltchenko if (!hdev) 18731da177e4SLinus Torvalds return -ENODEV; 18741da177e4SLinus Torvalds 18750736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 18760736cfa8SMarcel Holtmann err = -EBUSY; 18770736cfa8SMarcel Holtmann goto done; 18780736cfa8SMarcel Holtmann } 18790736cfa8SMarcel Holtmann 18805b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 18815b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 18825b69bef5SMarcel Holtmann goto done; 18835b69bef5SMarcel Holtmann } 18845b69bef5SMarcel Holtmann 188556f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 188656f87901SJohan Hedberg err = -EOPNOTSUPP; 188756f87901SJohan Hedberg goto done; 188856f87901SJohan Hedberg } 188956f87901SJohan Hedberg 189009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 18911da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1892a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 18931f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 18941da177e4SLinus Torvalds do_inquiry = 1; 18951da177e4SLinus Torvalds } 189609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18971da177e4SLinus Torvalds 189804837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 189970f23020SAndrei Emeltchenko 190070f23020SAndrei Emeltchenko if (do_inquiry) { 190101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 190201178cd4SJohan Hedberg timeo); 190370f23020SAndrei Emeltchenko if (err < 0) 19041da177e4SLinus Torvalds goto done; 19053e13fa1eSAndre Guedes 19063e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 19073e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 19083e13fa1eSAndre Guedes */ 19093e13fa1eSAndre Guedes if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, 19103e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 19113e13fa1eSAndre Guedes return -EINTR; 191270f23020SAndrei Emeltchenko } 19131da177e4SLinus Torvalds 19148fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 19158fc9ced3SGustavo Padovan * 255 entries 19168fc9ced3SGustavo Padovan */ 19171da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 19181da177e4SLinus Torvalds 19191da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 19201da177e4SLinus Torvalds * copy it to the user space. 19211da177e4SLinus Torvalds */ 192270f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 192370f23020SAndrei Emeltchenko if (!buf) { 19241da177e4SLinus Torvalds err = -ENOMEM; 19251da177e4SLinus Torvalds goto done; 19261da177e4SLinus Torvalds } 19271da177e4SLinus Torvalds 192809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 19291da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 193009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 19311da177e4SLinus Torvalds 19321da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 19331da177e4SLinus Torvalds 19341da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 19351da177e4SLinus Torvalds ptr += sizeof(ir); 19361da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 19371da177e4SLinus Torvalds ir.num_rsp)) 19381da177e4SLinus Torvalds err = -EFAULT; 19391da177e4SLinus Torvalds } else 19401da177e4SLinus Torvalds err = -EFAULT; 19411da177e4SLinus Torvalds 19421da177e4SLinus Torvalds kfree(buf); 19431da177e4SLinus Torvalds 19441da177e4SLinus Torvalds done: 19451da177e4SLinus Torvalds hci_dev_put(hdev); 19461da177e4SLinus Torvalds return err; 19471da177e4SLinus Torvalds } 19481da177e4SLinus Torvalds 1949cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 19501da177e4SLinus Torvalds { 19511da177e4SLinus Torvalds int ret = 0; 19521da177e4SLinus Torvalds 19531da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 19541da177e4SLinus Torvalds 19551da177e4SLinus Torvalds hci_req_lock(hdev); 19561da177e4SLinus Torvalds 195794324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 195894324962SJohan Hovold ret = -ENODEV; 195994324962SJohan Hovold goto done; 196094324962SJohan Hovold } 196194324962SJohan Hovold 1962a5c8f270SMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 1963a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1964a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1965bf543036SJohan Hedberg */ 1966a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 1967611b30f7SMarcel Holtmann ret = -ERFKILL; 1968611b30f7SMarcel Holtmann goto done; 1969611b30f7SMarcel Holtmann } 1970611b30f7SMarcel Holtmann 1971a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 1972a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 1973a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1974a5c8f270SMarcel Holtmann * or not. 1975a5c8f270SMarcel Holtmann * 1976c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 1977c6beca0eSMarcel Holtmann * if a public address or static random address is 1978c6beca0eSMarcel Holtmann * available. 1979c6beca0eSMarcel Holtmann * 1980a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1981a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1982a5c8f270SMarcel Holtmann */ 1983c6beca0eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 1984c6beca0eSMarcel Holtmann hdev->dev_type == HCI_BREDR && 1985a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1986a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1987a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1988a5c8f270SMarcel Holtmann goto done; 1989a5c8f270SMarcel Holtmann } 1990a5c8f270SMarcel Holtmann } 1991a5c8f270SMarcel Holtmann 19921da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 19931da177e4SLinus Torvalds ret = -EALREADY; 19941da177e4SLinus Torvalds goto done; 19951da177e4SLinus Torvalds } 19961da177e4SLinus Torvalds 19971da177e4SLinus Torvalds if (hdev->open(hdev)) { 19981da177e4SLinus Torvalds ret = -EIO; 19991da177e4SLinus Torvalds goto done; 20001da177e4SLinus Torvalds } 20011da177e4SLinus Torvalds 20021da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 20031da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 2004f41c70c4SMarcel Holtmann 2005f41c70c4SMarcel Holtmann if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags)) 2006f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 2007f41c70c4SMarcel Holtmann 2008f41c70c4SMarcel Holtmann if (!ret) { 2009f41c70c4SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 2010f41c70c4SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 2011f41c70c4SMarcel Holtmann 20120736cfa8SMarcel Holtmann if (!test_bit(HCI_RAW, &hdev->flags) && 20130736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 20142177bab5SJohan Hedberg ret = __hci_init(hdev); 20151da177e4SLinus Torvalds } 20161da177e4SLinus Torvalds 2017f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 2018f41c70c4SMarcel Holtmann 20191da177e4SLinus Torvalds if (!ret) { 20201da177e4SLinus Torvalds hci_dev_hold(hdev); 20211da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 20221da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 2023bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 20240736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 20251514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 202609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2027744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 202809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 202956e5cb86SJohan Hedberg } 20301da177e4SLinus Torvalds } else { 20311da177e4SLinus Torvalds /* Init failed, cleanup */ 20323eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2033c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 2034b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 20351da177e4SLinus Torvalds 20361da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 20371da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 20381da177e4SLinus Torvalds 20391da177e4SLinus Torvalds if (hdev->flush) 20401da177e4SLinus Torvalds hdev->flush(hdev); 20411da177e4SLinus Torvalds 20421da177e4SLinus Torvalds if (hdev->sent_cmd) { 20431da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 20441da177e4SLinus Torvalds hdev->sent_cmd = NULL; 20451da177e4SLinus Torvalds } 20461da177e4SLinus Torvalds 20471da177e4SLinus Torvalds hdev->close(hdev); 20481da177e4SLinus Torvalds hdev->flags = 0; 20491da177e4SLinus Torvalds } 20501da177e4SLinus Torvalds 20511da177e4SLinus Torvalds done: 20521da177e4SLinus Torvalds hci_req_unlock(hdev); 20531da177e4SLinus Torvalds return ret; 20541da177e4SLinus Torvalds } 20551da177e4SLinus Torvalds 2056cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 2057cbed0ca1SJohan Hedberg 2058cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 2059cbed0ca1SJohan Hedberg { 2060cbed0ca1SJohan Hedberg struct hci_dev *hdev; 2061cbed0ca1SJohan Hedberg int err; 2062cbed0ca1SJohan Hedberg 2063cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 2064cbed0ca1SJohan Hedberg if (!hdev) 2065cbed0ca1SJohan Hedberg return -ENODEV; 2066cbed0ca1SJohan Hedberg 2067e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 2068e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 2069e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 2070e1d08f40SJohan Hedberg * completed. 2071e1d08f40SJohan Hedberg */ 2072e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2073e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 2074e1d08f40SJohan Hedberg 2075a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 2076a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 2077a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 2078a5c8f270SMarcel Holtmann */ 2079e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 2080e1d08f40SJohan Hedberg 2081cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 2082cbed0ca1SJohan Hedberg 2083cbed0ca1SJohan Hedberg hci_dev_put(hdev); 2084cbed0ca1SJohan Hedberg 2085cbed0ca1SJohan Hedberg return err; 2086cbed0ca1SJohan Hedberg } 2087cbed0ca1SJohan Hedberg 20881da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 20891da177e4SLinus Torvalds { 20901da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 20911da177e4SLinus Torvalds 209278c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 209378c04c0bSVinicius Costa Gomes 20941da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 20951da177e4SLinus Torvalds hci_req_lock(hdev); 20961da177e4SLinus Torvalds 20971da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 2098b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 20991da177e4SLinus Torvalds hci_req_unlock(hdev); 21001da177e4SLinus Torvalds return 0; 21011da177e4SLinus Torvalds } 21021da177e4SLinus Torvalds 21033eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 21043eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2105b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 21061da177e4SLinus Torvalds 210716ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 2108e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 210916ab91abSJohan Hedberg hdev->discov_timeout = 0; 21105e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 2111310a3d48SMarcel Holtmann clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 211216ab91abSJohan Hedberg } 211316ab91abSJohan Hedberg 2114a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 21157d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 21167d78525dSJohan Hedberg 21177ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 21187ba8b4beSAndre Guedes 211909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 21201f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 21211da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 212209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 21231da177e4SLinus Torvalds 21241da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 21251da177e4SLinus Torvalds 21261da177e4SLinus Torvalds if (hdev->flush) 21271da177e4SLinus Torvalds hdev->flush(hdev); 21281da177e4SLinus Torvalds 21291da177e4SLinus Torvalds /* Reset device */ 21301da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 21311da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 21328af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 21333a6afbd2SMarcel Holtmann !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 2134a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 21351da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 213601178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 21371da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 21381da177e4SLinus Torvalds } 21391da177e4SLinus Torvalds 2140c347b765SGustavo F. Padovan /* flush cmd work */ 2141c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 21421da177e4SLinus Torvalds 21431da177e4SLinus Torvalds /* Drop queues */ 21441da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 21451da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 21461da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 21471da177e4SLinus Torvalds 21481da177e4SLinus Torvalds /* Drop last sent command */ 21491da177e4SLinus Torvalds if (hdev->sent_cmd) { 2150b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 21511da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 21521da177e4SLinus Torvalds hdev->sent_cmd = NULL; 21531da177e4SLinus Torvalds } 21541da177e4SLinus Torvalds 2155b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 2156b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 2157b6ddb638SJohan Hedberg 21581da177e4SLinus Torvalds /* After this point our queues are empty 21591da177e4SLinus Torvalds * and no tasks are scheduled. */ 21601da177e4SLinus Torvalds hdev->close(hdev); 21611da177e4SLinus Torvalds 216235b973c9SJohan Hedberg /* Clear flags */ 216335b973c9SJohan Hedberg hdev->flags = 0; 216435b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 216535b973c9SJohan Hedberg 216693c311a0SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 216793c311a0SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 216809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2169744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 217009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 21718ee56540SMarcel Holtmann } 217293c311a0SMarcel Holtmann } 21735add6af8SJohan Hedberg 2174ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 2175536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 2176ced5c338SAndrei Emeltchenko 2177e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 217809b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 2179e59fda8dSJohan Hedberg 21801da177e4SLinus Torvalds hci_req_unlock(hdev); 21811da177e4SLinus Torvalds 21821da177e4SLinus Torvalds hci_dev_put(hdev); 21831da177e4SLinus Torvalds return 0; 21841da177e4SLinus Torvalds } 21851da177e4SLinus Torvalds 21861da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 21871da177e4SLinus Torvalds { 21881da177e4SLinus Torvalds struct hci_dev *hdev; 21891da177e4SLinus Torvalds int err; 21901da177e4SLinus Torvalds 219170f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 219270f23020SAndrei Emeltchenko if (!hdev) 21931da177e4SLinus Torvalds return -ENODEV; 21948ee56540SMarcel Holtmann 21950736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 21960736cfa8SMarcel Holtmann err = -EBUSY; 21970736cfa8SMarcel Holtmann goto done; 21980736cfa8SMarcel Holtmann } 21990736cfa8SMarcel Holtmann 22008ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 22018ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 22028ee56540SMarcel Holtmann 22031da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 22048ee56540SMarcel Holtmann 22050736cfa8SMarcel Holtmann done: 22061da177e4SLinus Torvalds hci_dev_put(hdev); 22071da177e4SLinus Torvalds return err; 22081da177e4SLinus Torvalds } 22091da177e4SLinus Torvalds 22101da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 22111da177e4SLinus Torvalds { 22121da177e4SLinus Torvalds struct hci_dev *hdev; 22131da177e4SLinus Torvalds int ret = 0; 22141da177e4SLinus Torvalds 221570f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 221670f23020SAndrei Emeltchenko if (!hdev) 22171da177e4SLinus Torvalds return -ENODEV; 22181da177e4SLinus Torvalds 22191da177e4SLinus Torvalds hci_req_lock(hdev); 22201da177e4SLinus Torvalds 2221808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 2222808a049eSMarcel Holtmann ret = -ENETDOWN; 22231da177e4SLinus Torvalds goto done; 2224808a049eSMarcel Holtmann } 22251da177e4SLinus Torvalds 22260736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22270736cfa8SMarcel Holtmann ret = -EBUSY; 22280736cfa8SMarcel Holtmann goto done; 22290736cfa8SMarcel Holtmann } 22300736cfa8SMarcel Holtmann 22311da177e4SLinus Torvalds /* Drop queues */ 22321da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 22331da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 22341da177e4SLinus Torvalds 223509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 22361f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 22371da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 223809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 22391da177e4SLinus Torvalds 22401da177e4SLinus Torvalds if (hdev->flush) 22411da177e4SLinus Torvalds hdev->flush(hdev); 22421da177e4SLinus Torvalds 22431da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 22446ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 22451da177e4SLinus Torvalds 22461da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 224701178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 22481da177e4SLinus Torvalds 22491da177e4SLinus Torvalds done: 22501da177e4SLinus Torvalds hci_req_unlock(hdev); 22511da177e4SLinus Torvalds hci_dev_put(hdev); 22521da177e4SLinus Torvalds return ret; 22531da177e4SLinus Torvalds } 22541da177e4SLinus Torvalds 22551da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 22561da177e4SLinus Torvalds { 22571da177e4SLinus Torvalds struct hci_dev *hdev; 22581da177e4SLinus Torvalds int ret = 0; 22591da177e4SLinus Torvalds 226070f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 226170f23020SAndrei Emeltchenko if (!hdev) 22621da177e4SLinus Torvalds return -ENODEV; 22631da177e4SLinus Torvalds 22640736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22650736cfa8SMarcel Holtmann ret = -EBUSY; 22660736cfa8SMarcel Holtmann goto done; 22670736cfa8SMarcel Holtmann } 22680736cfa8SMarcel Holtmann 22691da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 22701da177e4SLinus Torvalds 22710736cfa8SMarcel Holtmann done: 22721da177e4SLinus Torvalds hci_dev_put(hdev); 22731da177e4SLinus Torvalds return ret; 22741da177e4SLinus Torvalds } 22751da177e4SLinus Torvalds 22761da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 22771da177e4SLinus Torvalds { 22781da177e4SLinus Torvalds struct hci_dev *hdev; 22791da177e4SLinus Torvalds struct hci_dev_req dr; 22801da177e4SLinus Torvalds int err = 0; 22811da177e4SLinus Torvalds 22821da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 22831da177e4SLinus Torvalds return -EFAULT; 22841da177e4SLinus Torvalds 228570f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 228670f23020SAndrei Emeltchenko if (!hdev) 22871da177e4SLinus Torvalds return -ENODEV; 22881da177e4SLinus Torvalds 22890736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22900736cfa8SMarcel Holtmann err = -EBUSY; 22910736cfa8SMarcel Holtmann goto done; 22920736cfa8SMarcel Holtmann } 22930736cfa8SMarcel Holtmann 22945b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 22955b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 22965b69bef5SMarcel Holtmann goto done; 22975b69bef5SMarcel Holtmann } 22985b69bef5SMarcel Holtmann 229956f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 230056f87901SJohan Hedberg err = -EOPNOTSUPP; 230156f87901SJohan Hedberg goto done; 230256f87901SJohan Hedberg } 230356f87901SJohan Hedberg 23041da177e4SLinus Torvalds switch (cmd) { 23051da177e4SLinus Torvalds case HCISETAUTH: 230601178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 23075f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23081da177e4SLinus Torvalds break; 23091da177e4SLinus Torvalds 23101da177e4SLinus Torvalds case HCISETENCRYPT: 23111da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 23121da177e4SLinus Torvalds err = -EOPNOTSUPP; 23131da177e4SLinus Torvalds break; 23141da177e4SLinus Torvalds } 23151da177e4SLinus Torvalds 23161da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 23171da177e4SLinus Torvalds /* Auth must be enabled first */ 231801178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 23195f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23201da177e4SLinus Torvalds if (err) 23211da177e4SLinus Torvalds break; 23221da177e4SLinus Torvalds } 23231da177e4SLinus Torvalds 232401178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 23255f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23261da177e4SLinus Torvalds break; 23271da177e4SLinus Torvalds 23281da177e4SLinus Torvalds case HCISETSCAN: 232901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 23305f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23311da177e4SLinus Torvalds break; 23321da177e4SLinus Torvalds 23331da177e4SLinus Torvalds case HCISETLINKPOL: 233401178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 23355f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23361da177e4SLinus Torvalds break; 23371da177e4SLinus Torvalds 23381da177e4SLinus Torvalds case HCISETLINKMODE: 2339e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2340e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2341e4e8e37cSMarcel Holtmann break; 2342e4e8e37cSMarcel Holtmann 2343e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2344e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 23451da177e4SLinus Torvalds break; 23461da177e4SLinus Torvalds 23471da177e4SLinus Torvalds case HCISETACLMTU: 23481da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 23491da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 23501da177e4SLinus Torvalds break; 23511da177e4SLinus Torvalds 23521da177e4SLinus Torvalds case HCISETSCOMTU: 23531da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 23541da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 23551da177e4SLinus Torvalds break; 23561da177e4SLinus Torvalds 23571da177e4SLinus Torvalds default: 23581da177e4SLinus Torvalds err = -EINVAL; 23591da177e4SLinus Torvalds break; 23601da177e4SLinus Torvalds } 2361e4e8e37cSMarcel Holtmann 23620736cfa8SMarcel Holtmann done: 23631da177e4SLinus Torvalds hci_dev_put(hdev); 23641da177e4SLinus Torvalds return err; 23651da177e4SLinus Torvalds } 23661da177e4SLinus Torvalds 23671da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 23681da177e4SLinus Torvalds { 23698035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 23701da177e4SLinus Torvalds struct hci_dev_list_req *dl; 23711da177e4SLinus Torvalds struct hci_dev_req *dr; 23721da177e4SLinus Torvalds int n = 0, size, err; 23731da177e4SLinus Torvalds __u16 dev_num; 23741da177e4SLinus Torvalds 23751da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 23761da177e4SLinus Torvalds return -EFAULT; 23771da177e4SLinus Torvalds 23781da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 23791da177e4SLinus Torvalds return -EINVAL; 23801da177e4SLinus Torvalds 23811da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 23821da177e4SLinus Torvalds 238370f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 238470f23020SAndrei Emeltchenko if (!dl) 23851da177e4SLinus Torvalds return -ENOMEM; 23861da177e4SLinus Torvalds 23871da177e4SLinus Torvalds dr = dl->dev_req; 23881da177e4SLinus Torvalds 2389f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 23908035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 2391a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2392e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 2393c542a06cSJohan Hedberg 2394a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2395a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2396c542a06cSJohan Hedberg 23971da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 23981da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 2399c542a06cSJohan Hedberg 24001da177e4SLinus Torvalds if (++n >= dev_num) 24011da177e4SLinus Torvalds break; 24021da177e4SLinus Torvalds } 2403f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 24041da177e4SLinus Torvalds 24051da177e4SLinus Torvalds dl->dev_num = n; 24061da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 24071da177e4SLinus Torvalds 24081da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 24091da177e4SLinus Torvalds kfree(dl); 24101da177e4SLinus Torvalds 24111da177e4SLinus Torvalds return err ? -EFAULT : 0; 24121da177e4SLinus Torvalds } 24131da177e4SLinus Torvalds 24141da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 24151da177e4SLinus Torvalds { 24161da177e4SLinus Torvalds struct hci_dev *hdev; 24171da177e4SLinus Torvalds struct hci_dev_info di; 24181da177e4SLinus Torvalds int err = 0; 24191da177e4SLinus Torvalds 24201da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 24211da177e4SLinus Torvalds return -EFAULT; 24221da177e4SLinus Torvalds 242370f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 242470f23020SAndrei Emeltchenko if (!hdev) 24251da177e4SLinus Torvalds return -ENODEV; 24261da177e4SLinus Torvalds 2427a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 24283243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 2429ab81cbf9SJohan Hedberg 2430a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2431a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2432c542a06cSJohan Hedberg 24331da177e4SLinus Torvalds strcpy(di.name, hdev->name); 24341da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 243560f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 24361da177e4SLinus Torvalds di.flags = hdev->flags; 24371da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2438572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 24391da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 24401da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 24411da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 24421da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2443572c7f84SJohan Hedberg } else { 2444572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2445572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2446572c7f84SJohan Hedberg di.sco_mtu = 0; 2447572c7f84SJohan Hedberg di.sco_pkts = 0; 2448572c7f84SJohan Hedberg } 24491da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 24501da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 24511da177e4SLinus Torvalds 24521da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 24531da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 24541da177e4SLinus Torvalds 24551da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 24561da177e4SLinus Torvalds err = -EFAULT; 24571da177e4SLinus Torvalds 24581da177e4SLinus Torvalds hci_dev_put(hdev); 24591da177e4SLinus Torvalds 24601da177e4SLinus Torvalds return err; 24611da177e4SLinus Torvalds } 24621da177e4SLinus Torvalds 24631da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 24641da177e4SLinus Torvalds 2465611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2466611b30f7SMarcel Holtmann { 2467611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2468611b30f7SMarcel Holtmann 2469611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2470611b30f7SMarcel Holtmann 24710736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 24720736cfa8SMarcel Holtmann return -EBUSY; 24730736cfa8SMarcel Holtmann 24745e130367SJohan Hedberg if (blocked) { 24755e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 2476bf543036SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 2477611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 24785e130367SJohan Hedberg } else { 24795e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 24805e130367SJohan Hedberg } 2481611b30f7SMarcel Holtmann 2482611b30f7SMarcel Holtmann return 0; 2483611b30f7SMarcel Holtmann } 2484611b30f7SMarcel Holtmann 2485611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2486611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2487611b30f7SMarcel Holtmann }; 2488611b30f7SMarcel Holtmann 2489ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2490ab81cbf9SJohan Hedberg { 2491ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 249296570ffcSJohan Hedberg int err; 2493ab81cbf9SJohan Hedberg 2494ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2495ab81cbf9SJohan Hedberg 2496cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 249796570ffcSJohan Hedberg if (err < 0) { 249896570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 2499ab81cbf9SJohan Hedberg return; 250096570ffcSJohan Hedberg } 2501ab81cbf9SJohan Hedberg 2502a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2503a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2504a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2505a5c8f270SMarcel Holtmann */ 2506a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 2507a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 2508a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2509a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2510bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2511bf543036SJohan Hedberg hci_dev_do_close(hdev); 2512bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 251319202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 251419202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2515bf543036SJohan Hedberg } 2516ab81cbf9SJohan Hedberg 2517a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 2518744cf19eSJohan Hedberg mgmt_index_added(hdev); 2519ab81cbf9SJohan Hedberg } 2520ab81cbf9SJohan Hedberg 2521ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2522ab81cbf9SJohan Hedberg { 25233243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 25243243553fSJohan Hedberg power_off.work); 2525ab81cbf9SJohan Hedberg 2526ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2527ab81cbf9SJohan Hedberg 25288ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2529ab81cbf9SJohan Hedberg } 2530ab81cbf9SJohan Hedberg 253116ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 253216ab91abSJohan Hedberg { 253316ab91abSJohan Hedberg struct hci_dev *hdev; 253416ab91abSJohan Hedberg 253516ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 253616ab91abSJohan Hedberg 253716ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 253816ab91abSJohan Hedberg 2539d1967ff8SMarcel Holtmann mgmt_discoverable_timeout(hdev); 254016ab91abSJohan Hedberg } 254116ab91abSJohan Hedberg 254235f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 25432aeb9a1aSJohan Hedberg { 25444821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 25452aeb9a1aSJohan Hedberg 25464821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 25474821002cSJohan Hedberg list_del(&uuid->list); 25482aeb9a1aSJohan Hedberg kfree(uuid); 25492aeb9a1aSJohan Hedberg } 25502aeb9a1aSJohan Hedberg } 25512aeb9a1aSJohan Hedberg 255235f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 255355ed8ca1SJohan Hedberg { 255455ed8ca1SJohan Hedberg struct list_head *p, *n; 255555ed8ca1SJohan Hedberg 255655ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 255755ed8ca1SJohan Hedberg struct link_key *key; 255855ed8ca1SJohan Hedberg 255955ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 256055ed8ca1SJohan Hedberg 256155ed8ca1SJohan Hedberg list_del(p); 256255ed8ca1SJohan Hedberg kfree(key); 256355ed8ca1SJohan Hedberg } 256455ed8ca1SJohan Hedberg } 256555ed8ca1SJohan Hedberg 256635f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2567b899efafSVinicius Costa Gomes { 2568b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2569b899efafSVinicius Costa Gomes 2570b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2571b899efafSVinicius Costa Gomes list_del(&k->list); 2572b899efafSVinicius Costa Gomes kfree(k); 2573b899efafSVinicius Costa Gomes } 2574b899efafSVinicius Costa Gomes } 2575b899efafSVinicius Costa Gomes 2576970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2577970c4e46SJohan Hedberg { 2578970c4e46SJohan Hedberg struct smp_irk *k, *tmp; 2579970c4e46SJohan Hedberg 2580970c4e46SJohan Hedberg list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { 2581970c4e46SJohan Hedberg list_del(&k->list); 2582970c4e46SJohan Hedberg kfree(k); 2583970c4e46SJohan Hedberg } 2584970c4e46SJohan Hedberg } 2585970c4e46SJohan Hedberg 258655ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 258755ed8ca1SJohan Hedberg { 258855ed8ca1SJohan Hedberg struct link_key *k; 258955ed8ca1SJohan Hedberg 25908035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 259155ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 259255ed8ca1SJohan Hedberg return k; 259355ed8ca1SJohan Hedberg 259455ed8ca1SJohan Hedberg return NULL; 259555ed8ca1SJohan Hedberg } 259655ed8ca1SJohan Hedberg 2597745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2598d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2599d25e28abSJohan Hedberg { 2600d25e28abSJohan Hedberg /* Legacy key */ 2601d25e28abSJohan Hedberg if (key_type < 0x03) 2602745c0ce3SVishal Agarwal return true; 2603d25e28abSJohan Hedberg 2604d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2605d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2606745c0ce3SVishal Agarwal return false; 2607d25e28abSJohan Hedberg 2608d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2609d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2610745c0ce3SVishal Agarwal return false; 2611d25e28abSJohan Hedberg 2612d25e28abSJohan Hedberg /* Security mode 3 case */ 2613d25e28abSJohan Hedberg if (!conn) 2614745c0ce3SVishal Agarwal return true; 2615d25e28abSJohan Hedberg 2616d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2617d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2618745c0ce3SVishal Agarwal return true; 2619d25e28abSJohan Hedberg 2620d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2621d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2622745c0ce3SVishal Agarwal return true; 2623d25e28abSJohan Hedberg 2624d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2625d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2626745c0ce3SVishal Agarwal return true; 2627d25e28abSJohan Hedberg 2628d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2629d25e28abSJohan Hedberg * persistently */ 2630745c0ce3SVishal Agarwal return false; 2631d25e28abSJohan Hedberg } 2632d25e28abSJohan Hedberg 263398a0b845SJohan Hedberg static bool ltk_type_master(u8 type) 263498a0b845SJohan Hedberg { 263598a0b845SJohan Hedberg if (type == HCI_SMP_STK || type == HCI_SMP_LTK) 263698a0b845SJohan Hedberg return true; 263798a0b845SJohan Hedberg 263898a0b845SJohan Hedberg return false; 263998a0b845SJohan Hedberg } 264098a0b845SJohan Hedberg 264198a0b845SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8], 264298a0b845SJohan Hedberg bool master) 264375d262c2SVinicius Costa Gomes { 2644c9839a11SVinicius Costa Gomes struct smp_ltk *k; 264575d262c2SVinicius Costa Gomes 2646c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 2647c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 2648c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 264975d262c2SVinicius Costa Gomes continue; 265075d262c2SVinicius Costa Gomes 265198a0b845SJohan Hedberg if (ltk_type_master(k->type) != master) 265298a0b845SJohan Hedberg continue; 265398a0b845SJohan Hedberg 265475d262c2SVinicius Costa Gomes return k; 265575d262c2SVinicius Costa Gomes } 265675d262c2SVinicius Costa Gomes 265775d262c2SVinicius Costa Gomes return NULL; 265875d262c2SVinicius Costa Gomes } 265975d262c2SVinicius Costa Gomes 2660c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 266198a0b845SJohan Hedberg u8 addr_type, bool master) 266275d262c2SVinicius Costa Gomes { 2663c9839a11SVinicius Costa Gomes struct smp_ltk *k; 266475d262c2SVinicius Costa Gomes 2665c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 2666c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 266798a0b845SJohan Hedberg bacmp(bdaddr, &k->bdaddr) == 0 && 266898a0b845SJohan Hedberg ltk_type_master(k->type) == master) 266975d262c2SVinicius Costa Gomes return k; 267075d262c2SVinicius Costa Gomes 267175d262c2SVinicius Costa Gomes return NULL; 267275d262c2SVinicius Costa Gomes } 267375d262c2SVinicius Costa Gomes 2674970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 2675970c4e46SJohan Hedberg { 2676970c4e46SJohan Hedberg struct smp_irk *irk; 2677970c4e46SJohan Hedberg 2678970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2679970c4e46SJohan Hedberg if (!bacmp(&irk->rpa, rpa)) 2680970c4e46SJohan Hedberg return irk; 2681970c4e46SJohan Hedberg } 2682970c4e46SJohan Hedberg 2683970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2684970c4e46SJohan Hedberg if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) { 2685970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2686970c4e46SJohan Hedberg return irk; 2687970c4e46SJohan Hedberg } 2688970c4e46SJohan Hedberg } 2689970c4e46SJohan Hedberg 2690970c4e46SJohan Hedberg return NULL; 2691970c4e46SJohan Hedberg } 2692970c4e46SJohan Hedberg 2693970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2694970c4e46SJohan Hedberg u8 addr_type) 2695970c4e46SJohan Hedberg { 2696970c4e46SJohan Hedberg struct smp_irk *irk; 2697970c4e46SJohan Hedberg 26986cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 26996cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 27006cfc9988SJohan Hedberg return NULL; 27016cfc9988SJohan Hedberg 2702970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2703970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 2704970c4e46SJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) 2705970c4e46SJohan Hedberg return irk; 2706970c4e46SJohan Hedberg } 2707970c4e46SJohan Hedberg 2708970c4e46SJohan Hedberg return NULL; 2709970c4e46SJohan Hedberg } 2710970c4e46SJohan Hedberg 2711d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 2712d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 271355ed8ca1SJohan Hedberg { 271455ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2715745c0ce3SVishal Agarwal u8 old_key_type; 2716745c0ce3SVishal Agarwal bool persistent; 271755ed8ca1SJohan Hedberg 271855ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 271955ed8ca1SJohan Hedberg if (old_key) { 272055ed8ca1SJohan Hedberg old_key_type = old_key->type; 272155ed8ca1SJohan Hedberg key = old_key; 272255ed8ca1SJohan Hedberg } else { 272312adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 27240a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 272555ed8ca1SJohan Hedberg if (!key) 272655ed8ca1SJohan Hedberg return -ENOMEM; 272755ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 272855ed8ca1SJohan Hedberg } 272955ed8ca1SJohan Hedberg 27306ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 273155ed8ca1SJohan Hedberg 2732d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2733d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2734d25e28abSJohan Hedberg * previous key */ 2735d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2736a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2737d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2738655fe6ecSJohan Hedberg if (conn) 2739655fe6ecSJohan Hedberg conn->key_type = type; 2740655fe6ecSJohan Hedberg } 2741d25e28abSJohan Hedberg 274255ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 27439b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 274455ed8ca1SJohan Hedberg key->pin_len = pin_len; 274555ed8ca1SJohan Hedberg 2746b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 274755ed8ca1SJohan Hedberg key->type = old_key_type; 27484748fed2SJohan Hedberg else 27494748fed2SJohan Hedberg key->type = type; 27504748fed2SJohan Hedberg 27514df378a1SJohan Hedberg if (!new_key) 27524df378a1SJohan Hedberg return 0; 27534df378a1SJohan Hedberg 27544df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 27554df378a1SJohan Hedberg 2756744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 27574df378a1SJohan Hedberg 27586ec5bcadSVishal Agarwal if (conn) 27596ec5bcadSVishal Agarwal conn->flush_key = !persistent; 276055ed8ca1SJohan Hedberg 276155ed8ca1SJohan Hedberg return 0; 276255ed8ca1SJohan Hedberg } 276355ed8ca1SJohan Hedberg 2764ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2765*35d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 2766*35d70271SJohan Hedberg u8 tk[16], u8 enc_size, __le16 ediv, u8 rand[8]) 276775d262c2SVinicius Costa Gomes { 2768c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 276998a0b845SJohan Hedberg bool master = ltk_type_master(type); 277075d262c2SVinicius Costa Gomes 277198a0b845SJohan Hedberg old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master); 2772c9839a11SVinicius Costa Gomes if (old_key) 277375d262c2SVinicius Costa Gomes key = old_key; 2774c9839a11SVinicius Costa Gomes else { 27750a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 277675d262c2SVinicius Costa Gomes if (!key) 2777ca9142b8SJohan Hedberg return NULL; 2778c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 277975d262c2SVinicius Costa Gomes } 278075d262c2SVinicius Costa Gomes 278175d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2782c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2783c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2784c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2785c9839a11SVinicius Costa Gomes key->ediv = ediv; 2786c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2787c9839a11SVinicius Costa Gomes key->type = type; 2788c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 278975d262c2SVinicius Costa Gomes 2790ca9142b8SJohan Hedberg return key; 279175d262c2SVinicius Costa Gomes } 279275d262c2SVinicius Costa Gomes 2793ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2794ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 2795970c4e46SJohan Hedberg { 2796970c4e46SJohan Hedberg struct smp_irk *irk; 2797970c4e46SJohan Hedberg 2798970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 2799970c4e46SJohan Hedberg if (!irk) { 2800970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 2801970c4e46SJohan Hedberg if (!irk) 2802ca9142b8SJohan Hedberg return NULL; 2803970c4e46SJohan Hedberg 2804970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 2805970c4e46SJohan Hedberg irk->addr_type = addr_type; 2806970c4e46SJohan Hedberg 2807970c4e46SJohan Hedberg list_add(&irk->list, &hdev->identity_resolving_keys); 2808970c4e46SJohan Hedberg } 2809970c4e46SJohan Hedberg 2810970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 2811970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2812970c4e46SJohan Hedberg 2813ca9142b8SJohan Hedberg return irk; 2814970c4e46SJohan Hedberg } 2815970c4e46SJohan Hedberg 281655ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 281755ed8ca1SJohan Hedberg { 281855ed8ca1SJohan Hedberg struct link_key *key; 281955ed8ca1SJohan Hedberg 282055ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 282155ed8ca1SJohan Hedberg if (!key) 282255ed8ca1SJohan Hedberg return -ENOENT; 282355ed8ca1SJohan Hedberg 28246ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 282555ed8ca1SJohan Hedberg 282655ed8ca1SJohan Hedberg list_del(&key->list); 282755ed8ca1SJohan Hedberg kfree(key); 282855ed8ca1SJohan Hedberg 282955ed8ca1SJohan Hedberg return 0; 283055ed8ca1SJohan Hedberg } 283155ed8ca1SJohan Hedberg 2832e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 2833b899efafSVinicius Costa Gomes { 2834b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2835c51ffa0bSJohan Hedberg int removed = 0; 2836b899efafSVinicius Costa Gomes 2837b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2838e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 2839b899efafSVinicius Costa Gomes continue; 2840b899efafSVinicius Costa Gomes 28416ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2842b899efafSVinicius Costa Gomes 2843b899efafSVinicius Costa Gomes list_del(&k->list); 2844b899efafSVinicius Costa Gomes kfree(k); 2845c51ffa0bSJohan Hedberg removed++; 2846b899efafSVinicius Costa Gomes } 2847b899efafSVinicius Costa Gomes 2848c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 2849b899efafSVinicius Costa Gomes } 2850b899efafSVinicius Costa Gomes 2851a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 2852a7ec7338SJohan Hedberg { 2853a7ec7338SJohan Hedberg struct smp_irk *k, *tmp; 2854a7ec7338SJohan Hedberg 2855a7ec7338SJohan Hedberg list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2856a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 2857a7ec7338SJohan Hedberg continue; 2858a7ec7338SJohan Hedberg 2859a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2860a7ec7338SJohan Hedberg 2861a7ec7338SJohan Hedberg list_del(&k->list); 2862a7ec7338SJohan Hedberg kfree(k); 2863a7ec7338SJohan Hedberg } 2864a7ec7338SJohan Hedberg } 2865a7ec7338SJohan Hedberg 28666bd32326SVille Tervo /* HCI command timer function */ 2867bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg) 28686bd32326SVille Tervo { 28696bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 28706bd32326SVille Tervo 2871bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2872bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2873bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2874bda4f23aSAndrei Emeltchenko 2875bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 2876bda4f23aSAndrei Emeltchenko } else { 28776bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 2878bda4f23aSAndrei Emeltchenko } 2879bda4f23aSAndrei Emeltchenko 28806bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2881c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 28826bd32326SVille Tervo } 28836bd32326SVille Tervo 28842763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 28852763eda6SSzymon Janc bdaddr_t *bdaddr) 28862763eda6SSzymon Janc { 28872763eda6SSzymon Janc struct oob_data *data; 28882763eda6SSzymon Janc 28892763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 28902763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 28912763eda6SSzymon Janc return data; 28922763eda6SSzymon Janc 28932763eda6SSzymon Janc return NULL; 28942763eda6SSzymon Janc } 28952763eda6SSzymon Janc 28962763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 28972763eda6SSzymon Janc { 28982763eda6SSzymon Janc struct oob_data *data; 28992763eda6SSzymon Janc 29002763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 29012763eda6SSzymon Janc if (!data) 29022763eda6SSzymon Janc return -ENOENT; 29032763eda6SSzymon Janc 29046ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 29052763eda6SSzymon Janc 29062763eda6SSzymon Janc list_del(&data->list); 29072763eda6SSzymon Janc kfree(data); 29082763eda6SSzymon Janc 29092763eda6SSzymon Janc return 0; 29102763eda6SSzymon Janc } 29112763eda6SSzymon Janc 291235f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 29132763eda6SSzymon Janc { 29142763eda6SSzymon Janc struct oob_data *data, *n; 29152763eda6SSzymon Janc 29162763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 29172763eda6SSzymon Janc list_del(&data->list); 29182763eda6SSzymon Janc kfree(data); 29192763eda6SSzymon Janc } 29202763eda6SSzymon Janc } 29212763eda6SSzymon Janc 29220798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 29230798872eSMarcel Holtmann u8 *hash, u8 *randomizer) 29242763eda6SSzymon Janc { 29252763eda6SSzymon Janc struct oob_data *data; 29262763eda6SSzymon Janc 29272763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 29282763eda6SSzymon Janc if (!data) { 29290a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 29302763eda6SSzymon Janc if (!data) 29312763eda6SSzymon Janc return -ENOMEM; 29322763eda6SSzymon Janc 29332763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 29342763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 29352763eda6SSzymon Janc } 29362763eda6SSzymon Janc 2937519ca9d0SMarcel Holtmann memcpy(data->hash192, hash, sizeof(data->hash192)); 2938519ca9d0SMarcel Holtmann memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192)); 29392763eda6SSzymon Janc 29400798872eSMarcel Holtmann memset(data->hash256, 0, sizeof(data->hash256)); 29410798872eSMarcel Holtmann memset(data->randomizer256, 0, sizeof(data->randomizer256)); 29420798872eSMarcel Holtmann 29430798872eSMarcel Holtmann BT_DBG("%s for %pMR", hdev->name, bdaddr); 29440798872eSMarcel Holtmann 29450798872eSMarcel Holtmann return 0; 29460798872eSMarcel Holtmann } 29470798872eSMarcel Holtmann 29480798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 29490798872eSMarcel Holtmann u8 *hash192, u8 *randomizer192, 29500798872eSMarcel Holtmann u8 *hash256, u8 *randomizer256) 29510798872eSMarcel Holtmann { 29520798872eSMarcel Holtmann struct oob_data *data; 29530798872eSMarcel Holtmann 29540798872eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, bdaddr); 29550798872eSMarcel Holtmann if (!data) { 29560a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 29570798872eSMarcel Holtmann if (!data) 29580798872eSMarcel Holtmann return -ENOMEM; 29590798872eSMarcel Holtmann 29600798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 29610798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 29620798872eSMarcel Holtmann } 29630798872eSMarcel Holtmann 29640798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 29650798872eSMarcel Holtmann memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192)); 29660798872eSMarcel Holtmann 29670798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 29680798872eSMarcel Holtmann memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256)); 29690798872eSMarcel Holtmann 29706ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 29712763eda6SSzymon Janc 29722763eda6SSzymon Janc return 0; 29732763eda6SSzymon Janc } 29742763eda6SSzymon Janc 2975b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 2976b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 2977b2a66aadSAntti Julku { 2978b2a66aadSAntti Julku struct bdaddr_list *b; 2979b2a66aadSAntti Julku 2980b9ee0a78SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) { 2981b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2982b2a66aadSAntti Julku return b; 2983b9ee0a78SMarcel Holtmann } 2984b2a66aadSAntti Julku 2985b2a66aadSAntti Julku return NULL; 2986b2a66aadSAntti Julku } 2987b2a66aadSAntti Julku 298835f7498aSJohan Hedberg void hci_blacklist_clear(struct hci_dev *hdev) 2989b2a66aadSAntti Julku { 2990b2a66aadSAntti Julku struct list_head *p, *n; 2991b2a66aadSAntti Julku 2992b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 2993b9ee0a78SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 2994b2a66aadSAntti Julku 2995b2a66aadSAntti Julku list_del(p); 2996b2a66aadSAntti Julku kfree(b); 2997b2a66aadSAntti Julku } 2998b2a66aadSAntti Julku } 2999b2a66aadSAntti Julku 300088c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3001b2a66aadSAntti Julku { 3002b2a66aadSAntti Julku struct bdaddr_list *entry; 3003b2a66aadSAntti Julku 3004b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3005b2a66aadSAntti Julku return -EBADF; 3006b2a66aadSAntti Julku 3007b9ee0a78SMarcel Holtmann if (hci_blacklist_lookup(hdev, bdaddr, type)) 30085e762444SAntti Julku return -EEXIST; 3009b2a66aadSAntti Julku 3010b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 30115e762444SAntti Julku if (!entry) 30125e762444SAntti Julku return -ENOMEM; 3013b2a66aadSAntti Julku 3014b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 3015b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 3016b2a66aadSAntti Julku 3017b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 3018b2a66aadSAntti Julku 301988c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 3020b2a66aadSAntti Julku } 3021b2a66aadSAntti Julku 302288c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3023b2a66aadSAntti Julku { 3024b2a66aadSAntti Julku struct bdaddr_list *entry; 3025b2a66aadSAntti Julku 302635f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 302735f7498aSJohan Hedberg hci_blacklist_clear(hdev); 302835f7498aSJohan Hedberg return 0; 302935f7498aSJohan Hedberg } 3030b2a66aadSAntti Julku 3031b9ee0a78SMarcel Holtmann entry = hci_blacklist_lookup(hdev, bdaddr, type); 30321ec918ceSSzymon Janc if (!entry) 30335e762444SAntti Julku return -ENOENT; 3034b2a66aadSAntti Julku 3035b2a66aadSAntti Julku list_del(&entry->list); 3036b2a66aadSAntti Julku kfree(entry); 3037b2a66aadSAntti Julku 303888c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 3039b2a66aadSAntti Julku } 3040b2a66aadSAntti Julku 304115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 304215819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 304315819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 304415819a70SAndre Guedes { 304515819a70SAndre Guedes struct hci_conn_params *params; 304615819a70SAndre Guedes 304715819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 304815819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 304915819a70SAndre Guedes params->addr_type == addr_type) { 305015819a70SAndre Guedes return params; 305115819a70SAndre Guedes } 305215819a70SAndre Guedes } 305315819a70SAndre Guedes 305415819a70SAndre Guedes return NULL; 305515819a70SAndre Guedes } 305615819a70SAndre Guedes 305715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 305815819a70SAndre Guedes void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, 305915819a70SAndre Guedes u16 conn_min_interval, u16 conn_max_interval) 306015819a70SAndre Guedes { 306115819a70SAndre Guedes struct hci_conn_params *params; 306215819a70SAndre Guedes 306315819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 306415819a70SAndre Guedes if (params) { 306515819a70SAndre Guedes params->conn_min_interval = conn_min_interval; 306615819a70SAndre Guedes params->conn_max_interval = conn_max_interval; 306715819a70SAndre Guedes return; 306815819a70SAndre Guedes } 306915819a70SAndre Guedes 307015819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 307115819a70SAndre Guedes if (!params) { 307215819a70SAndre Guedes BT_ERR("Out of memory"); 307315819a70SAndre Guedes return; 307415819a70SAndre Guedes } 307515819a70SAndre Guedes 307615819a70SAndre Guedes bacpy(¶ms->addr, addr); 307715819a70SAndre Guedes params->addr_type = addr_type; 307815819a70SAndre Guedes params->conn_min_interval = conn_min_interval; 307915819a70SAndre Guedes params->conn_max_interval = conn_max_interval; 308015819a70SAndre Guedes 308115819a70SAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 308215819a70SAndre Guedes 308315819a70SAndre Guedes BT_DBG("addr %pMR (type %u) conn_min_interval 0x%.4x " 308415819a70SAndre Guedes "conn_max_interval 0x%.4x", addr, addr_type, conn_min_interval, 308515819a70SAndre Guedes conn_max_interval); 308615819a70SAndre Guedes } 308715819a70SAndre Guedes 308815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 308915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 309015819a70SAndre Guedes { 309115819a70SAndre Guedes struct hci_conn_params *params; 309215819a70SAndre Guedes 309315819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 309415819a70SAndre Guedes if (!params) 309515819a70SAndre Guedes return; 309615819a70SAndre Guedes 309715819a70SAndre Guedes list_del(¶ms->list); 309815819a70SAndre Guedes kfree(params); 309915819a70SAndre Guedes 310015819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 310115819a70SAndre Guedes } 310215819a70SAndre Guedes 310315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 310415819a70SAndre Guedes void hci_conn_params_clear(struct hci_dev *hdev) 310515819a70SAndre Guedes { 310615819a70SAndre Guedes struct hci_conn_params *params, *tmp; 310715819a70SAndre Guedes 310815819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 310915819a70SAndre Guedes list_del(¶ms->list); 311015819a70SAndre Guedes kfree(params); 311115819a70SAndre Guedes } 311215819a70SAndre Guedes 311315819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 311415819a70SAndre Guedes } 311515819a70SAndre Guedes 31164c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 31177ba8b4beSAndre Guedes { 31184c87eaabSAndre Guedes if (status) { 31194c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 31207ba8b4beSAndre Guedes 31214c87eaabSAndre Guedes hci_dev_lock(hdev); 31224c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 31234c87eaabSAndre Guedes hci_dev_unlock(hdev); 31244c87eaabSAndre Guedes return; 31254c87eaabSAndre Guedes } 31267ba8b4beSAndre Guedes } 31277ba8b4beSAndre Guedes 31284c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 31297ba8b4beSAndre Guedes { 31304c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 31314c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 31324c87eaabSAndre Guedes struct hci_request req; 31334c87eaabSAndre Guedes struct hci_cp_inquiry cp; 31347ba8b4beSAndre Guedes int err; 31357ba8b4beSAndre Guedes 31364c87eaabSAndre Guedes if (status) { 31374c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 31384c87eaabSAndre Guedes return; 31397ba8b4beSAndre Guedes } 31407ba8b4beSAndre Guedes 31414c87eaabSAndre Guedes switch (hdev->discovery.type) { 31424c87eaabSAndre Guedes case DISCOV_TYPE_LE: 31434c87eaabSAndre Guedes hci_dev_lock(hdev); 31444c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 31454c87eaabSAndre Guedes hci_dev_unlock(hdev); 31464c87eaabSAndre Guedes break; 31477dbfac1dSAndre Guedes 31484c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 31494c87eaabSAndre Guedes hci_req_init(&req, hdev); 31507dbfac1dSAndre Guedes 31517dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 31524c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 31534c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 31544c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 31554c87eaabSAndre Guedes 31564c87eaabSAndre Guedes hci_dev_lock(hdev); 31574c87eaabSAndre Guedes 31584c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 31594c87eaabSAndre Guedes 31604c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 31614c87eaabSAndre Guedes if (err) { 31624c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 31634c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 31647dbfac1dSAndre Guedes } 31657dbfac1dSAndre Guedes 31664c87eaabSAndre Guedes hci_dev_unlock(hdev); 31674c87eaabSAndre Guedes break; 31684c87eaabSAndre Guedes } 31697dbfac1dSAndre Guedes } 31707dbfac1dSAndre Guedes 31717ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 31727ba8b4beSAndre Guedes { 31737ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 31747ba8b4beSAndre Guedes le_scan_disable.work); 31757ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 31764c87eaabSAndre Guedes struct hci_request req; 31774c87eaabSAndre Guedes int err; 31787ba8b4beSAndre Guedes 31797ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 31807ba8b4beSAndre Guedes 31814c87eaabSAndre Guedes hci_req_init(&req, hdev); 31827ba8b4beSAndre Guedes 31837ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 31844c87eaabSAndre Guedes cp.enable = LE_SCAN_DISABLE; 31854c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 31867ba8b4beSAndre Guedes 31874c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 31884c87eaabSAndre Guedes if (err) 31894c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 319028b75a89SAndre Guedes } 319128b75a89SAndre Guedes 31929be0dab7SDavid Herrmann /* Alloc HCI device */ 31939be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 31949be0dab7SDavid Herrmann { 31959be0dab7SDavid Herrmann struct hci_dev *hdev; 31969be0dab7SDavid Herrmann 31979be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 31989be0dab7SDavid Herrmann if (!hdev) 31999be0dab7SDavid Herrmann return NULL; 32009be0dab7SDavid Herrmann 3201b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3202b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3203b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3204b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3205b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 3206bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3207bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3208b1b813d4SDavid Herrmann 3209b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3210b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3211b1b813d4SDavid Herrmann 3212bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3213bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 32144e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = 0x0028; 32154e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = 0x0038; 3216bef64738SMarcel Holtmann 3217b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3218b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3219b1b813d4SDavid Herrmann 3220b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3221b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 3222b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3223b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3224b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3225970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3226b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 322715819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 32286b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3229b1b813d4SDavid Herrmann 3230b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3231b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3232b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3233b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3234b1b813d4SDavid Herrmann 3235b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3236b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 3237b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 3238b1b813d4SDavid Herrmann 3239b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3240b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3241b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3242b1b813d4SDavid Herrmann 3243b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 3244b1b813d4SDavid Herrmann 3245bda4f23aSAndrei Emeltchenko setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); 3246b1b813d4SDavid Herrmann 3247b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3248b1b813d4SDavid Herrmann discovery_init(hdev); 32499be0dab7SDavid Herrmann 32509be0dab7SDavid Herrmann return hdev; 32519be0dab7SDavid Herrmann } 32529be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 32539be0dab7SDavid Herrmann 32549be0dab7SDavid Herrmann /* Free HCI device */ 32559be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 32569be0dab7SDavid Herrmann { 32579be0dab7SDavid Herrmann /* will free via device release */ 32589be0dab7SDavid Herrmann put_device(&hdev->dev); 32599be0dab7SDavid Herrmann } 32609be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 32619be0dab7SDavid Herrmann 32621da177e4SLinus Torvalds /* Register HCI device */ 32631da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 32641da177e4SLinus Torvalds { 3265b1b813d4SDavid Herrmann int id, error; 32661da177e4SLinus Torvalds 3267010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 32681da177e4SLinus Torvalds return -EINVAL; 32691da177e4SLinus Torvalds 327008add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 327108add513SMat Martineau * so the index can be used as the AMP controller ID. 327208add513SMat Martineau */ 32733df92b31SSasha Levin switch (hdev->dev_type) { 32743df92b31SSasha Levin case HCI_BREDR: 32753df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 32761da177e4SLinus Torvalds break; 32773df92b31SSasha Levin case HCI_AMP: 32783df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 32793df92b31SSasha Levin break; 32803df92b31SSasha Levin default: 32813df92b31SSasha Levin return -EINVAL; 32821da177e4SLinus Torvalds } 32831da177e4SLinus Torvalds 32843df92b31SSasha Levin if (id < 0) 32853df92b31SSasha Levin return id; 32863df92b31SSasha Levin 32871da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 32881da177e4SLinus Torvalds hdev->id = id; 32892d8b3a11SAndrei Emeltchenko 32902d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 32912d8b3a11SAndrei Emeltchenko 3292d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3293d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 329433ca954dSDavid Herrmann if (!hdev->workqueue) { 329533ca954dSDavid Herrmann error = -ENOMEM; 329633ca954dSDavid Herrmann goto err; 329733ca954dSDavid Herrmann } 3298f48fd9c8SMarcel Holtmann 3299d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3300d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 33016ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 33026ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 33036ead1bbcSJohan Hedberg error = -ENOMEM; 33046ead1bbcSJohan Hedberg goto err; 33056ead1bbcSJohan Hedberg } 33066ead1bbcSJohan Hedberg 33070153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 33080153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 33090153e2ecSMarcel Holtmann 3310bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3311bdc3e0f1SMarcel Holtmann 331299780a7bSJohan Hedberg hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 331399780a7bSJohan Hedberg CRYPTO_ALG_ASYNC); 331499780a7bSJohan Hedberg if (IS_ERR(hdev->tfm_aes)) { 331599780a7bSJohan Hedberg BT_ERR("Unable to create crypto context"); 331699780a7bSJohan Hedberg error = PTR_ERR(hdev->tfm_aes); 331799780a7bSJohan Hedberg hdev->tfm_aes = NULL; 331899780a7bSJohan Hedberg goto err_wqueue; 331999780a7bSJohan Hedberg } 332099780a7bSJohan Hedberg 3321bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 332233ca954dSDavid Herrmann if (error < 0) 332399780a7bSJohan Hedberg goto err_tfm; 33241da177e4SLinus Torvalds 3325611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3326a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3327a8c5fb1aSGustavo Padovan hdev); 3328611b30f7SMarcel Holtmann if (hdev->rfkill) { 3329611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3330611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3331611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3332611b30f7SMarcel Holtmann } 3333611b30f7SMarcel Holtmann } 3334611b30f7SMarcel Holtmann 33355e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 33365e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 33375e130367SJohan Hedberg 3338a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 3339004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 3340ce2be9acSAndrei Emeltchenko 334101cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 334256f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 334356f87901SJohan Hedberg * through reading supported features during init. 334456f87901SJohan Hedberg */ 334556f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 334656f87901SJohan Hedberg } 3347ce2be9acSAndrei Emeltchenko 3348fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3349fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3350fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3351fcee3377SGustavo Padovan 33521da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 3353dc946bd8SDavid Herrmann hci_dev_hold(hdev); 33541da177e4SLinus Torvalds 335519202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3356fbe96d6fSMarcel Holtmann 33571da177e4SLinus Torvalds return id; 3358f48fd9c8SMarcel Holtmann 335999780a7bSJohan Hedberg err_tfm: 336099780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 336133ca954dSDavid Herrmann err_wqueue: 336233ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 33636ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 336433ca954dSDavid Herrmann err: 33653df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3366f48fd9c8SMarcel Holtmann 336733ca954dSDavid Herrmann return error; 33681da177e4SLinus Torvalds } 33691da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 33701da177e4SLinus Torvalds 33711da177e4SLinus Torvalds /* Unregister HCI device */ 337259735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 33731da177e4SLinus Torvalds { 33743df92b31SSasha Levin int i, id; 3375ef222013SMarcel Holtmann 3376c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 33771da177e4SLinus Torvalds 337894324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 337994324962SJohan Hovold 33803df92b31SSasha Levin id = hdev->id; 33813df92b31SSasha Levin 3382f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 33831da177e4SLinus Torvalds list_del(&hdev->list); 3384f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 33851da177e4SLinus Torvalds 33861da177e4SLinus Torvalds hci_dev_do_close(hdev); 33871da177e4SLinus Torvalds 3388cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 3389ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 3390ef222013SMarcel Holtmann 3391b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 3392b9b5ef18SGustavo Padovan 3393ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 3394a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 339509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3396744cf19eSJohan Hedberg mgmt_index_removed(hdev); 339709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 339856e5cb86SJohan Hedberg } 3399ab81cbf9SJohan Hedberg 34002e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 34012e58ef3eSJohan Hedberg * pending list */ 34022e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 34032e58ef3eSJohan Hedberg 34041da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 34051da177e4SLinus Torvalds 3406611b30f7SMarcel Holtmann if (hdev->rfkill) { 3407611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 3408611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3409611b30f7SMarcel Holtmann } 3410611b30f7SMarcel Holtmann 341199780a7bSJohan Hedberg if (hdev->tfm_aes) 341299780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 341399780a7bSJohan Hedberg 3414bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 3415147e2d59SDave Young 34160153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 34170153e2ecSMarcel Holtmann 3418f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 34196ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 3420f48fd9c8SMarcel Holtmann 342109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3422e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 34232aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 342455ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 3425b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 3426970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 34272763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 342815819a70SAndre Guedes hci_conn_params_clear(hdev); 342909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 3430e2e0cacbSJohan Hedberg 3431dc946bd8SDavid Herrmann hci_dev_put(hdev); 34323df92b31SSasha Levin 34333df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 34341da177e4SLinus Torvalds } 34351da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 34361da177e4SLinus Torvalds 34371da177e4SLinus Torvalds /* Suspend HCI device */ 34381da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 34391da177e4SLinus Torvalds { 34401da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 34411da177e4SLinus Torvalds return 0; 34421da177e4SLinus Torvalds } 34431da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 34441da177e4SLinus Torvalds 34451da177e4SLinus Torvalds /* Resume HCI device */ 34461da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 34471da177e4SLinus Torvalds { 34481da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 34491da177e4SLinus Torvalds return 0; 34501da177e4SLinus Torvalds } 34511da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 34521da177e4SLinus Torvalds 345376bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 3454e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 345576bca880SMarcel Holtmann { 345676bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 345776bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 345876bca880SMarcel Holtmann kfree_skb(skb); 345976bca880SMarcel Holtmann return -ENXIO; 346076bca880SMarcel Holtmann } 346176bca880SMarcel Holtmann 3462d82603c6SJorrit Schippers /* Incoming skb */ 346376bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 346476bca880SMarcel Holtmann 346576bca880SMarcel Holtmann /* Time stamp */ 346676bca880SMarcel Holtmann __net_timestamp(skb); 346776bca880SMarcel Holtmann 346876bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3469b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3470c78ae283SMarcel Holtmann 347176bca880SMarcel Holtmann return 0; 347276bca880SMarcel Holtmann } 347376bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 347476bca880SMarcel Holtmann 347533e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 34761e429f38SGustavo F. Padovan int count, __u8 index) 347733e882a5SSuraj Sumangala { 347833e882a5SSuraj Sumangala int len = 0; 347933e882a5SSuraj Sumangala int hlen = 0; 348033e882a5SSuraj Sumangala int remain = count; 348133e882a5SSuraj Sumangala struct sk_buff *skb; 348233e882a5SSuraj Sumangala struct bt_skb_cb *scb; 348333e882a5SSuraj Sumangala 348433e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 348533e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 348633e882a5SSuraj Sumangala return -EILSEQ; 348733e882a5SSuraj Sumangala 348833e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 348933e882a5SSuraj Sumangala 349033e882a5SSuraj Sumangala if (!skb) { 349133e882a5SSuraj Sumangala switch (type) { 349233e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 349333e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 349433e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 349533e882a5SSuraj Sumangala break; 349633e882a5SSuraj Sumangala case HCI_EVENT_PKT: 349733e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 349833e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 349933e882a5SSuraj Sumangala break; 350033e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 350133e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 350233e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 350333e882a5SSuraj Sumangala break; 350433e882a5SSuraj Sumangala } 350533e882a5SSuraj Sumangala 35061e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 350733e882a5SSuraj Sumangala if (!skb) 350833e882a5SSuraj Sumangala return -ENOMEM; 350933e882a5SSuraj Sumangala 351033e882a5SSuraj Sumangala scb = (void *) skb->cb; 351133e882a5SSuraj Sumangala scb->expect = hlen; 351233e882a5SSuraj Sumangala scb->pkt_type = type; 351333e882a5SSuraj Sumangala 351433e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 351533e882a5SSuraj Sumangala } 351633e882a5SSuraj Sumangala 351733e882a5SSuraj Sumangala while (count) { 351833e882a5SSuraj Sumangala scb = (void *) skb->cb; 351989bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 352033e882a5SSuraj Sumangala 352133e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 352233e882a5SSuraj Sumangala 352333e882a5SSuraj Sumangala count -= len; 352433e882a5SSuraj Sumangala data += len; 352533e882a5SSuraj Sumangala scb->expect -= len; 352633e882a5SSuraj Sumangala remain = count; 352733e882a5SSuraj Sumangala 352833e882a5SSuraj Sumangala switch (type) { 352933e882a5SSuraj Sumangala case HCI_EVENT_PKT: 353033e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 353133e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 353233e882a5SSuraj Sumangala scb->expect = h->plen; 353333e882a5SSuraj Sumangala 353433e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 353533e882a5SSuraj Sumangala kfree_skb(skb); 353633e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 353733e882a5SSuraj Sumangala return -ENOMEM; 353833e882a5SSuraj Sumangala } 353933e882a5SSuraj Sumangala } 354033e882a5SSuraj Sumangala break; 354133e882a5SSuraj Sumangala 354233e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 354333e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 354433e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 354533e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 354633e882a5SSuraj Sumangala 354733e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 354833e882a5SSuraj Sumangala kfree_skb(skb); 354933e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 355033e882a5SSuraj Sumangala return -ENOMEM; 355133e882a5SSuraj Sumangala } 355233e882a5SSuraj Sumangala } 355333e882a5SSuraj Sumangala break; 355433e882a5SSuraj Sumangala 355533e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 355633e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 355733e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 355833e882a5SSuraj Sumangala scb->expect = h->dlen; 355933e882a5SSuraj Sumangala 356033e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 356133e882a5SSuraj Sumangala kfree_skb(skb); 356233e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 356333e882a5SSuraj Sumangala return -ENOMEM; 356433e882a5SSuraj Sumangala } 356533e882a5SSuraj Sumangala } 356633e882a5SSuraj Sumangala break; 356733e882a5SSuraj Sumangala } 356833e882a5SSuraj Sumangala 356933e882a5SSuraj Sumangala if (scb->expect == 0) { 357033e882a5SSuraj Sumangala /* Complete frame */ 357133e882a5SSuraj Sumangala 357233e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 3573e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 357433e882a5SSuraj Sumangala 357533e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 357633e882a5SSuraj Sumangala return remain; 357733e882a5SSuraj Sumangala } 357833e882a5SSuraj Sumangala } 357933e882a5SSuraj Sumangala 358033e882a5SSuraj Sumangala return remain; 358133e882a5SSuraj Sumangala } 358233e882a5SSuraj Sumangala 3583ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 3584ef222013SMarcel Holtmann { 3585f39a3c06SSuraj Sumangala int rem = 0; 3586f39a3c06SSuraj Sumangala 3587ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 3588ef222013SMarcel Holtmann return -EILSEQ; 3589ef222013SMarcel Holtmann 3590da5f6c37SGustavo F. Padovan while (count) { 35911e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 3592f39a3c06SSuraj Sumangala if (rem < 0) 3593f39a3c06SSuraj Sumangala return rem; 3594ef222013SMarcel Holtmann 3595f39a3c06SSuraj Sumangala data += (count - rem); 3596f39a3c06SSuraj Sumangala count = rem; 3597f81c6224SJoe Perches } 3598ef222013SMarcel Holtmann 3599f39a3c06SSuraj Sumangala return rem; 3600ef222013SMarcel Holtmann } 3601ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 3602ef222013SMarcel Holtmann 360399811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 360499811510SSuraj Sumangala 360599811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 360699811510SSuraj Sumangala { 360799811510SSuraj Sumangala int type; 360899811510SSuraj Sumangala int rem = 0; 360999811510SSuraj Sumangala 3610da5f6c37SGustavo F. Padovan while (count) { 361199811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 361299811510SSuraj Sumangala 361399811510SSuraj Sumangala if (!skb) { 361499811510SSuraj Sumangala struct { char type; } *pkt; 361599811510SSuraj Sumangala 361699811510SSuraj Sumangala /* Start of the frame */ 361799811510SSuraj Sumangala pkt = data; 361899811510SSuraj Sumangala type = pkt->type; 361999811510SSuraj Sumangala 362099811510SSuraj Sumangala data++; 362199811510SSuraj Sumangala count--; 362299811510SSuraj Sumangala } else 362399811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 362499811510SSuraj Sumangala 36251e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 36261e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 362799811510SSuraj Sumangala if (rem < 0) 362899811510SSuraj Sumangala return rem; 362999811510SSuraj Sumangala 363099811510SSuraj Sumangala data += (count - rem); 363199811510SSuraj Sumangala count = rem; 3632f81c6224SJoe Perches } 363399811510SSuraj Sumangala 363499811510SSuraj Sumangala return rem; 363599811510SSuraj Sumangala } 363699811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 363799811510SSuraj Sumangala 36381da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 36391da177e4SLinus Torvalds 36401da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 36411da177e4SLinus Torvalds { 36421da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 36431da177e4SLinus Torvalds 3644f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 36451da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 3646f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 36471da177e4SLinus Torvalds 36481da177e4SLinus Torvalds return 0; 36491da177e4SLinus Torvalds } 36501da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 36511da177e4SLinus Torvalds 36521da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 36531da177e4SLinus Torvalds { 36541da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 36551da177e4SLinus Torvalds 3656f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 36571da177e4SLinus Torvalds list_del(&cb->list); 3658f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 36591da177e4SLinus Torvalds 36601da177e4SLinus Torvalds return 0; 36611da177e4SLinus Torvalds } 36621da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 36631da177e4SLinus Torvalds 366451086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 36651da177e4SLinus Torvalds { 36660d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 36671da177e4SLinus Torvalds 36681da177e4SLinus Torvalds /* Time stamp */ 3669a61bbcf2SPatrick McHardy __net_timestamp(skb); 36701da177e4SLinus Torvalds 3671cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3672cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3673cd82e61cSMarcel Holtmann 3674cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3675cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3676470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 36771da177e4SLinus Torvalds } 36781da177e4SLinus Torvalds 36791da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 36801da177e4SLinus Torvalds skb_orphan(skb); 36811da177e4SLinus Torvalds 36827bd8f09fSMarcel Holtmann if (hdev->send(hdev, skb) < 0) 368351086991SMarcel Holtmann BT_ERR("%s sending frame failed", hdev->name); 36841da177e4SLinus Torvalds } 36851da177e4SLinus Torvalds 36863119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 36873119ae95SJohan Hedberg { 36883119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 36893119ae95SJohan Hedberg req->hdev = hdev; 36905d73e034SAndre Guedes req->err = 0; 36913119ae95SJohan Hedberg } 36923119ae95SJohan Hedberg 36933119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 36943119ae95SJohan Hedberg { 36953119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 36963119ae95SJohan Hedberg struct sk_buff *skb; 36973119ae95SJohan Hedberg unsigned long flags; 36983119ae95SJohan Hedberg 36993119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 37003119ae95SJohan Hedberg 37015d73e034SAndre Guedes /* If an error occured during request building, remove all HCI 37025d73e034SAndre Guedes * commands queued on the HCI request queue. 37035d73e034SAndre Guedes */ 37045d73e034SAndre Guedes if (req->err) { 37055d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 37065d73e034SAndre Guedes return req->err; 37075d73e034SAndre Guedes } 37085d73e034SAndre Guedes 37093119ae95SJohan Hedberg /* Do not allow empty requests */ 37103119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 3711382b0c39SAndre Guedes return -ENODATA; 37123119ae95SJohan Hedberg 37133119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 37143119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 37153119ae95SJohan Hedberg 37163119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 37173119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 37183119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 37193119ae95SJohan Hedberg 37203119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 37213119ae95SJohan Hedberg 37223119ae95SJohan Hedberg return 0; 37233119ae95SJohan Hedberg } 37243119ae95SJohan Hedberg 37251ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 372607dc93ddSJohan Hedberg u32 plen, const void *param) 37271da177e4SLinus Torvalds { 37281da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 37291da177e4SLinus Torvalds struct hci_command_hdr *hdr; 37301da177e4SLinus Torvalds struct sk_buff *skb; 37311da177e4SLinus Torvalds 37321da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 37331ca3a9d0SJohan Hedberg if (!skb) 37341ca3a9d0SJohan Hedberg return NULL; 37351da177e4SLinus Torvalds 37361da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 3737a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 37381da177e4SLinus Torvalds hdr->plen = plen; 37391da177e4SLinus Torvalds 37401da177e4SLinus Torvalds if (plen) 37411da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 37421da177e4SLinus Torvalds 37431da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 37441da177e4SLinus Torvalds 37450d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 3746c78ae283SMarcel Holtmann 37471ca3a9d0SJohan Hedberg return skb; 37481ca3a9d0SJohan Hedberg } 37491ca3a9d0SJohan Hedberg 37501ca3a9d0SJohan Hedberg /* Send HCI command */ 375107dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 375207dc93ddSJohan Hedberg const void *param) 37531ca3a9d0SJohan Hedberg { 37541ca3a9d0SJohan Hedberg struct sk_buff *skb; 37551ca3a9d0SJohan Hedberg 37561ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 37571ca3a9d0SJohan Hedberg 37581ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 37591ca3a9d0SJohan Hedberg if (!skb) { 37601ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 37611ca3a9d0SJohan Hedberg return -ENOMEM; 37621ca3a9d0SJohan Hedberg } 37631ca3a9d0SJohan Hedberg 376411714b3dSJohan Hedberg /* Stand-alone HCI commands must be flaged as 376511714b3dSJohan Hedberg * single-command requests. 376611714b3dSJohan Hedberg */ 376711714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 376811714b3dSJohan Hedberg 37691da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3770c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 37711da177e4SLinus Torvalds 37721da177e4SLinus Torvalds return 0; 37731da177e4SLinus Torvalds } 37741da177e4SLinus Torvalds 377571c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 377607dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 377707dc93ddSJohan Hedberg const void *param, u8 event) 377871c76a17SJohan Hedberg { 377971c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 378071c76a17SJohan Hedberg struct sk_buff *skb; 378171c76a17SJohan Hedberg 378271c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 378371c76a17SJohan Hedberg 378434739c1eSAndre Guedes /* If an error occured during request building, there is no point in 378534739c1eSAndre Guedes * queueing the HCI command. We can simply return. 378634739c1eSAndre Guedes */ 378734739c1eSAndre Guedes if (req->err) 378834739c1eSAndre Guedes return; 378934739c1eSAndre Guedes 379071c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 379171c76a17SJohan Hedberg if (!skb) { 37925d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 37935d73e034SAndre Guedes hdev->name, opcode); 37945d73e034SAndre Guedes req->err = -ENOMEM; 3795e348fe6bSAndre Guedes return; 379671c76a17SJohan Hedberg } 379771c76a17SJohan Hedberg 379871c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 379971c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 380071c76a17SJohan Hedberg 380102350a72SJohan Hedberg bt_cb(skb)->req.event = event; 380202350a72SJohan Hedberg 380371c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 380471c76a17SJohan Hedberg } 380571c76a17SJohan Hedberg 380607dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 380707dc93ddSJohan Hedberg const void *param) 380802350a72SJohan Hedberg { 380902350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 381002350a72SJohan Hedberg } 381102350a72SJohan Hedberg 38121da177e4SLinus Torvalds /* Get data from the previously sent command */ 3813a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 38141da177e4SLinus Torvalds { 38151da177e4SLinus Torvalds struct hci_command_hdr *hdr; 38161da177e4SLinus Torvalds 38171da177e4SLinus Torvalds if (!hdev->sent_cmd) 38181da177e4SLinus Torvalds return NULL; 38191da177e4SLinus Torvalds 38201da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 38211da177e4SLinus Torvalds 3822a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 38231da177e4SLinus Torvalds return NULL; 38241da177e4SLinus Torvalds 3825f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 38261da177e4SLinus Torvalds 38271da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 38281da177e4SLinus Torvalds } 38291da177e4SLinus Torvalds 38301da177e4SLinus Torvalds /* Send ACL data */ 38311da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 38321da177e4SLinus Torvalds { 38331da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 38341da177e4SLinus Torvalds int len = skb->len; 38351da177e4SLinus Torvalds 3836badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3837badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 38389c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3839aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3840aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 38411da177e4SLinus Torvalds } 38421da177e4SLinus Torvalds 3843ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 384473d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 38451da177e4SLinus Torvalds { 3846ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 38471da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 38481da177e4SLinus Torvalds struct sk_buff *list; 38491da177e4SLinus Torvalds 3850087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3851087bfd99SGustavo Padovan skb->data_len = 0; 3852087bfd99SGustavo Padovan 3853087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3854204a6e54SAndrei Emeltchenko 3855204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3856204a6e54SAndrei Emeltchenko case HCI_BREDR: 3857087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3858204a6e54SAndrei Emeltchenko break; 3859204a6e54SAndrei Emeltchenko case HCI_AMP: 3860204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3861204a6e54SAndrei Emeltchenko break; 3862204a6e54SAndrei Emeltchenko default: 3863204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 3864204a6e54SAndrei Emeltchenko return; 3865204a6e54SAndrei Emeltchenko } 3866087bfd99SGustavo Padovan 386770f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 386870f23020SAndrei Emeltchenko if (!list) { 38691da177e4SLinus Torvalds /* Non fragmented */ 38701da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 38711da177e4SLinus Torvalds 387273d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 38731da177e4SLinus Torvalds } else { 38741da177e4SLinus Torvalds /* Fragmented */ 38751da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 38761da177e4SLinus Torvalds 38771da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 38781da177e4SLinus Torvalds 38791da177e4SLinus Torvalds /* Queue all fragments atomically */ 3880af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 38811da177e4SLinus Torvalds 388273d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3883e702112fSAndrei Emeltchenko 3884e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3885e702112fSAndrei Emeltchenko flags |= ACL_CONT; 38861da177e4SLinus Torvalds do { 38871da177e4SLinus Torvalds skb = list; list = list->next; 38881da177e4SLinus Torvalds 38890d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3890e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 38911da177e4SLinus Torvalds 38921da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 38931da177e4SLinus Torvalds 389473d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 38951da177e4SLinus Torvalds } while (list); 38961da177e4SLinus Torvalds 3897af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 38981da177e4SLinus Torvalds } 389973d80debSLuiz Augusto von Dentz } 390073d80debSLuiz Augusto von Dentz 390173d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 390273d80debSLuiz Augusto von Dentz { 3903ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 390473d80debSLuiz Augusto von Dentz 3905f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 390673d80debSLuiz Augusto von Dentz 3907ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 39081da177e4SLinus Torvalds 39093eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 39101da177e4SLinus Torvalds } 39111da177e4SLinus Torvalds 39121da177e4SLinus Torvalds /* Send SCO data */ 39130d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 39141da177e4SLinus Torvalds { 39151da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 39161da177e4SLinus Torvalds struct hci_sco_hdr hdr; 39171da177e4SLinus Torvalds 39181da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 39191da177e4SLinus Torvalds 3920aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 39211da177e4SLinus Torvalds hdr.dlen = skb->len; 39221da177e4SLinus Torvalds 3923badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 3924badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 39259c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 39261da177e4SLinus Torvalds 39270d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 3928c78ae283SMarcel Holtmann 39291da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 39303eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 39311da177e4SLinus Torvalds } 39321da177e4SLinus Torvalds 39331da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 39341da177e4SLinus Torvalds 39351da177e4SLinus Torvalds /* HCI Connection scheduler */ 39366039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 3937a8c5fb1aSGustavo Padovan int *quote) 39381da177e4SLinus Torvalds { 39391da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 39408035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 3941abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 39421da177e4SLinus Torvalds 39431da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 39441da177e4SLinus Torvalds * added and removed with TX task disabled. */ 3945bf4c6325SGustavo F. Padovan 3946bf4c6325SGustavo F. Padovan rcu_read_lock(); 3947bf4c6325SGustavo F. Padovan 3948bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3949769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 39501da177e4SLinus Torvalds continue; 3951769be974SMarcel Holtmann 3952769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 3953769be974SMarcel Holtmann continue; 3954769be974SMarcel Holtmann 39551da177e4SLinus Torvalds num++; 39561da177e4SLinus Torvalds 39571da177e4SLinus Torvalds if (c->sent < min) { 39581da177e4SLinus Torvalds min = c->sent; 39591da177e4SLinus Torvalds conn = c; 39601da177e4SLinus Torvalds } 396152087a79SLuiz Augusto von Dentz 396252087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 396352087a79SLuiz Augusto von Dentz break; 39641da177e4SLinus Torvalds } 39651da177e4SLinus Torvalds 3966bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3967bf4c6325SGustavo F. Padovan 39681da177e4SLinus Torvalds if (conn) { 39696ed58ec5SVille Tervo int cnt, q; 39706ed58ec5SVille Tervo 39716ed58ec5SVille Tervo switch (conn->type) { 39726ed58ec5SVille Tervo case ACL_LINK: 39736ed58ec5SVille Tervo cnt = hdev->acl_cnt; 39746ed58ec5SVille Tervo break; 39756ed58ec5SVille Tervo case SCO_LINK: 39766ed58ec5SVille Tervo case ESCO_LINK: 39776ed58ec5SVille Tervo cnt = hdev->sco_cnt; 39786ed58ec5SVille Tervo break; 39796ed58ec5SVille Tervo case LE_LINK: 39806ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 39816ed58ec5SVille Tervo break; 39826ed58ec5SVille Tervo default: 39836ed58ec5SVille Tervo cnt = 0; 39846ed58ec5SVille Tervo BT_ERR("Unknown link type"); 39856ed58ec5SVille Tervo } 39866ed58ec5SVille Tervo 39876ed58ec5SVille Tervo q = cnt / num; 39881da177e4SLinus Torvalds *quote = q ? q : 1; 39891da177e4SLinus Torvalds } else 39901da177e4SLinus Torvalds *quote = 0; 39911da177e4SLinus Torvalds 39921da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 39931da177e4SLinus Torvalds return conn; 39941da177e4SLinus Torvalds } 39951da177e4SLinus Torvalds 39966039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 39971da177e4SLinus Torvalds { 39981da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 39991da177e4SLinus Torvalds struct hci_conn *c; 40001da177e4SLinus Torvalds 4001bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 40021da177e4SLinus Torvalds 4003bf4c6325SGustavo F. Padovan rcu_read_lock(); 4004bf4c6325SGustavo F. Padovan 40051da177e4SLinus Torvalds /* Kill stalled connections */ 4006bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4007bae1f5d9SVille Tervo if (c->type == type && c->sent) { 40086ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 40096ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 4010bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 40111da177e4SLinus Torvalds } 40121da177e4SLinus Torvalds } 4013bf4c6325SGustavo F. Padovan 4014bf4c6325SGustavo F. Padovan rcu_read_unlock(); 40151da177e4SLinus Torvalds } 40161da177e4SLinus Torvalds 40176039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 401873d80debSLuiz Augusto von Dentz int *quote) 401973d80debSLuiz Augusto von Dentz { 402073d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 402173d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 4022abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 402373d80debSLuiz Augusto von Dentz struct hci_conn *conn; 402473d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 402573d80debSLuiz Augusto von Dentz 402673d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 402773d80debSLuiz Augusto von Dentz 4028bf4c6325SGustavo F. Padovan rcu_read_lock(); 4029bf4c6325SGustavo F. Padovan 4030bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 403173d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 403273d80debSLuiz Augusto von Dentz 403373d80debSLuiz Augusto von Dentz if (conn->type != type) 403473d80debSLuiz Augusto von Dentz continue; 403573d80debSLuiz Augusto von Dentz 403673d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 403773d80debSLuiz Augusto von Dentz continue; 403873d80debSLuiz Augusto von Dentz 403973d80debSLuiz Augusto von Dentz conn_num++; 404073d80debSLuiz Augusto von Dentz 40418192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 404273d80debSLuiz Augusto von Dentz struct sk_buff *skb; 404373d80debSLuiz Augusto von Dentz 404473d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 404573d80debSLuiz Augusto von Dentz continue; 404673d80debSLuiz Augusto von Dentz 404773d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 404873d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 404973d80debSLuiz Augusto von Dentz continue; 405073d80debSLuiz Augusto von Dentz 405173d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 405273d80debSLuiz Augusto von Dentz num = 0; 405373d80debSLuiz Augusto von Dentz min = ~0; 405473d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 405573d80debSLuiz Augusto von Dentz } 405673d80debSLuiz Augusto von Dentz 405773d80debSLuiz Augusto von Dentz num++; 405873d80debSLuiz Augusto von Dentz 405973d80debSLuiz Augusto von Dentz if (conn->sent < min) { 406073d80debSLuiz Augusto von Dentz min = conn->sent; 406173d80debSLuiz Augusto von Dentz chan = tmp; 406273d80debSLuiz Augusto von Dentz } 406373d80debSLuiz Augusto von Dentz } 406473d80debSLuiz Augusto von Dentz 406573d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 406673d80debSLuiz Augusto von Dentz break; 406773d80debSLuiz Augusto von Dentz } 406873d80debSLuiz Augusto von Dentz 4069bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4070bf4c6325SGustavo F. Padovan 407173d80debSLuiz Augusto von Dentz if (!chan) 407273d80debSLuiz Augusto von Dentz return NULL; 407373d80debSLuiz Augusto von Dentz 407473d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 407573d80debSLuiz Augusto von Dentz case ACL_LINK: 407673d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 407773d80debSLuiz Augusto von Dentz break; 4078bd1eb66bSAndrei Emeltchenko case AMP_LINK: 4079bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 4080bd1eb66bSAndrei Emeltchenko break; 408173d80debSLuiz Augusto von Dentz case SCO_LINK: 408273d80debSLuiz Augusto von Dentz case ESCO_LINK: 408373d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 408473d80debSLuiz Augusto von Dentz break; 408573d80debSLuiz Augusto von Dentz case LE_LINK: 408673d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 408773d80debSLuiz Augusto von Dentz break; 408873d80debSLuiz Augusto von Dentz default: 408973d80debSLuiz Augusto von Dentz cnt = 0; 409073d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 409173d80debSLuiz Augusto von Dentz } 409273d80debSLuiz Augusto von Dentz 409373d80debSLuiz Augusto von Dentz q = cnt / num; 409473d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 409573d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 409673d80debSLuiz Augusto von Dentz return chan; 409773d80debSLuiz Augusto von Dentz } 409873d80debSLuiz Augusto von Dentz 409902b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 410002b20f0bSLuiz Augusto von Dentz { 410102b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 410202b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 410302b20f0bSLuiz Augusto von Dentz int num = 0; 410402b20f0bSLuiz Augusto von Dentz 410502b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 410602b20f0bSLuiz Augusto von Dentz 4107bf4c6325SGustavo F. Padovan rcu_read_lock(); 4108bf4c6325SGustavo F. Padovan 4109bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 411002b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 411102b20f0bSLuiz Augusto von Dentz 411202b20f0bSLuiz Augusto von Dentz if (conn->type != type) 411302b20f0bSLuiz Augusto von Dentz continue; 411402b20f0bSLuiz Augusto von Dentz 411502b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 411602b20f0bSLuiz Augusto von Dentz continue; 411702b20f0bSLuiz Augusto von Dentz 411802b20f0bSLuiz Augusto von Dentz num++; 411902b20f0bSLuiz Augusto von Dentz 41208192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 412102b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 412202b20f0bSLuiz Augusto von Dentz 412302b20f0bSLuiz Augusto von Dentz if (chan->sent) { 412402b20f0bSLuiz Augusto von Dentz chan->sent = 0; 412502b20f0bSLuiz Augusto von Dentz continue; 412602b20f0bSLuiz Augusto von Dentz } 412702b20f0bSLuiz Augusto von Dentz 412802b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 412902b20f0bSLuiz Augusto von Dentz continue; 413002b20f0bSLuiz Augusto von Dentz 413102b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 413202b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 413302b20f0bSLuiz Augusto von Dentz continue; 413402b20f0bSLuiz Augusto von Dentz 413502b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 413602b20f0bSLuiz Augusto von Dentz 413702b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 413802b20f0bSLuiz Augusto von Dentz skb->priority); 413902b20f0bSLuiz Augusto von Dentz } 414002b20f0bSLuiz Augusto von Dentz 414102b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 414202b20f0bSLuiz Augusto von Dentz break; 414302b20f0bSLuiz Augusto von Dentz } 4144bf4c6325SGustavo F. Padovan 4145bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4146bf4c6325SGustavo F. Padovan 414702b20f0bSLuiz Augusto von Dentz } 414802b20f0bSLuiz Augusto von Dentz 4149b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4150b71d385aSAndrei Emeltchenko { 4151b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4152b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4153b71d385aSAndrei Emeltchenko } 4154b71d385aSAndrei Emeltchenko 41556039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 41561da177e4SLinus Torvalds { 41571da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 41581da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 41591da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 416063d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 41615f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 4162bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 41631da177e4SLinus Torvalds } 416463d2bc1bSAndrei Emeltchenko } 41651da177e4SLinus Torvalds 41666039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 416763d2bc1bSAndrei Emeltchenko { 416863d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 416963d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 417063d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 417163d2bc1bSAndrei Emeltchenko int quote; 417263d2bc1bSAndrei Emeltchenko 417363d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 417404837f64SMarcel Holtmann 417573d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 417673d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 4177ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4178ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 417973d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 418073d80debSLuiz Augusto von Dentz skb->len, skb->priority); 418173d80debSLuiz Augusto von Dentz 4182ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4183ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4184ec1cce24SLuiz Augusto von Dentz break; 4185ec1cce24SLuiz Augusto von Dentz 4186ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4187ec1cce24SLuiz Augusto von Dentz 418873d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 418973d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 419004837f64SMarcel Holtmann 419157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 41921da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 41931da177e4SLinus Torvalds 41941da177e4SLinus Torvalds hdev->acl_cnt--; 419573d80debSLuiz Augusto von Dentz chan->sent++; 419673d80debSLuiz Augusto von Dentz chan->conn->sent++; 41971da177e4SLinus Torvalds } 41981da177e4SLinus Torvalds } 419902b20f0bSLuiz Augusto von Dentz 420002b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 420102b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 42021da177e4SLinus Torvalds } 42031da177e4SLinus Torvalds 42046039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4205b71d385aSAndrei Emeltchenko { 420663d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4207b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4208b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4209b71d385aSAndrei Emeltchenko int quote; 4210bd1eb66bSAndrei Emeltchenko u8 type; 4211b71d385aSAndrei Emeltchenko 421263d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4213b71d385aSAndrei Emeltchenko 4214bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4215bd1eb66bSAndrei Emeltchenko 4216bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4217bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4218bd1eb66bSAndrei Emeltchenko else 4219bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4220bd1eb66bSAndrei Emeltchenko 4221b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4222bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4223b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4224b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4225b71d385aSAndrei Emeltchenko int blocks; 4226b71d385aSAndrei Emeltchenko 4227b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4228b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4229b71d385aSAndrei Emeltchenko 4230b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4231b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4232b71d385aSAndrei Emeltchenko break; 4233b71d385aSAndrei Emeltchenko 4234b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4235b71d385aSAndrei Emeltchenko 4236b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4237b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4238b71d385aSAndrei Emeltchenko return; 4239b71d385aSAndrei Emeltchenko 4240b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4241b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4242b71d385aSAndrei Emeltchenko 424357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4244b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4245b71d385aSAndrei Emeltchenko 4246b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4247b71d385aSAndrei Emeltchenko quote -= blocks; 4248b71d385aSAndrei Emeltchenko 4249b71d385aSAndrei Emeltchenko chan->sent += blocks; 4250b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4251b71d385aSAndrei Emeltchenko } 4252b71d385aSAndrei Emeltchenko } 4253b71d385aSAndrei Emeltchenko 4254b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4255bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4256b71d385aSAndrei Emeltchenko } 4257b71d385aSAndrei Emeltchenko 42586039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4259b71d385aSAndrei Emeltchenko { 4260b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4261b71d385aSAndrei Emeltchenko 4262bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4263bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 4264bd1eb66bSAndrei Emeltchenko return; 4265bd1eb66bSAndrei Emeltchenko 4266bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4267bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4268b71d385aSAndrei Emeltchenko return; 4269b71d385aSAndrei Emeltchenko 4270b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4271b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4272b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4273b71d385aSAndrei Emeltchenko break; 4274b71d385aSAndrei Emeltchenko 4275b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4276b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4277b71d385aSAndrei Emeltchenko break; 4278b71d385aSAndrei Emeltchenko } 4279b71d385aSAndrei Emeltchenko } 4280b71d385aSAndrei Emeltchenko 42811da177e4SLinus Torvalds /* Schedule SCO */ 42826039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 42831da177e4SLinus Torvalds { 42841da177e4SLinus Torvalds struct hci_conn *conn; 42851da177e4SLinus Torvalds struct sk_buff *skb; 42861da177e4SLinus Torvalds int quote; 42871da177e4SLinus Torvalds 42881da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 42891da177e4SLinus Torvalds 429052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 429152087a79SLuiz Augusto von Dentz return; 429252087a79SLuiz Augusto von Dentz 42931da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 42941da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 42951da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 429657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 42971da177e4SLinus Torvalds 42981da177e4SLinus Torvalds conn->sent++; 42991da177e4SLinus Torvalds if (conn->sent == ~0) 43001da177e4SLinus Torvalds conn->sent = 0; 43011da177e4SLinus Torvalds } 43021da177e4SLinus Torvalds } 43031da177e4SLinus Torvalds } 43041da177e4SLinus Torvalds 43056039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 4306b6a0dc82SMarcel Holtmann { 4307b6a0dc82SMarcel Holtmann struct hci_conn *conn; 4308b6a0dc82SMarcel Holtmann struct sk_buff *skb; 4309b6a0dc82SMarcel Holtmann int quote; 4310b6a0dc82SMarcel Holtmann 4311b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 4312b6a0dc82SMarcel Holtmann 431352087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 431452087a79SLuiz Augusto von Dentz return; 431552087a79SLuiz Augusto von Dentz 43168fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 43178fc9ced3SGustavo Padovan "e))) { 4318b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 4319b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 432057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4321b6a0dc82SMarcel Holtmann 4322b6a0dc82SMarcel Holtmann conn->sent++; 4323b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 4324b6a0dc82SMarcel Holtmann conn->sent = 0; 4325b6a0dc82SMarcel Holtmann } 4326b6a0dc82SMarcel Holtmann } 4327b6a0dc82SMarcel Holtmann } 4328b6a0dc82SMarcel Holtmann 43296039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 43306ed58ec5SVille Tervo { 433173d80debSLuiz Augusto von Dentz struct hci_chan *chan; 43326ed58ec5SVille Tervo struct sk_buff *skb; 433302b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 43346ed58ec5SVille Tervo 43356ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 43366ed58ec5SVille Tervo 433752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 433852087a79SLuiz Augusto von Dentz return; 433952087a79SLuiz Augusto von Dentz 43406ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 43416ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 43426ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 4343bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 43446ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 4345bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 43466ed58ec5SVille Tervo } 43476ed58ec5SVille Tervo 43486ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 434902b20f0bSLuiz Augusto von Dentz tmp = cnt; 435073d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 4351ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4352ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 435373d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 435473d80debSLuiz Augusto von Dentz skb->len, skb->priority); 43556ed58ec5SVille Tervo 4356ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4357ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4358ec1cce24SLuiz Augusto von Dentz break; 4359ec1cce24SLuiz Augusto von Dentz 4360ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4361ec1cce24SLuiz Augusto von Dentz 436257d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 43636ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 43646ed58ec5SVille Tervo 43656ed58ec5SVille Tervo cnt--; 436673d80debSLuiz Augusto von Dentz chan->sent++; 436773d80debSLuiz Augusto von Dentz chan->conn->sent++; 43686ed58ec5SVille Tervo } 43696ed58ec5SVille Tervo } 437073d80debSLuiz Augusto von Dentz 43716ed58ec5SVille Tervo if (hdev->le_pkts) 43726ed58ec5SVille Tervo hdev->le_cnt = cnt; 43736ed58ec5SVille Tervo else 43746ed58ec5SVille Tervo hdev->acl_cnt = cnt; 437502b20f0bSLuiz Augusto von Dentz 437602b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 437702b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 43786ed58ec5SVille Tervo } 43796ed58ec5SVille Tervo 43803eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 43811da177e4SLinus Torvalds { 43823eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 43831da177e4SLinus Torvalds struct sk_buff *skb; 43841da177e4SLinus Torvalds 43856ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 43866ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 43871da177e4SLinus Torvalds 438852de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 43891da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 43901da177e4SLinus Torvalds hci_sched_acl(hdev); 43911da177e4SLinus Torvalds hci_sched_sco(hdev); 4392b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 43936ed58ec5SVille Tervo hci_sched_le(hdev); 439452de599eSMarcel Holtmann } 43956ed58ec5SVille Tervo 43961da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 43971da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 439857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 43991da177e4SLinus Torvalds } 44001da177e4SLinus Torvalds 440125985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 44021da177e4SLinus Torvalds 44031da177e4SLinus Torvalds /* ACL data packet */ 44046039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 44051da177e4SLinus Torvalds { 44061da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 44071da177e4SLinus Torvalds struct hci_conn *conn; 44081da177e4SLinus Torvalds __u16 handle, flags; 44091da177e4SLinus Torvalds 44101da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 44111da177e4SLinus Torvalds 44121da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 44131da177e4SLinus Torvalds flags = hci_flags(handle); 44141da177e4SLinus Torvalds handle = hci_handle(handle); 44151da177e4SLinus Torvalds 4416f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4417a8c5fb1aSGustavo Padovan handle, flags); 44181da177e4SLinus Torvalds 44191da177e4SLinus Torvalds hdev->stat.acl_rx++; 44201da177e4SLinus Torvalds 44211da177e4SLinus Torvalds hci_dev_lock(hdev); 44221da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 44231da177e4SLinus Torvalds hci_dev_unlock(hdev); 44241da177e4SLinus Torvalds 44251da177e4SLinus Torvalds if (conn) { 442665983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 442704837f64SMarcel Holtmann 44281da177e4SLinus Torvalds /* Send to upper protocol */ 4429686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 44301da177e4SLinus Torvalds return; 44311da177e4SLinus Torvalds } else { 44321da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 44331da177e4SLinus Torvalds hdev->name, handle); 44341da177e4SLinus Torvalds } 44351da177e4SLinus Torvalds 44361da177e4SLinus Torvalds kfree_skb(skb); 44371da177e4SLinus Torvalds } 44381da177e4SLinus Torvalds 44391da177e4SLinus Torvalds /* SCO data packet */ 44406039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 44411da177e4SLinus Torvalds { 44421da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 44431da177e4SLinus Torvalds struct hci_conn *conn; 44441da177e4SLinus Torvalds __u16 handle; 44451da177e4SLinus Torvalds 44461da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 44471da177e4SLinus Torvalds 44481da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 44491da177e4SLinus Torvalds 4450f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 44511da177e4SLinus Torvalds 44521da177e4SLinus Torvalds hdev->stat.sco_rx++; 44531da177e4SLinus Torvalds 44541da177e4SLinus Torvalds hci_dev_lock(hdev); 44551da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 44561da177e4SLinus Torvalds hci_dev_unlock(hdev); 44571da177e4SLinus Torvalds 44581da177e4SLinus Torvalds if (conn) { 44591da177e4SLinus Torvalds /* Send to upper protocol */ 4460686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 44611da177e4SLinus Torvalds return; 44621da177e4SLinus Torvalds } else { 44631da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 44641da177e4SLinus Torvalds hdev->name, handle); 44651da177e4SLinus Torvalds } 44661da177e4SLinus Torvalds 44671da177e4SLinus Torvalds kfree_skb(skb); 44681da177e4SLinus Torvalds } 44691da177e4SLinus Torvalds 44709238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 44719238f36aSJohan Hedberg { 44729238f36aSJohan Hedberg struct sk_buff *skb; 44739238f36aSJohan Hedberg 44749238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 44759238f36aSJohan Hedberg if (!skb) 44769238f36aSJohan Hedberg return true; 44779238f36aSJohan Hedberg 44789238f36aSJohan Hedberg return bt_cb(skb)->req.start; 44799238f36aSJohan Hedberg } 44809238f36aSJohan Hedberg 448142c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 448242c6b129SJohan Hedberg { 448342c6b129SJohan Hedberg struct hci_command_hdr *sent; 448442c6b129SJohan Hedberg struct sk_buff *skb; 448542c6b129SJohan Hedberg u16 opcode; 448642c6b129SJohan Hedberg 448742c6b129SJohan Hedberg if (!hdev->sent_cmd) 448842c6b129SJohan Hedberg return; 448942c6b129SJohan Hedberg 449042c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 449142c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 449242c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 449342c6b129SJohan Hedberg return; 449442c6b129SJohan Hedberg 449542c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 449642c6b129SJohan Hedberg if (!skb) 449742c6b129SJohan Hedberg return; 449842c6b129SJohan Hedberg 449942c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 450042c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 450142c6b129SJohan Hedberg } 450242c6b129SJohan Hedberg 45039238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 45049238f36aSJohan Hedberg { 45059238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 45069238f36aSJohan Hedberg struct sk_buff *skb; 45079238f36aSJohan Hedberg unsigned long flags; 45089238f36aSJohan Hedberg 45099238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 45109238f36aSJohan Hedberg 451142c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 451242c6b129SJohan Hedberg * sent we need to do special handling of it. 45139238f36aSJohan Hedberg */ 451442c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 451542c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 451642c6b129SJohan Hedberg * reset complete event during init and any pending 451742c6b129SJohan Hedberg * command will never be completed. In such a case we 451842c6b129SJohan Hedberg * need to resend whatever was the last sent 451942c6b129SJohan Hedberg * command. 452042c6b129SJohan Hedberg */ 452142c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 452242c6b129SJohan Hedberg hci_resend_last(hdev); 452342c6b129SJohan Hedberg 45249238f36aSJohan Hedberg return; 452542c6b129SJohan Hedberg } 45269238f36aSJohan Hedberg 45279238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 45289238f36aSJohan Hedberg * this request the request is not yet complete. 45299238f36aSJohan Hedberg */ 45309238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 45319238f36aSJohan Hedberg return; 45329238f36aSJohan Hedberg 45339238f36aSJohan Hedberg /* If this was the last command in a request the complete 45349238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 45359238f36aSJohan Hedberg * command queue (hdev->cmd_q). 45369238f36aSJohan Hedberg */ 45379238f36aSJohan Hedberg if (hdev->sent_cmd) { 45389238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 453953e21fbcSJohan Hedberg 454053e21fbcSJohan Hedberg if (req_complete) { 454153e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 454253e21fbcSJohan Hedberg * avoid calling the callback more than once if 454353e21fbcSJohan Hedberg * this function gets called again. 454453e21fbcSJohan Hedberg */ 454553e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 454653e21fbcSJohan Hedberg 45479238f36aSJohan Hedberg goto call_complete; 45489238f36aSJohan Hedberg } 454953e21fbcSJohan Hedberg } 45509238f36aSJohan Hedberg 45519238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 45529238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 45539238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 45549238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 45559238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 45569238f36aSJohan Hedberg break; 45579238f36aSJohan Hedberg } 45589238f36aSJohan Hedberg 45599238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 45609238f36aSJohan Hedberg kfree_skb(skb); 45619238f36aSJohan Hedberg } 45629238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 45639238f36aSJohan Hedberg 45649238f36aSJohan Hedberg call_complete: 45659238f36aSJohan Hedberg if (req_complete) 45669238f36aSJohan Hedberg req_complete(hdev, status); 45679238f36aSJohan Hedberg } 45689238f36aSJohan Hedberg 4569b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 45701da177e4SLinus Torvalds { 4571b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 45721da177e4SLinus Torvalds struct sk_buff *skb; 45731da177e4SLinus Torvalds 45741da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 45751da177e4SLinus Torvalds 45761da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 4577cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4578cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4579cd82e61cSMarcel Holtmann 45801da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 45811da177e4SLinus Torvalds /* Send copy to the sockets */ 4582470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 45831da177e4SLinus Torvalds } 45841da177e4SLinus Torvalds 45850736cfa8SMarcel Holtmann if (test_bit(HCI_RAW, &hdev->flags) || 45860736cfa8SMarcel Holtmann test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 45871da177e4SLinus Torvalds kfree_skb(skb); 45881da177e4SLinus Torvalds continue; 45891da177e4SLinus Torvalds } 45901da177e4SLinus Torvalds 45911da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 45921da177e4SLinus Torvalds /* Don't process data packets in this states. */ 45930d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 45941da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 45951da177e4SLinus Torvalds case HCI_SCODATA_PKT: 45961da177e4SLinus Torvalds kfree_skb(skb); 45971da177e4SLinus Torvalds continue; 45983ff50b79SStephen Hemminger } 45991da177e4SLinus Torvalds } 46001da177e4SLinus Torvalds 46011da177e4SLinus Torvalds /* Process frame */ 46020d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 46031da177e4SLinus Torvalds case HCI_EVENT_PKT: 4604b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 46051da177e4SLinus Torvalds hci_event_packet(hdev, skb); 46061da177e4SLinus Torvalds break; 46071da177e4SLinus Torvalds 46081da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 46091da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 46101da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 46111da177e4SLinus Torvalds break; 46121da177e4SLinus Torvalds 46131da177e4SLinus Torvalds case HCI_SCODATA_PKT: 46141da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 46151da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 46161da177e4SLinus Torvalds break; 46171da177e4SLinus Torvalds 46181da177e4SLinus Torvalds default: 46191da177e4SLinus Torvalds kfree_skb(skb); 46201da177e4SLinus Torvalds break; 46211da177e4SLinus Torvalds } 46221da177e4SLinus Torvalds } 46231da177e4SLinus Torvalds } 46241da177e4SLinus Torvalds 4625c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 46261da177e4SLinus Torvalds { 4627c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 46281da177e4SLinus Torvalds struct sk_buff *skb; 46291da177e4SLinus Torvalds 46302104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 46312104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 46321da177e4SLinus Torvalds 46331da177e4SLinus Torvalds /* Send queued commands */ 46345a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 46355a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 46365a08ecceSAndrei Emeltchenko if (!skb) 46375a08ecceSAndrei Emeltchenko return; 46385a08ecceSAndrei Emeltchenko 46391da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 46401da177e4SLinus Torvalds 4641a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 464270f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 46431da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 464457d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 46457bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 46467bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 46477bdb8a5cSSzymon Janc else 46486bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 46495f246e89SAndrei Emeltchenko jiffies + HCI_CMD_TIMEOUT); 46501da177e4SLinus Torvalds } else { 46511da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4652c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 46531da177e4SLinus Torvalds } 46541da177e4SLinus Torvalds } 46551da177e4SLinus Torvalds } 4656