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 6028f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr) 6038f8625cdSMarcel Holtmann { 6048f8625cdSMarcel Holtmann struct hci_dev *hdev = f->private; 6058f8625cdSMarcel Holtmann struct list_head *p, *n; 6068f8625cdSMarcel Holtmann 6078f8625cdSMarcel Holtmann hci_dev_lock(hdev); 608f813f1beSJohan Hedberg list_for_each_safe(p, n, &hdev->long_term_keys) { 6098f8625cdSMarcel Holtmann struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list); 610f813f1beSJohan Hedberg seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %*phN %*phN\n", 6118f8625cdSMarcel Holtmann <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, 6128f8625cdSMarcel Holtmann ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), 6138f8625cdSMarcel Holtmann 8, ltk->rand, 16, ltk->val); 6148f8625cdSMarcel Holtmann } 6158f8625cdSMarcel Holtmann hci_dev_unlock(hdev); 6168f8625cdSMarcel Holtmann 6178f8625cdSMarcel Holtmann return 0; 6188f8625cdSMarcel Holtmann } 6198f8625cdSMarcel Holtmann 6208f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file) 6218f8625cdSMarcel Holtmann { 6228f8625cdSMarcel Holtmann return single_open(file, long_term_keys_show, inode->i_private); 6238f8625cdSMarcel Holtmann } 6248f8625cdSMarcel Holtmann 6258f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = { 6268f8625cdSMarcel Holtmann .open = long_term_keys_open, 6278f8625cdSMarcel Holtmann .read = seq_read, 6288f8625cdSMarcel Holtmann .llseek = seq_lseek, 6298f8625cdSMarcel Holtmann .release = single_release, 6308f8625cdSMarcel Holtmann }; 6318f8625cdSMarcel Holtmann 6324e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val) 6334e70c7e7SMarcel Holtmann { 6344e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6354e70c7e7SMarcel Holtmann 6364e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval) 6374e70c7e7SMarcel Holtmann return -EINVAL; 6384e70c7e7SMarcel Holtmann 6394e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6404e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = val; 6414e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 6424e70c7e7SMarcel Holtmann 6434e70c7e7SMarcel Holtmann return 0; 6444e70c7e7SMarcel Holtmann } 6454e70c7e7SMarcel Holtmann 6464e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val) 6474e70c7e7SMarcel Holtmann { 6484e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6494e70c7e7SMarcel Holtmann 6504e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6514e70c7e7SMarcel Holtmann *val = hdev->le_conn_min_interval; 6524e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 6534e70c7e7SMarcel Holtmann 6544e70c7e7SMarcel Holtmann return 0; 6554e70c7e7SMarcel Holtmann } 6564e70c7e7SMarcel Holtmann 6574e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get, 6584e70c7e7SMarcel Holtmann conn_min_interval_set, "%llu\n"); 6594e70c7e7SMarcel Holtmann 6604e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val) 6614e70c7e7SMarcel Holtmann { 6624e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6634e70c7e7SMarcel Holtmann 6644e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval) 6654e70c7e7SMarcel Holtmann return -EINVAL; 6664e70c7e7SMarcel Holtmann 6674e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6684e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = val; 6694e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 6704e70c7e7SMarcel Holtmann 6714e70c7e7SMarcel Holtmann return 0; 6724e70c7e7SMarcel Holtmann } 6734e70c7e7SMarcel Holtmann 6744e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val) 6754e70c7e7SMarcel Holtmann { 6764e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 6774e70c7e7SMarcel Holtmann 6784e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 6794e70c7e7SMarcel Holtmann *val = hdev->le_conn_max_interval; 6804e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 6814e70c7e7SMarcel Holtmann 6824e70c7e7SMarcel Holtmann return 0; 6834e70c7e7SMarcel Holtmann } 6844e70c7e7SMarcel Holtmann 6854e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, 6864e70c7e7SMarcel Holtmann conn_max_interval_set, "%llu\n"); 6874e70c7e7SMarcel Holtmann 68889863109SJukka Rissanen static ssize_t lowpan_read(struct file *file, char __user *user_buf, 68989863109SJukka Rissanen size_t count, loff_t *ppos) 69089863109SJukka Rissanen { 69189863109SJukka Rissanen struct hci_dev *hdev = file->private_data; 69289863109SJukka Rissanen char buf[3]; 69389863109SJukka Rissanen 69489863109SJukka Rissanen buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N'; 69589863109SJukka Rissanen buf[1] = '\n'; 69689863109SJukka Rissanen buf[2] = '\0'; 69789863109SJukka Rissanen return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 69889863109SJukka Rissanen } 69989863109SJukka Rissanen 70089863109SJukka Rissanen static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer, 70189863109SJukka Rissanen size_t count, loff_t *position) 70289863109SJukka Rissanen { 70389863109SJukka Rissanen struct hci_dev *hdev = fp->private_data; 70489863109SJukka Rissanen bool enable; 70589863109SJukka Rissanen char buf[32]; 70689863109SJukka Rissanen size_t buf_size = min(count, (sizeof(buf)-1)); 70789863109SJukka Rissanen 70889863109SJukka Rissanen if (copy_from_user(buf, user_buffer, buf_size)) 70989863109SJukka Rissanen return -EFAULT; 71089863109SJukka Rissanen 71189863109SJukka Rissanen buf[buf_size] = '\0'; 71289863109SJukka Rissanen 71389863109SJukka Rissanen if (strtobool(buf, &enable) < 0) 71489863109SJukka Rissanen return -EINVAL; 71589863109SJukka Rissanen 71689863109SJukka Rissanen if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags)) 71789863109SJukka Rissanen return -EALREADY; 71889863109SJukka Rissanen 71989863109SJukka Rissanen change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags); 72089863109SJukka Rissanen 72189863109SJukka Rissanen return count; 72289863109SJukka Rissanen } 72389863109SJukka Rissanen 72489863109SJukka Rissanen static const struct file_operations lowpan_debugfs_fops = { 72589863109SJukka Rissanen .open = simple_open, 72689863109SJukka Rissanen .read = lowpan_read, 72789863109SJukka Rissanen .write = lowpan_write, 72889863109SJukka Rissanen .llseek = default_llseek, 72989863109SJukka Rissanen }; 73089863109SJukka Rissanen 7311da177e4SLinus Torvalds /* ---- HCI requests ---- */ 7321da177e4SLinus Torvalds 73342c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 7341da177e4SLinus Torvalds { 73542c6b129SJohan Hedberg BT_DBG("%s result 0x%2.2x", hdev->name, result); 73675fb0e32SJohan Hedberg 7371da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 7381da177e4SLinus Torvalds hdev->req_result = result; 7391da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 7401da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 7411da177e4SLinus Torvalds } 7421da177e4SLinus Torvalds } 7431da177e4SLinus Torvalds 7441da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 7451da177e4SLinus Torvalds { 7461da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 7471da177e4SLinus Torvalds 7481da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 7491da177e4SLinus Torvalds hdev->req_result = err; 7501da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 7511da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 7521da177e4SLinus Torvalds } 7531da177e4SLinus Torvalds } 7541da177e4SLinus Torvalds 75577a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 75677a63e0aSFengguang Wu u8 event) 75775e84b7cSJohan Hedberg { 75875e84b7cSJohan Hedberg struct hci_ev_cmd_complete *ev; 75975e84b7cSJohan Hedberg struct hci_event_hdr *hdr; 76075e84b7cSJohan Hedberg struct sk_buff *skb; 76175e84b7cSJohan Hedberg 76275e84b7cSJohan Hedberg hci_dev_lock(hdev); 76375e84b7cSJohan Hedberg 76475e84b7cSJohan Hedberg skb = hdev->recv_evt; 76575e84b7cSJohan Hedberg hdev->recv_evt = NULL; 76675e84b7cSJohan Hedberg 76775e84b7cSJohan Hedberg hci_dev_unlock(hdev); 76875e84b7cSJohan Hedberg 76975e84b7cSJohan Hedberg if (!skb) 77075e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 77175e84b7cSJohan Hedberg 77275e84b7cSJohan Hedberg if (skb->len < sizeof(*hdr)) { 77375e84b7cSJohan Hedberg BT_ERR("Too short HCI event"); 77475e84b7cSJohan Hedberg goto failed; 77575e84b7cSJohan Hedberg } 77675e84b7cSJohan Hedberg 77775e84b7cSJohan Hedberg hdr = (void *) skb->data; 77875e84b7cSJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 77975e84b7cSJohan Hedberg 7807b1abbbeSJohan Hedberg if (event) { 7817b1abbbeSJohan Hedberg if (hdr->evt != event) 7827b1abbbeSJohan Hedberg goto failed; 7837b1abbbeSJohan Hedberg return skb; 7847b1abbbeSJohan Hedberg } 7857b1abbbeSJohan Hedberg 78675e84b7cSJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 78775e84b7cSJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 78875e84b7cSJohan Hedberg goto failed; 78975e84b7cSJohan Hedberg } 79075e84b7cSJohan Hedberg 79175e84b7cSJohan Hedberg if (skb->len < sizeof(*ev)) { 79275e84b7cSJohan Hedberg BT_ERR("Too short cmd_complete event"); 79375e84b7cSJohan Hedberg goto failed; 79475e84b7cSJohan Hedberg } 79575e84b7cSJohan Hedberg 79675e84b7cSJohan Hedberg ev = (void *) skb->data; 79775e84b7cSJohan Hedberg skb_pull(skb, sizeof(*ev)); 79875e84b7cSJohan Hedberg 79975e84b7cSJohan Hedberg if (opcode == __le16_to_cpu(ev->opcode)) 80075e84b7cSJohan Hedberg return skb; 80175e84b7cSJohan Hedberg 80275e84b7cSJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 80375e84b7cSJohan Hedberg __le16_to_cpu(ev->opcode)); 80475e84b7cSJohan Hedberg 80575e84b7cSJohan Hedberg failed: 80675e84b7cSJohan Hedberg kfree_skb(skb); 80775e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 80875e84b7cSJohan Hedberg } 80975e84b7cSJohan Hedberg 8107b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 81107dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout) 81275e84b7cSJohan Hedberg { 81375e84b7cSJohan Hedberg DECLARE_WAITQUEUE(wait, current); 81475e84b7cSJohan Hedberg struct hci_request req; 81575e84b7cSJohan Hedberg int err = 0; 81675e84b7cSJohan Hedberg 81775e84b7cSJohan Hedberg BT_DBG("%s", hdev->name); 81875e84b7cSJohan Hedberg 81975e84b7cSJohan Hedberg hci_req_init(&req, hdev); 82075e84b7cSJohan Hedberg 8217b1abbbeSJohan Hedberg hci_req_add_ev(&req, opcode, plen, param, event); 82275e84b7cSJohan Hedberg 82375e84b7cSJohan Hedberg hdev->req_status = HCI_REQ_PEND; 82475e84b7cSJohan Hedberg 82575e84b7cSJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 82675e84b7cSJohan Hedberg if (err < 0) 82775e84b7cSJohan Hedberg return ERR_PTR(err); 82875e84b7cSJohan Hedberg 82975e84b7cSJohan Hedberg add_wait_queue(&hdev->req_wait_q, &wait); 83075e84b7cSJohan Hedberg set_current_state(TASK_INTERRUPTIBLE); 83175e84b7cSJohan Hedberg 83275e84b7cSJohan Hedberg schedule_timeout(timeout); 83375e84b7cSJohan Hedberg 83475e84b7cSJohan Hedberg remove_wait_queue(&hdev->req_wait_q, &wait); 83575e84b7cSJohan Hedberg 83675e84b7cSJohan Hedberg if (signal_pending(current)) 83775e84b7cSJohan Hedberg return ERR_PTR(-EINTR); 83875e84b7cSJohan Hedberg 83975e84b7cSJohan Hedberg switch (hdev->req_status) { 84075e84b7cSJohan Hedberg case HCI_REQ_DONE: 84175e84b7cSJohan Hedberg err = -bt_to_errno(hdev->req_result); 84275e84b7cSJohan Hedberg break; 84375e84b7cSJohan Hedberg 84475e84b7cSJohan Hedberg case HCI_REQ_CANCELED: 84575e84b7cSJohan Hedberg err = -hdev->req_result; 84675e84b7cSJohan Hedberg break; 84775e84b7cSJohan Hedberg 84875e84b7cSJohan Hedberg default: 84975e84b7cSJohan Hedberg err = -ETIMEDOUT; 85075e84b7cSJohan Hedberg break; 85175e84b7cSJohan Hedberg } 85275e84b7cSJohan Hedberg 85375e84b7cSJohan Hedberg hdev->req_status = hdev->req_result = 0; 85475e84b7cSJohan Hedberg 85575e84b7cSJohan Hedberg BT_DBG("%s end: err %d", hdev->name, err); 85675e84b7cSJohan Hedberg 85775e84b7cSJohan Hedberg if (err < 0) 85875e84b7cSJohan Hedberg return ERR_PTR(err); 85975e84b7cSJohan Hedberg 8607b1abbbeSJohan Hedberg return hci_get_cmd_complete(hdev, opcode, event); 8617b1abbbeSJohan Hedberg } 8627b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev); 8637b1abbbeSJohan Hedberg 8647b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 86507dc93ddSJohan Hedberg const void *param, u32 timeout) 8667b1abbbeSJohan Hedberg { 8677b1abbbeSJohan Hedberg return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); 86875e84b7cSJohan Hedberg } 86975e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync); 87075e84b7cSJohan Hedberg 8711da177e4SLinus Torvalds /* Execute request and wait for completion. */ 87201178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev, 87342c6b129SJohan Hedberg void (*func)(struct hci_request *req, 87442c6b129SJohan Hedberg unsigned long opt), 8751da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 8761da177e4SLinus Torvalds { 87742c6b129SJohan Hedberg struct hci_request req; 8781da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 8791da177e4SLinus Torvalds int err = 0; 8801da177e4SLinus Torvalds 8811da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 8821da177e4SLinus Torvalds 88342c6b129SJohan Hedberg hci_req_init(&req, hdev); 88442c6b129SJohan Hedberg 8851da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 8861da177e4SLinus Torvalds 88742c6b129SJohan Hedberg func(&req, opt); 88853cce22dSJohan Hedberg 88942c6b129SJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 89042c6b129SJohan Hedberg if (err < 0) { 89153cce22dSJohan Hedberg hdev->req_status = 0; 892920c8300SAndre Guedes 893920c8300SAndre Guedes /* ENODATA means the HCI request command queue is empty. 894920c8300SAndre Guedes * This can happen when a request with conditionals doesn't 895920c8300SAndre Guedes * trigger any commands to be sent. This is normal behavior 896920c8300SAndre Guedes * and should not trigger an error return. 89742c6b129SJohan Hedberg */ 898920c8300SAndre Guedes if (err == -ENODATA) 89942c6b129SJohan Hedberg return 0; 900920c8300SAndre Guedes 901920c8300SAndre Guedes return err; 90253cce22dSJohan Hedberg } 90353cce22dSJohan Hedberg 904bc4445c7SAndre Guedes add_wait_queue(&hdev->req_wait_q, &wait); 905bc4445c7SAndre Guedes set_current_state(TASK_INTERRUPTIBLE); 906bc4445c7SAndre Guedes 9071da177e4SLinus Torvalds schedule_timeout(timeout); 9081da177e4SLinus Torvalds 9091da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 9101da177e4SLinus Torvalds 9111da177e4SLinus Torvalds if (signal_pending(current)) 9121da177e4SLinus Torvalds return -EINTR; 9131da177e4SLinus Torvalds 9141da177e4SLinus Torvalds switch (hdev->req_status) { 9151da177e4SLinus Torvalds case HCI_REQ_DONE: 916e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 9171da177e4SLinus Torvalds break; 9181da177e4SLinus Torvalds 9191da177e4SLinus Torvalds case HCI_REQ_CANCELED: 9201da177e4SLinus Torvalds err = -hdev->req_result; 9211da177e4SLinus Torvalds break; 9221da177e4SLinus Torvalds 9231da177e4SLinus Torvalds default: 9241da177e4SLinus Torvalds err = -ETIMEDOUT; 9251da177e4SLinus Torvalds break; 9263ff50b79SStephen Hemminger } 9271da177e4SLinus Torvalds 928a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 9291da177e4SLinus Torvalds 9301da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 9311da177e4SLinus Torvalds 9321da177e4SLinus Torvalds return err; 9331da177e4SLinus Torvalds } 9341da177e4SLinus Torvalds 93501178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev, 93642c6b129SJohan Hedberg void (*req)(struct hci_request *req, 93742c6b129SJohan Hedberg unsigned long opt), 9381da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 9391da177e4SLinus Torvalds { 9401da177e4SLinus Torvalds int ret; 9411da177e4SLinus Torvalds 9427c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 9437c6a329eSMarcel Holtmann return -ENETDOWN; 9447c6a329eSMarcel Holtmann 9451da177e4SLinus Torvalds /* Serialize all requests */ 9461da177e4SLinus Torvalds hci_req_lock(hdev); 94701178cd4SJohan Hedberg ret = __hci_req_sync(hdev, req, opt, timeout); 9481da177e4SLinus Torvalds hci_req_unlock(hdev); 9491da177e4SLinus Torvalds 9501da177e4SLinus Torvalds return ret; 9511da177e4SLinus Torvalds } 9521da177e4SLinus Torvalds 95342c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt) 9541da177e4SLinus Torvalds { 95542c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 9561da177e4SLinus Torvalds 9571da177e4SLinus Torvalds /* Reset device */ 95842c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 95942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 9601da177e4SLinus Torvalds } 9611da177e4SLinus Torvalds 96242c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 9631da177e4SLinus Torvalds { 96442c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 9652455a3eaSAndrei Emeltchenko 9661da177e4SLinus Torvalds /* Read Local Supported Features */ 96742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 9681da177e4SLinus Torvalds 9691143e5a6SMarcel Holtmann /* Read Local Version */ 97042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 9712177bab5SJohan Hedberg 9722177bab5SJohan Hedberg /* Read BD Address */ 97342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 9741da177e4SLinus Torvalds } 9751da177e4SLinus Torvalds 97642c6b129SJohan Hedberg static void amp_init(struct hci_request *req) 977e61ef499SAndrei Emeltchenko { 97842c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 9792455a3eaSAndrei Emeltchenko 980e61ef499SAndrei Emeltchenko /* Read Local Version */ 98142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 9826bcbc489SAndrei Emeltchenko 983f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 984f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 985f6996cfeSMarcel Holtmann 986f6996cfeSMarcel Holtmann /* Read Local Supported Features */ 987f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 988f6996cfeSMarcel Holtmann 9896bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 99042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 991e71dfabaSAndrei Emeltchenko 992e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 99342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 9947528ca1cSMarcel Holtmann 995f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 996f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 997f38ba941SMarcel Holtmann 9987528ca1cSMarcel Holtmann /* Read Location Data */ 9997528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 1000e61ef499SAndrei Emeltchenko } 1001e61ef499SAndrei Emeltchenko 100242c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 1003e61ef499SAndrei Emeltchenko { 100442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1005e61ef499SAndrei Emeltchenko 1006e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 1007e61ef499SAndrei Emeltchenko 100811778716SAndrei Emeltchenko /* Reset */ 100911778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 101042c6b129SJohan Hedberg hci_reset_req(req, 0); 101111778716SAndrei Emeltchenko 1012e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 1013e61ef499SAndrei Emeltchenko case HCI_BREDR: 101442c6b129SJohan Hedberg bredr_init(req); 1015e61ef499SAndrei Emeltchenko break; 1016e61ef499SAndrei Emeltchenko 1017e61ef499SAndrei Emeltchenko case HCI_AMP: 101842c6b129SJohan Hedberg amp_init(req); 1019e61ef499SAndrei Emeltchenko break; 1020e61ef499SAndrei Emeltchenko 1021e61ef499SAndrei Emeltchenko default: 1022e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 1023e61ef499SAndrei Emeltchenko break; 1024e61ef499SAndrei Emeltchenko } 1025e61ef499SAndrei Emeltchenko } 1026e61ef499SAndrei Emeltchenko 102742c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 10282177bab5SJohan Hedberg { 10294ca048e3SMarcel Holtmann struct hci_dev *hdev = req->hdev; 10304ca048e3SMarcel Holtmann 10312177bab5SJohan Hedberg __le16 param; 10322177bab5SJohan Hedberg __u8 flt_type; 10332177bab5SJohan Hedberg 10342177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 103542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 10362177bab5SJohan Hedberg 10372177bab5SJohan Hedberg /* Read Class of Device */ 103842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 10392177bab5SJohan Hedberg 10402177bab5SJohan Hedberg /* Read Local Name */ 104142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 10422177bab5SJohan Hedberg 10432177bab5SJohan Hedberg /* Read Voice Setting */ 104442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 10452177bab5SJohan Hedberg 1046b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 1047b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 1048b4cb9fb2SMarcel Holtmann 10494b836f39SMarcel Holtmann /* Read Current IAC LAP */ 10504b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 10514b836f39SMarcel Holtmann 10522177bab5SJohan Hedberg /* Clear Event Filters */ 10532177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 105442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 10552177bab5SJohan Hedberg 10562177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 10572177bab5SJohan Hedberg param = __constant_cpu_to_le16(0x7d00); 105842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 10592177bab5SJohan Hedberg 10604ca048e3SMarcel Holtmann /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, 10614ca048e3SMarcel Holtmann * but it does not support page scan related HCI commands. 10624ca048e3SMarcel Holtmann */ 10634ca048e3SMarcel Holtmann if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) { 1064f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 1065f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 1066f332ec66SJohan Hedberg } 10672177bab5SJohan Hedberg } 10682177bab5SJohan Hedberg 106942c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 10702177bab5SJohan Hedberg { 1071c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 1072c73eee91SJohan Hedberg 10732177bab5SJohan Hedberg /* Read LE Buffer Size */ 107442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 10752177bab5SJohan Hedberg 10762177bab5SJohan Hedberg /* Read LE Local Supported Features */ 107742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 10782177bab5SJohan Hedberg 10792177bab5SJohan Hedberg /* Read LE Advertising Channel TX Power */ 108042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 10812177bab5SJohan Hedberg 10822177bab5SJohan Hedberg /* Read LE White List Size */ 108342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 10842177bab5SJohan Hedberg 10852177bab5SJohan Hedberg /* Read LE Supported States */ 108642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 1087c73eee91SJohan Hedberg 1088c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 1089c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1090c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 10912177bab5SJohan Hedberg } 10922177bab5SJohan Hedberg 10932177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 10942177bab5SJohan Hedberg { 10952177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 10962177bab5SJohan Hedberg return 0x02; 10972177bab5SJohan Hedberg 10982177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 10992177bab5SJohan Hedberg return 0x01; 11002177bab5SJohan Hedberg 11012177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 11022177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 11032177bab5SJohan Hedberg return 0x01; 11042177bab5SJohan Hedberg 11052177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 11062177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 11072177bab5SJohan Hedberg return 0x01; 11082177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 11092177bab5SJohan Hedberg return 0x01; 11102177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 11112177bab5SJohan Hedberg return 0x01; 11122177bab5SJohan Hedberg } 11132177bab5SJohan Hedberg 11142177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 11152177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 11162177bab5SJohan Hedberg return 0x01; 11172177bab5SJohan Hedberg 11182177bab5SJohan Hedberg return 0x00; 11192177bab5SJohan Hedberg } 11202177bab5SJohan Hedberg 112142c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 11222177bab5SJohan Hedberg { 11232177bab5SJohan Hedberg u8 mode; 11242177bab5SJohan Hedberg 112542c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 11262177bab5SJohan Hedberg 112742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 11282177bab5SJohan Hedberg } 11292177bab5SJohan Hedberg 113042c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 11312177bab5SJohan Hedberg { 113242c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 113342c6b129SJohan Hedberg 11342177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 11352177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 11362177bab5SJohan Hedberg * command otherwise. 11372177bab5SJohan Hedberg */ 11382177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 11392177bab5SJohan Hedberg 11402177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 11412177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 11422177bab5SJohan Hedberg */ 11432177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 11442177bab5SJohan Hedberg return; 11452177bab5SJohan Hedberg 11462177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 11472177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 11482177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 11492177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 11502177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 11512177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 1152c7882cbdSMarcel Holtmann } else { 1153c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 1154c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 1155c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 1156c7882cbdSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 1157c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 1158c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 1159c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 1160c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 1161c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 1162c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 1163c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 11642177bab5SJohan Hedberg } 11652177bab5SJohan Hedberg 11662177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 11672177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 11682177bab5SJohan Hedberg 11692177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 11702177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 11712177bab5SJohan Hedberg 11722177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 11732177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 11742177bab5SJohan Hedberg 11752177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 11762177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 11772177bab5SJohan Hedberg 11782177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 11792177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 11802177bab5SJohan Hedberg 11812177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 11822177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 11832177bab5SJohan Hedberg 11842177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 11852177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 11862177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 11872177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 11882177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 11892177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 11902177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 11912177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 11922177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 11932177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 11942177bab5SJohan Hedberg * Features Notification 11952177bab5SJohan Hedberg */ 11962177bab5SJohan Hedberg } 11972177bab5SJohan Hedberg 11982177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 11992177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 12002177bab5SJohan Hedberg 120142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 12022177bab5SJohan Hedberg 12032177bab5SJohan Hedberg if (lmp_le_capable(hdev)) { 12042177bab5SJohan Hedberg memset(events, 0, sizeof(events)); 12052177bab5SJohan Hedberg events[0] = 0x1f; 120642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, 12072177bab5SJohan Hedberg sizeof(events), events); 12082177bab5SJohan Hedberg } 12092177bab5SJohan Hedberg } 12102177bab5SJohan Hedberg 121142c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 12122177bab5SJohan Hedberg { 121342c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 121442c6b129SJohan Hedberg 12152177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 121642c6b129SJohan Hedberg bredr_setup(req); 121756f87901SJohan Hedberg else 121856f87901SJohan Hedberg clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 12192177bab5SJohan Hedberg 12202177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 122142c6b129SJohan Hedberg le_setup(req); 12222177bab5SJohan Hedberg 122342c6b129SJohan Hedberg hci_setup_event_mask(req); 12242177bab5SJohan Hedberg 12253f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 12263f8e2d75SJohan Hedberg * local supported commands HCI command. 12273f8e2d75SJohan Hedberg */ 12283f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 122942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 12302177bab5SJohan Hedberg 12312177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 123257af75a8SMarcel Holtmann /* When SSP is available, then the host features page 123357af75a8SMarcel Holtmann * should also be available as well. However some 123457af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 123557af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 123657af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 123757af75a8SMarcel Holtmann */ 123857af75a8SMarcel Holtmann hdev->max_page = 0x01; 123957af75a8SMarcel Holtmann 12402177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 12412177bab5SJohan Hedberg u8 mode = 0x01; 124242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 12432177bab5SJohan Hedberg sizeof(mode), &mode); 12442177bab5SJohan Hedberg } else { 12452177bab5SJohan Hedberg struct hci_cp_write_eir cp; 12462177bab5SJohan Hedberg 12472177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 12482177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 12492177bab5SJohan Hedberg 125042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 12512177bab5SJohan Hedberg } 12522177bab5SJohan Hedberg } 12532177bab5SJohan Hedberg 12542177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 125542c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 12562177bab5SJohan Hedberg 12572177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 125842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 12592177bab5SJohan Hedberg 12602177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 12612177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 12622177bab5SJohan Hedberg 12632177bab5SJohan Hedberg cp.page = 0x01; 126442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 126542c6b129SJohan Hedberg sizeof(cp), &cp); 12662177bab5SJohan Hedberg } 12672177bab5SJohan Hedberg 12682177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 12692177bab5SJohan Hedberg u8 enable = 1; 127042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 12712177bab5SJohan Hedberg &enable); 12722177bab5SJohan Hedberg } 12732177bab5SJohan Hedberg } 12742177bab5SJohan Hedberg 127542c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 12762177bab5SJohan Hedberg { 127742c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 12782177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 12792177bab5SJohan Hedberg u16 link_policy = 0; 12802177bab5SJohan Hedberg 12812177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 12822177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 12832177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 12842177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 12852177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 12862177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 12872177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 12882177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 12892177bab5SJohan Hedberg 12902177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 129142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 12922177bab5SJohan Hedberg } 12932177bab5SJohan Hedberg 129442c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 12952177bab5SJohan Hedberg { 129642c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 12972177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 12982177bab5SJohan Hedberg 1299c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 1300c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1301c73eee91SJohan Hedberg return; 1302c73eee91SJohan Hedberg 13032177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 13042177bab5SJohan Hedberg 13052177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 13062177bab5SJohan Hedberg cp.le = 0x01; 13072177bab5SJohan Hedberg cp.simul = lmp_le_br_capable(hdev); 13082177bab5SJohan Hedberg } 13092177bab5SJohan Hedberg 13102177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 131142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 13122177bab5SJohan Hedberg &cp); 13132177bab5SJohan Hedberg } 13142177bab5SJohan Hedberg 1315d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 1316d62e6d67SJohan Hedberg { 1317d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 1318d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1319d62e6d67SJohan Hedberg 1320d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 1321d62e6d67SJohan Hedberg * enable all necessary events for it. 1322d62e6d67SJohan Hedberg */ 132353b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 1324d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 1325d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 1326d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 1327d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 1328d62e6d67SJohan Hedberg } 1329d62e6d67SJohan Hedberg 1330d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 1331d62e6d67SJohan Hedberg * enable all necessary events for it. 1332d62e6d67SJohan Hedberg */ 133353b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 1334d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 1335d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 1336d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 1337d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 1338d62e6d67SJohan Hedberg } 1339d62e6d67SJohan Hedberg 134040c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 134140c59fcbSMarcel Holtmann if (lmp_ping_capable(hdev)) 134240c59fcbSMarcel Holtmann events[2] |= 0x80; 134340c59fcbSMarcel Holtmann 1344d62e6d67SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 1345d62e6d67SJohan Hedberg } 1346d62e6d67SJohan Hedberg 134742c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 13482177bab5SJohan Hedberg { 134942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1350d2c5d77fSJohan Hedberg u8 p; 135142c6b129SJohan Hedberg 1352b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 1353b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 1354b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 1355b8f4e068SGustavo Padovan * 1356b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 1357b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 1358b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 1359b8f4e068SGustavo Padovan * command redundant anyway. 1360f9f462faSMarcel Holtmann * 1361f9f462faSMarcel Holtmann * Some controllers indicate that they support handling deleting 1362f9f462faSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 1363f9f462faSMarcel Holtmann * just disable this command. 1364b8f4e068SGustavo Padovan */ 1365f9f462faSMarcel Holtmann if (hdev->commands[6] & 0x80 && 1366f9f462faSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 136759f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 136859f45d57SJohan Hedberg 136959f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 137059f45d57SJohan Hedberg cp.delete_all = 0x01; 137159f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 137259f45d57SJohan Hedberg sizeof(cp), &cp); 137359f45d57SJohan Hedberg } 137459f45d57SJohan Hedberg 13752177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 137642c6b129SJohan Hedberg hci_setup_link_policy(req); 13772177bab5SJohan Hedberg 137879830f66SMarcel Holtmann if (lmp_le_capable(hdev)) { 1379bef34c0aSMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 1380bef34c0aSMarcel Holtmann /* If the controller has a public BD_ADDR, then 1381bef34c0aSMarcel Holtmann * by default use that one. If this is a LE only 1382bef34c0aSMarcel Holtmann * controller without a public address, default 1383bef34c0aSMarcel Holtmann * to the random address. 138479830f66SMarcel Holtmann */ 138579830f66SMarcel Holtmann if (bacmp(&hdev->bdaddr, BDADDR_ANY)) 138679830f66SMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_PUBLIC; 138779830f66SMarcel Holtmann else 138879830f66SMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_RANDOM; 1389bef34c0aSMarcel Holtmann } 139079830f66SMarcel Holtmann 139142c6b129SJohan Hedberg hci_set_le_support(req); 139279830f66SMarcel Holtmann } 1393d2c5d77fSJohan Hedberg 1394d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 1395d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 1396d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 1397d2c5d77fSJohan Hedberg 1398d2c5d77fSJohan Hedberg cp.page = p; 1399d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 1400d2c5d77fSJohan Hedberg sizeof(cp), &cp); 1401d2c5d77fSJohan Hedberg } 14022177bab5SJohan Hedberg } 14032177bab5SJohan Hedberg 14045d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt) 14055d4e7e8dSJohan Hedberg { 14065d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 14075d4e7e8dSJohan Hedberg 1408d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 1409d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 1410d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 1411d62e6d67SJohan Hedberg 14125d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 141353b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 14145d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 1415a6d0d690SMarcel Holtmann 1416a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 14175afeac14SMarcel Holtmann if ((lmp_sc_capable(hdev) || 14185afeac14SMarcel Holtmann test_bit(HCI_FORCE_SC, &hdev->dev_flags)) && 1419a6d0d690SMarcel Holtmann test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) { 1420a6d0d690SMarcel Holtmann u8 support = 0x01; 1421a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 1422a6d0d690SMarcel Holtmann sizeof(support), &support); 1423a6d0d690SMarcel Holtmann } 14245d4e7e8dSJohan Hedberg } 14255d4e7e8dSJohan Hedberg 14262177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 14272177bab5SJohan Hedberg { 14282177bab5SJohan Hedberg int err; 14292177bab5SJohan Hedberg 14302177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 14312177bab5SJohan Hedberg if (err < 0) 14322177bab5SJohan Hedberg return err; 14332177bab5SJohan Hedberg 14344b4148e9SMarcel Holtmann /* The Device Under Test (DUT) mode is special and available for 14354b4148e9SMarcel Holtmann * all controller types. So just create it early on. 14364b4148e9SMarcel Holtmann */ 14374b4148e9SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 14384b4148e9SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 14394b4148e9SMarcel Holtmann &dut_mode_fops); 14404b4148e9SMarcel Holtmann } 14414b4148e9SMarcel Holtmann 14422177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 14432177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 14442177bab5SJohan Hedberg * first stage init. 14452177bab5SJohan Hedberg */ 14462177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 14472177bab5SJohan Hedberg return 0; 14482177bab5SJohan Hedberg 14492177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 14502177bab5SJohan Hedberg if (err < 0) 14512177bab5SJohan Hedberg return err; 14522177bab5SJohan Hedberg 14535d4e7e8dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 14545d4e7e8dSJohan Hedberg if (err < 0) 14555d4e7e8dSJohan Hedberg return err; 14565d4e7e8dSJohan Hedberg 1457baf27f6eSMarcel Holtmann err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 1458baf27f6eSMarcel Holtmann if (err < 0) 1459baf27f6eSMarcel Holtmann return err; 1460baf27f6eSMarcel Holtmann 1461baf27f6eSMarcel Holtmann /* Only create debugfs entries during the initial setup 1462baf27f6eSMarcel Holtmann * phase and not every time the controller gets powered on. 1463baf27f6eSMarcel Holtmann */ 1464baf27f6eSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 1465baf27f6eSMarcel Holtmann return 0; 1466baf27f6eSMarcel Holtmann 1467dfb826a8SMarcel Holtmann debugfs_create_file("features", 0444, hdev->debugfs, hdev, 1468dfb826a8SMarcel Holtmann &features_fops); 1469ceeb3bc0SMarcel Holtmann debugfs_create_u16("manufacturer", 0444, hdev->debugfs, 1470ceeb3bc0SMarcel Holtmann &hdev->manufacturer); 1471ceeb3bc0SMarcel Holtmann debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); 1472ceeb3bc0SMarcel Holtmann debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); 147370afe0b8SMarcel Holtmann debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, 147470afe0b8SMarcel Holtmann &blacklist_fops); 147547219839SMarcel Holtmann debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); 147647219839SMarcel Holtmann 1477baf27f6eSMarcel Holtmann if (lmp_bredr_capable(hdev)) { 1478baf27f6eSMarcel Holtmann debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, 1479baf27f6eSMarcel Holtmann hdev, &inquiry_cache_fops); 148002d08d15SMarcel Holtmann debugfs_create_file("link_keys", 0400, hdev->debugfs, 148102d08d15SMarcel Holtmann hdev, &link_keys_fops); 1482babdbb3cSMarcel Holtmann debugfs_create_file("dev_class", 0444, hdev->debugfs, 1483babdbb3cSMarcel Holtmann hdev, &dev_class_fops); 1484041000b9SMarcel Holtmann debugfs_create_file("voice_setting", 0444, hdev->debugfs, 1485041000b9SMarcel Holtmann hdev, &voice_setting_fops); 1486baf27f6eSMarcel Holtmann } 1487baf27f6eSMarcel Holtmann 148806f5b778SMarcel Holtmann if (lmp_ssp_capable(hdev)) { 1489ebd1e33bSMarcel Holtmann debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, 1490ebd1e33bSMarcel Holtmann hdev, &auto_accept_delay_fops); 149106f5b778SMarcel Holtmann debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs, 149206f5b778SMarcel Holtmann hdev, &ssp_debug_mode_fops); 14935afeac14SMarcel Holtmann debugfs_create_file("force_sc_support", 0644, hdev->debugfs, 14945afeac14SMarcel Holtmann hdev, &force_sc_support_fops); 1495134c2a89SMarcel Holtmann debugfs_create_file("sc_only_mode", 0444, hdev->debugfs, 1496134c2a89SMarcel Holtmann hdev, &sc_only_mode_fops); 149706f5b778SMarcel Holtmann } 1498ebd1e33bSMarcel Holtmann 14992bfa3531SMarcel Holtmann if (lmp_sniff_capable(hdev)) { 15002bfa3531SMarcel Holtmann debugfs_create_file("idle_timeout", 0644, hdev->debugfs, 15012bfa3531SMarcel Holtmann hdev, &idle_timeout_fops); 15022bfa3531SMarcel Holtmann debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs, 15032bfa3531SMarcel Holtmann hdev, &sniff_min_interval_fops); 15042bfa3531SMarcel Holtmann debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs, 15052bfa3531SMarcel Holtmann hdev, &sniff_max_interval_fops); 15062bfa3531SMarcel Holtmann } 15072bfa3531SMarcel Holtmann 1508d0f729b8SMarcel Holtmann if (lmp_le_capable(hdev)) { 1509d0f729b8SMarcel Holtmann debugfs_create_u8("white_list_size", 0444, hdev->debugfs, 1510d0f729b8SMarcel Holtmann &hdev->le_white_list_size); 1511e7b8fc92SMarcel Holtmann debugfs_create_file("static_address", 0444, hdev->debugfs, 1512e7b8fc92SMarcel Holtmann hdev, &static_address_fops); 151392202185SMarcel Holtmann debugfs_create_file("own_address_type", 0644, hdev->debugfs, 151492202185SMarcel Holtmann hdev, &own_address_type_fops); 15158f8625cdSMarcel Holtmann debugfs_create_file("long_term_keys", 0400, hdev->debugfs, 15168f8625cdSMarcel Holtmann hdev, &long_term_keys_fops); 15174e70c7e7SMarcel Holtmann debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, 15184e70c7e7SMarcel Holtmann hdev, &conn_min_interval_fops); 15194e70c7e7SMarcel Holtmann debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, 15204e70c7e7SMarcel Holtmann hdev, &conn_max_interval_fops); 152189863109SJukka Rissanen debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev, 152289863109SJukka Rissanen &lowpan_debugfs_fops); 1523d0f729b8SMarcel Holtmann } 1524e7b8fc92SMarcel Holtmann 1525baf27f6eSMarcel Holtmann return 0; 15262177bab5SJohan Hedberg } 15272177bab5SJohan Hedberg 152842c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 15291da177e4SLinus Torvalds { 15301da177e4SLinus Torvalds __u8 scan = opt; 15311da177e4SLinus Torvalds 153242c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 15331da177e4SLinus Torvalds 15341da177e4SLinus Torvalds /* Inquiry and Page scans */ 153542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 15361da177e4SLinus Torvalds } 15371da177e4SLinus Torvalds 153842c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 15391da177e4SLinus Torvalds { 15401da177e4SLinus Torvalds __u8 auth = opt; 15411da177e4SLinus Torvalds 154242c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 15431da177e4SLinus Torvalds 15441da177e4SLinus Torvalds /* Authentication */ 154542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 15461da177e4SLinus Torvalds } 15471da177e4SLinus Torvalds 154842c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 15491da177e4SLinus Torvalds { 15501da177e4SLinus Torvalds __u8 encrypt = opt; 15511da177e4SLinus Torvalds 155242c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 15531da177e4SLinus Torvalds 1554e4e8e37cSMarcel Holtmann /* Encryption */ 155542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 15561da177e4SLinus Torvalds } 15571da177e4SLinus Torvalds 155842c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 1559e4e8e37cSMarcel Holtmann { 1560e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1561e4e8e37cSMarcel Holtmann 156242c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1563e4e8e37cSMarcel Holtmann 1564e4e8e37cSMarcel Holtmann /* Default link policy */ 156542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1566e4e8e37cSMarcel Holtmann } 1567e4e8e37cSMarcel Holtmann 15681da177e4SLinus Torvalds /* Get HCI device by index. 15691da177e4SLinus Torvalds * Device is held on return. */ 15701da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 15711da177e4SLinus Torvalds { 15728035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 15731da177e4SLinus Torvalds 15741da177e4SLinus Torvalds BT_DBG("%d", index); 15751da177e4SLinus Torvalds 15761da177e4SLinus Torvalds if (index < 0) 15771da177e4SLinus Torvalds return NULL; 15781da177e4SLinus Torvalds 15791da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 15808035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 15811da177e4SLinus Torvalds if (d->id == index) { 15821da177e4SLinus Torvalds hdev = hci_dev_hold(d); 15831da177e4SLinus Torvalds break; 15841da177e4SLinus Torvalds } 15851da177e4SLinus Torvalds } 15861da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 15871da177e4SLinus Torvalds return hdev; 15881da177e4SLinus Torvalds } 15891da177e4SLinus Torvalds 15901da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1591ff9ef578SJohan Hedberg 159230dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 159330dc78e1SJohan Hedberg { 159430dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 159530dc78e1SJohan Hedberg 15966fbe195dSAndre Guedes switch (discov->state) { 1597343f935bSAndre Guedes case DISCOVERY_FINDING: 15986fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 159930dc78e1SJohan Hedberg return true; 160030dc78e1SJohan Hedberg 16016fbe195dSAndre Guedes default: 160230dc78e1SJohan Hedberg return false; 160330dc78e1SJohan Hedberg } 16046fbe195dSAndre Guedes } 160530dc78e1SJohan Hedberg 1606ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1607ff9ef578SJohan Hedberg { 1608ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1609ff9ef578SJohan Hedberg 1610ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 1611ff9ef578SJohan Hedberg return; 1612ff9ef578SJohan Hedberg 1613ff9ef578SJohan Hedberg switch (state) { 1614ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 16157b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 1616ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1617ff9ef578SJohan Hedberg break; 1618ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1619ff9ef578SJohan Hedberg break; 1620343f935bSAndre Guedes case DISCOVERY_FINDING: 1621ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1622ff9ef578SJohan Hedberg break; 162330dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 162430dc78e1SJohan Hedberg break; 1625ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1626ff9ef578SJohan Hedberg break; 1627ff9ef578SJohan Hedberg } 1628ff9ef578SJohan Hedberg 1629ff9ef578SJohan Hedberg hdev->discovery.state = state; 1630ff9ef578SJohan Hedberg } 1631ff9ef578SJohan Hedberg 16321f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 16331da177e4SLinus Torvalds { 163430883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1635b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 16361da177e4SLinus Torvalds 1637561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1638561aafbcSJohan Hedberg list_del(&p->all); 1639b57c1a56SJohan Hedberg kfree(p); 16401da177e4SLinus Torvalds } 1641561aafbcSJohan Hedberg 1642561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1643561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 16441da177e4SLinus Torvalds } 16451da177e4SLinus Torvalds 1646a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1647a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 16481da177e4SLinus Torvalds { 164930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 16501da177e4SLinus Torvalds struct inquiry_entry *e; 16511da177e4SLinus Torvalds 16526ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 16531da177e4SLinus Torvalds 1654561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 16551da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 16561da177e4SLinus Torvalds return e; 16571da177e4SLinus Torvalds } 16581da177e4SLinus Torvalds 1659b57c1a56SJohan Hedberg return NULL; 1660b57c1a56SJohan Hedberg } 1661b57c1a56SJohan Hedberg 1662561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1663561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1664561aafbcSJohan Hedberg { 166530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1666561aafbcSJohan Hedberg struct inquiry_entry *e; 1667561aafbcSJohan Hedberg 16686ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1669561aafbcSJohan Hedberg 1670561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1671561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1672561aafbcSJohan Hedberg return e; 1673561aafbcSJohan Hedberg } 1674561aafbcSJohan Hedberg 1675561aafbcSJohan Hedberg return NULL; 1676561aafbcSJohan Hedberg } 1677561aafbcSJohan Hedberg 167830dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 167930dc78e1SJohan Hedberg bdaddr_t *bdaddr, 168030dc78e1SJohan Hedberg int state) 168130dc78e1SJohan Hedberg { 168230dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 168330dc78e1SJohan Hedberg struct inquiry_entry *e; 168430dc78e1SJohan Hedberg 16856ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 168630dc78e1SJohan Hedberg 168730dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 168830dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 168930dc78e1SJohan Hedberg return e; 169030dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 169130dc78e1SJohan Hedberg return e; 169230dc78e1SJohan Hedberg } 169330dc78e1SJohan Hedberg 169430dc78e1SJohan Hedberg return NULL; 169530dc78e1SJohan Hedberg } 169630dc78e1SJohan Hedberg 1697a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1698a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1699a3d4e20aSJohan Hedberg { 1700a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1701a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1702a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1703a3d4e20aSJohan Hedberg 1704a3d4e20aSJohan Hedberg list_del(&ie->list); 1705a3d4e20aSJohan Hedberg 1706a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1707a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1708a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1709a3d4e20aSJohan Hedberg break; 1710a3d4e20aSJohan Hedberg pos = &p->list; 1711a3d4e20aSJohan Hedberg } 1712a3d4e20aSJohan Hedberg 1713a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1714a3d4e20aSJohan Hedberg } 1715a3d4e20aSJohan Hedberg 17163175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1717388fc8faSJohan Hedberg bool name_known, bool *ssp) 17181da177e4SLinus Torvalds { 171930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 172070f23020SAndrei Emeltchenko struct inquiry_entry *ie; 17211da177e4SLinus Torvalds 17226ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 17231da177e4SLinus Torvalds 17242b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 17252b2fec4dSSzymon Janc 1726388fc8faSJohan Hedberg if (ssp) 1727388fc8faSJohan Hedberg *ssp = data->ssp_mode; 1728388fc8faSJohan Hedberg 172970f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1730a3d4e20aSJohan Hedberg if (ie) { 1731388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 1732388fc8faSJohan Hedberg *ssp = true; 1733388fc8faSJohan Hedberg 1734a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1735a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1736a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1737a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1738a3d4e20aSJohan Hedberg } 1739a3d4e20aSJohan Hedberg 1740561aafbcSJohan Hedberg goto update; 1741a3d4e20aSJohan Hedberg } 1742561aafbcSJohan Hedberg 17431da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 174470f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 174570f23020SAndrei Emeltchenko if (!ie) 17463175405bSJohan Hedberg return false; 174770f23020SAndrei Emeltchenko 1748561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1749561aafbcSJohan Hedberg 1750561aafbcSJohan Hedberg if (name_known) { 1751561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1752561aafbcSJohan Hedberg } else { 1753561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1754561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1755561aafbcSJohan Hedberg } 1756561aafbcSJohan Hedberg 1757561aafbcSJohan Hedberg update: 1758561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1759561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1760561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1761561aafbcSJohan Hedberg list_del(&ie->list); 17621da177e4SLinus Torvalds } 17631da177e4SLinus Torvalds 176470f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 176570f23020SAndrei Emeltchenko ie->timestamp = jiffies; 17661da177e4SLinus Torvalds cache->timestamp = jiffies; 17673175405bSJohan Hedberg 17683175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 17693175405bSJohan Hedberg return false; 17703175405bSJohan Hedberg 17713175405bSJohan Hedberg return true; 17721da177e4SLinus Torvalds } 17731da177e4SLinus Torvalds 17741da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 17751da177e4SLinus Torvalds { 177630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 17771da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 17781da177e4SLinus Torvalds struct inquiry_entry *e; 17791da177e4SLinus Torvalds int copied = 0; 17801da177e4SLinus Torvalds 1781561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 17821da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1783b57c1a56SJohan Hedberg 1784b57c1a56SJohan Hedberg if (copied >= num) 1785b57c1a56SJohan Hedberg break; 1786b57c1a56SJohan Hedberg 17871da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 17881da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 17891da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 17901da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 17911da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 17921da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1793b57c1a56SJohan Hedberg 17941da177e4SLinus Torvalds info++; 1795b57c1a56SJohan Hedberg copied++; 17961da177e4SLinus Torvalds } 17971da177e4SLinus Torvalds 17981da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 17991da177e4SLinus Torvalds return copied; 18001da177e4SLinus Torvalds } 18011da177e4SLinus Torvalds 180242c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 18031da177e4SLinus Torvalds { 18041da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 180542c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 18061da177e4SLinus Torvalds struct hci_cp_inquiry cp; 18071da177e4SLinus Torvalds 18081da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 18091da177e4SLinus Torvalds 18101da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 18111da177e4SLinus Torvalds return; 18121da177e4SLinus Torvalds 18131da177e4SLinus Torvalds /* Start Inquiry */ 18141da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 18151da177e4SLinus Torvalds cp.length = ir->length; 18161da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 181742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 18181da177e4SLinus Torvalds } 18191da177e4SLinus Torvalds 18203e13fa1eSAndre Guedes static int wait_inquiry(void *word) 18213e13fa1eSAndre Guedes { 18223e13fa1eSAndre Guedes schedule(); 18233e13fa1eSAndre Guedes return signal_pending(current); 18243e13fa1eSAndre Guedes } 18253e13fa1eSAndre Guedes 18261da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 18271da177e4SLinus Torvalds { 18281da177e4SLinus Torvalds __u8 __user *ptr = arg; 18291da177e4SLinus Torvalds struct hci_inquiry_req ir; 18301da177e4SLinus Torvalds struct hci_dev *hdev; 18311da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 18321da177e4SLinus Torvalds long timeo; 18331da177e4SLinus Torvalds __u8 *buf; 18341da177e4SLinus Torvalds 18351da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 18361da177e4SLinus Torvalds return -EFAULT; 18371da177e4SLinus Torvalds 18385a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 18395a08ecceSAndrei Emeltchenko if (!hdev) 18401da177e4SLinus Torvalds return -ENODEV; 18411da177e4SLinus Torvalds 18420736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 18430736cfa8SMarcel Holtmann err = -EBUSY; 18440736cfa8SMarcel Holtmann goto done; 18450736cfa8SMarcel Holtmann } 18460736cfa8SMarcel Holtmann 18475b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 18485b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 18495b69bef5SMarcel Holtmann goto done; 18505b69bef5SMarcel Holtmann } 18515b69bef5SMarcel Holtmann 185256f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 185356f87901SJohan Hedberg err = -EOPNOTSUPP; 185456f87901SJohan Hedberg goto done; 185556f87901SJohan Hedberg } 185656f87901SJohan Hedberg 185709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 18581da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1859a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 18601f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 18611da177e4SLinus Torvalds do_inquiry = 1; 18621da177e4SLinus Torvalds } 186309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18641da177e4SLinus Torvalds 186504837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 186670f23020SAndrei Emeltchenko 186770f23020SAndrei Emeltchenko if (do_inquiry) { 186801178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 186901178cd4SJohan Hedberg timeo); 187070f23020SAndrei Emeltchenko if (err < 0) 18711da177e4SLinus Torvalds goto done; 18723e13fa1eSAndre Guedes 18733e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 18743e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 18753e13fa1eSAndre Guedes */ 18763e13fa1eSAndre Guedes if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, 18773e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 18783e13fa1eSAndre Guedes return -EINTR; 187970f23020SAndrei Emeltchenko } 18801da177e4SLinus Torvalds 18818fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 18828fc9ced3SGustavo Padovan * 255 entries 18838fc9ced3SGustavo Padovan */ 18841da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 18851da177e4SLinus Torvalds 18861da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 18871da177e4SLinus Torvalds * copy it to the user space. 18881da177e4SLinus Torvalds */ 188970f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 189070f23020SAndrei Emeltchenko if (!buf) { 18911da177e4SLinus Torvalds err = -ENOMEM; 18921da177e4SLinus Torvalds goto done; 18931da177e4SLinus Torvalds } 18941da177e4SLinus Torvalds 189509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 18961da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 189709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18981da177e4SLinus Torvalds 18991da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 19001da177e4SLinus Torvalds 19011da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 19021da177e4SLinus Torvalds ptr += sizeof(ir); 19031da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 19041da177e4SLinus Torvalds ir.num_rsp)) 19051da177e4SLinus Torvalds err = -EFAULT; 19061da177e4SLinus Torvalds } else 19071da177e4SLinus Torvalds err = -EFAULT; 19081da177e4SLinus Torvalds 19091da177e4SLinus Torvalds kfree(buf); 19101da177e4SLinus Torvalds 19111da177e4SLinus Torvalds done: 19121da177e4SLinus Torvalds hci_dev_put(hdev); 19131da177e4SLinus Torvalds return err; 19141da177e4SLinus Torvalds } 19151da177e4SLinus Torvalds 1916cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 19171da177e4SLinus Torvalds { 19181da177e4SLinus Torvalds int ret = 0; 19191da177e4SLinus Torvalds 19201da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 19211da177e4SLinus Torvalds 19221da177e4SLinus Torvalds hci_req_lock(hdev); 19231da177e4SLinus Torvalds 192494324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 192594324962SJohan Hovold ret = -ENODEV; 192694324962SJohan Hovold goto done; 192794324962SJohan Hovold } 192894324962SJohan Hovold 1929a5c8f270SMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 1930a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1931a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1932bf543036SJohan Hedberg */ 1933a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 1934611b30f7SMarcel Holtmann ret = -ERFKILL; 1935611b30f7SMarcel Holtmann goto done; 1936611b30f7SMarcel Holtmann } 1937611b30f7SMarcel Holtmann 1938a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 1939a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 1940a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1941a5c8f270SMarcel Holtmann * or not. 1942a5c8f270SMarcel Holtmann * 1943c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 1944c6beca0eSMarcel Holtmann * if a public address or static random address is 1945c6beca0eSMarcel Holtmann * available. 1946c6beca0eSMarcel Holtmann * 1947a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1948a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1949a5c8f270SMarcel Holtmann */ 1950c6beca0eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 1951c6beca0eSMarcel Holtmann hdev->dev_type == HCI_BREDR && 1952a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1953a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1954a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1955a5c8f270SMarcel Holtmann goto done; 1956a5c8f270SMarcel Holtmann } 1957a5c8f270SMarcel Holtmann } 1958a5c8f270SMarcel Holtmann 19591da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 19601da177e4SLinus Torvalds ret = -EALREADY; 19611da177e4SLinus Torvalds goto done; 19621da177e4SLinus Torvalds } 19631da177e4SLinus Torvalds 19641da177e4SLinus Torvalds if (hdev->open(hdev)) { 19651da177e4SLinus Torvalds ret = -EIO; 19661da177e4SLinus Torvalds goto done; 19671da177e4SLinus Torvalds } 19681da177e4SLinus Torvalds 19691da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 19701da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1971f41c70c4SMarcel Holtmann 1972f41c70c4SMarcel Holtmann if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags)) 1973f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1974f41c70c4SMarcel Holtmann 1975f41c70c4SMarcel Holtmann if (!ret) { 1976f41c70c4SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 1977f41c70c4SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 1978f41c70c4SMarcel Holtmann 19790736cfa8SMarcel Holtmann if (!test_bit(HCI_RAW, &hdev->flags) && 19800736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 19812177bab5SJohan Hedberg ret = __hci_init(hdev); 19821da177e4SLinus Torvalds } 19831da177e4SLinus Torvalds 1984f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1985f41c70c4SMarcel Holtmann 19861da177e4SLinus Torvalds if (!ret) { 19871da177e4SLinus Torvalds hci_dev_hold(hdev); 19881da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 19891da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 1990bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 19910736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 19921514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 199309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1994744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 199509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 199656e5cb86SJohan Hedberg } 19971da177e4SLinus Torvalds } else { 19981da177e4SLinus Torvalds /* Init failed, cleanup */ 19993eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2000c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 2001b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 20021da177e4SLinus Torvalds 20031da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 20041da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 20051da177e4SLinus Torvalds 20061da177e4SLinus Torvalds if (hdev->flush) 20071da177e4SLinus Torvalds hdev->flush(hdev); 20081da177e4SLinus Torvalds 20091da177e4SLinus Torvalds if (hdev->sent_cmd) { 20101da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 20111da177e4SLinus Torvalds hdev->sent_cmd = NULL; 20121da177e4SLinus Torvalds } 20131da177e4SLinus Torvalds 20141da177e4SLinus Torvalds hdev->close(hdev); 20151da177e4SLinus Torvalds hdev->flags = 0; 20161da177e4SLinus Torvalds } 20171da177e4SLinus Torvalds 20181da177e4SLinus Torvalds done: 20191da177e4SLinus Torvalds hci_req_unlock(hdev); 20201da177e4SLinus Torvalds return ret; 20211da177e4SLinus Torvalds } 20221da177e4SLinus Torvalds 2023cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 2024cbed0ca1SJohan Hedberg 2025cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 2026cbed0ca1SJohan Hedberg { 2027cbed0ca1SJohan Hedberg struct hci_dev *hdev; 2028cbed0ca1SJohan Hedberg int err; 2029cbed0ca1SJohan Hedberg 2030cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 2031cbed0ca1SJohan Hedberg if (!hdev) 2032cbed0ca1SJohan Hedberg return -ENODEV; 2033cbed0ca1SJohan Hedberg 2034e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 2035e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 2036e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 2037e1d08f40SJohan Hedberg * completed. 2038e1d08f40SJohan Hedberg */ 2039e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2040e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 2041e1d08f40SJohan Hedberg 2042a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 2043a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 2044a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 2045a5c8f270SMarcel Holtmann */ 2046e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 2047e1d08f40SJohan Hedberg 2048cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 2049cbed0ca1SJohan Hedberg 2050cbed0ca1SJohan Hedberg hci_dev_put(hdev); 2051cbed0ca1SJohan Hedberg 2052cbed0ca1SJohan Hedberg return err; 2053cbed0ca1SJohan Hedberg } 2054cbed0ca1SJohan Hedberg 20551da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 20561da177e4SLinus Torvalds { 20571da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 20581da177e4SLinus Torvalds 205978c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 206078c04c0bSVinicius Costa Gomes 20611da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 20621da177e4SLinus Torvalds hci_req_lock(hdev); 20631da177e4SLinus Torvalds 20641da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 2065b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 20661da177e4SLinus Torvalds hci_req_unlock(hdev); 20671da177e4SLinus Torvalds return 0; 20681da177e4SLinus Torvalds } 20691da177e4SLinus Torvalds 20703eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 20713eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2072b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 20731da177e4SLinus Torvalds 207416ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 2075e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 207616ab91abSJohan Hedberg hdev->discov_timeout = 0; 20775e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 2078310a3d48SMarcel Holtmann clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 207916ab91abSJohan Hedberg } 208016ab91abSJohan Hedberg 2081a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 20827d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 20837d78525dSJohan Hedberg 20847ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 20857ba8b4beSAndre Guedes 208609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 20871f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 20881da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 208909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 20901da177e4SLinus Torvalds 20911da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 20921da177e4SLinus Torvalds 20931da177e4SLinus Torvalds if (hdev->flush) 20941da177e4SLinus Torvalds hdev->flush(hdev); 20951da177e4SLinus Torvalds 20961da177e4SLinus Torvalds /* Reset device */ 20971da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 20981da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 20998af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 21003a6afbd2SMarcel Holtmann !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 2101a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 21021da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 210301178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 21041da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 21051da177e4SLinus Torvalds } 21061da177e4SLinus Torvalds 2107c347b765SGustavo F. Padovan /* flush cmd work */ 2108c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 21091da177e4SLinus Torvalds 21101da177e4SLinus Torvalds /* Drop queues */ 21111da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 21121da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 21131da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 21141da177e4SLinus Torvalds 21151da177e4SLinus Torvalds /* Drop last sent command */ 21161da177e4SLinus Torvalds if (hdev->sent_cmd) { 2117b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 21181da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 21191da177e4SLinus Torvalds hdev->sent_cmd = NULL; 21201da177e4SLinus Torvalds } 21211da177e4SLinus Torvalds 2122b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 2123b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 2124b6ddb638SJohan Hedberg 21251da177e4SLinus Torvalds /* After this point our queues are empty 21261da177e4SLinus Torvalds * and no tasks are scheduled. */ 21271da177e4SLinus Torvalds hdev->close(hdev); 21281da177e4SLinus Torvalds 212935b973c9SJohan Hedberg /* Clear flags */ 213035b973c9SJohan Hedberg hdev->flags = 0; 213135b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 213235b973c9SJohan Hedberg 213393c311a0SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 213493c311a0SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 213509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2136744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 213709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 21388ee56540SMarcel Holtmann } 213993c311a0SMarcel Holtmann } 21405add6af8SJohan Hedberg 2141ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 2142536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 2143ced5c338SAndrei Emeltchenko 2144e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 214509b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 2146e59fda8dSJohan Hedberg 21471da177e4SLinus Torvalds hci_req_unlock(hdev); 21481da177e4SLinus Torvalds 21491da177e4SLinus Torvalds hci_dev_put(hdev); 21501da177e4SLinus Torvalds return 0; 21511da177e4SLinus Torvalds } 21521da177e4SLinus Torvalds 21531da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 21541da177e4SLinus Torvalds { 21551da177e4SLinus Torvalds struct hci_dev *hdev; 21561da177e4SLinus Torvalds int err; 21571da177e4SLinus Torvalds 215870f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 215970f23020SAndrei Emeltchenko if (!hdev) 21601da177e4SLinus Torvalds return -ENODEV; 21618ee56540SMarcel Holtmann 21620736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 21630736cfa8SMarcel Holtmann err = -EBUSY; 21640736cfa8SMarcel Holtmann goto done; 21650736cfa8SMarcel Holtmann } 21660736cfa8SMarcel Holtmann 21678ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 21688ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 21698ee56540SMarcel Holtmann 21701da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 21718ee56540SMarcel Holtmann 21720736cfa8SMarcel Holtmann done: 21731da177e4SLinus Torvalds hci_dev_put(hdev); 21741da177e4SLinus Torvalds return err; 21751da177e4SLinus Torvalds } 21761da177e4SLinus Torvalds 21771da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 21781da177e4SLinus Torvalds { 21791da177e4SLinus Torvalds struct hci_dev *hdev; 21801da177e4SLinus Torvalds int ret = 0; 21811da177e4SLinus Torvalds 218270f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 218370f23020SAndrei Emeltchenko if (!hdev) 21841da177e4SLinus Torvalds return -ENODEV; 21851da177e4SLinus Torvalds 21861da177e4SLinus Torvalds hci_req_lock(hdev); 21871da177e4SLinus Torvalds 2188808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 2189808a049eSMarcel Holtmann ret = -ENETDOWN; 21901da177e4SLinus Torvalds goto done; 2191808a049eSMarcel Holtmann } 21921da177e4SLinus Torvalds 21930736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 21940736cfa8SMarcel Holtmann ret = -EBUSY; 21950736cfa8SMarcel Holtmann goto done; 21960736cfa8SMarcel Holtmann } 21970736cfa8SMarcel Holtmann 21981da177e4SLinus Torvalds /* Drop queues */ 21991da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 22001da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 22011da177e4SLinus Torvalds 220209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 22031f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 22041da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 220509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 22061da177e4SLinus Torvalds 22071da177e4SLinus Torvalds if (hdev->flush) 22081da177e4SLinus Torvalds hdev->flush(hdev); 22091da177e4SLinus Torvalds 22101da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 22116ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 22121da177e4SLinus Torvalds 22131da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 221401178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 22151da177e4SLinus Torvalds 22161da177e4SLinus Torvalds done: 22171da177e4SLinus Torvalds hci_req_unlock(hdev); 22181da177e4SLinus Torvalds hci_dev_put(hdev); 22191da177e4SLinus Torvalds return ret; 22201da177e4SLinus Torvalds } 22211da177e4SLinus Torvalds 22221da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 22231da177e4SLinus Torvalds { 22241da177e4SLinus Torvalds struct hci_dev *hdev; 22251da177e4SLinus Torvalds int ret = 0; 22261da177e4SLinus Torvalds 222770f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 222870f23020SAndrei Emeltchenko if (!hdev) 22291da177e4SLinus Torvalds return -ENODEV; 22301da177e4SLinus Torvalds 22310736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22320736cfa8SMarcel Holtmann ret = -EBUSY; 22330736cfa8SMarcel Holtmann goto done; 22340736cfa8SMarcel Holtmann } 22350736cfa8SMarcel Holtmann 22361da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 22371da177e4SLinus Torvalds 22380736cfa8SMarcel Holtmann done: 22391da177e4SLinus Torvalds hci_dev_put(hdev); 22401da177e4SLinus Torvalds return ret; 22411da177e4SLinus Torvalds } 22421da177e4SLinus Torvalds 22431da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 22441da177e4SLinus Torvalds { 22451da177e4SLinus Torvalds struct hci_dev *hdev; 22461da177e4SLinus Torvalds struct hci_dev_req dr; 22471da177e4SLinus Torvalds int err = 0; 22481da177e4SLinus Torvalds 22491da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 22501da177e4SLinus Torvalds return -EFAULT; 22511da177e4SLinus Torvalds 225270f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 225370f23020SAndrei Emeltchenko if (!hdev) 22541da177e4SLinus Torvalds return -ENODEV; 22551da177e4SLinus Torvalds 22560736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22570736cfa8SMarcel Holtmann err = -EBUSY; 22580736cfa8SMarcel Holtmann goto done; 22590736cfa8SMarcel Holtmann } 22600736cfa8SMarcel Holtmann 22615b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 22625b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 22635b69bef5SMarcel Holtmann goto done; 22645b69bef5SMarcel Holtmann } 22655b69bef5SMarcel Holtmann 226656f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 226756f87901SJohan Hedberg err = -EOPNOTSUPP; 226856f87901SJohan Hedberg goto done; 226956f87901SJohan Hedberg } 227056f87901SJohan Hedberg 22711da177e4SLinus Torvalds switch (cmd) { 22721da177e4SLinus Torvalds case HCISETAUTH: 227301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 22745f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 22751da177e4SLinus Torvalds break; 22761da177e4SLinus Torvalds 22771da177e4SLinus Torvalds case HCISETENCRYPT: 22781da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 22791da177e4SLinus Torvalds err = -EOPNOTSUPP; 22801da177e4SLinus Torvalds break; 22811da177e4SLinus Torvalds } 22821da177e4SLinus Torvalds 22831da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 22841da177e4SLinus Torvalds /* Auth must be enabled first */ 228501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 22865f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 22871da177e4SLinus Torvalds if (err) 22881da177e4SLinus Torvalds break; 22891da177e4SLinus Torvalds } 22901da177e4SLinus Torvalds 229101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 22925f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 22931da177e4SLinus Torvalds break; 22941da177e4SLinus Torvalds 22951da177e4SLinus Torvalds case HCISETSCAN: 229601178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 22975f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 22981da177e4SLinus Torvalds break; 22991da177e4SLinus Torvalds 23001da177e4SLinus Torvalds case HCISETLINKPOL: 230101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 23025f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23031da177e4SLinus Torvalds break; 23041da177e4SLinus Torvalds 23051da177e4SLinus Torvalds case HCISETLINKMODE: 2306e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2307e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2308e4e8e37cSMarcel Holtmann break; 2309e4e8e37cSMarcel Holtmann 2310e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2311e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 23121da177e4SLinus Torvalds break; 23131da177e4SLinus Torvalds 23141da177e4SLinus Torvalds case HCISETACLMTU: 23151da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 23161da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 23171da177e4SLinus Torvalds break; 23181da177e4SLinus Torvalds 23191da177e4SLinus Torvalds case HCISETSCOMTU: 23201da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 23211da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 23221da177e4SLinus Torvalds break; 23231da177e4SLinus Torvalds 23241da177e4SLinus Torvalds default: 23251da177e4SLinus Torvalds err = -EINVAL; 23261da177e4SLinus Torvalds break; 23271da177e4SLinus Torvalds } 2328e4e8e37cSMarcel Holtmann 23290736cfa8SMarcel Holtmann done: 23301da177e4SLinus Torvalds hci_dev_put(hdev); 23311da177e4SLinus Torvalds return err; 23321da177e4SLinus Torvalds } 23331da177e4SLinus Torvalds 23341da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 23351da177e4SLinus Torvalds { 23368035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 23371da177e4SLinus Torvalds struct hci_dev_list_req *dl; 23381da177e4SLinus Torvalds struct hci_dev_req *dr; 23391da177e4SLinus Torvalds int n = 0, size, err; 23401da177e4SLinus Torvalds __u16 dev_num; 23411da177e4SLinus Torvalds 23421da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 23431da177e4SLinus Torvalds return -EFAULT; 23441da177e4SLinus Torvalds 23451da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 23461da177e4SLinus Torvalds return -EINVAL; 23471da177e4SLinus Torvalds 23481da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 23491da177e4SLinus Torvalds 235070f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 235170f23020SAndrei Emeltchenko if (!dl) 23521da177e4SLinus Torvalds return -ENOMEM; 23531da177e4SLinus Torvalds 23541da177e4SLinus Torvalds dr = dl->dev_req; 23551da177e4SLinus Torvalds 2356f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 23578035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 2358a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2359e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 2360c542a06cSJohan Hedberg 2361a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2362a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2363c542a06cSJohan Hedberg 23641da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 23651da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 2366c542a06cSJohan Hedberg 23671da177e4SLinus Torvalds if (++n >= dev_num) 23681da177e4SLinus Torvalds break; 23691da177e4SLinus Torvalds } 2370f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 23711da177e4SLinus Torvalds 23721da177e4SLinus Torvalds dl->dev_num = n; 23731da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 23741da177e4SLinus Torvalds 23751da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 23761da177e4SLinus Torvalds kfree(dl); 23771da177e4SLinus Torvalds 23781da177e4SLinus Torvalds return err ? -EFAULT : 0; 23791da177e4SLinus Torvalds } 23801da177e4SLinus Torvalds 23811da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 23821da177e4SLinus Torvalds { 23831da177e4SLinus Torvalds struct hci_dev *hdev; 23841da177e4SLinus Torvalds struct hci_dev_info di; 23851da177e4SLinus Torvalds int err = 0; 23861da177e4SLinus Torvalds 23871da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 23881da177e4SLinus Torvalds return -EFAULT; 23891da177e4SLinus Torvalds 239070f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 239170f23020SAndrei Emeltchenko if (!hdev) 23921da177e4SLinus Torvalds return -ENODEV; 23931da177e4SLinus Torvalds 2394a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 23953243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 2396ab81cbf9SJohan Hedberg 2397a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2398a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2399c542a06cSJohan Hedberg 24001da177e4SLinus Torvalds strcpy(di.name, hdev->name); 24011da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 240260f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 24031da177e4SLinus Torvalds di.flags = hdev->flags; 24041da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2405572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 24061da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 24071da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 24081da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 24091da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2410572c7f84SJohan Hedberg } else { 2411572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2412572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2413572c7f84SJohan Hedberg di.sco_mtu = 0; 2414572c7f84SJohan Hedberg di.sco_pkts = 0; 2415572c7f84SJohan Hedberg } 24161da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 24171da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 24181da177e4SLinus Torvalds 24191da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 24201da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 24211da177e4SLinus Torvalds 24221da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 24231da177e4SLinus Torvalds err = -EFAULT; 24241da177e4SLinus Torvalds 24251da177e4SLinus Torvalds hci_dev_put(hdev); 24261da177e4SLinus Torvalds 24271da177e4SLinus Torvalds return err; 24281da177e4SLinus Torvalds } 24291da177e4SLinus Torvalds 24301da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 24311da177e4SLinus Torvalds 2432611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2433611b30f7SMarcel Holtmann { 2434611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2435611b30f7SMarcel Holtmann 2436611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2437611b30f7SMarcel Holtmann 24380736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 24390736cfa8SMarcel Holtmann return -EBUSY; 24400736cfa8SMarcel Holtmann 24415e130367SJohan Hedberg if (blocked) { 24425e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 2443bf543036SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 2444611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 24455e130367SJohan Hedberg } else { 24465e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 24475e130367SJohan Hedberg } 2448611b30f7SMarcel Holtmann 2449611b30f7SMarcel Holtmann return 0; 2450611b30f7SMarcel Holtmann } 2451611b30f7SMarcel Holtmann 2452611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2453611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2454611b30f7SMarcel Holtmann }; 2455611b30f7SMarcel Holtmann 2456ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2457ab81cbf9SJohan Hedberg { 2458ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 245996570ffcSJohan Hedberg int err; 2460ab81cbf9SJohan Hedberg 2461ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2462ab81cbf9SJohan Hedberg 2463cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 246496570ffcSJohan Hedberg if (err < 0) { 246596570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 2466ab81cbf9SJohan Hedberg return; 246796570ffcSJohan Hedberg } 2468ab81cbf9SJohan Hedberg 2469a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2470a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2471a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2472a5c8f270SMarcel Holtmann */ 2473a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 2474a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 2475a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2476a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2477bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2478bf543036SJohan Hedberg hci_dev_do_close(hdev); 2479bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 248019202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 248119202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2482bf543036SJohan Hedberg } 2483ab81cbf9SJohan Hedberg 2484a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 2485744cf19eSJohan Hedberg mgmt_index_added(hdev); 2486ab81cbf9SJohan Hedberg } 2487ab81cbf9SJohan Hedberg 2488ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2489ab81cbf9SJohan Hedberg { 24903243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 24913243553fSJohan Hedberg power_off.work); 2492ab81cbf9SJohan Hedberg 2493ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2494ab81cbf9SJohan Hedberg 24958ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2496ab81cbf9SJohan Hedberg } 2497ab81cbf9SJohan Hedberg 249816ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 249916ab91abSJohan Hedberg { 250016ab91abSJohan Hedberg struct hci_dev *hdev; 250116ab91abSJohan Hedberg 250216ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 250316ab91abSJohan Hedberg 250416ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 250516ab91abSJohan Hedberg 2506d1967ff8SMarcel Holtmann mgmt_discoverable_timeout(hdev); 250716ab91abSJohan Hedberg } 250816ab91abSJohan Hedberg 2509*35f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 25102aeb9a1aSJohan Hedberg { 25114821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 25122aeb9a1aSJohan Hedberg 25134821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 25144821002cSJohan Hedberg list_del(&uuid->list); 25152aeb9a1aSJohan Hedberg kfree(uuid); 25162aeb9a1aSJohan Hedberg } 25172aeb9a1aSJohan Hedberg } 25182aeb9a1aSJohan Hedberg 2519*35f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 252055ed8ca1SJohan Hedberg { 252155ed8ca1SJohan Hedberg struct list_head *p, *n; 252255ed8ca1SJohan Hedberg 252355ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 252455ed8ca1SJohan Hedberg struct link_key *key; 252555ed8ca1SJohan Hedberg 252655ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 252755ed8ca1SJohan Hedberg 252855ed8ca1SJohan Hedberg list_del(p); 252955ed8ca1SJohan Hedberg kfree(key); 253055ed8ca1SJohan Hedberg } 253155ed8ca1SJohan Hedberg } 253255ed8ca1SJohan Hedberg 2533*35f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2534b899efafSVinicius Costa Gomes { 2535b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2536b899efafSVinicius Costa Gomes 2537b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2538b899efafSVinicius Costa Gomes list_del(&k->list); 2539b899efafSVinicius Costa Gomes kfree(k); 2540b899efafSVinicius Costa Gomes } 2541b899efafSVinicius Costa Gomes } 2542b899efafSVinicius Costa Gomes 2543970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2544970c4e46SJohan Hedberg { 2545970c4e46SJohan Hedberg struct smp_irk *k, *tmp; 2546970c4e46SJohan Hedberg 2547970c4e46SJohan Hedberg list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { 2548970c4e46SJohan Hedberg list_del(&k->list); 2549970c4e46SJohan Hedberg kfree(k); 2550970c4e46SJohan Hedberg } 2551970c4e46SJohan Hedberg } 2552970c4e46SJohan Hedberg 255355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 255455ed8ca1SJohan Hedberg { 255555ed8ca1SJohan Hedberg struct link_key *k; 255655ed8ca1SJohan Hedberg 25578035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 255855ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 255955ed8ca1SJohan Hedberg return k; 256055ed8ca1SJohan Hedberg 256155ed8ca1SJohan Hedberg return NULL; 256255ed8ca1SJohan Hedberg } 256355ed8ca1SJohan Hedberg 2564745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2565d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2566d25e28abSJohan Hedberg { 2567d25e28abSJohan Hedberg /* Legacy key */ 2568d25e28abSJohan Hedberg if (key_type < 0x03) 2569745c0ce3SVishal Agarwal return true; 2570d25e28abSJohan Hedberg 2571d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2572d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2573745c0ce3SVishal Agarwal return false; 2574d25e28abSJohan Hedberg 2575d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2576d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2577745c0ce3SVishal Agarwal return false; 2578d25e28abSJohan Hedberg 2579d25e28abSJohan Hedberg /* Security mode 3 case */ 2580d25e28abSJohan Hedberg if (!conn) 2581745c0ce3SVishal Agarwal return true; 2582d25e28abSJohan Hedberg 2583d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2584d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2585745c0ce3SVishal Agarwal return true; 2586d25e28abSJohan Hedberg 2587d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2588d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2589745c0ce3SVishal Agarwal return true; 2590d25e28abSJohan Hedberg 2591d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2592d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2593745c0ce3SVishal Agarwal return true; 2594d25e28abSJohan Hedberg 2595d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2596d25e28abSJohan Hedberg * persistently */ 2597745c0ce3SVishal Agarwal return false; 2598d25e28abSJohan Hedberg } 2599d25e28abSJohan Hedberg 260098a0b845SJohan Hedberg static bool ltk_type_master(u8 type) 260198a0b845SJohan Hedberg { 260298a0b845SJohan Hedberg if (type == HCI_SMP_STK || type == HCI_SMP_LTK) 260398a0b845SJohan Hedberg return true; 260498a0b845SJohan Hedberg 260598a0b845SJohan Hedberg return false; 260698a0b845SJohan Hedberg } 260798a0b845SJohan Hedberg 260898a0b845SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8], 260998a0b845SJohan Hedberg bool master) 261075d262c2SVinicius Costa Gomes { 2611c9839a11SVinicius Costa Gomes struct smp_ltk *k; 261275d262c2SVinicius Costa Gomes 2613c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 2614c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 2615c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 261675d262c2SVinicius Costa Gomes continue; 261775d262c2SVinicius Costa Gomes 261898a0b845SJohan Hedberg if (ltk_type_master(k->type) != master) 261998a0b845SJohan Hedberg continue; 262098a0b845SJohan Hedberg 262175d262c2SVinicius Costa Gomes return k; 262275d262c2SVinicius Costa Gomes } 262375d262c2SVinicius Costa Gomes 262475d262c2SVinicius Costa Gomes return NULL; 262575d262c2SVinicius Costa Gomes } 262675d262c2SVinicius Costa Gomes 2627c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 262898a0b845SJohan Hedberg u8 addr_type, bool master) 262975d262c2SVinicius Costa Gomes { 2630c9839a11SVinicius Costa Gomes struct smp_ltk *k; 263175d262c2SVinicius Costa Gomes 2632c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 2633c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 263498a0b845SJohan Hedberg bacmp(bdaddr, &k->bdaddr) == 0 && 263598a0b845SJohan Hedberg ltk_type_master(k->type) == master) 263675d262c2SVinicius Costa Gomes return k; 263775d262c2SVinicius Costa Gomes 263875d262c2SVinicius Costa Gomes return NULL; 263975d262c2SVinicius Costa Gomes } 264075d262c2SVinicius Costa Gomes 2641970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 2642970c4e46SJohan Hedberg { 2643970c4e46SJohan Hedberg struct smp_irk *irk; 2644970c4e46SJohan Hedberg 2645970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2646970c4e46SJohan Hedberg if (!bacmp(&irk->rpa, rpa)) 2647970c4e46SJohan Hedberg return irk; 2648970c4e46SJohan Hedberg } 2649970c4e46SJohan Hedberg 2650970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2651970c4e46SJohan Hedberg if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) { 2652970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2653970c4e46SJohan Hedberg return irk; 2654970c4e46SJohan Hedberg } 2655970c4e46SJohan Hedberg } 2656970c4e46SJohan Hedberg 2657970c4e46SJohan Hedberg return NULL; 2658970c4e46SJohan Hedberg } 2659970c4e46SJohan Hedberg 2660970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2661970c4e46SJohan Hedberg u8 addr_type) 2662970c4e46SJohan Hedberg { 2663970c4e46SJohan Hedberg struct smp_irk *irk; 2664970c4e46SJohan Hedberg 2665970c4e46SJohan Hedberg list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { 2666970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 2667970c4e46SJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) 2668970c4e46SJohan Hedberg return irk; 2669970c4e46SJohan Hedberg } 2670970c4e46SJohan Hedberg 2671970c4e46SJohan Hedberg return NULL; 2672970c4e46SJohan Hedberg } 2673970c4e46SJohan Hedberg 2674d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 2675d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 267655ed8ca1SJohan Hedberg { 267755ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2678745c0ce3SVishal Agarwal u8 old_key_type; 2679745c0ce3SVishal Agarwal bool persistent; 268055ed8ca1SJohan Hedberg 268155ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 268255ed8ca1SJohan Hedberg if (old_key) { 268355ed8ca1SJohan Hedberg old_key_type = old_key->type; 268455ed8ca1SJohan Hedberg key = old_key; 268555ed8ca1SJohan Hedberg } else { 268612adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 268755ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 268855ed8ca1SJohan Hedberg if (!key) 268955ed8ca1SJohan Hedberg return -ENOMEM; 269055ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 269155ed8ca1SJohan Hedberg } 269255ed8ca1SJohan Hedberg 26936ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 269455ed8ca1SJohan Hedberg 2695d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2696d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2697d25e28abSJohan Hedberg * previous key */ 2698d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2699a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2700d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2701655fe6ecSJohan Hedberg if (conn) 2702655fe6ecSJohan Hedberg conn->key_type = type; 2703655fe6ecSJohan Hedberg } 2704d25e28abSJohan Hedberg 270555ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 27069b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 270755ed8ca1SJohan Hedberg key->pin_len = pin_len; 270855ed8ca1SJohan Hedberg 2709b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 271055ed8ca1SJohan Hedberg key->type = old_key_type; 27114748fed2SJohan Hedberg else 27124748fed2SJohan Hedberg key->type = type; 27134748fed2SJohan Hedberg 27144df378a1SJohan Hedberg if (!new_key) 27154df378a1SJohan Hedberg return 0; 27164df378a1SJohan Hedberg 27174df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 27184df378a1SJohan Hedberg 2719744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 27204df378a1SJohan Hedberg 27216ec5bcadSVishal Agarwal if (conn) 27226ec5bcadSVishal Agarwal conn->flush_key = !persistent; 272355ed8ca1SJohan Hedberg 272455ed8ca1SJohan Hedberg return 0; 272555ed8ca1SJohan Hedberg } 272655ed8ca1SJohan Hedberg 2727c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 27289a006657SAndrei Emeltchenko int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 272904124681SGustavo F. Padovan ediv, u8 rand[8]) 273075d262c2SVinicius Costa Gomes { 2731c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 273298a0b845SJohan Hedberg bool master = ltk_type_master(type); 27330fe442ffSMarcel Holtmann u8 persistent; 273475d262c2SVinicius Costa Gomes 273598a0b845SJohan Hedberg old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master); 2736c9839a11SVinicius Costa Gomes if (old_key) 273775d262c2SVinicius Costa Gomes key = old_key; 2738c9839a11SVinicius Costa Gomes else { 2739c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 274075d262c2SVinicius Costa Gomes if (!key) 274175d262c2SVinicius Costa Gomes return -ENOMEM; 2742c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 274375d262c2SVinicius Costa Gomes } 274475d262c2SVinicius Costa Gomes 274575d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2746c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2747c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2748c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2749c9839a11SVinicius Costa Gomes key->ediv = ediv; 2750c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2751c9839a11SVinicius Costa Gomes key->type = type; 2752c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 275375d262c2SVinicius Costa Gomes 2754c9839a11SVinicius Costa Gomes if (!new_key) 2755c9839a11SVinicius Costa Gomes return 0; 275675d262c2SVinicius Costa Gomes 27570fe442ffSMarcel Holtmann if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 27580fe442ffSMarcel Holtmann persistent = 0; 27590fe442ffSMarcel Holtmann else 27600fe442ffSMarcel Holtmann persistent = 1; 27610fe442ffSMarcel Holtmann 276221b93b75SJohan Hedberg if (type == HCI_SMP_LTK || type == HCI_SMP_LTK_SLAVE) 27630fe442ffSMarcel Holtmann mgmt_new_ltk(hdev, key, persistent); 2764261cc5aaSVinicius Costa Gomes 276575d262c2SVinicius Costa Gomes return 0; 276675d262c2SVinicius Costa Gomes } 276775d262c2SVinicius Costa Gomes 2768970c4e46SJohan Hedberg int hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, 2769970c4e46SJohan Hedberg u8 val[16], bdaddr_t *rpa) 2770970c4e46SJohan Hedberg { 2771970c4e46SJohan Hedberg struct smp_irk *irk; 2772970c4e46SJohan Hedberg 2773970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 2774970c4e46SJohan Hedberg if (!irk) { 2775970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 2776970c4e46SJohan Hedberg if (!irk) 2777970c4e46SJohan Hedberg return -ENOMEM; 2778970c4e46SJohan Hedberg 2779970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 2780970c4e46SJohan Hedberg irk->addr_type = addr_type; 2781970c4e46SJohan Hedberg 2782970c4e46SJohan Hedberg list_add(&irk->list, &hdev->identity_resolving_keys); 2783970c4e46SJohan Hedberg } 2784970c4e46SJohan Hedberg 2785970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 2786970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2787970c4e46SJohan Hedberg 2788970c4e46SJohan Hedberg return 0; 2789970c4e46SJohan Hedberg } 2790970c4e46SJohan Hedberg 279155ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 279255ed8ca1SJohan Hedberg { 279355ed8ca1SJohan Hedberg struct link_key *key; 279455ed8ca1SJohan Hedberg 279555ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 279655ed8ca1SJohan Hedberg if (!key) 279755ed8ca1SJohan Hedberg return -ENOENT; 279855ed8ca1SJohan Hedberg 27996ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 280055ed8ca1SJohan Hedberg 280155ed8ca1SJohan Hedberg list_del(&key->list); 280255ed8ca1SJohan Hedberg kfree(key); 280355ed8ca1SJohan Hedberg 280455ed8ca1SJohan Hedberg return 0; 280555ed8ca1SJohan Hedberg } 280655ed8ca1SJohan Hedberg 2807e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 2808b899efafSVinicius Costa Gomes { 2809b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2810b899efafSVinicius Costa Gomes 2811b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2812e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 2813b899efafSVinicius Costa Gomes continue; 2814b899efafSVinicius Costa Gomes 28156ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2816b899efafSVinicius Costa Gomes 2817b899efafSVinicius Costa Gomes list_del(&k->list); 2818b899efafSVinicius Costa Gomes kfree(k); 2819b899efafSVinicius Costa Gomes } 2820b899efafSVinicius Costa Gomes 2821b899efafSVinicius Costa Gomes return 0; 2822b899efafSVinicius Costa Gomes } 2823b899efafSVinicius Costa Gomes 28246bd32326SVille Tervo /* HCI command timer function */ 2825bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg) 28266bd32326SVille Tervo { 28276bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 28286bd32326SVille Tervo 2829bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2830bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2831bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2832bda4f23aSAndrei Emeltchenko 2833bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 2834bda4f23aSAndrei Emeltchenko } else { 28356bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 2836bda4f23aSAndrei Emeltchenko } 2837bda4f23aSAndrei Emeltchenko 28386bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2839c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 28406bd32326SVille Tervo } 28416bd32326SVille Tervo 28422763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 28432763eda6SSzymon Janc bdaddr_t *bdaddr) 28442763eda6SSzymon Janc { 28452763eda6SSzymon Janc struct oob_data *data; 28462763eda6SSzymon Janc 28472763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 28482763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 28492763eda6SSzymon Janc return data; 28502763eda6SSzymon Janc 28512763eda6SSzymon Janc return NULL; 28522763eda6SSzymon Janc } 28532763eda6SSzymon Janc 28542763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 28552763eda6SSzymon Janc { 28562763eda6SSzymon Janc struct oob_data *data; 28572763eda6SSzymon Janc 28582763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 28592763eda6SSzymon Janc if (!data) 28602763eda6SSzymon Janc return -ENOENT; 28612763eda6SSzymon Janc 28626ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 28632763eda6SSzymon Janc 28642763eda6SSzymon Janc list_del(&data->list); 28652763eda6SSzymon Janc kfree(data); 28662763eda6SSzymon Janc 28672763eda6SSzymon Janc return 0; 28682763eda6SSzymon Janc } 28692763eda6SSzymon Janc 2870*35f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 28712763eda6SSzymon Janc { 28722763eda6SSzymon Janc struct oob_data *data, *n; 28732763eda6SSzymon Janc 28742763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 28752763eda6SSzymon Janc list_del(&data->list); 28762763eda6SSzymon Janc kfree(data); 28772763eda6SSzymon Janc } 28782763eda6SSzymon Janc } 28792763eda6SSzymon Janc 28800798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 28810798872eSMarcel Holtmann u8 *hash, u8 *randomizer) 28822763eda6SSzymon Janc { 28832763eda6SSzymon Janc struct oob_data *data; 28842763eda6SSzymon Janc 28852763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 28862763eda6SSzymon Janc if (!data) { 28870798872eSMarcel Holtmann data = kmalloc(sizeof(*data), GFP_ATOMIC); 28882763eda6SSzymon Janc if (!data) 28892763eda6SSzymon Janc return -ENOMEM; 28902763eda6SSzymon Janc 28912763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 28922763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 28932763eda6SSzymon Janc } 28942763eda6SSzymon Janc 2895519ca9d0SMarcel Holtmann memcpy(data->hash192, hash, sizeof(data->hash192)); 2896519ca9d0SMarcel Holtmann memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192)); 28972763eda6SSzymon Janc 28980798872eSMarcel Holtmann memset(data->hash256, 0, sizeof(data->hash256)); 28990798872eSMarcel Holtmann memset(data->randomizer256, 0, sizeof(data->randomizer256)); 29000798872eSMarcel Holtmann 29010798872eSMarcel Holtmann BT_DBG("%s for %pMR", hdev->name, bdaddr); 29020798872eSMarcel Holtmann 29030798872eSMarcel Holtmann return 0; 29040798872eSMarcel Holtmann } 29050798872eSMarcel Holtmann 29060798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 29070798872eSMarcel Holtmann u8 *hash192, u8 *randomizer192, 29080798872eSMarcel Holtmann u8 *hash256, u8 *randomizer256) 29090798872eSMarcel Holtmann { 29100798872eSMarcel Holtmann struct oob_data *data; 29110798872eSMarcel Holtmann 29120798872eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, bdaddr); 29130798872eSMarcel Holtmann if (!data) { 29140798872eSMarcel Holtmann data = kmalloc(sizeof(*data), GFP_ATOMIC); 29150798872eSMarcel Holtmann if (!data) 29160798872eSMarcel Holtmann return -ENOMEM; 29170798872eSMarcel Holtmann 29180798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 29190798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 29200798872eSMarcel Holtmann } 29210798872eSMarcel Holtmann 29220798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 29230798872eSMarcel Holtmann memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192)); 29240798872eSMarcel Holtmann 29250798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 29260798872eSMarcel Holtmann memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256)); 29270798872eSMarcel Holtmann 29286ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 29292763eda6SSzymon Janc 29302763eda6SSzymon Janc return 0; 29312763eda6SSzymon Janc } 29322763eda6SSzymon Janc 2933b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 2934b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 2935b2a66aadSAntti Julku { 2936b2a66aadSAntti Julku struct bdaddr_list *b; 2937b2a66aadSAntti Julku 2938b9ee0a78SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) { 2939b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2940b2a66aadSAntti Julku return b; 2941b9ee0a78SMarcel Holtmann } 2942b2a66aadSAntti Julku 2943b2a66aadSAntti Julku return NULL; 2944b2a66aadSAntti Julku } 2945b2a66aadSAntti Julku 2946*35f7498aSJohan Hedberg void hci_blacklist_clear(struct hci_dev *hdev) 2947b2a66aadSAntti Julku { 2948b2a66aadSAntti Julku struct list_head *p, *n; 2949b2a66aadSAntti Julku 2950b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 2951b9ee0a78SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 2952b2a66aadSAntti Julku 2953b2a66aadSAntti Julku list_del(p); 2954b2a66aadSAntti Julku kfree(b); 2955b2a66aadSAntti Julku } 2956b2a66aadSAntti Julku } 2957b2a66aadSAntti Julku 295888c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2959b2a66aadSAntti Julku { 2960b2a66aadSAntti Julku struct bdaddr_list *entry; 2961b2a66aadSAntti Julku 2962b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 2963b2a66aadSAntti Julku return -EBADF; 2964b2a66aadSAntti Julku 2965b9ee0a78SMarcel Holtmann if (hci_blacklist_lookup(hdev, bdaddr, type)) 29665e762444SAntti Julku return -EEXIST; 2967b2a66aadSAntti Julku 2968b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 29695e762444SAntti Julku if (!entry) 29705e762444SAntti Julku return -ENOMEM; 2971b2a66aadSAntti Julku 2972b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 2973b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 2974b2a66aadSAntti Julku 2975b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 2976b2a66aadSAntti Julku 297788c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 2978b2a66aadSAntti Julku } 2979b2a66aadSAntti Julku 298088c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2981b2a66aadSAntti Julku { 2982b2a66aadSAntti Julku struct bdaddr_list *entry; 2983b2a66aadSAntti Julku 2984*35f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 2985*35f7498aSJohan Hedberg hci_blacklist_clear(hdev); 2986*35f7498aSJohan Hedberg return 0; 2987*35f7498aSJohan Hedberg } 2988b2a66aadSAntti Julku 2989b9ee0a78SMarcel Holtmann entry = hci_blacklist_lookup(hdev, bdaddr, type); 29901ec918ceSSzymon Janc if (!entry) 29915e762444SAntti Julku return -ENOENT; 2992b2a66aadSAntti Julku 2993b2a66aadSAntti Julku list_del(&entry->list); 2994b2a66aadSAntti Julku kfree(entry); 2995b2a66aadSAntti Julku 299688c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 2997b2a66aadSAntti Julku } 2998b2a66aadSAntti Julku 299915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 300015819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 300115819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 300215819a70SAndre Guedes { 300315819a70SAndre Guedes struct hci_conn_params *params; 300415819a70SAndre Guedes 300515819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 300615819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 300715819a70SAndre Guedes params->addr_type == addr_type) { 300815819a70SAndre Guedes return params; 300915819a70SAndre Guedes } 301015819a70SAndre Guedes } 301115819a70SAndre Guedes 301215819a70SAndre Guedes return NULL; 301315819a70SAndre Guedes } 301415819a70SAndre Guedes 301515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 301615819a70SAndre Guedes void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, 301715819a70SAndre Guedes u16 conn_min_interval, u16 conn_max_interval) 301815819a70SAndre Guedes { 301915819a70SAndre Guedes struct hci_conn_params *params; 302015819a70SAndre Guedes 302115819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 302215819a70SAndre Guedes if (params) { 302315819a70SAndre Guedes params->conn_min_interval = conn_min_interval; 302415819a70SAndre Guedes params->conn_max_interval = conn_max_interval; 302515819a70SAndre Guedes return; 302615819a70SAndre Guedes } 302715819a70SAndre Guedes 302815819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 302915819a70SAndre Guedes if (!params) { 303015819a70SAndre Guedes BT_ERR("Out of memory"); 303115819a70SAndre Guedes return; 303215819a70SAndre Guedes } 303315819a70SAndre Guedes 303415819a70SAndre Guedes bacpy(¶ms->addr, addr); 303515819a70SAndre Guedes params->addr_type = addr_type; 303615819a70SAndre Guedes params->conn_min_interval = conn_min_interval; 303715819a70SAndre Guedes params->conn_max_interval = conn_max_interval; 303815819a70SAndre Guedes 303915819a70SAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 304015819a70SAndre Guedes 304115819a70SAndre Guedes BT_DBG("addr %pMR (type %u) conn_min_interval 0x%.4x " 304215819a70SAndre Guedes "conn_max_interval 0x%.4x", addr, addr_type, conn_min_interval, 304315819a70SAndre Guedes conn_max_interval); 304415819a70SAndre Guedes } 304515819a70SAndre Guedes 304615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 304715819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 304815819a70SAndre Guedes { 304915819a70SAndre Guedes struct hci_conn_params *params; 305015819a70SAndre Guedes 305115819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 305215819a70SAndre Guedes if (!params) 305315819a70SAndre Guedes return; 305415819a70SAndre Guedes 305515819a70SAndre Guedes list_del(¶ms->list); 305615819a70SAndre Guedes kfree(params); 305715819a70SAndre Guedes 305815819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 305915819a70SAndre Guedes } 306015819a70SAndre Guedes 306115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 306215819a70SAndre Guedes void hci_conn_params_clear(struct hci_dev *hdev) 306315819a70SAndre Guedes { 306415819a70SAndre Guedes struct hci_conn_params *params, *tmp; 306515819a70SAndre Guedes 306615819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 306715819a70SAndre Guedes list_del(¶ms->list); 306815819a70SAndre Guedes kfree(params); 306915819a70SAndre Guedes } 307015819a70SAndre Guedes 307115819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 307215819a70SAndre Guedes } 307315819a70SAndre Guedes 30744c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 30757ba8b4beSAndre Guedes { 30764c87eaabSAndre Guedes if (status) { 30774c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 30787ba8b4beSAndre Guedes 30794c87eaabSAndre Guedes hci_dev_lock(hdev); 30804c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 30814c87eaabSAndre Guedes hci_dev_unlock(hdev); 30824c87eaabSAndre Guedes return; 30834c87eaabSAndre Guedes } 30847ba8b4beSAndre Guedes } 30857ba8b4beSAndre Guedes 30864c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 30877ba8b4beSAndre Guedes { 30884c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 30894c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 30904c87eaabSAndre Guedes struct hci_request req; 30914c87eaabSAndre Guedes struct hci_cp_inquiry cp; 30927ba8b4beSAndre Guedes int err; 30937ba8b4beSAndre Guedes 30944c87eaabSAndre Guedes if (status) { 30954c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 30964c87eaabSAndre Guedes return; 30977ba8b4beSAndre Guedes } 30987ba8b4beSAndre Guedes 30994c87eaabSAndre Guedes switch (hdev->discovery.type) { 31004c87eaabSAndre Guedes case DISCOV_TYPE_LE: 31014c87eaabSAndre Guedes hci_dev_lock(hdev); 31024c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 31034c87eaabSAndre Guedes hci_dev_unlock(hdev); 31044c87eaabSAndre Guedes break; 31057dbfac1dSAndre Guedes 31064c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 31074c87eaabSAndre Guedes hci_req_init(&req, hdev); 31087dbfac1dSAndre Guedes 31097dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 31104c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 31114c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 31124c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 31134c87eaabSAndre Guedes 31144c87eaabSAndre Guedes hci_dev_lock(hdev); 31154c87eaabSAndre Guedes 31164c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 31174c87eaabSAndre Guedes 31184c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 31194c87eaabSAndre Guedes if (err) { 31204c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 31214c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 31227dbfac1dSAndre Guedes } 31237dbfac1dSAndre Guedes 31244c87eaabSAndre Guedes hci_dev_unlock(hdev); 31254c87eaabSAndre Guedes break; 31264c87eaabSAndre Guedes } 31277dbfac1dSAndre Guedes } 31287dbfac1dSAndre Guedes 31297ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 31307ba8b4beSAndre Guedes { 31317ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 31327ba8b4beSAndre Guedes le_scan_disable.work); 31337ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 31344c87eaabSAndre Guedes struct hci_request req; 31354c87eaabSAndre Guedes int err; 31367ba8b4beSAndre Guedes 31377ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 31387ba8b4beSAndre Guedes 31394c87eaabSAndre Guedes hci_req_init(&req, hdev); 31407ba8b4beSAndre Guedes 31417ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 31424c87eaabSAndre Guedes cp.enable = LE_SCAN_DISABLE; 31434c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 31447ba8b4beSAndre Guedes 31454c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 31464c87eaabSAndre Guedes if (err) 31474c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 314828b75a89SAndre Guedes } 314928b75a89SAndre Guedes 31509be0dab7SDavid Herrmann /* Alloc HCI device */ 31519be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 31529be0dab7SDavid Herrmann { 31539be0dab7SDavid Herrmann struct hci_dev *hdev; 31549be0dab7SDavid Herrmann 31559be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 31569be0dab7SDavid Herrmann if (!hdev) 31579be0dab7SDavid Herrmann return NULL; 31589be0dab7SDavid Herrmann 3159b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3160b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3161b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3162b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3163b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 3164bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3165bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3166b1b813d4SDavid Herrmann 3167b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3168b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3169b1b813d4SDavid Herrmann 3170bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3171bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 31724e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = 0x0028; 31734e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = 0x0038; 3174bef64738SMarcel Holtmann 3175b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3176b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3177b1b813d4SDavid Herrmann 3178b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3179b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 3180b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3181b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3182b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3183970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3184b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 318515819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 31866b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3187b1b813d4SDavid Herrmann 3188b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3189b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3190b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3191b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3192b1b813d4SDavid Herrmann 3193b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3194b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 3195b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 3196b1b813d4SDavid Herrmann 3197b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3198b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3199b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3200b1b813d4SDavid Herrmann 3201b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 3202b1b813d4SDavid Herrmann 3203bda4f23aSAndrei Emeltchenko setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); 3204b1b813d4SDavid Herrmann 3205b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3206b1b813d4SDavid Herrmann discovery_init(hdev); 32079be0dab7SDavid Herrmann 32089be0dab7SDavid Herrmann return hdev; 32099be0dab7SDavid Herrmann } 32109be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 32119be0dab7SDavid Herrmann 32129be0dab7SDavid Herrmann /* Free HCI device */ 32139be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 32149be0dab7SDavid Herrmann { 32159be0dab7SDavid Herrmann /* will free via device release */ 32169be0dab7SDavid Herrmann put_device(&hdev->dev); 32179be0dab7SDavid Herrmann } 32189be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 32199be0dab7SDavid Herrmann 32201da177e4SLinus Torvalds /* Register HCI device */ 32211da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 32221da177e4SLinus Torvalds { 3223b1b813d4SDavid Herrmann int id, error; 32241da177e4SLinus Torvalds 3225010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 32261da177e4SLinus Torvalds return -EINVAL; 32271da177e4SLinus Torvalds 322808add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 322908add513SMat Martineau * so the index can be used as the AMP controller ID. 323008add513SMat Martineau */ 32313df92b31SSasha Levin switch (hdev->dev_type) { 32323df92b31SSasha Levin case HCI_BREDR: 32333df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 32341da177e4SLinus Torvalds break; 32353df92b31SSasha Levin case HCI_AMP: 32363df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 32373df92b31SSasha Levin break; 32383df92b31SSasha Levin default: 32393df92b31SSasha Levin return -EINVAL; 32401da177e4SLinus Torvalds } 32411da177e4SLinus Torvalds 32423df92b31SSasha Levin if (id < 0) 32433df92b31SSasha Levin return id; 32443df92b31SSasha Levin 32451da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 32461da177e4SLinus Torvalds hdev->id = id; 32472d8b3a11SAndrei Emeltchenko 32482d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 32492d8b3a11SAndrei Emeltchenko 3250d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3251d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 325233ca954dSDavid Herrmann if (!hdev->workqueue) { 325333ca954dSDavid Herrmann error = -ENOMEM; 325433ca954dSDavid Herrmann goto err; 325533ca954dSDavid Herrmann } 3256f48fd9c8SMarcel Holtmann 3257d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3258d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 32596ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 32606ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 32616ead1bbcSJohan Hedberg error = -ENOMEM; 32626ead1bbcSJohan Hedberg goto err; 32636ead1bbcSJohan Hedberg } 32646ead1bbcSJohan Hedberg 32650153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 32660153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 32670153e2ecSMarcel Holtmann 3268bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3269bdc3e0f1SMarcel Holtmann 327099780a7bSJohan Hedberg hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 327199780a7bSJohan Hedberg CRYPTO_ALG_ASYNC); 327299780a7bSJohan Hedberg if (IS_ERR(hdev->tfm_aes)) { 327399780a7bSJohan Hedberg BT_ERR("Unable to create crypto context"); 327499780a7bSJohan Hedberg error = PTR_ERR(hdev->tfm_aes); 327599780a7bSJohan Hedberg hdev->tfm_aes = NULL; 327699780a7bSJohan Hedberg goto err_wqueue; 327799780a7bSJohan Hedberg } 327899780a7bSJohan Hedberg 3279bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 328033ca954dSDavid Herrmann if (error < 0) 328199780a7bSJohan Hedberg goto err_tfm; 32821da177e4SLinus Torvalds 3283611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3284a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3285a8c5fb1aSGustavo Padovan hdev); 3286611b30f7SMarcel Holtmann if (hdev->rfkill) { 3287611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3288611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3289611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3290611b30f7SMarcel Holtmann } 3291611b30f7SMarcel Holtmann } 3292611b30f7SMarcel Holtmann 32935e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 32945e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 32955e130367SJohan Hedberg 3296a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 3297004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 3298ce2be9acSAndrei Emeltchenko 329901cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 330056f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 330156f87901SJohan Hedberg * through reading supported features during init. 330256f87901SJohan Hedberg */ 330356f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 330456f87901SJohan Hedberg } 3305ce2be9acSAndrei Emeltchenko 3306fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3307fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3308fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3309fcee3377SGustavo Padovan 33101da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 3311dc946bd8SDavid Herrmann hci_dev_hold(hdev); 33121da177e4SLinus Torvalds 331319202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3314fbe96d6fSMarcel Holtmann 33151da177e4SLinus Torvalds return id; 3316f48fd9c8SMarcel Holtmann 331799780a7bSJohan Hedberg err_tfm: 331899780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 331933ca954dSDavid Herrmann err_wqueue: 332033ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 33216ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 332233ca954dSDavid Herrmann err: 33233df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3324f48fd9c8SMarcel Holtmann 332533ca954dSDavid Herrmann return error; 33261da177e4SLinus Torvalds } 33271da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 33281da177e4SLinus Torvalds 33291da177e4SLinus Torvalds /* Unregister HCI device */ 333059735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 33311da177e4SLinus Torvalds { 33323df92b31SSasha Levin int i, id; 3333ef222013SMarcel Holtmann 3334c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 33351da177e4SLinus Torvalds 333694324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 333794324962SJohan Hovold 33383df92b31SSasha Levin id = hdev->id; 33393df92b31SSasha Levin 3340f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 33411da177e4SLinus Torvalds list_del(&hdev->list); 3342f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 33431da177e4SLinus Torvalds 33441da177e4SLinus Torvalds hci_dev_do_close(hdev); 33451da177e4SLinus Torvalds 3346cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 3347ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 3348ef222013SMarcel Holtmann 3349b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 3350b9b5ef18SGustavo Padovan 3351ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 3352a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 335309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3354744cf19eSJohan Hedberg mgmt_index_removed(hdev); 335509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 335656e5cb86SJohan Hedberg } 3357ab81cbf9SJohan Hedberg 33582e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 33592e58ef3eSJohan Hedberg * pending list */ 33602e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 33612e58ef3eSJohan Hedberg 33621da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 33631da177e4SLinus Torvalds 3364611b30f7SMarcel Holtmann if (hdev->rfkill) { 3365611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 3366611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3367611b30f7SMarcel Holtmann } 3368611b30f7SMarcel Holtmann 336999780a7bSJohan Hedberg if (hdev->tfm_aes) 337099780a7bSJohan Hedberg crypto_free_blkcipher(hdev->tfm_aes); 337199780a7bSJohan Hedberg 3372bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 3373147e2d59SDave Young 33740153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 33750153e2ecSMarcel Holtmann 3376f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 33776ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 3378f48fd9c8SMarcel Holtmann 337909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3380e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 33812aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 338255ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 3383b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 3384970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 33852763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 338615819a70SAndre Guedes hci_conn_params_clear(hdev); 338709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 3388e2e0cacbSJohan Hedberg 3389dc946bd8SDavid Herrmann hci_dev_put(hdev); 33903df92b31SSasha Levin 33913df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 33921da177e4SLinus Torvalds } 33931da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 33941da177e4SLinus Torvalds 33951da177e4SLinus Torvalds /* Suspend HCI device */ 33961da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 33971da177e4SLinus Torvalds { 33981da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 33991da177e4SLinus Torvalds return 0; 34001da177e4SLinus Torvalds } 34011da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 34021da177e4SLinus Torvalds 34031da177e4SLinus Torvalds /* Resume HCI device */ 34041da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 34051da177e4SLinus Torvalds { 34061da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 34071da177e4SLinus Torvalds return 0; 34081da177e4SLinus Torvalds } 34091da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 34101da177e4SLinus Torvalds 341176bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 3412e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 341376bca880SMarcel Holtmann { 341476bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 341576bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 341676bca880SMarcel Holtmann kfree_skb(skb); 341776bca880SMarcel Holtmann return -ENXIO; 341876bca880SMarcel Holtmann } 341976bca880SMarcel Holtmann 3420d82603c6SJorrit Schippers /* Incoming skb */ 342176bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 342276bca880SMarcel Holtmann 342376bca880SMarcel Holtmann /* Time stamp */ 342476bca880SMarcel Holtmann __net_timestamp(skb); 342576bca880SMarcel Holtmann 342676bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3427b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3428c78ae283SMarcel Holtmann 342976bca880SMarcel Holtmann return 0; 343076bca880SMarcel Holtmann } 343176bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 343276bca880SMarcel Holtmann 343333e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 34341e429f38SGustavo F. Padovan int count, __u8 index) 343533e882a5SSuraj Sumangala { 343633e882a5SSuraj Sumangala int len = 0; 343733e882a5SSuraj Sumangala int hlen = 0; 343833e882a5SSuraj Sumangala int remain = count; 343933e882a5SSuraj Sumangala struct sk_buff *skb; 344033e882a5SSuraj Sumangala struct bt_skb_cb *scb; 344133e882a5SSuraj Sumangala 344233e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 344333e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 344433e882a5SSuraj Sumangala return -EILSEQ; 344533e882a5SSuraj Sumangala 344633e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 344733e882a5SSuraj Sumangala 344833e882a5SSuraj Sumangala if (!skb) { 344933e882a5SSuraj Sumangala switch (type) { 345033e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 345133e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 345233e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 345333e882a5SSuraj Sumangala break; 345433e882a5SSuraj Sumangala case HCI_EVENT_PKT: 345533e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 345633e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 345733e882a5SSuraj Sumangala break; 345833e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 345933e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 346033e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 346133e882a5SSuraj Sumangala break; 346233e882a5SSuraj Sumangala } 346333e882a5SSuraj Sumangala 34641e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 346533e882a5SSuraj Sumangala if (!skb) 346633e882a5SSuraj Sumangala return -ENOMEM; 346733e882a5SSuraj Sumangala 346833e882a5SSuraj Sumangala scb = (void *) skb->cb; 346933e882a5SSuraj Sumangala scb->expect = hlen; 347033e882a5SSuraj Sumangala scb->pkt_type = type; 347133e882a5SSuraj Sumangala 347233e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 347333e882a5SSuraj Sumangala } 347433e882a5SSuraj Sumangala 347533e882a5SSuraj Sumangala while (count) { 347633e882a5SSuraj Sumangala scb = (void *) skb->cb; 347789bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 347833e882a5SSuraj Sumangala 347933e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 348033e882a5SSuraj Sumangala 348133e882a5SSuraj Sumangala count -= len; 348233e882a5SSuraj Sumangala data += len; 348333e882a5SSuraj Sumangala scb->expect -= len; 348433e882a5SSuraj Sumangala remain = count; 348533e882a5SSuraj Sumangala 348633e882a5SSuraj Sumangala switch (type) { 348733e882a5SSuraj Sumangala case HCI_EVENT_PKT: 348833e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 348933e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 349033e882a5SSuraj Sumangala scb->expect = h->plen; 349133e882a5SSuraj Sumangala 349233e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 349333e882a5SSuraj Sumangala kfree_skb(skb); 349433e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 349533e882a5SSuraj Sumangala return -ENOMEM; 349633e882a5SSuraj Sumangala } 349733e882a5SSuraj Sumangala } 349833e882a5SSuraj Sumangala break; 349933e882a5SSuraj Sumangala 350033e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 350133e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 350233e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 350333e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 350433e882a5SSuraj Sumangala 350533e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 350633e882a5SSuraj Sumangala kfree_skb(skb); 350733e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 350833e882a5SSuraj Sumangala return -ENOMEM; 350933e882a5SSuraj Sumangala } 351033e882a5SSuraj Sumangala } 351133e882a5SSuraj Sumangala break; 351233e882a5SSuraj Sumangala 351333e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 351433e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 351533e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 351633e882a5SSuraj Sumangala scb->expect = h->dlen; 351733e882a5SSuraj Sumangala 351833e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 351933e882a5SSuraj Sumangala kfree_skb(skb); 352033e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 352133e882a5SSuraj Sumangala return -ENOMEM; 352233e882a5SSuraj Sumangala } 352333e882a5SSuraj Sumangala } 352433e882a5SSuraj Sumangala break; 352533e882a5SSuraj Sumangala } 352633e882a5SSuraj Sumangala 352733e882a5SSuraj Sumangala if (scb->expect == 0) { 352833e882a5SSuraj Sumangala /* Complete frame */ 352933e882a5SSuraj Sumangala 353033e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 3531e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 353233e882a5SSuraj Sumangala 353333e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 353433e882a5SSuraj Sumangala return remain; 353533e882a5SSuraj Sumangala } 353633e882a5SSuraj Sumangala } 353733e882a5SSuraj Sumangala 353833e882a5SSuraj Sumangala return remain; 353933e882a5SSuraj Sumangala } 354033e882a5SSuraj Sumangala 3541ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 3542ef222013SMarcel Holtmann { 3543f39a3c06SSuraj Sumangala int rem = 0; 3544f39a3c06SSuraj Sumangala 3545ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 3546ef222013SMarcel Holtmann return -EILSEQ; 3547ef222013SMarcel Holtmann 3548da5f6c37SGustavo F. Padovan while (count) { 35491e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 3550f39a3c06SSuraj Sumangala if (rem < 0) 3551f39a3c06SSuraj Sumangala return rem; 3552ef222013SMarcel Holtmann 3553f39a3c06SSuraj Sumangala data += (count - rem); 3554f39a3c06SSuraj Sumangala count = rem; 3555f81c6224SJoe Perches } 3556ef222013SMarcel Holtmann 3557f39a3c06SSuraj Sumangala return rem; 3558ef222013SMarcel Holtmann } 3559ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 3560ef222013SMarcel Holtmann 356199811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 356299811510SSuraj Sumangala 356399811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 356499811510SSuraj Sumangala { 356599811510SSuraj Sumangala int type; 356699811510SSuraj Sumangala int rem = 0; 356799811510SSuraj Sumangala 3568da5f6c37SGustavo F. Padovan while (count) { 356999811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 357099811510SSuraj Sumangala 357199811510SSuraj Sumangala if (!skb) { 357299811510SSuraj Sumangala struct { char type; } *pkt; 357399811510SSuraj Sumangala 357499811510SSuraj Sumangala /* Start of the frame */ 357599811510SSuraj Sumangala pkt = data; 357699811510SSuraj Sumangala type = pkt->type; 357799811510SSuraj Sumangala 357899811510SSuraj Sumangala data++; 357999811510SSuraj Sumangala count--; 358099811510SSuraj Sumangala } else 358199811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 358299811510SSuraj Sumangala 35831e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 35841e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 358599811510SSuraj Sumangala if (rem < 0) 358699811510SSuraj Sumangala return rem; 358799811510SSuraj Sumangala 358899811510SSuraj Sumangala data += (count - rem); 358999811510SSuraj Sumangala count = rem; 3590f81c6224SJoe Perches } 359199811510SSuraj Sumangala 359299811510SSuraj Sumangala return rem; 359399811510SSuraj Sumangala } 359499811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 359599811510SSuraj Sumangala 35961da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 35971da177e4SLinus Torvalds 35981da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 35991da177e4SLinus Torvalds { 36001da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 36011da177e4SLinus Torvalds 3602f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 36031da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 3604f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 36051da177e4SLinus Torvalds 36061da177e4SLinus Torvalds return 0; 36071da177e4SLinus Torvalds } 36081da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 36091da177e4SLinus Torvalds 36101da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 36111da177e4SLinus Torvalds { 36121da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 36131da177e4SLinus Torvalds 3614f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 36151da177e4SLinus Torvalds list_del(&cb->list); 3616f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 36171da177e4SLinus Torvalds 36181da177e4SLinus Torvalds return 0; 36191da177e4SLinus Torvalds } 36201da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 36211da177e4SLinus Torvalds 362251086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 36231da177e4SLinus Torvalds { 36240d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 36251da177e4SLinus Torvalds 36261da177e4SLinus Torvalds /* Time stamp */ 3627a61bbcf2SPatrick McHardy __net_timestamp(skb); 36281da177e4SLinus Torvalds 3629cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3630cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3631cd82e61cSMarcel Holtmann 3632cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3633cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3634470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 36351da177e4SLinus Torvalds } 36361da177e4SLinus Torvalds 36371da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 36381da177e4SLinus Torvalds skb_orphan(skb); 36391da177e4SLinus Torvalds 36407bd8f09fSMarcel Holtmann if (hdev->send(hdev, skb) < 0) 364151086991SMarcel Holtmann BT_ERR("%s sending frame failed", hdev->name); 36421da177e4SLinus Torvalds } 36431da177e4SLinus Torvalds 36443119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 36453119ae95SJohan Hedberg { 36463119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 36473119ae95SJohan Hedberg req->hdev = hdev; 36485d73e034SAndre Guedes req->err = 0; 36493119ae95SJohan Hedberg } 36503119ae95SJohan Hedberg 36513119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 36523119ae95SJohan Hedberg { 36533119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 36543119ae95SJohan Hedberg struct sk_buff *skb; 36553119ae95SJohan Hedberg unsigned long flags; 36563119ae95SJohan Hedberg 36573119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 36583119ae95SJohan Hedberg 36595d73e034SAndre Guedes /* If an error occured during request building, remove all HCI 36605d73e034SAndre Guedes * commands queued on the HCI request queue. 36615d73e034SAndre Guedes */ 36625d73e034SAndre Guedes if (req->err) { 36635d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 36645d73e034SAndre Guedes return req->err; 36655d73e034SAndre Guedes } 36665d73e034SAndre Guedes 36673119ae95SJohan Hedberg /* Do not allow empty requests */ 36683119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 3669382b0c39SAndre Guedes return -ENODATA; 36703119ae95SJohan Hedberg 36713119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 36723119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 36733119ae95SJohan Hedberg 36743119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 36753119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 36763119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 36773119ae95SJohan Hedberg 36783119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 36793119ae95SJohan Hedberg 36803119ae95SJohan Hedberg return 0; 36813119ae95SJohan Hedberg } 36823119ae95SJohan Hedberg 36831ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 368407dc93ddSJohan Hedberg u32 plen, const void *param) 36851da177e4SLinus Torvalds { 36861da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 36871da177e4SLinus Torvalds struct hci_command_hdr *hdr; 36881da177e4SLinus Torvalds struct sk_buff *skb; 36891da177e4SLinus Torvalds 36901da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 36911ca3a9d0SJohan Hedberg if (!skb) 36921ca3a9d0SJohan Hedberg return NULL; 36931da177e4SLinus Torvalds 36941da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 3695a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 36961da177e4SLinus Torvalds hdr->plen = plen; 36971da177e4SLinus Torvalds 36981da177e4SLinus Torvalds if (plen) 36991da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 37001da177e4SLinus Torvalds 37011da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 37021da177e4SLinus Torvalds 37030d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 3704c78ae283SMarcel Holtmann 37051ca3a9d0SJohan Hedberg return skb; 37061ca3a9d0SJohan Hedberg } 37071ca3a9d0SJohan Hedberg 37081ca3a9d0SJohan Hedberg /* Send HCI command */ 370907dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 371007dc93ddSJohan Hedberg const void *param) 37111ca3a9d0SJohan Hedberg { 37121ca3a9d0SJohan Hedberg struct sk_buff *skb; 37131ca3a9d0SJohan Hedberg 37141ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 37151ca3a9d0SJohan Hedberg 37161ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 37171ca3a9d0SJohan Hedberg if (!skb) { 37181ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 37191ca3a9d0SJohan Hedberg return -ENOMEM; 37201ca3a9d0SJohan Hedberg } 37211ca3a9d0SJohan Hedberg 372211714b3dSJohan Hedberg /* Stand-alone HCI commands must be flaged as 372311714b3dSJohan Hedberg * single-command requests. 372411714b3dSJohan Hedberg */ 372511714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 372611714b3dSJohan Hedberg 37271da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3728c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 37291da177e4SLinus Torvalds 37301da177e4SLinus Torvalds return 0; 37311da177e4SLinus Torvalds } 37321da177e4SLinus Torvalds 373371c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 373407dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 373507dc93ddSJohan Hedberg const void *param, u8 event) 373671c76a17SJohan Hedberg { 373771c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 373871c76a17SJohan Hedberg struct sk_buff *skb; 373971c76a17SJohan Hedberg 374071c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 374171c76a17SJohan Hedberg 374234739c1eSAndre Guedes /* If an error occured during request building, there is no point in 374334739c1eSAndre Guedes * queueing the HCI command. We can simply return. 374434739c1eSAndre Guedes */ 374534739c1eSAndre Guedes if (req->err) 374634739c1eSAndre Guedes return; 374734739c1eSAndre Guedes 374871c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 374971c76a17SJohan Hedberg if (!skb) { 37505d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 37515d73e034SAndre Guedes hdev->name, opcode); 37525d73e034SAndre Guedes req->err = -ENOMEM; 3753e348fe6bSAndre Guedes return; 375471c76a17SJohan Hedberg } 375571c76a17SJohan Hedberg 375671c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 375771c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 375871c76a17SJohan Hedberg 375902350a72SJohan Hedberg bt_cb(skb)->req.event = event; 376002350a72SJohan Hedberg 376171c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 376271c76a17SJohan Hedberg } 376371c76a17SJohan Hedberg 376407dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 376507dc93ddSJohan Hedberg const void *param) 376602350a72SJohan Hedberg { 376702350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 376802350a72SJohan Hedberg } 376902350a72SJohan Hedberg 37701da177e4SLinus Torvalds /* Get data from the previously sent command */ 3771a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 37721da177e4SLinus Torvalds { 37731da177e4SLinus Torvalds struct hci_command_hdr *hdr; 37741da177e4SLinus Torvalds 37751da177e4SLinus Torvalds if (!hdev->sent_cmd) 37761da177e4SLinus Torvalds return NULL; 37771da177e4SLinus Torvalds 37781da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 37791da177e4SLinus Torvalds 3780a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 37811da177e4SLinus Torvalds return NULL; 37821da177e4SLinus Torvalds 3783f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 37841da177e4SLinus Torvalds 37851da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 37861da177e4SLinus Torvalds } 37871da177e4SLinus Torvalds 37881da177e4SLinus Torvalds /* Send ACL data */ 37891da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 37901da177e4SLinus Torvalds { 37911da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 37921da177e4SLinus Torvalds int len = skb->len; 37931da177e4SLinus Torvalds 3794badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3795badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 37969c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3797aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3798aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 37991da177e4SLinus Torvalds } 38001da177e4SLinus Torvalds 3801ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 380273d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 38031da177e4SLinus Torvalds { 3804ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 38051da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 38061da177e4SLinus Torvalds struct sk_buff *list; 38071da177e4SLinus Torvalds 3808087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3809087bfd99SGustavo Padovan skb->data_len = 0; 3810087bfd99SGustavo Padovan 3811087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3812204a6e54SAndrei Emeltchenko 3813204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3814204a6e54SAndrei Emeltchenko case HCI_BREDR: 3815087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3816204a6e54SAndrei Emeltchenko break; 3817204a6e54SAndrei Emeltchenko case HCI_AMP: 3818204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3819204a6e54SAndrei Emeltchenko break; 3820204a6e54SAndrei Emeltchenko default: 3821204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 3822204a6e54SAndrei Emeltchenko return; 3823204a6e54SAndrei Emeltchenko } 3824087bfd99SGustavo Padovan 382570f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 382670f23020SAndrei Emeltchenko if (!list) { 38271da177e4SLinus Torvalds /* Non fragmented */ 38281da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 38291da177e4SLinus Torvalds 383073d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 38311da177e4SLinus Torvalds } else { 38321da177e4SLinus Torvalds /* Fragmented */ 38331da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 38341da177e4SLinus Torvalds 38351da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 38361da177e4SLinus Torvalds 38371da177e4SLinus Torvalds /* Queue all fragments atomically */ 3838af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 38391da177e4SLinus Torvalds 384073d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3841e702112fSAndrei Emeltchenko 3842e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3843e702112fSAndrei Emeltchenko flags |= ACL_CONT; 38441da177e4SLinus Torvalds do { 38451da177e4SLinus Torvalds skb = list; list = list->next; 38461da177e4SLinus Torvalds 38470d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3848e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 38491da177e4SLinus Torvalds 38501da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 38511da177e4SLinus Torvalds 385273d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 38531da177e4SLinus Torvalds } while (list); 38541da177e4SLinus Torvalds 3855af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 38561da177e4SLinus Torvalds } 385773d80debSLuiz Augusto von Dentz } 385873d80debSLuiz Augusto von Dentz 385973d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 386073d80debSLuiz Augusto von Dentz { 3861ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 386273d80debSLuiz Augusto von Dentz 3863f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 386473d80debSLuiz Augusto von Dentz 3865ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 38661da177e4SLinus Torvalds 38673eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 38681da177e4SLinus Torvalds } 38691da177e4SLinus Torvalds 38701da177e4SLinus Torvalds /* Send SCO data */ 38710d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 38721da177e4SLinus Torvalds { 38731da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 38741da177e4SLinus Torvalds struct hci_sco_hdr hdr; 38751da177e4SLinus Torvalds 38761da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 38771da177e4SLinus Torvalds 3878aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 38791da177e4SLinus Torvalds hdr.dlen = skb->len; 38801da177e4SLinus Torvalds 3881badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 3882badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 38839c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 38841da177e4SLinus Torvalds 38850d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 3886c78ae283SMarcel Holtmann 38871da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 38883eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 38891da177e4SLinus Torvalds } 38901da177e4SLinus Torvalds 38911da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 38921da177e4SLinus Torvalds 38931da177e4SLinus Torvalds /* HCI Connection scheduler */ 38946039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 3895a8c5fb1aSGustavo Padovan int *quote) 38961da177e4SLinus Torvalds { 38971da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 38988035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 3899abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 39001da177e4SLinus Torvalds 39011da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 39021da177e4SLinus Torvalds * added and removed with TX task disabled. */ 3903bf4c6325SGustavo F. Padovan 3904bf4c6325SGustavo F. Padovan rcu_read_lock(); 3905bf4c6325SGustavo F. Padovan 3906bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3907769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 39081da177e4SLinus Torvalds continue; 3909769be974SMarcel Holtmann 3910769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 3911769be974SMarcel Holtmann continue; 3912769be974SMarcel Holtmann 39131da177e4SLinus Torvalds num++; 39141da177e4SLinus Torvalds 39151da177e4SLinus Torvalds if (c->sent < min) { 39161da177e4SLinus Torvalds min = c->sent; 39171da177e4SLinus Torvalds conn = c; 39181da177e4SLinus Torvalds } 391952087a79SLuiz Augusto von Dentz 392052087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 392152087a79SLuiz Augusto von Dentz break; 39221da177e4SLinus Torvalds } 39231da177e4SLinus Torvalds 3924bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3925bf4c6325SGustavo F. Padovan 39261da177e4SLinus Torvalds if (conn) { 39276ed58ec5SVille Tervo int cnt, q; 39286ed58ec5SVille Tervo 39296ed58ec5SVille Tervo switch (conn->type) { 39306ed58ec5SVille Tervo case ACL_LINK: 39316ed58ec5SVille Tervo cnt = hdev->acl_cnt; 39326ed58ec5SVille Tervo break; 39336ed58ec5SVille Tervo case SCO_LINK: 39346ed58ec5SVille Tervo case ESCO_LINK: 39356ed58ec5SVille Tervo cnt = hdev->sco_cnt; 39366ed58ec5SVille Tervo break; 39376ed58ec5SVille Tervo case LE_LINK: 39386ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 39396ed58ec5SVille Tervo break; 39406ed58ec5SVille Tervo default: 39416ed58ec5SVille Tervo cnt = 0; 39426ed58ec5SVille Tervo BT_ERR("Unknown link type"); 39436ed58ec5SVille Tervo } 39446ed58ec5SVille Tervo 39456ed58ec5SVille Tervo q = cnt / num; 39461da177e4SLinus Torvalds *quote = q ? q : 1; 39471da177e4SLinus Torvalds } else 39481da177e4SLinus Torvalds *quote = 0; 39491da177e4SLinus Torvalds 39501da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 39511da177e4SLinus Torvalds return conn; 39521da177e4SLinus Torvalds } 39531da177e4SLinus Torvalds 39546039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 39551da177e4SLinus Torvalds { 39561da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 39571da177e4SLinus Torvalds struct hci_conn *c; 39581da177e4SLinus Torvalds 3959bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 39601da177e4SLinus Torvalds 3961bf4c6325SGustavo F. Padovan rcu_read_lock(); 3962bf4c6325SGustavo F. Padovan 39631da177e4SLinus Torvalds /* Kill stalled connections */ 3964bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3965bae1f5d9SVille Tervo if (c->type == type && c->sent) { 39666ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 39676ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 3968bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 39691da177e4SLinus Torvalds } 39701da177e4SLinus Torvalds } 3971bf4c6325SGustavo F. Padovan 3972bf4c6325SGustavo F. Padovan rcu_read_unlock(); 39731da177e4SLinus Torvalds } 39741da177e4SLinus Torvalds 39756039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 397673d80debSLuiz Augusto von Dentz int *quote) 397773d80debSLuiz Augusto von Dentz { 397873d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 397973d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 3980abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 398173d80debSLuiz Augusto von Dentz struct hci_conn *conn; 398273d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 398373d80debSLuiz Augusto von Dentz 398473d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 398573d80debSLuiz Augusto von Dentz 3986bf4c6325SGustavo F. Padovan rcu_read_lock(); 3987bf4c6325SGustavo F. Padovan 3988bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 398973d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 399073d80debSLuiz Augusto von Dentz 399173d80debSLuiz Augusto von Dentz if (conn->type != type) 399273d80debSLuiz Augusto von Dentz continue; 399373d80debSLuiz Augusto von Dentz 399473d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 399573d80debSLuiz Augusto von Dentz continue; 399673d80debSLuiz Augusto von Dentz 399773d80debSLuiz Augusto von Dentz conn_num++; 399873d80debSLuiz Augusto von Dentz 39998192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 400073d80debSLuiz Augusto von Dentz struct sk_buff *skb; 400173d80debSLuiz Augusto von Dentz 400273d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 400373d80debSLuiz Augusto von Dentz continue; 400473d80debSLuiz Augusto von Dentz 400573d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 400673d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 400773d80debSLuiz Augusto von Dentz continue; 400873d80debSLuiz Augusto von Dentz 400973d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 401073d80debSLuiz Augusto von Dentz num = 0; 401173d80debSLuiz Augusto von Dentz min = ~0; 401273d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 401373d80debSLuiz Augusto von Dentz } 401473d80debSLuiz Augusto von Dentz 401573d80debSLuiz Augusto von Dentz num++; 401673d80debSLuiz Augusto von Dentz 401773d80debSLuiz Augusto von Dentz if (conn->sent < min) { 401873d80debSLuiz Augusto von Dentz min = conn->sent; 401973d80debSLuiz Augusto von Dentz chan = tmp; 402073d80debSLuiz Augusto von Dentz } 402173d80debSLuiz Augusto von Dentz } 402273d80debSLuiz Augusto von Dentz 402373d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 402473d80debSLuiz Augusto von Dentz break; 402573d80debSLuiz Augusto von Dentz } 402673d80debSLuiz Augusto von Dentz 4027bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4028bf4c6325SGustavo F. Padovan 402973d80debSLuiz Augusto von Dentz if (!chan) 403073d80debSLuiz Augusto von Dentz return NULL; 403173d80debSLuiz Augusto von Dentz 403273d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 403373d80debSLuiz Augusto von Dentz case ACL_LINK: 403473d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 403573d80debSLuiz Augusto von Dentz break; 4036bd1eb66bSAndrei Emeltchenko case AMP_LINK: 4037bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 4038bd1eb66bSAndrei Emeltchenko break; 403973d80debSLuiz Augusto von Dentz case SCO_LINK: 404073d80debSLuiz Augusto von Dentz case ESCO_LINK: 404173d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 404273d80debSLuiz Augusto von Dentz break; 404373d80debSLuiz Augusto von Dentz case LE_LINK: 404473d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 404573d80debSLuiz Augusto von Dentz break; 404673d80debSLuiz Augusto von Dentz default: 404773d80debSLuiz Augusto von Dentz cnt = 0; 404873d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 404973d80debSLuiz Augusto von Dentz } 405073d80debSLuiz Augusto von Dentz 405173d80debSLuiz Augusto von Dentz q = cnt / num; 405273d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 405373d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 405473d80debSLuiz Augusto von Dentz return chan; 405573d80debSLuiz Augusto von Dentz } 405673d80debSLuiz Augusto von Dentz 405702b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 405802b20f0bSLuiz Augusto von Dentz { 405902b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 406002b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 406102b20f0bSLuiz Augusto von Dentz int num = 0; 406202b20f0bSLuiz Augusto von Dentz 406302b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 406402b20f0bSLuiz Augusto von Dentz 4065bf4c6325SGustavo F. Padovan rcu_read_lock(); 4066bf4c6325SGustavo F. Padovan 4067bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 406802b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 406902b20f0bSLuiz Augusto von Dentz 407002b20f0bSLuiz Augusto von Dentz if (conn->type != type) 407102b20f0bSLuiz Augusto von Dentz continue; 407202b20f0bSLuiz Augusto von Dentz 407302b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 407402b20f0bSLuiz Augusto von Dentz continue; 407502b20f0bSLuiz Augusto von Dentz 407602b20f0bSLuiz Augusto von Dentz num++; 407702b20f0bSLuiz Augusto von Dentz 40788192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 407902b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 408002b20f0bSLuiz Augusto von Dentz 408102b20f0bSLuiz Augusto von Dentz if (chan->sent) { 408202b20f0bSLuiz Augusto von Dentz chan->sent = 0; 408302b20f0bSLuiz Augusto von Dentz continue; 408402b20f0bSLuiz Augusto von Dentz } 408502b20f0bSLuiz Augusto von Dentz 408602b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 408702b20f0bSLuiz Augusto von Dentz continue; 408802b20f0bSLuiz Augusto von Dentz 408902b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 409002b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 409102b20f0bSLuiz Augusto von Dentz continue; 409202b20f0bSLuiz Augusto von Dentz 409302b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 409402b20f0bSLuiz Augusto von Dentz 409502b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 409602b20f0bSLuiz Augusto von Dentz skb->priority); 409702b20f0bSLuiz Augusto von Dentz } 409802b20f0bSLuiz Augusto von Dentz 409902b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 410002b20f0bSLuiz Augusto von Dentz break; 410102b20f0bSLuiz Augusto von Dentz } 4102bf4c6325SGustavo F. Padovan 4103bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4104bf4c6325SGustavo F. Padovan 410502b20f0bSLuiz Augusto von Dentz } 410602b20f0bSLuiz Augusto von Dentz 4107b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4108b71d385aSAndrei Emeltchenko { 4109b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4110b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4111b71d385aSAndrei Emeltchenko } 4112b71d385aSAndrei Emeltchenko 41136039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 41141da177e4SLinus Torvalds { 41151da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 41161da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 41171da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 411863d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 41195f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 4120bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 41211da177e4SLinus Torvalds } 412263d2bc1bSAndrei Emeltchenko } 41231da177e4SLinus Torvalds 41246039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 412563d2bc1bSAndrei Emeltchenko { 412663d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 412763d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 412863d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 412963d2bc1bSAndrei Emeltchenko int quote; 413063d2bc1bSAndrei Emeltchenko 413163d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 413204837f64SMarcel Holtmann 413373d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 413473d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 4135ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4136ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 413773d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 413873d80debSLuiz Augusto von Dentz skb->len, skb->priority); 413973d80debSLuiz Augusto von Dentz 4140ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4141ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4142ec1cce24SLuiz Augusto von Dentz break; 4143ec1cce24SLuiz Augusto von Dentz 4144ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4145ec1cce24SLuiz Augusto von Dentz 414673d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 414773d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 414804837f64SMarcel Holtmann 414957d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 41501da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 41511da177e4SLinus Torvalds 41521da177e4SLinus Torvalds hdev->acl_cnt--; 415373d80debSLuiz Augusto von Dentz chan->sent++; 415473d80debSLuiz Augusto von Dentz chan->conn->sent++; 41551da177e4SLinus Torvalds } 41561da177e4SLinus Torvalds } 415702b20f0bSLuiz Augusto von Dentz 415802b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 415902b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 41601da177e4SLinus Torvalds } 41611da177e4SLinus Torvalds 41626039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4163b71d385aSAndrei Emeltchenko { 416463d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4165b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4166b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4167b71d385aSAndrei Emeltchenko int quote; 4168bd1eb66bSAndrei Emeltchenko u8 type; 4169b71d385aSAndrei Emeltchenko 417063d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4171b71d385aSAndrei Emeltchenko 4172bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4173bd1eb66bSAndrei Emeltchenko 4174bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4175bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4176bd1eb66bSAndrei Emeltchenko else 4177bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4178bd1eb66bSAndrei Emeltchenko 4179b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4180bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4181b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4182b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4183b71d385aSAndrei Emeltchenko int blocks; 4184b71d385aSAndrei Emeltchenko 4185b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4186b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4187b71d385aSAndrei Emeltchenko 4188b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4189b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4190b71d385aSAndrei Emeltchenko break; 4191b71d385aSAndrei Emeltchenko 4192b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4193b71d385aSAndrei Emeltchenko 4194b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4195b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4196b71d385aSAndrei Emeltchenko return; 4197b71d385aSAndrei Emeltchenko 4198b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4199b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4200b71d385aSAndrei Emeltchenko 420157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4202b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4203b71d385aSAndrei Emeltchenko 4204b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4205b71d385aSAndrei Emeltchenko quote -= blocks; 4206b71d385aSAndrei Emeltchenko 4207b71d385aSAndrei Emeltchenko chan->sent += blocks; 4208b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4209b71d385aSAndrei Emeltchenko } 4210b71d385aSAndrei Emeltchenko } 4211b71d385aSAndrei Emeltchenko 4212b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4213bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4214b71d385aSAndrei Emeltchenko } 4215b71d385aSAndrei Emeltchenko 42166039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4217b71d385aSAndrei Emeltchenko { 4218b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4219b71d385aSAndrei Emeltchenko 4220bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4221bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 4222bd1eb66bSAndrei Emeltchenko return; 4223bd1eb66bSAndrei Emeltchenko 4224bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4225bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4226b71d385aSAndrei Emeltchenko return; 4227b71d385aSAndrei Emeltchenko 4228b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4229b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4230b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4231b71d385aSAndrei Emeltchenko break; 4232b71d385aSAndrei Emeltchenko 4233b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4234b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4235b71d385aSAndrei Emeltchenko break; 4236b71d385aSAndrei Emeltchenko } 4237b71d385aSAndrei Emeltchenko } 4238b71d385aSAndrei Emeltchenko 42391da177e4SLinus Torvalds /* Schedule SCO */ 42406039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 42411da177e4SLinus Torvalds { 42421da177e4SLinus Torvalds struct hci_conn *conn; 42431da177e4SLinus Torvalds struct sk_buff *skb; 42441da177e4SLinus Torvalds int quote; 42451da177e4SLinus Torvalds 42461da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 42471da177e4SLinus Torvalds 424852087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 424952087a79SLuiz Augusto von Dentz return; 425052087a79SLuiz Augusto von Dentz 42511da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 42521da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 42531da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 425457d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 42551da177e4SLinus Torvalds 42561da177e4SLinus Torvalds conn->sent++; 42571da177e4SLinus Torvalds if (conn->sent == ~0) 42581da177e4SLinus Torvalds conn->sent = 0; 42591da177e4SLinus Torvalds } 42601da177e4SLinus Torvalds } 42611da177e4SLinus Torvalds } 42621da177e4SLinus Torvalds 42636039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 4264b6a0dc82SMarcel Holtmann { 4265b6a0dc82SMarcel Holtmann struct hci_conn *conn; 4266b6a0dc82SMarcel Holtmann struct sk_buff *skb; 4267b6a0dc82SMarcel Holtmann int quote; 4268b6a0dc82SMarcel Holtmann 4269b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 4270b6a0dc82SMarcel Holtmann 427152087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 427252087a79SLuiz Augusto von Dentz return; 427352087a79SLuiz Augusto von Dentz 42748fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 42758fc9ced3SGustavo Padovan "e))) { 4276b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 4277b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 427857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4279b6a0dc82SMarcel Holtmann 4280b6a0dc82SMarcel Holtmann conn->sent++; 4281b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 4282b6a0dc82SMarcel Holtmann conn->sent = 0; 4283b6a0dc82SMarcel Holtmann } 4284b6a0dc82SMarcel Holtmann } 4285b6a0dc82SMarcel Holtmann } 4286b6a0dc82SMarcel Holtmann 42876039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 42886ed58ec5SVille Tervo { 428973d80debSLuiz Augusto von Dentz struct hci_chan *chan; 42906ed58ec5SVille Tervo struct sk_buff *skb; 429102b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 42926ed58ec5SVille Tervo 42936ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 42946ed58ec5SVille Tervo 429552087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 429652087a79SLuiz Augusto von Dentz return; 429752087a79SLuiz Augusto von Dentz 42986ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 42996ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 43006ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 4301bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 43026ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 4303bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 43046ed58ec5SVille Tervo } 43056ed58ec5SVille Tervo 43066ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 430702b20f0bSLuiz Augusto von Dentz tmp = cnt; 430873d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 4309ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4310ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 431173d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 431273d80debSLuiz Augusto von Dentz skb->len, skb->priority); 43136ed58ec5SVille Tervo 4314ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4315ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4316ec1cce24SLuiz Augusto von Dentz break; 4317ec1cce24SLuiz Augusto von Dentz 4318ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4319ec1cce24SLuiz Augusto von Dentz 432057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 43216ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 43226ed58ec5SVille Tervo 43236ed58ec5SVille Tervo cnt--; 432473d80debSLuiz Augusto von Dentz chan->sent++; 432573d80debSLuiz Augusto von Dentz chan->conn->sent++; 43266ed58ec5SVille Tervo } 43276ed58ec5SVille Tervo } 432873d80debSLuiz Augusto von Dentz 43296ed58ec5SVille Tervo if (hdev->le_pkts) 43306ed58ec5SVille Tervo hdev->le_cnt = cnt; 43316ed58ec5SVille Tervo else 43326ed58ec5SVille Tervo hdev->acl_cnt = cnt; 433302b20f0bSLuiz Augusto von Dentz 433402b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 433502b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 43366ed58ec5SVille Tervo } 43376ed58ec5SVille Tervo 43383eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 43391da177e4SLinus Torvalds { 43403eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 43411da177e4SLinus Torvalds struct sk_buff *skb; 43421da177e4SLinus Torvalds 43436ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 43446ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 43451da177e4SLinus Torvalds 434652de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 43471da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 43481da177e4SLinus Torvalds hci_sched_acl(hdev); 43491da177e4SLinus Torvalds hci_sched_sco(hdev); 4350b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 43516ed58ec5SVille Tervo hci_sched_le(hdev); 435252de599eSMarcel Holtmann } 43536ed58ec5SVille Tervo 43541da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 43551da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 435657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 43571da177e4SLinus Torvalds } 43581da177e4SLinus Torvalds 435925985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 43601da177e4SLinus Torvalds 43611da177e4SLinus Torvalds /* ACL data packet */ 43626039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 43631da177e4SLinus Torvalds { 43641da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 43651da177e4SLinus Torvalds struct hci_conn *conn; 43661da177e4SLinus Torvalds __u16 handle, flags; 43671da177e4SLinus Torvalds 43681da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 43691da177e4SLinus Torvalds 43701da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 43711da177e4SLinus Torvalds flags = hci_flags(handle); 43721da177e4SLinus Torvalds handle = hci_handle(handle); 43731da177e4SLinus Torvalds 4374f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4375a8c5fb1aSGustavo Padovan handle, flags); 43761da177e4SLinus Torvalds 43771da177e4SLinus Torvalds hdev->stat.acl_rx++; 43781da177e4SLinus Torvalds 43791da177e4SLinus Torvalds hci_dev_lock(hdev); 43801da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 43811da177e4SLinus Torvalds hci_dev_unlock(hdev); 43821da177e4SLinus Torvalds 43831da177e4SLinus Torvalds if (conn) { 438465983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 438504837f64SMarcel Holtmann 43861da177e4SLinus Torvalds /* Send to upper protocol */ 4387686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 43881da177e4SLinus Torvalds return; 43891da177e4SLinus Torvalds } else { 43901da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 43911da177e4SLinus Torvalds hdev->name, handle); 43921da177e4SLinus Torvalds } 43931da177e4SLinus Torvalds 43941da177e4SLinus Torvalds kfree_skb(skb); 43951da177e4SLinus Torvalds } 43961da177e4SLinus Torvalds 43971da177e4SLinus Torvalds /* SCO data packet */ 43986039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 43991da177e4SLinus Torvalds { 44001da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 44011da177e4SLinus Torvalds struct hci_conn *conn; 44021da177e4SLinus Torvalds __u16 handle; 44031da177e4SLinus Torvalds 44041da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 44051da177e4SLinus Torvalds 44061da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 44071da177e4SLinus Torvalds 4408f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 44091da177e4SLinus Torvalds 44101da177e4SLinus Torvalds hdev->stat.sco_rx++; 44111da177e4SLinus Torvalds 44121da177e4SLinus Torvalds hci_dev_lock(hdev); 44131da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 44141da177e4SLinus Torvalds hci_dev_unlock(hdev); 44151da177e4SLinus Torvalds 44161da177e4SLinus Torvalds if (conn) { 44171da177e4SLinus Torvalds /* Send to upper protocol */ 4418686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 44191da177e4SLinus Torvalds return; 44201da177e4SLinus Torvalds } else { 44211da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 44221da177e4SLinus Torvalds hdev->name, handle); 44231da177e4SLinus Torvalds } 44241da177e4SLinus Torvalds 44251da177e4SLinus Torvalds kfree_skb(skb); 44261da177e4SLinus Torvalds } 44271da177e4SLinus Torvalds 44289238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 44299238f36aSJohan Hedberg { 44309238f36aSJohan Hedberg struct sk_buff *skb; 44319238f36aSJohan Hedberg 44329238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 44339238f36aSJohan Hedberg if (!skb) 44349238f36aSJohan Hedberg return true; 44359238f36aSJohan Hedberg 44369238f36aSJohan Hedberg return bt_cb(skb)->req.start; 44379238f36aSJohan Hedberg } 44389238f36aSJohan Hedberg 443942c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 444042c6b129SJohan Hedberg { 444142c6b129SJohan Hedberg struct hci_command_hdr *sent; 444242c6b129SJohan Hedberg struct sk_buff *skb; 444342c6b129SJohan Hedberg u16 opcode; 444442c6b129SJohan Hedberg 444542c6b129SJohan Hedberg if (!hdev->sent_cmd) 444642c6b129SJohan Hedberg return; 444742c6b129SJohan Hedberg 444842c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 444942c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 445042c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 445142c6b129SJohan Hedberg return; 445242c6b129SJohan Hedberg 445342c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 445442c6b129SJohan Hedberg if (!skb) 445542c6b129SJohan Hedberg return; 445642c6b129SJohan Hedberg 445742c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 445842c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 445942c6b129SJohan Hedberg } 446042c6b129SJohan Hedberg 44619238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 44629238f36aSJohan Hedberg { 44639238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 44649238f36aSJohan Hedberg struct sk_buff *skb; 44659238f36aSJohan Hedberg unsigned long flags; 44669238f36aSJohan Hedberg 44679238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 44689238f36aSJohan Hedberg 446942c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 447042c6b129SJohan Hedberg * sent we need to do special handling of it. 44719238f36aSJohan Hedberg */ 447242c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 447342c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 447442c6b129SJohan Hedberg * reset complete event during init and any pending 447542c6b129SJohan Hedberg * command will never be completed. In such a case we 447642c6b129SJohan Hedberg * need to resend whatever was the last sent 447742c6b129SJohan Hedberg * command. 447842c6b129SJohan Hedberg */ 447942c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 448042c6b129SJohan Hedberg hci_resend_last(hdev); 448142c6b129SJohan Hedberg 44829238f36aSJohan Hedberg return; 448342c6b129SJohan Hedberg } 44849238f36aSJohan Hedberg 44859238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 44869238f36aSJohan Hedberg * this request the request is not yet complete. 44879238f36aSJohan Hedberg */ 44889238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 44899238f36aSJohan Hedberg return; 44909238f36aSJohan Hedberg 44919238f36aSJohan Hedberg /* If this was the last command in a request the complete 44929238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 44939238f36aSJohan Hedberg * command queue (hdev->cmd_q). 44949238f36aSJohan Hedberg */ 44959238f36aSJohan Hedberg if (hdev->sent_cmd) { 44969238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 449753e21fbcSJohan Hedberg 449853e21fbcSJohan Hedberg if (req_complete) { 449953e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 450053e21fbcSJohan Hedberg * avoid calling the callback more than once if 450153e21fbcSJohan Hedberg * this function gets called again. 450253e21fbcSJohan Hedberg */ 450353e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 450453e21fbcSJohan Hedberg 45059238f36aSJohan Hedberg goto call_complete; 45069238f36aSJohan Hedberg } 450753e21fbcSJohan Hedberg } 45089238f36aSJohan Hedberg 45099238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 45109238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 45119238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 45129238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 45139238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 45149238f36aSJohan Hedberg break; 45159238f36aSJohan Hedberg } 45169238f36aSJohan Hedberg 45179238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 45189238f36aSJohan Hedberg kfree_skb(skb); 45199238f36aSJohan Hedberg } 45209238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 45219238f36aSJohan Hedberg 45229238f36aSJohan Hedberg call_complete: 45239238f36aSJohan Hedberg if (req_complete) 45249238f36aSJohan Hedberg req_complete(hdev, status); 45259238f36aSJohan Hedberg } 45269238f36aSJohan Hedberg 4527b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 45281da177e4SLinus Torvalds { 4529b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 45301da177e4SLinus Torvalds struct sk_buff *skb; 45311da177e4SLinus Torvalds 45321da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 45331da177e4SLinus Torvalds 45341da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 4535cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4536cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4537cd82e61cSMarcel Holtmann 45381da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 45391da177e4SLinus Torvalds /* Send copy to the sockets */ 4540470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 45411da177e4SLinus Torvalds } 45421da177e4SLinus Torvalds 45430736cfa8SMarcel Holtmann if (test_bit(HCI_RAW, &hdev->flags) || 45440736cfa8SMarcel Holtmann test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 45451da177e4SLinus Torvalds kfree_skb(skb); 45461da177e4SLinus Torvalds continue; 45471da177e4SLinus Torvalds } 45481da177e4SLinus Torvalds 45491da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 45501da177e4SLinus Torvalds /* Don't process data packets in this states. */ 45510d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 45521da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 45531da177e4SLinus Torvalds case HCI_SCODATA_PKT: 45541da177e4SLinus Torvalds kfree_skb(skb); 45551da177e4SLinus Torvalds continue; 45563ff50b79SStephen Hemminger } 45571da177e4SLinus Torvalds } 45581da177e4SLinus Torvalds 45591da177e4SLinus Torvalds /* Process frame */ 45600d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 45611da177e4SLinus Torvalds case HCI_EVENT_PKT: 4562b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 45631da177e4SLinus Torvalds hci_event_packet(hdev, skb); 45641da177e4SLinus Torvalds break; 45651da177e4SLinus Torvalds 45661da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 45671da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 45681da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 45691da177e4SLinus Torvalds break; 45701da177e4SLinus Torvalds 45711da177e4SLinus Torvalds case HCI_SCODATA_PKT: 45721da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 45731da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 45741da177e4SLinus Torvalds break; 45751da177e4SLinus Torvalds 45761da177e4SLinus Torvalds default: 45771da177e4SLinus Torvalds kfree_skb(skb); 45781da177e4SLinus Torvalds break; 45791da177e4SLinus Torvalds } 45801da177e4SLinus Torvalds } 45811da177e4SLinus Torvalds } 45821da177e4SLinus Torvalds 4583c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 45841da177e4SLinus Torvalds { 4585c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 45861da177e4SLinus Torvalds struct sk_buff *skb; 45871da177e4SLinus Torvalds 45882104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 45892104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 45901da177e4SLinus Torvalds 45911da177e4SLinus Torvalds /* Send queued commands */ 45925a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 45935a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 45945a08ecceSAndrei Emeltchenko if (!skb) 45955a08ecceSAndrei Emeltchenko return; 45965a08ecceSAndrei Emeltchenko 45971da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 45981da177e4SLinus Torvalds 4599a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 460070f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 46011da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 460257d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 46037bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 46047bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 46057bdb8a5cSSzymon Janc else 46066bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 46075f246e89SAndrei Emeltchenko jiffies + HCI_CMD_TIMEOUT); 46081da177e4SLinus Torvalds } else { 46091da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4610c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 46111da177e4SLinus Torvalds } 46121da177e4SLinus Torvalds } 46131da177e4SLinus Torvalds } 4614