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> 374bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h> 38af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h> 391da177e4SLinus Torvalds 40970c4e46SJohan Hedberg #include "smp.h" 41970c4e46SJohan Hedberg 42b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 43c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 443eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds /* HCI device list */ 471da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 481da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds /* HCI callback list */ 511da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 521da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 531da177e4SLinus Torvalds 543df92b31SSasha Levin /* HCI ID Numbering */ 553df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 563df92b31SSasha Levin 57899de765SMarcel Holtmann /* ----- HCI requests ----- */ 58899de765SMarcel Holtmann 59899de765SMarcel Holtmann #define HCI_REQ_DONE 0 60899de765SMarcel Holtmann #define HCI_REQ_PEND 1 61899de765SMarcel Holtmann #define HCI_REQ_CANCELED 2 62899de765SMarcel Holtmann 63899de765SMarcel Holtmann #define hci_req_lock(d) mutex_lock(&d->req_lock) 64899de765SMarcel Holtmann #define hci_req_unlock(d) mutex_unlock(&d->req_lock) 65899de765SMarcel Holtmann 661da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 671da177e4SLinus Torvalds 686516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 691da177e4SLinus Torvalds { 70040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 711da177e4SLinus Torvalds } 721da177e4SLinus Torvalds 73baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */ 74baf27f6eSMarcel Holtmann 754b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf, 764b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 774b4148e9SMarcel Holtmann { 784b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 794b4148e9SMarcel Holtmann char buf[3]; 804b4148e9SMarcel Holtmann 81111902f7SMarcel Holtmann buf[0] = test_bit(HCI_DUT_MODE, &hdev->dbg_flags) ? 'Y': 'N'; 824b4148e9SMarcel Holtmann buf[1] = '\n'; 834b4148e9SMarcel Holtmann buf[2] = '\0'; 844b4148e9SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 854b4148e9SMarcel Holtmann } 864b4148e9SMarcel Holtmann 874b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf, 884b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 894b4148e9SMarcel Holtmann { 904b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 914b4148e9SMarcel Holtmann struct sk_buff *skb; 924b4148e9SMarcel Holtmann char buf[32]; 934b4148e9SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 944b4148e9SMarcel Holtmann bool enable; 954b4148e9SMarcel Holtmann int err; 964b4148e9SMarcel Holtmann 974b4148e9SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 984b4148e9SMarcel Holtmann return -ENETDOWN; 994b4148e9SMarcel Holtmann 1004b4148e9SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 1014b4148e9SMarcel Holtmann return -EFAULT; 1024b4148e9SMarcel Holtmann 1034b4148e9SMarcel Holtmann buf[buf_size] = '\0'; 1044b4148e9SMarcel Holtmann if (strtobool(buf, &enable)) 1054b4148e9SMarcel Holtmann return -EINVAL; 1064b4148e9SMarcel Holtmann 107111902f7SMarcel Holtmann if (enable == test_bit(HCI_DUT_MODE, &hdev->dbg_flags)) 1084b4148e9SMarcel Holtmann return -EALREADY; 1094b4148e9SMarcel Holtmann 1104b4148e9SMarcel Holtmann hci_req_lock(hdev); 1114b4148e9SMarcel Holtmann if (enable) 1124b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL, 1134b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1144b4148e9SMarcel Holtmann else 1154b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, 1164b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1174b4148e9SMarcel Holtmann hci_req_unlock(hdev); 1184b4148e9SMarcel Holtmann 1194b4148e9SMarcel Holtmann if (IS_ERR(skb)) 1204b4148e9SMarcel Holtmann return PTR_ERR(skb); 1214b4148e9SMarcel Holtmann 1224b4148e9SMarcel Holtmann err = -bt_to_errno(skb->data[0]); 1234b4148e9SMarcel Holtmann kfree_skb(skb); 1244b4148e9SMarcel Holtmann 1254b4148e9SMarcel Holtmann if (err < 0) 1264b4148e9SMarcel Holtmann return err; 1274b4148e9SMarcel Holtmann 128111902f7SMarcel Holtmann change_bit(HCI_DUT_MODE, &hdev->dbg_flags); 1294b4148e9SMarcel Holtmann 1304b4148e9SMarcel Holtmann return count; 1314b4148e9SMarcel Holtmann } 1324b4148e9SMarcel Holtmann 1334b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = { 1344b4148e9SMarcel Holtmann .open = simple_open, 1354b4148e9SMarcel Holtmann .read = dut_mode_read, 1364b4148e9SMarcel Holtmann .write = dut_mode_write, 1374b4148e9SMarcel Holtmann .llseek = default_llseek, 1384b4148e9SMarcel Holtmann }; 1394b4148e9SMarcel Holtmann 140dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr) 141dfb826a8SMarcel Holtmann { 142dfb826a8SMarcel Holtmann struct hci_dev *hdev = f->private; 143dfb826a8SMarcel Holtmann u8 p; 144dfb826a8SMarcel Holtmann 145dfb826a8SMarcel Holtmann hci_dev_lock(hdev); 146dfb826a8SMarcel Holtmann for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 147cfbb2b5bSMarcel Holtmann seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 148dfb826a8SMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p, 149dfb826a8SMarcel Holtmann hdev->features[p][0], hdev->features[p][1], 150dfb826a8SMarcel Holtmann hdev->features[p][2], hdev->features[p][3], 151dfb826a8SMarcel Holtmann hdev->features[p][4], hdev->features[p][5], 152dfb826a8SMarcel Holtmann hdev->features[p][6], hdev->features[p][7]); 153dfb826a8SMarcel Holtmann } 154cfbb2b5bSMarcel Holtmann if (lmp_le_capable(hdev)) 155cfbb2b5bSMarcel Holtmann seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 156cfbb2b5bSMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", 157cfbb2b5bSMarcel Holtmann hdev->le_features[0], hdev->le_features[1], 158cfbb2b5bSMarcel Holtmann hdev->le_features[2], hdev->le_features[3], 159cfbb2b5bSMarcel Holtmann hdev->le_features[4], hdev->le_features[5], 160cfbb2b5bSMarcel Holtmann hdev->le_features[6], hdev->le_features[7]); 161dfb826a8SMarcel Holtmann hci_dev_unlock(hdev); 162dfb826a8SMarcel Holtmann 163dfb826a8SMarcel Holtmann return 0; 164dfb826a8SMarcel Holtmann } 165dfb826a8SMarcel Holtmann 166dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file) 167dfb826a8SMarcel Holtmann { 168dfb826a8SMarcel Holtmann return single_open(file, features_show, inode->i_private); 169dfb826a8SMarcel Holtmann } 170dfb826a8SMarcel Holtmann 171dfb826a8SMarcel Holtmann static const struct file_operations features_fops = { 172dfb826a8SMarcel Holtmann .open = features_open, 173dfb826a8SMarcel Holtmann .read = seq_read, 174dfb826a8SMarcel Holtmann .llseek = seq_lseek, 175dfb826a8SMarcel Holtmann .release = single_release, 176dfb826a8SMarcel Holtmann }; 177dfb826a8SMarcel Holtmann 17870afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p) 17970afe0b8SMarcel Holtmann { 18070afe0b8SMarcel Holtmann struct hci_dev *hdev = f->private; 18170afe0b8SMarcel Holtmann struct bdaddr_list *b; 18270afe0b8SMarcel Holtmann 18370afe0b8SMarcel Holtmann hci_dev_lock(hdev); 18470afe0b8SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) 185b25f0785SMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 18670afe0b8SMarcel Holtmann hci_dev_unlock(hdev); 18770afe0b8SMarcel Holtmann 18870afe0b8SMarcel Holtmann return 0; 18970afe0b8SMarcel Holtmann } 19070afe0b8SMarcel Holtmann 19170afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file) 19270afe0b8SMarcel Holtmann { 19370afe0b8SMarcel Holtmann return single_open(file, blacklist_show, inode->i_private); 19470afe0b8SMarcel Holtmann } 19570afe0b8SMarcel Holtmann 19670afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = { 19770afe0b8SMarcel Holtmann .open = blacklist_open, 19870afe0b8SMarcel Holtmann .read = seq_read, 19970afe0b8SMarcel Holtmann .llseek = seq_lseek, 20070afe0b8SMarcel Holtmann .release = single_release, 20170afe0b8SMarcel Holtmann }; 20270afe0b8SMarcel Holtmann 20347219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p) 20447219839SMarcel Holtmann { 20547219839SMarcel Holtmann struct hci_dev *hdev = f->private; 20647219839SMarcel Holtmann struct bt_uuid *uuid; 20747219839SMarcel Holtmann 20847219839SMarcel Holtmann hci_dev_lock(hdev); 20947219839SMarcel Holtmann list_for_each_entry(uuid, &hdev->uuids, list) { 21058f01aa9SMarcel Holtmann u8 i, val[16]; 21147219839SMarcel Holtmann 21258f01aa9SMarcel Holtmann /* The Bluetooth UUID values are stored in big endian, 21358f01aa9SMarcel Holtmann * but with reversed byte order. So convert them into 21458f01aa9SMarcel Holtmann * the right order for the %pUb modifier. 21558f01aa9SMarcel Holtmann */ 21658f01aa9SMarcel Holtmann for (i = 0; i < 16; i++) 21758f01aa9SMarcel Holtmann val[i] = uuid->uuid[15 - i]; 21847219839SMarcel Holtmann 21958f01aa9SMarcel Holtmann seq_printf(f, "%pUb\n", val); 22047219839SMarcel Holtmann } 22147219839SMarcel Holtmann hci_dev_unlock(hdev); 22247219839SMarcel Holtmann 22347219839SMarcel Holtmann return 0; 22447219839SMarcel Holtmann } 22547219839SMarcel Holtmann 22647219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file) 22747219839SMarcel Holtmann { 22847219839SMarcel Holtmann return single_open(file, uuids_show, inode->i_private); 22947219839SMarcel Holtmann } 23047219839SMarcel Holtmann 23147219839SMarcel Holtmann static const struct file_operations uuids_fops = { 23247219839SMarcel Holtmann .open = uuids_open, 23347219839SMarcel Holtmann .read = seq_read, 23447219839SMarcel Holtmann .llseek = seq_lseek, 23547219839SMarcel Holtmann .release = single_release, 23647219839SMarcel Holtmann }; 23747219839SMarcel Holtmann 238baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p) 239baf27f6eSMarcel Holtmann { 240baf27f6eSMarcel Holtmann struct hci_dev *hdev = f->private; 241baf27f6eSMarcel Holtmann struct discovery_state *cache = &hdev->discovery; 242baf27f6eSMarcel Holtmann struct inquiry_entry *e; 243baf27f6eSMarcel Holtmann 244baf27f6eSMarcel Holtmann hci_dev_lock(hdev); 245baf27f6eSMarcel Holtmann 246baf27f6eSMarcel Holtmann list_for_each_entry(e, &cache->all, all) { 247baf27f6eSMarcel Holtmann struct inquiry_data *data = &e->data; 248baf27f6eSMarcel Holtmann seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", 249baf27f6eSMarcel Holtmann &data->bdaddr, 250baf27f6eSMarcel Holtmann data->pscan_rep_mode, data->pscan_period_mode, 251baf27f6eSMarcel Holtmann data->pscan_mode, data->dev_class[2], 252baf27f6eSMarcel Holtmann data->dev_class[1], data->dev_class[0], 253baf27f6eSMarcel Holtmann __le16_to_cpu(data->clock_offset), 254baf27f6eSMarcel Holtmann data->rssi, data->ssp_mode, e->timestamp); 255baf27f6eSMarcel Holtmann } 256baf27f6eSMarcel Holtmann 257baf27f6eSMarcel Holtmann hci_dev_unlock(hdev); 258baf27f6eSMarcel Holtmann 259baf27f6eSMarcel Holtmann return 0; 260baf27f6eSMarcel Holtmann } 261baf27f6eSMarcel Holtmann 262baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file) 263baf27f6eSMarcel Holtmann { 264baf27f6eSMarcel Holtmann return single_open(file, inquiry_cache_show, inode->i_private); 265baf27f6eSMarcel Holtmann } 266baf27f6eSMarcel Holtmann 267baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = { 268baf27f6eSMarcel Holtmann .open = inquiry_cache_open, 269baf27f6eSMarcel Holtmann .read = seq_read, 270baf27f6eSMarcel Holtmann .llseek = seq_lseek, 271baf27f6eSMarcel Holtmann .release = single_release, 272baf27f6eSMarcel Holtmann }; 273baf27f6eSMarcel Holtmann 27402d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr) 27502d08d15SMarcel Holtmann { 27602d08d15SMarcel Holtmann struct hci_dev *hdev = f->private; 2770378b597SJohan Hedberg struct link_key *key; 27802d08d15SMarcel Holtmann 2790378b597SJohan Hedberg rcu_read_lock(); 2800378b597SJohan Hedberg list_for_each_entry_rcu(key, &hdev->link_keys, list) 28102d08d15SMarcel Holtmann seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type, 28202d08d15SMarcel Holtmann HCI_LINK_KEY_SIZE, key->val, key->pin_len); 2830378b597SJohan Hedberg rcu_read_unlock(); 28402d08d15SMarcel Holtmann 28502d08d15SMarcel Holtmann return 0; 28602d08d15SMarcel Holtmann } 28702d08d15SMarcel Holtmann 28802d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file) 28902d08d15SMarcel Holtmann { 29002d08d15SMarcel Holtmann return single_open(file, link_keys_show, inode->i_private); 29102d08d15SMarcel Holtmann } 29202d08d15SMarcel Holtmann 29302d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = { 29402d08d15SMarcel Holtmann .open = link_keys_open, 29502d08d15SMarcel Holtmann .read = seq_read, 29602d08d15SMarcel Holtmann .llseek = seq_lseek, 29702d08d15SMarcel Holtmann .release = single_release, 29802d08d15SMarcel Holtmann }; 29902d08d15SMarcel Holtmann 300babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr) 301babdbb3cSMarcel Holtmann { 302babdbb3cSMarcel Holtmann struct hci_dev *hdev = f->private; 303babdbb3cSMarcel Holtmann 304babdbb3cSMarcel Holtmann hci_dev_lock(hdev); 305babdbb3cSMarcel Holtmann seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], 306babdbb3cSMarcel Holtmann hdev->dev_class[1], hdev->dev_class[0]); 307babdbb3cSMarcel Holtmann hci_dev_unlock(hdev); 308babdbb3cSMarcel Holtmann 309babdbb3cSMarcel Holtmann return 0; 310babdbb3cSMarcel Holtmann } 311babdbb3cSMarcel Holtmann 312babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file) 313babdbb3cSMarcel Holtmann { 314babdbb3cSMarcel Holtmann return single_open(file, dev_class_show, inode->i_private); 315babdbb3cSMarcel Holtmann } 316babdbb3cSMarcel Holtmann 317babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = { 318babdbb3cSMarcel Holtmann .open = dev_class_open, 319babdbb3cSMarcel Holtmann .read = seq_read, 320babdbb3cSMarcel Holtmann .llseek = seq_lseek, 321babdbb3cSMarcel Holtmann .release = single_release, 322babdbb3cSMarcel Holtmann }; 323babdbb3cSMarcel Holtmann 324041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val) 325041000b9SMarcel Holtmann { 326041000b9SMarcel Holtmann struct hci_dev *hdev = data; 327041000b9SMarcel Holtmann 328041000b9SMarcel Holtmann hci_dev_lock(hdev); 329041000b9SMarcel Holtmann *val = hdev->voice_setting; 330041000b9SMarcel Holtmann hci_dev_unlock(hdev); 331041000b9SMarcel Holtmann 332041000b9SMarcel Holtmann return 0; 333041000b9SMarcel Holtmann } 334041000b9SMarcel Holtmann 335041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get, 336041000b9SMarcel Holtmann NULL, "0x%4.4llx\n"); 337041000b9SMarcel Holtmann 338ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val) 339ebd1e33bSMarcel Holtmann { 340ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 341ebd1e33bSMarcel Holtmann 342ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 343ebd1e33bSMarcel Holtmann hdev->auto_accept_delay = val; 344ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 345ebd1e33bSMarcel Holtmann 346ebd1e33bSMarcel Holtmann return 0; 347ebd1e33bSMarcel Holtmann } 348ebd1e33bSMarcel Holtmann 349ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val) 350ebd1e33bSMarcel Holtmann { 351ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 352ebd1e33bSMarcel Holtmann 353ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 354ebd1e33bSMarcel Holtmann *val = hdev->auto_accept_delay; 355ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 356ebd1e33bSMarcel Holtmann 357ebd1e33bSMarcel Holtmann return 0; 358ebd1e33bSMarcel Holtmann } 359ebd1e33bSMarcel Holtmann 360ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, 361ebd1e33bSMarcel Holtmann auto_accept_delay_set, "%llu\n"); 362ebd1e33bSMarcel Holtmann 3635afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf, 3645afeac14SMarcel Holtmann size_t count, loff_t *ppos) 3655afeac14SMarcel Holtmann { 3665afeac14SMarcel Holtmann struct hci_dev *hdev = file->private_data; 3675afeac14SMarcel Holtmann char buf[3]; 3685afeac14SMarcel Holtmann 369111902f7SMarcel Holtmann buf[0] = test_bit(HCI_FORCE_SC, &hdev->dbg_flags) ? 'Y': 'N'; 3705afeac14SMarcel Holtmann buf[1] = '\n'; 3715afeac14SMarcel Holtmann buf[2] = '\0'; 3725afeac14SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 3735afeac14SMarcel Holtmann } 3745afeac14SMarcel Holtmann 3755afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file, 3765afeac14SMarcel Holtmann const char __user *user_buf, 3775afeac14SMarcel Holtmann size_t count, loff_t *ppos) 3785afeac14SMarcel Holtmann { 3795afeac14SMarcel Holtmann struct hci_dev *hdev = file->private_data; 3805afeac14SMarcel Holtmann char buf[32]; 3815afeac14SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 3825afeac14SMarcel Holtmann bool enable; 3835afeac14SMarcel Holtmann 3845afeac14SMarcel Holtmann if (test_bit(HCI_UP, &hdev->flags)) 3855afeac14SMarcel Holtmann return -EBUSY; 3865afeac14SMarcel Holtmann 3875afeac14SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 3885afeac14SMarcel Holtmann return -EFAULT; 3895afeac14SMarcel Holtmann 3905afeac14SMarcel Holtmann buf[buf_size] = '\0'; 3915afeac14SMarcel Holtmann if (strtobool(buf, &enable)) 3925afeac14SMarcel Holtmann return -EINVAL; 3935afeac14SMarcel Holtmann 394111902f7SMarcel Holtmann if (enable == test_bit(HCI_FORCE_SC, &hdev->dbg_flags)) 3955afeac14SMarcel Holtmann return -EALREADY; 3965afeac14SMarcel Holtmann 397111902f7SMarcel Holtmann change_bit(HCI_FORCE_SC, &hdev->dbg_flags); 3985afeac14SMarcel Holtmann 3995afeac14SMarcel Holtmann return count; 4005afeac14SMarcel Holtmann } 4015afeac14SMarcel Holtmann 4025afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = { 4035afeac14SMarcel Holtmann .open = simple_open, 4045afeac14SMarcel Holtmann .read = force_sc_support_read, 4055afeac14SMarcel Holtmann .write = force_sc_support_write, 4065afeac14SMarcel Holtmann .llseek = default_llseek, 4075afeac14SMarcel Holtmann }; 4085afeac14SMarcel Holtmann 409858cdc78SJohan Hedberg static ssize_t force_lesc_support_read(struct file *file, char __user *user_buf, 410858cdc78SJohan Hedberg size_t count, loff_t *ppos) 411858cdc78SJohan Hedberg { 412858cdc78SJohan Hedberg struct hci_dev *hdev = file->private_data; 413858cdc78SJohan Hedberg char buf[3]; 414858cdc78SJohan Hedberg 415858cdc78SJohan Hedberg buf[0] = test_bit(HCI_FORCE_LESC, &hdev->dbg_flags) ? 'Y': 'N'; 416858cdc78SJohan Hedberg buf[1] = '\n'; 417858cdc78SJohan Hedberg buf[2] = '\0'; 418858cdc78SJohan Hedberg return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 419858cdc78SJohan Hedberg } 420858cdc78SJohan Hedberg 421858cdc78SJohan Hedberg static ssize_t force_lesc_support_write(struct file *file, 422858cdc78SJohan Hedberg const char __user *user_buf, 423858cdc78SJohan Hedberg size_t count, loff_t *ppos) 424858cdc78SJohan Hedberg { 425858cdc78SJohan Hedberg struct hci_dev *hdev = file->private_data; 426858cdc78SJohan Hedberg char buf[32]; 427858cdc78SJohan Hedberg size_t buf_size = min(count, (sizeof(buf)-1)); 428858cdc78SJohan Hedberg bool enable; 429858cdc78SJohan Hedberg 430858cdc78SJohan Hedberg if (copy_from_user(buf, user_buf, buf_size)) 431858cdc78SJohan Hedberg return -EFAULT; 432858cdc78SJohan Hedberg 433858cdc78SJohan Hedberg buf[buf_size] = '\0'; 434858cdc78SJohan Hedberg if (strtobool(buf, &enable)) 435858cdc78SJohan Hedberg return -EINVAL; 436858cdc78SJohan Hedberg 437858cdc78SJohan Hedberg if (enable == test_bit(HCI_FORCE_LESC, &hdev->dbg_flags)) 438858cdc78SJohan Hedberg return -EALREADY; 439858cdc78SJohan Hedberg 440858cdc78SJohan Hedberg change_bit(HCI_FORCE_LESC, &hdev->dbg_flags); 441858cdc78SJohan Hedberg 442858cdc78SJohan Hedberg return count; 443858cdc78SJohan Hedberg } 444858cdc78SJohan Hedberg 445858cdc78SJohan Hedberg static const struct file_operations force_lesc_support_fops = { 446858cdc78SJohan Hedberg .open = simple_open, 447858cdc78SJohan Hedberg .read = force_lesc_support_read, 448858cdc78SJohan Hedberg .write = force_lesc_support_write, 449858cdc78SJohan Hedberg .llseek = default_llseek, 450858cdc78SJohan Hedberg }; 451858cdc78SJohan Hedberg 452134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf, 453134c2a89SMarcel Holtmann size_t count, loff_t *ppos) 454134c2a89SMarcel Holtmann { 455134c2a89SMarcel Holtmann struct hci_dev *hdev = file->private_data; 456134c2a89SMarcel Holtmann char buf[3]; 457134c2a89SMarcel Holtmann 458134c2a89SMarcel Holtmann buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N'; 459134c2a89SMarcel Holtmann buf[1] = '\n'; 460134c2a89SMarcel Holtmann buf[2] = '\0'; 461134c2a89SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 462134c2a89SMarcel Holtmann } 463134c2a89SMarcel Holtmann 464134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = { 465134c2a89SMarcel Holtmann .open = simple_open, 466134c2a89SMarcel Holtmann .read = sc_only_mode_read, 467134c2a89SMarcel Holtmann .llseek = default_llseek, 468134c2a89SMarcel Holtmann }; 469134c2a89SMarcel Holtmann 4702bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val) 4712bfa3531SMarcel Holtmann { 4722bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4732bfa3531SMarcel Holtmann 4742bfa3531SMarcel Holtmann if (val != 0 && (val < 500 || val > 3600000)) 4752bfa3531SMarcel Holtmann return -EINVAL; 4762bfa3531SMarcel Holtmann 4772bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4782bfa3531SMarcel Holtmann hdev->idle_timeout = val; 4792bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4802bfa3531SMarcel Holtmann 4812bfa3531SMarcel Holtmann return 0; 4822bfa3531SMarcel Holtmann } 4832bfa3531SMarcel Holtmann 4842bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val) 4852bfa3531SMarcel Holtmann { 4862bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4872bfa3531SMarcel Holtmann 4882bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4892bfa3531SMarcel Holtmann *val = hdev->idle_timeout; 4902bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4912bfa3531SMarcel Holtmann 4922bfa3531SMarcel Holtmann return 0; 4932bfa3531SMarcel Holtmann } 4942bfa3531SMarcel Holtmann 4952bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get, 4962bfa3531SMarcel Holtmann idle_timeout_set, "%llu\n"); 4972bfa3531SMarcel Holtmann 498c982b2eaSJohan Hedberg static int rpa_timeout_set(void *data, u64 val) 499c982b2eaSJohan Hedberg { 500c982b2eaSJohan Hedberg struct hci_dev *hdev = data; 501c982b2eaSJohan Hedberg 502c982b2eaSJohan Hedberg /* Require the RPA timeout to be at least 30 seconds and at most 503c982b2eaSJohan Hedberg * 24 hours. 504c982b2eaSJohan Hedberg */ 505c982b2eaSJohan Hedberg if (val < 30 || val > (60 * 60 * 24)) 506c982b2eaSJohan Hedberg return -EINVAL; 507c982b2eaSJohan Hedberg 508c982b2eaSJohan Hedberg hci_dev_lock(hdev); 509c982b2eaSJohan Hedberg hdev->rpa_timeout = val; 510c982b2eaSJohan Hedberg hci_dev_unlock(hdev); 511c982b2eaSJohan Hedberg 512c982b2eaSJohan Hedberg return 0; 513c982b2eaSJohan Hedberg } 514c982b2eaSJohan Hedberg 515c982b2eaSJohan Hedberg static int rpa_timeout_get(void *data, u64 *val) 516c982b2eaSJohan Hedberg { 517c982b2eaSJohan Hedberg struct hci_dev *hdev = data; 518c982b2eaSJohan Hedberg 519c982b2eaSJohan Hedberg hci_dev_lock(hdev); 520c982b2eaSJohan Hedberg *val = hdev->rpa_timeout; 521c982b2eaSJohan Hedberg hci_dev_unlock(hdev); 522c982b2eaSJohan Hedberg 523c982b2eaSJohan Hedberg return 0; 524c982b2eaSJohan Hedberg } 525c982b2eaSJohan Hedberg 526c982b2eaSJohan Hedberg DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get, 527c982b2eaSJohan Hedberg rpa_timeout_set, "%llu\n"); 528c982b2eaSJohan Hedberg 5292bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val) 5302bfa3531SMarcel Holtmann { 5312bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5322bfa3531SMarcel Holtmann 5332bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val > hdev->sniff_max_interval) 5342bfa3531SMarcel Holtmann return -EINVAL; 5352bfa3531SMarcel Holtmann 5362bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5372bfa3531SMarcel Holtmann hdev->sniff_min_interval = val; 5382bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5392bfa3531SMarcel Holtmann 5402bfa3531SMarcel Holtmann return 0; 5412bfa3531SMarcel Holtmann } 5422bfa3531SMarcel Holtmann 5432bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val) 5442bfa3531SMarcel Holtmann { 5452bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5462bfa3531SMarcel Holtmann 5472bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5482bfa3531SMarcel Holtmann *val = hdev->sniff_min_interval; 5492bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5502bfa3531SMarcel Holtmann 5512bfa3531SMarcel Holtmann return 0; 5522bfa3531SMarcel Holtmann } 5532bfa3531SMarcel Holtmann 5542bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get, 5552bfa3531SMarcel Holtmann sniff_min_interval_set, "%llu\n"); 5562bfa3531SMarcel Holtmann 5572bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val) 5582bfa3531SMarcel Holtmann { 5592bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5602bfa3531SMarcel Holtmann 5612bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val < hdev->sniff_min_interval) 5622bfa3531SMarcel Holtmann return -EINVAL; 5632bfa3531SMarcel Holtmann 5642bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5652bfa3531SMarcel Holtmann hdev->sniff_max_interval = val; 5662bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5672bfa3531SMarcel Holtmann 5682bfa3531SMarcel Holtmann return 0; 5692bfa3531SMarcel Holtmann } 5702bfa3531SMarcel Holtmann 5712bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val) 5722bfa3531SMarcel Holtmann { 5732bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 5742bfa3531SMarcel Holtmann 5752bfa3531SMarcel Holtmann hci_dev_lock(hdev); 5762bfa3531SMarcel Holtmann *val = hdev->sniff_max_interval; 5772bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 5782bfa3531SMarcel Holtmann 5792bfa3531SMarcel Holtmann return 0; 5802bfa3531SMarcel Holtmann } 5812bfa3531SMarcel Holtmann 5822bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, 5832bfa3531SMarcel Holtmann sniff_max_interval_set, "%llu\n"); 5842bfa3531SMarcel Holtmann 58531ad1691SAndrzej Kaczmarek static int conn_info_min_age_set(void *data, u64 val) 58631ad1691SAndrzej Kaczmarek { 58731ad1691SAndrzej Kaczmarek struct hci_dev *hdev = data; 58831ad1691SAndrzej Kaczmarek 58931ad1691SAndrzej Kaczmarek if (val == 0 || val > hdev->conn_info_max_age) 59031ad1691SAndrzej Kaczmarek return -EINVAL; 59131ad1691SAndrzej Kaczmarek 59231ad1691SAndrzej Kaczmarek hci_dev_lock(hdev); 59331ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = val; 59431ad1691SAndrzej Kaczmarek hci_dev_unlock(hdev); 59531ad1691SAndrzej Kaczmarek 59631ad1691SAndrzej Kaczmarek return 0; 59731ad1691SAndrzej Kaczmarek } 59831ad1691SAndrzej Kaczmarek 59931ad1691SAndrzej Kaczmarek static int conn_info_min_age_get(void *data, u64 *val) 60031ad1691SAndrzej Kaczmarek { 60131ad1691SAndrzej Kaczmarek struct hci_dev *hdev = data; 60231ad1691SAndrzej Kaczmarek 60331ad1691SAndrzej Kaczmarek hci_dev_lock(hdev); 60431ad1691SAndrzej Kaczmarek *val = hdev->conn_info_min_age; 60531ad1691SAndrzej Kaczmarek hci_dev_unlock(hdev); 60631ad1691SAndrzej Kaczmarek 60731ad1691SAndrzej Kaczmarek return 0; 60831ad1691SAndrzej Kaczmarek } 60931ad1691SAndrzej Kaczmarek 61031ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_min_age_fops, conn_info_min_age_get, 61131ad1691SAndrzej Kaczmarek conn_info_min_age_set, "%llu\n"); 61231ad1691SAndrzej Kaczmarek 61331ad1691SAndrzej Kaczmarek static int conn_info_max_age_set(void *data, u64 val) 61431ad1691SAndrzej Kaczmarek { 61531ad1691SAndrzej Kaczmarek struct hci_dev *hdev = data; 61631ad1691SAndrzej Kaczmarek 61731ad1691SAndrzej Kaczmarek if (val == 0 || val < hdev->conn_info_min_age) 61831ad1691SAndrzej Kaczmarek return -EINVAL; 61931ad1691SAndrzej Kaczmarek 62031ad1691SAndrzej Kaczmarek hci_dev_lock(hdev); 62131ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = val; 62231ad1691SAndrzej Kaczmarek hci_dev_unlock(hdev); 62331ad1691SAndrzej Kaczmarek 62431ad1691SAndrzej Kaczmarek return 0; 62531ad1691SAndrzej Kaczmarek } 62631ad1691SAndrzej Kaczmarek 62731ad1691SAndrzej Kaczmarek static int conn_info_max_age_get(void *data, u64 *val) 62831ad1691SAndrzej Kaczmarek { 62931ad1691SAndrzej Kaczmarek struct hci_dev *hdev = data; 63031ad1691SAndrzej Kaczmarek 63131ad1691SAndrzej Kaczmarek hci_dev_lock(hdev); 63231ad1691SAndrzej Kaczmarek *val = hdev->conn_info_max_age; 63331ad1691SAndrzej Kaczmarek hci_dev_unlock(hdev); 63431ad1691SAndrzej Kaczmarek 63531ad1691SAndrzej Kaczmarek return 0; 63631ad1691SAndrzej Kaczmarek } 63731ad1691SAndrzej Kaczmarek 63831ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get, 63931ad1691SAndrzej Kaczmarek conn_info_max_age_set, "%llu\n"); 64031ad1691SAndrzej Kaczmarek 641ac345813SMarcel Holtmann static int identity_show(struct seq_file *f, void *p) 642ac345813SMarcel Holtmann { 643ac345813SMarcel Holtmann struct hci_dev *hdev = f->private; 644a1f4c318SJohan Hedberg bdaddr_t addr; 645ac345813SMarcel Holtmann u8 addr_type; 646ac345813SMarcel Holtmann 647ac345813SMarcel Holtmann hci_dev_lock(hdev); 648ac345813SMarcel Holtmann 649a1f4c318SJohan Hedberg hci_copy_identity_address(hdev, &addr, &addr_type); 650ac345813SMarcel Holtmann 651a1f4c318SJohan Hedberg seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type, 652473deef2SMarcel Holtmann 16, hdev->irk, &hdev->rpa); 653ac345813SMarcel Holtmann 654ac345813SMarcel Holtmann hci_dev_unlock(hdev); 655ac345813SMarcel Holtmann 656ac345813SMarcel Holtmann return 0; 657ac345813SMarcel Holtmann } 658ac345813SMarcel Holtmann 659ac345813SMarcel Holtmann static int identity_open(struct inode *inode, struct file *file) 660ac345813SMarcel Holtmann { 661ac345813SMarcel Holtmann return single_open(file, identity_show, inode->i_private); 662ac345813SMarcel Holtmann } 663ac345813SMarcel Holtmann 664ac345813SMarcel Holtmann static const struct file_operations identity_fops = { 665ac345813SMarcel Holtmann .open = identity_open, 666ac345813SMarcel Holtmann .read = seq_read, 667ac345813SMarcel Holtmann .llseek = seq_lseek, 668ac345813SMarcel Holtmann .release = single_release, 669ac345813SMarcel Holtmann }; 670ac345813SMarcel Holtmann 6717a4cd51dSMarcel Holtmann static int random_address_show(struct seq_file *f, void *p) 6727a4cd51dSMarcel Holtmann { 6737a4cd51dSMarcel Holtmann struct hci_dev *hdev = f->private; 6747a4cd51dSMarcel Holtmann 6757a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 6767a4cd51dSMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->random_addr); 6777a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 6787a4cd51dSMarcel Holtmann 6797a4cd51dSMarcel Holtmann return 0; 6807a4cd51dSMarcel Holtmann } 6817a4cd51dSMarcel Holtmann 6827a4cd51dSMarcel Holtmann static int random_address_open(struct inode *inode, struct file *file) 6837a4cd51dSMarcel Holtmann { 6847a4cd51dSMarcel Holtmann return single_open(file, random_address_show, inode->i_private); 6857a4cd51dSMarcel Holtmann } 6867a4cd51dSMarcel Holtmann 6877a4cd51dSMarcel Holtmann static const struct file_operations random_address_fops = { 6887a4cd51dSMarcel Holtmann .open = random_address_open, 6897a4cd51dSMarcel Holtmann .read = seq_read, 6907a4cd51dSMarcel Holtmann .llseek = seq_lseek, 6917a4cd51dSMarcel Holtmann .release = single_release, 6927a4cd51dSMarcel Holtmann }; 6937a4cd51dSMarcel Holtmann 694e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p) 695e7b8fc92SMarcel Holtmann { 696e7b8fc92SMarcel Holtmann struct hci_dev *hdev = f->private; 697e7b8fc92SMarcel Holtmann 698e7b8fc92SMarcel Holtmann hci_dev_lock(hdev); 699e7b8fc92SMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->static_addr); 700e7b8fc92SMarcel Holtmann hci_dev_unlock(hdev); 701e7b8fc92SMarcel Holtmann 702e7b8fc92SMarcel Holtmann return 0; 703e7b8fc92SMarcel Holtmann } 704e7b8fc92SMarcel Holtmann 705e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file) 706e7b8fc92SMarcel Holtmann { 707e7b8fc92SMarcel Holtmann return single_open(file, static_address_show, inode->i_private); 708e7b8fc92SMarcel Holtmann } 709e7b8fc92SMarcel Holtmann 710e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = { 711e7b8fc92SMarcel Holtmann .open = static_address_open, 712e7b8fc92SMarcel Holtmann .read = seq_read, 713e7b8fc92SMarcel Holtmann .llseek = seq_lseek, 714e7b8fc92SMarcel Holtmann .release = single_release, 715e7b8fc92SMarcel Holtmann }; 716e7b8fc92SMarcel Holtmann 717b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file, 718b32bba6cSMarcel Holtmann char __user *user_buf, 719b32bba6cSMarcel Holtmann size_t count, loff_t *ppos) 72092202185SMarcel Holtmann { 721b32bba6cSMarcel Holtmann struct hci_dev *hdev = file->private_data; 722b32bba6cSMarcel Holtmann char buf[3]; 72392202185SMarcel Holtmann 724111902f7SMarcel Holtmann buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N'; 725b32bba6cSMarcel Holtmann buf[1] = '\n'; 726b32bba6cSMarcel Holtmann buf[2] = '\0'; 727b32bba6cSMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 728b32bba6cSMarcel Holtmann } 729b32bba6cSMarcel Holtmann 730b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file, 731b32bba6cSMarcel Holtmann const char __user *user_buf, 732b32bba6cSMarcel Holtmann size_t count, loff_t *ppos) 733b32bba6cSMarcel Holtmann { 734b32bba6cSMarcel Holtmann struct hci_dev *hdev = file->private_data; 735b32bba6cSMarcel Holtmann char buf[32]; 736b32bba6cSMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 737b32bba6cSMarcel Holtmann bool enable; 738b32bba6cSMarcel Holtmann 739b32bba6cSMarcel Holtmann if (test_bit(HCI_UP, &hdev->flags)) 740b32bba6cSMarcel Holtmann return -EBUSY; 741b32bba6cSMarcel Holtmann 742b32bba6cSMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 743b32bba6cSMarcel Holtmann return -EFAULT; 744b32bba6cSMarcel Holtmann 745b32bba6cSMarcel Holtmann buf[buf_size] = '\0'; 746b32bba6cSMarcel Holtmann if (strtobool(buf, &enable)) 74792202185SMarcel Holtmann return -EINVAL; 74892202185SMarcel Holtmann 749111902f7SMarcel Holtmann if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags)) 750b32bba6cSMarcel Holtmann return -EALREADY; 75192202185SMarcel Holtmann 752111902f7SMarcel Holtmann change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags); 753b32bba6cSMarcel Holtmann 754b32bba6cSMarcel Holtmann return count; 75592202185SMarcel Holtmann } 75692202185SMarcel Holtmann 757b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = { 758b32bba6cSMarcel Holtmann .open = simple_open, 759b32bba6cSMarcel Holtmann .read = force_static_address_read, 760b32bba6cSMarcel Holtmann .write = force_static_address_write, 761b32bba6cSMarcel Holtmann .llseek = default_llseek, 762b32bba6cSMarcel Holtmann }; 76392202185SMarcel Holtmann 764d2ab0ac1SMarcel Holtmann static int white_list_show(struct seq_file *f, void *ptr) 765d2ab0ac1SMarcel Holtmann { 766d2ab0ac1SMarcel Holtmann struct hci_dev *hdev = f->private; 767d2ab0ac1SMarcel Holtmann struct bdaddr_list *b; 768d2ab0ac1SMarcel Holtmann 769d2ab0ac1SMarcel Holtmann hci_dev_lock(hdev); 770d2ab0ac1SMarcel Holtmann list_for_each_entry(b, &hdev->le_white_list, list) 771d2ab0ac1SMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 772d2ab0ac1SMarcel Holtmann hci_dev_unlock(hdev); 773d2ab0ac1SMarcel Holtmann 774d2ab0ac1SMarcel Holtmann return 0; 775d2ab0ac1SMarcel Holtmann } 776d2ab0ac1SMarcel Holtmann 777d2ab0ac1SMarcel Holtmann static int white_list_open(struct inode *inode, struct file *file) 778d2ab0ac1SMarcel Holtmann { 779d2ab0ac1SMarcel Holtmann return single_open(file, white_list_show, inode->i_private); 780d2ab0ac1SMarcel Holtmann } 781d2ab0ac1SMarcel Holtmann 782d2ab0ac1SMarcel Holtmann static const struct file_operations white_list_fops = { 783d2ab0ac1SMarcel Holtmann .open = white_list_open, 784d2ab0ac1SMarcel Holtmann .read = seq_read, 785d2ab0ac1SMarcel Holtmann .llseek = seq_lseek, 786d2ab0ac1SMarcel Holtmann .release = single_release, 787d2ab0ac1SMarcel Holtmann }; 788d2ab0ac1SMarcel Holtmann 7893698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr) 7903698d704SMarcel Holtmann { 7913698d704SMarcel Holtmann struct hci_dev *hdev = f->private; 792adae20cbSJohan Hedberg struct smp_irk *irk; 7933698d704SMarcel Holtmann 794adae20cbSJohan Hedberg rcu_read_lock(); 795adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 7963698d704SMarcel Holtmann seq_printf(f, "%pMR (type %u) %*phN %pMR\n", 7973698d704SMarcel Holtmann &irk->bdaddr, irk->addr_type, 7983698d704SMarcel Holtmann 16, irk->val, &irk->rpa); 7993698d704SMarcel Holtmann } 800adae20cbSJohan Hedberg rcu_read_unlock(); 8013698d704SMarcel Holtmann 8023698d704SMarcel Holtmann return 0; 8033698d704SMarcel Holtmann } 8043698d704SMarcel Holtmann 8053698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file) 8063698d704SMarcel Holtmann { 8073698d704SMarcel Holtmann return single_open(file, identity_resolving_keys_show, 8083698d704SMarcel Holtmann inode->i_private); 8093698d704SMarcel Holtmann } 8103698d704SMarcel Holtmann 8113698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = { 8123698d704SMarcel Holtmann .open = identity_resolving_keys_open, 8133698d704SMarcel Holtmann .read = seq_read, 8143698d704SMarcel Holtmann .llseek = seq_lseek, 8153698d704SMarcel Holtmann .release = single_release, 8163698d704SMarcel Holtmann }; 8173698d704SMarcel Holtmann 8188f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr) 8198f8625cdSMarcel Holtmann { 8208f8625cdSMarcel Holtmann struct hci_dev *hdev = f->private; 821970d0f1bSJohan Hedberg struct smp_ltk *ltk; 8228f8625cdSMarcel Holtmann 823970d0f1bSJohan Hedberg rcu_read_lock(); 824970d0f1bSJohan Hedberg list_for_each_entry_rcu(ltk, &hdev->long_term_keys, list) 825fe39c7b2SMarcel Holtmann seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n", 8268f8625cdSMarcel Holtmann <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, 8278f8625cdSMarcel Holtmann ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), 828fe39c7b2SMarcel Holtmann __le64_to_cpu(ltk->rand), 16, ltk->val); 829970d0f1bSJohan Hedberg rcu_read_unlock(); 8308f8625cdSMarcel Holtmann 8318f8625cdSMarcel Holtmann return 0; 8328f8625cdSMarcel Holtmann } 8338f8625cdSMarcel Holtmann 8348f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file) 8358f8625cdSMarcel Holtmann { 8368f8625cdSMarcel Holtmann return single_open(file, long_term_keys_show, inode->i_private); 8378f8625cdSMarcel Holtmann } 8388f8625cdSMarcel Holtmann 8398f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = { 8408f8625cdSMarcel Holtmann .open = long_term_keys_open, 8418f8625cdSMarcel Holtmann .read = seq_read, 8428f8625cdSMarcel Holtmann .llseek = seq_lseek, 8438f8625cdSMarcel Holtmann .release = single_release, 8448f8625cdSMarcel Holtmann }; 8458f8625cdSMarcel Holtmann 8464e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val) 8474e70c7e7SMarcel Holtmann { 8484e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 8494e70c7e7SMarcel Holtmann 8504e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval) 8514e70c7e7SMarcel Holtmann return -EINVAL; 8524e70c7e7SMarcel Holtmann 8534e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 8544e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = val; 8554e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8564e70c7e7SMarcel Holtmann 8574e70c7e7SMarcel Holtmann return 0; 8584e70c7e7SMarcel Holtmann } 8594e70c7e7SMarcel Holtmann 8604e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val) 8614e70c7e7SMarcel Holtmann { 8624e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 8634e70c7e7SMarcel Holtmann 8644e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 8654e70c7e7SMarcel Holtmann *val = hdev->le_conn_min_interval; 8664e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8674e70c7e7SMarcel Holtmann 8684e70c7e7SMarcel Holtmann return 0; 8694e70c7e7SMarcel Holtmann } 8704e70c7e7SMarcel Holtmann 8714e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get, 8724e70c7e7SMarcel Holtmann conn_min_interval_set, "%llu\n"); 8734e70c7e7SMarcel Holtmann 8744e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val) 8754e70c7e7SMarcel Holtmann { 8764e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 8774e70c7e7SMarcel Holtmann 8784e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval) 8794e70c7e7SMarcel Holtmann return -EINVAL; 8804e70c7e7SMarcel Holtmann 8814e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 8824e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = val; 8834e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8844e70c7e7SMarcel Holtmann 8854e70c7e7SMarcel Holtmann return 0; 8864e70c7e7SMarcel Holtmann } 8874e70c7e7SMarcel Holtmann 8884e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val) 8894e70c7e7SMarcel Holtmann { 8904e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 8914e70c7e7SMarcel Holtmann 8924e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 8934e70c7e7SMarcel Holtmann *val = hdev->le_conn_max_interval; 8944e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 8954e70c7e7SMarcel Holtmann 8964e70c7e7SMarcel Holtmann return 0; 8974e70c7e7SMarcel Holtmann } 8984e70c7e7SMarcel Holtmann 8994e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, 9004e70c7e7SMarcel Holtmann conn_max_interval_set, "%llu\n"); 9014e70c7e7SMarcel Holtmann 902816a93d1SMarcel Holtmann static int conn_latency_set(void *data, u64 val) 903816a93d1SMarcel Holtmann { 904816a93d1SMarcel Holtmann struct hci_dev *hdev = data; 905816a93d1SMarcel Holtmann 906816a93d1SMarcel Holtmann if (val > 0x01f3) 907816a93d1SMarcel Holtmann return -EINVAL; 908816a93d1SMarcel Holtmann 909816a93d1SMarcel Holtmann hci_dev_lock(hdev); 910816a93d1SMarcel Holtmann hdev->le_conn_latency = val; 911816a93d1SMarcel Holtmann hci_dev_unlock(hdev); 912816a93d1SMarcel Holtmann 913816a93d1SMarcel Holtmann return 0; 914816a93d1SMarcel Holtmann } 915816a93d1SMarcel Holtmann 916816a93d1SMarcel Holtmann static int conn_latency_get(void *data, u64 *val) 917816a93d1SMarcel Holtmann { 918816a93d1SMarcel Holtmann struct hci_dev *hdev = data; 919816a93d1SMarcel Holtmann 920816a93d1SMarcel Holtmann hci_dev_lock(hdev); 921816a93d1SMarcel Holtmann *val = hdev->le_conn_latency; 922816a93d1SMarcel Holtmann hci_dev_unlock(hdev); 923816a93d1SMarcel Holtmann 924816a93d1SMarcel Holtmann return 0; 925816a93d1SMarcel Holtmann } 926816a93d1SMarcel Holtmann 927816a93d1SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get, 928816a93d1SMarcel Holtmann conn_latency_set, "%llu\n"); 929816a93d1SMarcel Holtmann 930f1649577SMarcel Holtmann static int supervision_timeout_set(void *data, u64 val) 931f1649577SMarcel Holtmann { 932f1649577SMarcel Holtmann struct hci_dev *hdev = data; 933f1649577SMarcel Holtmann 934f1649577SMarcel Holtmann if (val < 0x000a || val > 0x0c80) 935f1649577SMarcel Holtmann return -EINVAL; 936f1649577SMarcel Holtmann 937f1649577SMarcel Holtmann hci_dev_lock(hdev); 938f1649577SMarcel Holtmann hdev->le_supv_timeout = val; 939f1649577SMarcel Holtmann hci_dev_unlock(hdev); 940f1649577SMarcel Holtmann 941f1649577SMarcel Holtmann return 0; 942f1649577SMarcel Holtmann } 943f1649577SMarcel Holtmann 944f1649577SMarcel Holtmann static int supervision_timeout_get(void *data, u64 *val) 945f1649577SMarcel Holtmann { 946f1649577SMarcel Holtmann struct hci_dev *hdev = data; 947f1649577SMarcel Holtmann 948f1649577SMarcel Holtmann hci_dev_lock(hdev); 949f1649577SMarcel Holtmann *val = hdev->le_supv_timeout; 950f1649577SMarcel Holtmann hci_dev_unlock(hdev); 951f1649577SMarcel Holtmann 952f1649577SMarcel Holtmann return 0; 953f1649577SMarcel Holtmann } 954f1649577SMarcel Holtmann 955f1649577SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get, 956f1649577SMarcel Holtmann supervision_timeout_set, "%llu\n"); 957f1649577SMarcel Holtmann 9583f959d46SMarcel Holtmann static int adv_channel_map_set(void *data, u64 val) 9593f959d46SMarcel Holtmann { 9603f959d46SMarcel Holtmann struct hci_dev *hdev = data; 9613f959d46SMarcel Holtmann 9623f959d46SMarcel Holtmann if (val < 0x01 || val > 0x07) 9633f959d46SMarcel Holtmann return -EINVAL; 9643f959d46SMarcel Holtmann 9653f959d46SMarcel Holtmann hci_dev_lock(hdev); 9663f959d46SMarcel Holtmann hdev->le_adv_channel_map = val; 9673f959d46SMarcel Holtmann hci_dev_unlock(hdev); 9683f959d46SMarcel Holtmann 9693f959d46SMarcel Holtmann return 0; 9703f959d46SMarcel Holtmann } 9713f959d46SMarcel Holtmann 9723f959d46SMarcel Holtmann static int adv_channel_map_get(void *data, u64 *val) 9733f959d46SMarcel Holtmann { 9743f959d46SMarcel Holtmann struct hci_dev *hdev = data; 9753f959d46SMarcel Holtmann 9763f959d46SMarcel Holtmann hci_dev_lock(hdev); 9773f959d46SMarcel Holtmann *val = hdev->le_adv_channel_map; 9783f959d46SMarcel Holtmann hci_dev_unlock(hdev); 9793f959d46SMarcel Holtmann 9803f959d46SMarcel Holtmann return 0; 9813f959d46SMarcel Holtmann } 9823f959d46SMarcel Holtmann 9833f959d46SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get, 9843f959d46SMarcel Holtmann adv_channel_map_set, "%llu\n"); 9853f959d46SMarcel Holtmann 986729a1051SGeorg Lukas static int adv_min_interval_set(void *data, u64 val) 98789863109SJukka Rissanen { 988729a1051SGeorg Lukas struct hci_dev *hdev = data; 98989863109SJukka Rissanen 990729a1051SGeorg Lukas if (val < 0x0020 || val > 0x4000 || val > hdev->le_adv_max_interval) 99189863109SJukka Rissanen return -EINVAL; 99289863109SJukka Rissanen 9937d474e06SAndre Guedes hci_dev_lock(hdev); 994729a1051SGeorg Lukas hdev->le_adv_min_interval = val; 9957d474e06SAndre Guedes hci_dev_unlock(hdev); 9967d474e06SAndre Guedes 9977d474e06SAndre Guedes return 0; 9987d474e06SAndre Guedes } 9997d474e06SAndre Guedes 1000729a1051SGeorg Lukas static int adv_min_interval_get(void *data, u64 *val) 10017d474e06SAndre Guedes { 1002729a1051SGeorg Lukas struct hci_dev *hdev = data; 1003729a1051SGeorg Lukas 1004729a1051SGeorg Lukas hci_dev_lock(hdev); 1005729a1051SGeorg Lukas *val = hdev->le_adv_min_interval; 1006729a1051SGeorg Lukas hci_dev_unlock(hdev); 1007729a1051SGeorg Lukas 1008729a1051SGeorg Lukas return 0; 10097d474e06SAndre Guedes } 10107d474e06SAndre Guedes 1011729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_min_interval_fops, adv_min_interval_get, 1012729a1051SGeorg Lukas adv_min_interval_set, "%llu\n"); 10137d474e06SAndre Guedes 1014729a1051SGeorg Lukas static int adv_max_interval_set(void *data, u64 val) 1015729a1051SGeorg Lukas { 1016729a1051SGeorg Lukas struct hci_dev *hdev = data; 1017729a1051SGeorg Lukas 1018729a1051SGeorg Lukas if (val < 0x0020 || val > 0x4000 || val < hdev->le_adv_min_interval) 10197d474e06SAndre Guedes return -EINVAL; 10207d474e06SAndre Guedes 10217d474e06SAndre Guedes hci_dev_lock(hdev); 1022729a1051SGeorg Lukas hdev->le_adv_max_interval = val; 10237d474e06SAndre Guedes hci_dev_unlock(hdev); 10247d474e06SAndre Guedes 1025729a1051SGeorg Lukas return 0; 10267d474e06SAndre Guedes } 10277d474e06SAndre Guedes 1028729a1051SGeorg Lukas static int adv_max_interval_get(void *data, u64 *val) 1029729a1051SGeorg Lukas { 1030729a1051SGeorg Lukas struct hci_dev *hdev = data; 1031729a1051SGeorg Lukas 10327d474e06SAndre Guedes hci_dev_lock(hdev); 1033729a1051SGeorg Lukas *val = hdev->le_adv_max_interval; 10347d474e06SAndre Guedes hci_dev_unlock(hdev); 1035729a1051SGeorg Lukas 1036729a1051SGeorg Lukas return 0; 1037729a1051SGeorg Lukas } 1038729a1051SGeorg Lukas 1039729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get, 1040729a1051SGeorg Lukas adv_max_interval_set, "%llu\n"); 1041729a1051SGeorg Lukas 10420b3c7d37SMarcel Holtmann static int device_list_show(struct seq_file *f, void *ptr) 10437d474e06SAndre Guedes { 10440b3c7d37SMarcel Holtmann struct hci_dev *hdev = f->private; 10457d474e06SAndre Guedes struct hci_conn_params *p; 104640f4938aSMarcel Holtmann struct bdaddr_list *b; 10477d474e06SAndre Guedes 10487d474e06SAndre Guedes hci_dev_lock(hdev); 104940f4938aSMarcel Holtmann list_for_each_entry(b, &hdev->whitelist, list) 105040f4938aSMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 10517d474e06SAndre Guedes list_for_each_entry(p, &hdev->le_conn_params, list) { 105240f4938aSMarcel Holtmann seq_printf(f, "%pMR (type %u) %u\n", &p->addr, p->addr_type, 10537d474e06SAndre Guedes p->auto_connect); 10547d474e06SAndre Guedes } 10557d474e06SAndre Guedes hci_dev_unlock(hdev); 10567d474e06SAndre Guedes 10577d474e06SAndre Guedes return 0; 10587d474e06SAndre Guedes } 10597d474e06SAndre Guedes 10600b3c7d37SMarcel Holtmann static int device_list_open(struct inode *inode, struct file *file) 10617d474e06SAndre Guedes { 10620b3c7d37SMarcel Holtmann return single_open(file, device_list_show, inode->i_private); 10637d474e06SAndre Guedes } 10647d474e06SAndre Guedes 10650b3c7d37SMarcel Holtmann static const struct file_operations device_list_fops = { 10660b3c7d37SMarcel Holtmann .open = device_list_open, 10677d474e06SAndre Guedes .read = seq_read, 10687d474e06SAndre Guedes .llseek = seq_lseek, 10697d474e06SAndre Guedes .release = single_release, 10707d474e06SAndre Guedes }; 10717d474e06SAndre Guedes 10721da177e4SLinus Torvalds /* ---- HCI requests ---- */ 10731da177e4SLinus Torvalds 107442c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 10751da177e4SLinus Torvalds { 107642c6b129SJohan Hedberg BT_DBG("%s result 0x%2.2x", hdev->name, result); 107775fb0e32SJohan Hedberg 10781da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 10791da177e4SLinus Torvalds hdev->req_result = result; 10801da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 10811da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 10821da177e4SLinus Torvalds } 10831da177e4SLinus Torvalds } 10841da177e4SLinus Torvalds 10851da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 10861da177e4SLinus Torvalds { 10871da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 10881da177e4SLinus Torvalds 10891da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 10901da177e4SLinus Torvalds hdev->req_result = err; 10911da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 10921da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 10931da177e4SLinus Torvalds } 10941da177e4SLinus Torvalds } 10951da177e4SLinus Torvalds 109677a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 109777a63e0aSFengguang Wu u8 event) 109875e84b7cSJohan Hedberg { 109975e84b7cSJohan Hedberg struct hci_ev_cmd_complete *ev; 110075e84b7cSJohan Hedberg struct hci_event_hdr *hdr; 110175e84b7cSJohan Hedberg struct sk_buff *skb; 110275e84b7cSJohan Hedberg 110375e84b7cSJohan Hedberg hci_dev_lock(hdev); 110475e84b7cSJohan Hedberg 110575e84b7cSJohan Hedberg skb = hdev->recv_evt; 110675e84b7cSJohan Hedberg hdev->recv_evt = NULL; 110775e84b7cSJohan Hedberg 110875e84b7cSJohan Hedberg hci_dev_unlock(hdev); 110975e84b7cSJohan Hedberg 111075e84b7cSJohan Hedberg if (!skb) 111175e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 111275e84b7cSJohan Hedberg 111375e84b7cSJohan Hedberg if (skb->len < sizeof(*hdr)) { 111475e84b7cSJohan Hedberg BT_ERR("Too short HCI event"); 111575e84b7cSJohan Hedberg goto failed; 111675e84b7cSJohan Hedberg } 111775e84b7cSJohan Hedberg 111875e84b7cSJohan Hedberg hdr = (void *) skb->data; 111975e84b7cSJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 112075e84b7cSJohan Hedberg 11217b1abbbeSJohan Hedberg if (event) { 11227b1abbbeSJohan Hedberg if (hdr->evt != event) 11237b1abbbeSJohan Hedberg goto failed; 11247b1abbbeSJohan Hedberg return skb; 11257b1abbbeSJohan Hedberg } 11267b1abbbeSJohan Hedberg 112775e84b7cSJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 112875e84b7cSJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 112975e84b7cSJohan Hedberg goto failed; 113075e84b7cSJohan Hedberg } 113175e84b7cSJohan Hedberg 113275e84b7cSJohan Hedberg if (skb->len < sizeof(*ev)) { 113375e84b7cSJohan Hedberg BT_ERR("Too short cmd_complete event"); 113475e84b7cSJohan Hedberg goto failed; 113575e84b7cSJohan Hedberg } 113675e84b7cSJohan Hedberg 113775e84b7cSJohan Hedberg ev = (void *) skb->data; 113875e84b7cSJohan Hedberg skb_pull(skb, sizeof(*ev)); 113975e84b7cSJohan Hedberg 114075e84b7cSJohan Hedberg if (opcode == __le16_to_cpu(ev->opcode)) 114175e84b7cSJohan Hedberg return skb; 114275e84b7cSJohan Hedberg 114375e84b7cSJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 114475e84b7cSJohan Hedberg __le16_to_cpu(ev->opcode)); 114575e84b7cSJohan Hedberg 114675e84b7cSJohan Hedberg failed: 114775e84b7cSJohan Hedberg kfree_skb(skb); 114875e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 114975e84b7cSJohan Hedberg } 115075e84b7cSJohan Hedberg 11517b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 115207dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout) 115375e84b7cSJohan Hedberg { 115475e84b7cSJohan Hedberg DECLARE_WAITQUEUE(wait, current); 115575e84b7cSJohan Hedberg struct hci_request req; 115675e84b7cSJohan Hedberg int err = 0; 115775e84b7cSJohan Hedberg 115875e84b7cSJohan Hedberg BT_DBG("%s", hdev->name); 115975e84b7cSJohan Hedberg 116075e84b7cSJohan Hedberg hci_req_init(&req, hdev); 116175e84b7cSJohan Hedberg 11627b1abbbeSJohan Hedberg hci_req_add_ev(&req, opcode, plen, param, event); 116375e84b7cSJohan Hedberg 116475e84b7cSJohan Hedberg hdev->req_status = HCI_REQ_PEND; 116575e84b7cSJohan Hedberg 116675e84b7cSJohan Hedberg add_wait_queue(&hdev->req_wait_q, &wait); 116775e84b7cSJohan Hedberg set_current_state(TASK_INTERRUPTIBLE); 116875e84b7cSJohan Hedberg 1169039fada5SChan-yeol Park err = hci_req_run(&req, hci_req_sync_complete); 1170039fada5SChan-yeol Park if (err < 0) { 1171039fada5SChan-yeol Park remove_wait_queue(&hdev->req_wait_q, &wait); 117222a3ceabSJohan Hedberg set_current_state(TASK_RUNNING); 1173039fada5SChan-yeol Park return ERR_PTR(err); 1174039fada5SChan-yeol Park } 1175039fada5SChan-yeol Park 117675e84b7cSJohan Hedberg schedule_timeout(timeout); 117775e84b7cSJohan Hedberg 117875e84b7cSJohan Hedberg remove_wait_queue(&hdev->req_wait_q, &wait); 117975e84b7cSJohan Hedberg 118075e84b7cSJohan Hedberg if (signal_pending(current)) 118175e84b7cSJohan Hedberg return ERR_PTR(-EINTR); 118275e84b7cSJohan Hedberg 118375e84b7cSJohan Hedberg switch (hdev->req_status) { 118475e84b7cSJohan Hedberg case HCI_REQ_DONE: 118575e84b7cSJohan Hedberg err = -bt_to_errno(hdev->req_result); 118675e84b7cSJohan Hedberg break; 118775e84b7cSJohan Hedberg 118875e84b7cSJohan Hedberg case HCI_REQ_CANCELED: 118975e84b7cSJohan Hedberg err = -hdev->req_result; 119075e84b7cSJohan Hedberg break; 119175e84b7cSJohan Hedberg 119275e84b7cSJohan Hedberg default: 119375e84b7cSJohan Hedberg err = -ETIMEDOUT; 119475e84b7cSJohan Hedberg break; 119575e84b7cSJohan Hedberg } 119675e84b7cSJohan Hedberg 119775e84b7cSJohan Hedberg hdev->req_status = hdev->req_result = 0; 119875e84b7cSJohan Hedberg 119975e84b7cSJohan Hedberg BT_DBG("%s end: err %d", hdev->name, err); 120075e84b7cSJohan Hedberg 120175e84b7cSJohan Hedberg if (err < 0) 120275e84b7cSJohan Hedberg return ERR_PTR(err); 120375e84b7cSJohan Hedberg 12047b1abbbeSJohan Hedberg return hci_get_cmd_complete(hdev, opcode, event); 12057b1abbbeSJohan Hedberg } 12067b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev); 12077b1abbbeSJohan Hedberg 12087b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 120907dc93ddSJohan Hedberg const void *param, u32 timeout) 12107b1abbbeSJohan Hedberg { 12117b1abbbeSJohan Hedberg return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); 121275e84b7cSJohan Hedberg } 121375e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync); 121475e84b7cSJohan Hedberg 12151da177e4SLinus Torvalds /* Execute request and wait for completion. */ 121601178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev, 121742c6b129SJohan Hedberg void (*func)(struct hci_request *req, 121842c6b129SJohan Hedberg unsigned long opt), 12191da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 12201da177e4SLinus Torvalds { 122142c6b129SJohan Hedberg struct hci_request req; 12221da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 12231da177e4SLinus Torvalds int err = 0; 12241da177e4SLinus Torvalds 12251da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 12261da177e4SLinus Torvalds 122742c6b129SJohan Hedberg hci_req_init(&req, hdev); 122842c6b129SJohan Hedberg 12291da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 12301da177e4SLinus Torvalds 123142c6b129SJohan Hedberg func(&req, opt); 123253cce22dSJohan Hedberg 1233039fada5SChan-yeol Park add_wait_queue(&hdev->req_wait_q, &wait); 1234039fada5SChan-yeol Park set_current_state(TASK_INTERRUPTIBLE); 1235039fada5SChan-yeol Park 123642c6b129SJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 123742c6b129SJohan Hedberg if (err < 0) { 123853cce22dSJohan Hedberg hdev->req_status = 0; 1239920c8300SAndre Guedes 1240039fada5SChan-yeol Park remove_wait_queue(&hdev->req_wait_q, &wait); 124122a3ceabSJohan Hedberg set_current_state(TASK_RUNNING); 1242039fada5SChan-yeol Park 1243920c8300SAndre Guedes /* ENODATA means the HCI request command queue is empty. 1244920c8300SAndre Guedes * This can happen when a request with conditionals doesn't 1245920c8300SAndre Guedes * trigger any commands to be sent. This is normal behavior 1246920c8300SAndre Guedes * and should not trigger an error return. 124742c6b129SJohan Hedberg */ 1248920c8300SAndre Guedes if (err == -ENODATA) 124942c6b129SJohan Hedberg return 0; 1250920c8300SAndre Guedes 1251920c8300SAndre Guedes return err; 125253cce22dSJohan Hedberg } 125353cce22dSJohan Hedberg 12541da177e4SLinus Torvalds schedule_timeout(timeout); 12551da177e4SLinus Torvalds 12561da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 12571da177e4SLinus Torvalds 12581da177e4SLinus Torvalds if (signal_pending(current)) 12591da177e4SLinus Torvalds return -EINTR; 12601da177e4SLinus Torvalds 12611da177e4SLinus Torvalds switch (hdev->req_status) { 12621da177e4SLinus Torvalds case HCI_REQ_DONE: 1263e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 12641da177e4SLinus Torvalds break; 12651da177e4SLinus Torvalds 12661da177e4SLinus Torvalds case HCI_REQ_CANCELED: 12671da177e4SLinus Torvalds err = -hdev->req_result; 12681da177e4SLinus Torvalds break; 12691da177e4SLinus Torvalds 12701da177e4SLinus Torvalds default: 12711da177e4SLinus Torvalds err = -ETIMEDOUT; 12721da177e4SLinus Torvalds break; 12733ff50b79SStephen Hemminger } 12741da177e4SLinus Torvalds 1275a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 12761da177e4SLinus Torvalds 12771da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 12781da177e4SLinus Torvalds 12791da177e4SLinus Torvalds return err; 12801da177e4SLinus Torvalds } 12811da177e4SLinus Torvalds 128201178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev, 128342c6b129SJohan Hedberg void (*req)(struct hci_request *req, 128442c6b129SJohan Hedberg unsigned long opt), 12851da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 12861da177e4SLinus Torvalds { 12871da177e4SLinus Torvalds int ret; 12881da177e4SLinus Torvalds 12897c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 12907c6a329eSMarcel Holtmann return -ENETDOWN; 12917c6a329eSMarcel Holtmann 12921da177e4SLinus Torvalds /* Serialize all requests */ 12931da177e4SLinus Torvalds hci_req_lock(hdev); 129401178cd4SJohan Hedberg ret = __hci_req_sync(hdev, req, opt, timeout); 12951da177e4SLinus Torvalds hci_req_unlock(hdev); 12961da177e4SLinus Torvalds 12971da177e4SLinus Torvalds return ret; 12981da177e4SLinus Torvalds } 12991da177e4SLinus Torvalds 130042c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt) 13011da177e4SLinus Torvalds { 130242c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 13031da177e4SLinus Torvalds 13041da177e4SLinus Torvalds /* Reset device */ 130542c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 130642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 13071da177e4SLinus Torvalds } 13081da177e4SLinus Torvalds 130942c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 13101da177e4SLinus Torvalds { 131142c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 13122455a3eaSAndrei Emeltchenko 13131da177e4SLinus Torvalds /* Read Local Supported Features */ 131442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 13151da177e4SLinus Torvalds 13161143e5a6SMarcel Holtmann /* Read Local Version */ 131742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 13182177bab5SJohan Hedberg 13192177bab5SJohan Hedberg /* Read BD Address */ 132042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 13211da177e4SLinus Torvalds } 13221da177e4SLinus Torvalds 132342c6b129SJohan Hedberg static void amp_init(struct hci_request *req) 1324e61ef499SAndrei Emeltchenko { 132542c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 13262455a3eaSAndrei Emeltchenko 1327e61ef499SAndrei Emeltchenko /* Read Local Version */ 132842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 13296bcbc489SAndrei Emeltchenko 1330f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 1331f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 1332f6996cfeSMarcel Holtmann 1333f6996cfeSMarcel Holtmann /* Read Local Supported Features */ 1334f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 1335f6996cfeSMarcel Holtmann 13366bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 133742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 1338e71dfabaSAndrei Emeltchenko 1339e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 134042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 13417528ca1cSMarcel Holtmann 1342f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 1343f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 1344f38ba941SMarcel Holtmann 13457528ca1cSMarcel Holtmann /* Read Location Data */ 13467528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 1347e61ef499SAndrei Emeltchenko } 1348e61ef499SAndrei Emeltchenko 134942c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 1350e61ef499SAndrei Emeltchenko { 135142c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1352e61ef499SAndrei Emeltchenko 1353e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 1354e61ef499SAndrei Emeltchenko 135511778716SAndrei Emeltchenko /* Reset */ 135611778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 135742c6b129SJohan Hedberg hci_reset_req(req, 0); 135811778716SAndrei Emeltchenko 1359e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 1360e61ef499SAndrei Emeltchenko case HCI_BREDR: 136142c6b129SJohan Hedberg bredr_init(req); 1362e61ef499SAndrei Emeltchenko break; 1363e61ef499SAndrei Emeltchenko 1364e61ef499SAndrei Emeltchenko case HCI_AMP: 136542c6b129SJohan Hedberg amp_init(req); 1366e61ef499SAndrei Emeltchenko break; 1367e61ef499SAndrei Emeltchenko 1368e61ef499SAndrei Emeltchenko default: 1369e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 1370e61ef499SAndrei Emeltchenko break; 1371e61ef499SAndrei Emeltchenko } 1372e61ef499SAndrei Emeltchenko } 1373e61ef499SAndrei Emeltchenko 137442c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 13752177bab5SJohan Hedberg { 13764ca048e3SMarcel Holtmann struct hci_dev *hdev = req->hdev; 13774ca048e3SMarcel Holtmann 13782177bab5SJohan Hedberg __le16 param; 13792177bab5SJohan Hedberg __u8 flt_type; 13802177bab5SJohan Hedberg 13812177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 138242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 13832177bab5SJohan Hedberg 13842177bab5SJohan Hedberg /* Read Class of Device */ 138542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 13862177bab5SJohan Hedberg 13872177bab5SJohan Hedberg /* Read Local Name */ 138842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 13892177bab5SJohan Hedberg 13902177bab5SJohan Hedberg /* Read Voice Setting */ 139142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 13922177bab5SJohan Hedberg 1393b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 1394b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 1395b4cb9fb2SMarcel Holtmann 13964b836f39SMarcel Holtmann /* Read Current IAC LAP */ 13974b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 13984b836f39SMarcel Holtmann 13992177bab5SJohan Hedberg /* Clear Event Filters */ 14002177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 140142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 14022177bab5SJohan Hedberg 14032177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 1404dcf4adbfSJoe Perches param = cpu_to_le16(0x7d00); 140542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 14062177bab5SJohan Hedberg 14074ca048e3SMarcel Holtmann /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, 14084ca048e3SMarcel Holtmann * but it does not support page scan related HCI commands. 14094ca048e3SMarcel Holtmann */ 14104ca048e3SMarcel Holtmann if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) { 1411f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 1412f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 1413f332ec66SJohan Hedberg } 14142177bab5SJohan Hedberg } 14152177bab5SJohan Hedberg 141642c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 14172177bab5SJohan Hedberg { 1418c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 1419c73eee91SJohan Hedberg 14202177bab5SJohan Hedberg /* Read LE Buffer Size */ 142142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 14222177bab5SJohan Hedberg 14232177bab5SJohan Hedberg /* Read LE Local Supported Features */ 142442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 14252177bab5SJohan Hedberg 1426747d3f03SMarcel Holtmann /* Read LE Supported States */ 1427747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 1428747d3f03SMarcel Holtmann 14292177bab5SJohan Hedberg /* Read LE White List Size */ 143042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 14312177bab5SJohan Hedberg 1432747d3f03SMarcel Holtmann /* Clear LE White List */ 1433747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL); 1434c73eee91SJohan Hedberg 1435c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 1436c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1437c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 14382177bab5SJohan Hedberg } 14392177bab5SJohan Hedberg 14402177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 14412177bab5SJohan Hedberg { 14422177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 14432177bab5SJohan Hedberg return 0x02; 14442177bab5SJohan Hedberg 14452177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 14462177bab5SJohan Hedberg return 0x01; 14472177bab5SJohan Hedberg 14482177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 14492177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 14502177bab5SJohan Hedberg return 0x01; 14512177bab5SJohan Hedberg 14522177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 14532177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 14542177bab5SJohan Hedberg return 0x01; 14552177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 14562177bab5SJohan Hedberg return 0x01; 14572177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 14582177bab5SJohan Hedberg return 0x01; 14592177bab5SJohan Hedberg } 14602177bab5SJohan Hedberg 14612177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 14622177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 14632177bab5SJohan Hedberg return 0x01; 14642177bab5SJohan Hedberg 14652177bab5SJohan Hedberg return 0x00; 14662177bab5SJohan Hedberg } 14672177bab5SJohan Hedberg 146842c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 14692177bab5SJohan Hedberg { 14702177bab5SJohan Hedberg u8 mode; 14712177bab5SJohan Hedberg 147242c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 14732177bab5SJohan Hedberg 147442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 14752177bab5SJohan Hedberg } 14762177bab5SJohan Hedberg 147742c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 14782177bab5SJohan Hedberg { 147942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 148042c6b129SJohan Hedberg 14812177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 14822177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 14832177bab5SJohan Hedberg * command otherwise. 14842177bab5SJohan Hedberg */ 14852177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 14862177bab5SJohan Hedberg 14872177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 14882177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 14892177bab5SJohan Hedberg */ 14902177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 14912177bab5SJohan Hedberg return; 14922177bab5SJohan Hedberg 14932177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 14942177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 14952177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 14962177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 14972177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 14982177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 1499c7882cbdSMarcel Holtmann } else { 1500c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 1501c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 1502c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 1503c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 1504c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 1505c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 1506c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 1507c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 1508c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 15090da71f1bSMarcel Holtmann 15100da71f1bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) { 15110da71f1bSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 1512c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 15132177bab5SJohan Hedberg } 15140da71f1bSMarcel Holtmann } 15152177bab5SJohan Hedberg 15162177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 15172177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 15182177bab5SJohan Hedberg 15192177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 15202177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 15212177bab5SJohan Hedberg 15222177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 15232177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 15242177bab5SJohan Hedberg 15252177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 15262177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 15272177bab5SJohan Hedberg 15282177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 15292177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 15302177bab5SJohan Hedberg 15312177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 15322177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 15332177bab5SJohan Hedberg 15342177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 15352177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 15362177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 15372177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 15382177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 15392177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 15402177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 15412177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 15422177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 15432177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 15442177bab5SJohan Hedberg * Features Notification 15452177bab5SJohan Hedberg */ 15462177bab5SJohan Hedberg } 15472177bab5SJohan Hedberg 15482177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 15492177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 15502177bab5SJohan Hedberg 155142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 15522177bab5SJohan Hedberg } 15532177bab5SJohan Hedberg 155442c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 15552177bab5SJohan Hedberg { 155642c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 155742c6b129SJohan Hedberg 15582177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 155942c6b129SJohan Hedberg bredr_setup(req); 156056f87901SJohan Hedberg else 156156f87901SJohan Hedberg clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 15622177bab5SJohan Hedberg 15632177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 156442c6b129SJohan Hedberg le_setup(req); 15652177bab5SJohan Hedberg 15663f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 15673f8e2d75SJohan Hedberg * local supported commands HCI command. 15683f8e2d75SJohan Hedberg */ 15693f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 157042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 15712177bab5SJohan Hedberg 15722177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 157357af75a8SMarcel Holtmann /* When SSP is available, then the host features page 157457af75a8SMarcel Holtmann * should also be available as well. However some 157557af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 157657af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 157757af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 157857af75a8SMarcel Holtmann */ 157957af75a8SMarcel Holtmann hdev->max_page = 0x01; 158057af75a8SMarcel Holtmann 15812177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 15822177bab5SJohan Hedberg u8 mode = 0x01; 158342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 15842177bab5SJohan Hedberg sizeof(mode), &mode); 15852177bab5SJohan Hedberg } else { 15862177bab5SJohan Hedberg struct hci_cp_write_eir cp; 15872177bab5SJohan Hedberg 15882177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 15892177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 15902177bab5SJohan Hedberg 159142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 15922177bab5SJohan Hedberg } 15932177bab5SJohan Hedberg } 15942177bab5SJohan Hedberg 15952177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 159642c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 15972177bab5SJohan Hedberg 15982177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 159942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 16002177bab5SJohan Hedberg 16012177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 16022177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 16032177bab5SJohan Hedberg 16042177bab5SJohan Hedberg cp.page = 0x01; 160542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 160642c6b129SJohan Hedberg sizeof(cp), &cp); 16072177bab5SJohan Hedberg } 16082177bab5SJohan Hedberg 16092177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 16102177bab5SJohan Hedberg u8 enable = 1; 161142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 16122177bab5SJohan Hedberg &enable); 16132177bab5SJohan Hedberg } 16142177bab5SJohan Hedberg } 16152177bab5SJohan Hedberg 161642c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 16172177bab5SJohan Hedberg { 161842c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 16192177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 16202177bab5SJohan Hedberg u16 link_policy = 0; 16212177bab5SJohan Hedberg 16222177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 16232177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 16242177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 16252177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 16262177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 16272177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 16282177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 16292177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 16302177bab5SJohan Hedberg 16312177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 163242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 16332177bab5SJohan Hedberg } 16342177bab5SJohan Hedberg 163542c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 16362177bab5SJohan Hedberg { 163742c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 16382177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 16392177bab5SJohan Hedberg 1640c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 1641c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1642c73eee91SJohan Hedberg return; 1643c73eee91SJohan Hedberg 16442177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 16452177bab5SJohan Hedberg 16462177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 16472177bab5SJohan Hedberg cp.le = 0x01; 164832226e4fSMarcel Holtmann cp.simul = 0x00; 16492177bab5SJohan Hedberg } 16502177bab5SJohan Hedberg 16512177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 165242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 16532177bab5SJohan Hedberg &cp); 16542177bab5SJohan Hedberg } 16552177bab5SJohan Hedberg 1656d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 1657d62e6d67SJohan Hedberg { 1658d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 1659d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1660d62e6d67SJohan Hedberg 1661d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 1662d62e6d67SJohan Hedberg * enable all necessary events for it. 1663d62e6d67SJohan Hedberg */ 166453b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 1665d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 1666d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 1667d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 1668d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 1669d62e6d67SJohan Hedberg } 1670d62e6d67SJohan Hedberg 1671d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 1672d62e6d67SJohan Hedberg * enable all necessary events for it. 1673d62e6d67SJohan Hedberg */ 167453b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 1675d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 1676d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 1677d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 1678d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 1679d62e6d67SJohan Hedberg } 1680d62e6d67SJohan Hedberg 168140c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 1682cd7ca0ecSMarcel Holtmann if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) 168340c59fcbSMarcel Holtmann events[2] |= 0x80; 168440c59fcbSMarcel Holtmann 1685d62e6d67SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 1686d62e6d67SJohan Hedberg } 1687d62e6d67SJohan Hedberg 168842c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 16892177bab5SJohan Hedberg { 169042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1691d2c5d77fSJohan Hedberg u8 p; 169242c6b129SJohan Hedberg 16930da71f1bSMarcel Holtmann hci_setup_event_mask(req); 16940da71f1bSMarcel Holtmann 1695b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 1696b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 1697b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 1698b8f4e068SGustavo Padovan * 1699b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 1700b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 1701b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 1702b8f4e068SGustavo Padovan * command redundant anyway. 1703f9f462faSMarcel Holtmann * 1704f9f462faSMarcel Holtmann * Some controllers indicate that they support handling deleting 1705f9f462faSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 1706f9f462faSMarcel Holtmann * just disable this command. 1707b8f4e068SGustavo Padovan */ 1708f9f462faSMarcel Holtmann if (hdev->commands[6] & 0x80 && 1709f9f462faSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 171059f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 171159f45d57SJohan Hedberg 171259f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 171359f45d57SJohan Hedberg cp.delete_all = 0x01; 171459f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 171559f45d57SJohan Hedberg sizeof(cp), &cp); 171659f45d57SJohan Hedberg } 171759f45d57SJohan Hedberg 17182177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 171942c6b129SJohan Hedberg hci_setup_link_policy(req); 17202177bab5SJohan Hedberg 17219193c6e8SAndre Guedes if (lmp_le_capable(hdev)) { 17229193c6e8SAndre Guedes u8 events[8]; 17239193c6e8SAndre Guedes 17249193c6e8SAndre Guedes memset(events, 0, sizeof(events)); 17254d6c705bSMarcel Holtmann events[0] = 0x0f; 17264d6c705bSMarcel Holtmann 17274d6c705bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) 17284d6c705bSMarcel Holtmann events[0] |= 0x10; /* LE Long Term Key Request */ 1729662bc2e6SAndre Guedes 1730662bc2e6SAndre Guedes /* If controller supports the Connection Parameters Request 1731662bc2e6SAndre Guedes * Link Layer Procedure, enable the corresponding event. 1732662bc2e6SAndre Guedes */ 1733662bc2e6SAndre Guedes if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC) 1734662bc2e6SAndre Guedes events[0] |= 0x20; /* LE Remote Connection 1735662bc2e6SAndre Guedes * Parameter Request 1736662bc2e6SAndre Guedes */ 1737662bc2e6SAndre Guedes 17384b71bba4SMarcel Holtmann /* If the controller supports Extended Scanner Filter 17394b71bba4SMarcel Holtmann * Policies, enable the correspondig event. 17404b71bba4SMarcel Holtmann */ 17414b71bba4SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY) 17424b71bba4SMarcel Holtmann events[1] |= 0x04; /* LE Direct Advertising 17434b71bba4SMarcel Holtmann * Report 17444b71bba4SMarcel Holtmann */ 17454b71bba4SMarcel Holtmann 17469193c6e8SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), 17479193c6e8SAndre Guedes events); 17489193c6e8SAndre Guedes 174915a49ccaSMarcel Holtmann if (hdev->commands[25] & 0x40) { 175015a49ccaSMarcel Holtmann /* Read LE Advertising Channel TX Power */ 175115a49ccaSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 175215a49ccaSMarcel Holtmann } 175315a49ccaSMarcel Holtmann 175442c6b129SJohan Hedberg hci_set_le_support(req); 17559193c6e8SAndre Guedes } 1756d2c5d77fSJohan Hedberg 1757d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 1758d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 1759d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 1760d2c5d77fSJohan Hedberg 1761d2c5d77fSJohan Hedberg cp.page = p; 1762d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 1763d2c5d77fSJohan Hedberg sizeof(cp), &cp); 1764d2c5d77fSJohan Hedberg } 17652177bab5SJohan Hedberg } 17662177bab5SJohan Hedberg 17675d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt) 17685d4e7e8dSJohan Hedberg { 17695d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 17705d4e7e8dSJohan Hedberg 1771d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 1772d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 1773d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 1774d62e6d67SJohan Hedberg 1775109e3191SMarcel Holtmann /* Read local codec list if the HCI command is supported */ 1776109e3191SMarcel Holtmann if (hdev->commands[29] & 0x20) 1777109e3191SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL); 1778109e3191SMarcel Holtmann 1779f4fe73edSMarcel Holtmann /* Get MWS transport configuration if the HCI command is supported */ 1780f4fe73edSMarcel Holtmann if (hdev->commands[30] & 0x08) 1781f4fe73edSMarcel Holtmann hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL); 1782f4fe73edSMarcel Holtmann 17835d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 178453b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 17855d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 1786a6d0d690SMarcel Holtmann 1787a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 1788710f11c0SJohan Hedberg if (bredr_sc_enabled(hdev)) { 1789a6d0d690SMarcel Holtmann u8 support = 0x01; 1790a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 1791a6d0d690SMarcel Holtmann sizeof(support), &support); 1792a6d0d690SMarcel Holtmann } 17935d4e7e8dSJohan Hedberg } 17945d4e7e8dSJohan Hedberg 17952177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 17962177bab5SJohan Hedberg { 17972177bab5SJohan Hedberg int err; 17982177bab5SJohan Hedberg 17992177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 18002177bab5SJohan Hedberg if (err < 0) 18012177bab5SJohan Hedberg return err; 18022177bab5SJohan Hedberg 18034b4148e9SMarcel Holtmann /* The Device Under Test (DUT) mode is special and available for 18044b4148e9SMarcel Holtmann * all controller types. So just create it early on. 18054b4148e9SMarcel Holtmann */ 18064b4148e9SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 18074b4148e9SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 18084b4148e9SMarcel Holtmann &dut_mode_fops); 18094b4148e9SMarcel Holtmann } 18104b4148e9SMarcel Holtmann 18112177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 18122177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 18132177bab5SJohan Hedberg * first stage init. 18142177bab5SJohan Hedberg */ 18152177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 18162177bab5SJohan Hedberg return 0; 18172177bab5SJohan Hedberg 18182177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 18192177bab5SJohan Hedberg if (err < 0) 18202177bab5SJohan Hedberg return err; 18212177bab5SJohan Hedberg 18225d4e7e8dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 18235d4e7e8dSJohan Hedberg if (err < 0) 18245d4e7e8dSJohan Hedberg return err; 18255d4e7e8dSJohan Hedberg 1826baf27f6eSMarcel Holtmann err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 1827baf27f6eSMarcel Holtmann if (err < 0) 1828baf27f6eSMarcel Holtmann return err; 1829baf27f6eSMarcel Holtmann 1830baf27f6eSMarcel Holtmann /* Only create debugfs entries during the initial setup 1831baf27f6eSMarcel Holtmann * phase and not every time the controller gets powered on. 1832baf27f6eSMarcel Holtmann */ 1833baf27f6eSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 1834baf27f6eSMarcel Holtmann return 0; 1835baf27f6eSMarcel Holtmann 1836dfb826a8SMarcel Holtmann debugfs_create_file("features", 0444, hdev->debugfs, hdev, 1837dfb826a8SMarcel Holtmann &features_fops); 1838ceeb3bc0SMarcel Holtmann debugfs_create_u16("manufacturer", 0444, hdev->debugfs, 1839ceeb3bc0SMarcel Holtmann &hdev->manufacturer); 1840ceeb3bc0SMarcel Holtmann debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); 1841ceeb3bc0SMarcel Holtmann debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); 184240f4938aSMarcel Holtmann debugfs_create_file("device_list", 0444, hdev->debugfs, hdev, 184340f4938aSMarcel Holtmann &device_list_fops); 184470afe0b8SMarcel Holtmann debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, 184570afe0b8SMarcel Holtmann &blacklist_fops); 184647219839SMarcel Holtmann debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); 184747219839SMarcel Holtmann 184831ad1691SAndrzej Kaczmarek debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev, 184931ad1691SAndrzej Kaczmarek &conn_info_min_age_fops); 185031ad1691SAndrzej Kaczmarek debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev, 185131ad1691SAndrzej Kaczmarek &conn_info_max_age_fops); 185231ad1691SAndrzej Kaczmarek 1853baf27f6eSMarcel Holtmann if (lmp_bredr_capable(hdev)) { 1854baf27f6eSMarcel Holtmann debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, 1855baf27f6eSMarcel Holtmann hdev, &inquiry_cache_fops); 185602d08d15SMarcel Holtmann debugfs_create_file("link_keys", 0400, hdev->debugfs, 185702d08d15SMarcel Holtmann hdev, &link_keys_fops); 1858babdbb3cSMarcel Holtmann debugfs_create_file("dev_class", 0444, hdev->debugfs, 1859babdbb3cSMarcel Holtmann hdev, &dev_class_fops); 1860041000b9SMarcel Holtmann debugfs_create_file("voice_setting", 0444, hdev->debugfs, 1861041000b9SMarcel Holtmann hdev, &voice_setting_fops); 1862baf27f6eSMarcel Holtmann } 1863baf27f6eSMarcel Holtmann 186406f5b778SMarcel Holtmann if (lmp_ssp_capable(hdev)) { 1865ebd1e33bSMarcel Holtmann debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, 1866ebd1e33bSMarcel Holtmann hdev, &auto_accept_delay_fops); 18675afeac14SMarcel Holtmann debugfs_create_file("force_sc_support", 0644, hdev->debugfs, 18685afeac14SMarcel Holtmann hdev, &force_sc_support_fops); 1869134c2a89SMarcel Holtmann debugfs_create_file("sc_only_mode", 0444, hdev->debugfs, 1870134c2a89SMarcel Holtmann hdev, &sc_only_mode_fops); 1871858cdc78SJohan Hedberg if (lmp_le_capable(hdev)) 1872858cdc78SJohan Hedberg debugfs_create_file("force_lesc_support", 0644, 1873858cdc78SJohan Hedberg hdev->debugfs, hdev, 1874858cdc78SJohan Hedberg &force_lesc_support_fops); 187506f5b778SMarcel Holtmann } 1876ebd1e33bSMarcel Holtmann 18772bfa3531SMarcel Holtmann if (lmp_sniff_capable(hdev)) { 18782bfa3531SMarcel Holtmann debugfs_create_file("idle_timeout", 0644, hdev->debugfs, 18792bfa3531SMarcel Holtmann hdev, &idle_timeout_fops); 18802bfa3531SMarcel Holtmann debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs, 18812bfa3531SMarcel Holtmann hdev, &sniff_min_interval_fops); 18822bfa3531SMarcel Holtmann debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs, 18832bfa3531SMarcel Holtmann hdev, &sniff_max_interval_fops); 18842bfa3531SMarcel Holtmann } 18852bfa3531SMarcel Holtmann 1886d0f729b8SMarcel Holtmann if (lmp_le_capable(hdev)) { 1887ac345813SMarcel Holtmann debugfs_create_file("identity", 0400, hdev->debugfs, 1888ac345813SMarcel Holtmann hdev, &identity_fops); 1889ac345813SMarcel Holtmann debugfs_create_file("rpa_timeout", 0644, hdev->debugfs, 1890ac345813SMarcel Holtmann hdev, &rpa_timeout_fops); 18917a4cd51dSMarcel Holtmann debugfs_create_file("random_address", 0444, hdev->debugfs, 18927a4cd51dSMarcel Holtmann hdev, &random_address_fops); 1893e7b8fc92SMarcel Holtmann debugfs_create_file("static_address", 0444, hdev->debugfs, 1894e7b8fc92SMarcel Holtmann hdev, &static_address_fops); 1895b32bba6cSMarcel Holtmann 1896b32bba6cSMarcel Holtmann /* For controllers with a public address, provide a debug 1897b32bba6cSMarcel Holtmann * option to force the usage of the configured static 1898b32bba6cSMarcel Holtmann * address. By default the public address is used. 1899b32bba6cSMarcel Holtmann */ 1900b32bba6cSMarcel Holtmann if (bacmp(&hdev->bdaddr, BDADDR_ANY)) 1901b32bba6cSMarcel Holtmann debugfs_create_file("force_static_address", 0644, 1902b32bba6cSMarcel Holtmann hdev->debugfs, hdev, 1903b32bba6cSMarcel Holtmann &force_static_address_fops); 1904b32bba6cSMarcel Holtmann 1905b32bba6cSMarcel Holtmann debugfs_create_u8("white_list_size", 0444, hdev->debugfs, 1906b32bba6cSMarcel Holtmann &hdev->le_white_list_size); 1907d2ab0ac1SMarcel Holtmann debugfs_create_file("white_list", 0444, hdev->debugfs, hdev, 1908d2ab0ac1SMarcel Holtmann &white_list_fops); 19093698d704SMarcel Holtmann debugfs_create_file("identity_resolving_keys", 0400, 19103698d704SMarcel Holtmann hdev->debugfs, hdev, 19113698d704SMarcel Holtmann &identity_resolving_keys_fops); 19128f8625cdSMarcel Holtmann debugfs_create_file("long_term_keys", 0400, hdev->debugfs, 19138f8625cdSMarcel Holtmann hdev, &long_term_keys_fops); 19144e70c7e7SMarcel Holtmann debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, 19154e70c7e7SMarcel Holtmann hdev, &conn_min_interval_fops); 19164e70c7e7SMarcel Holtmann debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, 19174e70c7e7SMarcel Holtmann hdev, &conn_max_interval_fops); 1918816a93d1SMarcel Holtmann debugfs_create_file("conn_latency", 0644, hdev->debugfs, 1919816a93d1SMarcel Holtmann hdev, &conn_latency_fops); 1920f1649577SMarcel Holtmann debugfs_create_file("supervision_timeout", 0644, hdev->debugfs, 1921f1649577SMarcel Holtmann hdev, &supervision_timeout_fops); 19223f959d46SMarcel Holtmann debugfs_create_file("adv_channel_map", 0644, hdev->debugfs, 19233f959d46SMarcel Holtmann hdev, &adv_channel_map_fops); 1924729a1051SGeorg Lukas debugfs_create_file("adv_min_interval", 0644, hdev->debugfs, 1925729a1051SGeorg Lukas hdev, &adv_min_interval_fops); 1926729a1051SGeorg Lukas debugfs_create_file("adv_max_interval", 0644, hdev->debugfs, 1927729a1051SGeorg Lukas hdev, &adv_max_interval_fops); 1928b9a7a61eSLukasz Rymanowski debugfs_create_u16("discov_interleaved_timeout", 0644, 1929b9a7a61eSLukasz Rymanowski hdev->debugfs, 1930b9a7a61eSLukasz Rymanowski &hdev->discov_interleaved_timeout); 193154506918SJohan Hedberg 1932711eafe3SJohan Hedberg smp_register(hdev); 1933d0f729b8SMarcel Holtmann } 1934e7b8fc92SMarcel Holtmann 1935baf27f6eSMarcel Holtmann return 0; 19362177bab5SJohan Hedberg } 19372177bab5SJohan Hedberg 19380ebca7d6SMarcel Holtmann static void hci_init0_req(struct hci_request *req, unsigned long opt) 19390ebca7d6SMarcel Holtmann { 19400ebca7d6SMarcel Holtmann struct hci_dev *hdev = req->hdev; 19410ebca7d6SMarcel Holtmann 19420ebca7d6SMarcel Holtmann BT_DBG("%s %ld", hdev->name, opt); 19430ebca7d6SMarcel Holtmann 19440ebca7d6SMarcel Holtmann /* Reset */ 19450ebca7d6SMarcel Holtmann if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 19460ebca7d6SMarcel Holtmann hci_reset_req(req, 0); 19470ebca7d6SMarcel Holtmann 19480ebca7d6SMarcel Holtmann /* Read Local Version */ 19490ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 19500ebca7d6SMarcel Holtmann 19510ebca7d6SMarcel Holtmann /* Read BD Address */ 19520ebca7d6SMarcel Holtmann if (hdev->set_bdaddr) 19530ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 19540ebca7d6SMarcel Holtmann } 19550ebca7d6SMarcel Holtmann 19560ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev) 19570ebca7d6SMarcel Holtmann { 19580ebca7d6SMarcel Holtmann int err; 19590ebca7d6SMarcel Holtmann 1960cc78b44bSMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 1961cc78b44bSMarcel Holtmann return 0; 1962cc78b44bSMarcel Holtmann 19630ebca7d6SMarcel Holtmann err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT); 19640ebca7d6SMarcel Holtmann if (err < 0) 19650ebca7d6SMarcel Holtmann return err; 19660ebca7d6SMarcel Holtmann 19670ebca7d6SMarcel Holtmann return 0; 19680ebca7d6SMarcel Holtmann } 19690ebca7d6SMarcel Holtmann 197042c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 19711da177e4SLinus Torvalds { 19721da177e4SLinus Torvalds __u8 scan = opt; 19731da177e4SLinus Torvalds 197442c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 19751da177e4SLinus Torvalds 19761da177e4SLinus Torvalds /* Inquiry and Page scans */ 197742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 19781da177e4SLinus Torvalds } 19791da177e4SLinus Torvalds 198042c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 19811da177e4SLinus Torvalds { 19821da177e4SLinus Torvalds __u8 auth = opt; 19831da177e4SLinus Torvalds 198442c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 19851da177e4SLinus Torvalds 19861da177e4SLinus Torvalds /* Authentication */ 198742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 19881da177e4SLinus Torvalds } 19891da177e4SLinus Torvalds 199042c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 19911da177e4SLinus Torvalds { 19921da177e4SLinus Torvalds __u8 encrypt = opt; 19931da177e4SLinus Torvalds 199442c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 19951da177e4SLinus Torvalds 1996e4e8e37cSMarcel Holtmann /* Encryption */ 199742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 19981da177e4SLinus Torvalds } 19991da177e4SLinus Torvalds 200042c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 2001e4e8e37cSMarcel Holtmann { 2002e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 2003e4e8e37cSMarcel Holtmann 200442c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 2005e4e8e37cSMarcel Holtmann 2006e4e8e37cSMarcel Holtmann /* Default link policy */ 200742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 2008e4e8e37cSMarcel Holtmann } 2009e4e8e37cSMarcel Holtmann 20101da177e4SLinus Torvalds /* Get HCI device by index. 20111da177e4SLinus Torvalds * Device is held on return. */ 20121da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 20131da177e4SLinus Torvalds { 20148035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 20151da177e4SLinus Torvalds 20161da177e4SLinus Torvalds BT_DBG("%d", index); 20171da177e4SLinus Torvalds 20181da177e4SLinus Torvalds if (index < 0) 20191da177e4SLinus Torvalds return NULL; 20201da177e4SLinus Torvalds 20211da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 20228035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 20231da177e4SLinus Torvalds if (d->id == index) { 20241da177e4SLinus Torvalds hdev = hci_dev_hold(d); 20251da177e4SLinus Torvalds break; 20261da177e4SLinus Torvalds } 20271da177e4SLinus Torvalds } 20281da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 20291da177e4SLinus Torvalds return hdev; 20301da177e4SLinus Torvalds } 20311da177e4SLinus Torvalds 20321da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 2033ff9ef578SJohan Hedberg 203430dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 203530dc78e1SJohan Hedberg { 203630dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 203730dc78e1SJohan Hedberg 20386fbe195dSAndre Guedes switch (discov->state) { 2039343f935bSAndre Guedes case DISCOVERY_FINDING: 20406fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 204130dc78e1SJohan Hedberg return true; 204230dc78e1SJohan Hedberg 20436fbe195dSAndre Guedes default: 204430dc78e1SJohan Hedberg return false; 204530dc78e1SJohan Hedberg } 20466fbe195dSAndre Guedes } 204730dc78e1SJohan Hedberg 2048ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 2049ff9ef578SJohan Hedberg { 2050bb3e0a33SJohan Hedberg int old_state = hdev->discovery.state; 2051bb3e0a33SJohan Hedberg 2052ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 2053ff9ef578SJohan Hedberg 2054bb3e0a33SJohan Hedberg if (old_state == state) 2055ff9ef578SJohan Hedberg return; 2056ff9ef578SJohan Hedberg 2057bb3e0a33SJohan Hedberg hdev->discovery.state = state; 2058bb3e0a33SJohan Hedberg 2059ff9ef578SJohan Hedberg switch (state) { 2060ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 2061c54c3860SAndre Guedes hci_update_background_scan(hdev); 2062c54c3860SAndre Guedes 2063bb3e0a33SJohan Hedberg if (old_state != DISCOVERY_STARTING) 2064ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 2065ff9ef578SJohan Hedberg break; 2066ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 2067ff9ef578SJohan Hedberg break; 2068343f935bSAndre Guedes case DISCOVERY_FINDING: 2069ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 2070ff9ef578SJohan Hedberg break; 207130dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 207230dc78e1SJohan Hedberg break; 2073ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 2074ff9ef578SJohan Hedberg break; 2075ff9ef578SJohan Hedberg } 2076ff9ef578SJohan Hedberg } 2077ff9ef578SJohan Hedberg 20781f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 20791da177e4SLinus Torvalds { 208030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 2081b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 20821da177e4SLinus Torvalds 2083561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 2084561aafbcSJohan Hedberg list_del(&p->all); 2085b57c1a56SJohan Hedberg kfree(p); 20861da177e4SLinus Torvalds } 2087561aafbcSJohan Hedberg 2088561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 2089561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 20901da177e4SLinus Torvalds } 20911da177e4SLinus Torvalds 2092a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 2093a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 20941da177e4SLinus Torvalds { 209530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 20961da177e4SLinus Torvalds struct inquiry_entry *e; 20971da177e4SLinus Torvalds 20986ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 20991da177e4SLinus Torvalds 2100561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 21011da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 21021da177e4SLinus Torvalds return e; 21031da177e4SLinus Torvalds } 21041da177e4SLinus Torvalds 2105b57c1a56SJohan Hedberg return NULL; 2106b57c1a56SJohan Hedberg } 2107b57c1a56SJohan Hedberg 2108561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 2109561aafbcSJohan Hedberg bdaddr_t *bdaddr) 2110561aafbcSJohan Hedberg { 211130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 2112561aafbcSJohan Hedberg struct inquiry_entry *e; 2113561aafbcSJohan Hedberg 21146ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 2115561aafbcSJohan Hedberg 2116561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 2117561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 2118561aafbcSJohan Hedberg return e; 2119561aafbcSJohan Hedberg } 2120561aafbcSJohan Hedberg 2121561aafbcSJohan Hedberg return NULL; 2122561aafbcSJohan Hedberg } 2123561aafbcSJohan Hedberg 212430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 212530dc78e1SJohan Hedberg bdaddr_t *bdaddr, 212630dc78e1SJohan Hedberg int state) 212730dc78e1SJohan Hedberg { 212830dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 212930dc78e1SJohan Hedberg struct inquiry_entry *e; 213030dc78e1SJohan Hedberg 21316ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 213230dc78e1SJohan Hedberg 213330dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 213430dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 213530dc78e1SJohan Hedberg return e; 213630dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 213730dc78e1SJohan Hedberg return e; 213830dc78e1SJohan Hedberg } 213930dc78e1SJohan Hedberg 214030dc78e1SJohan Hedberg return NULL; 214130dc78e1SJohan Hedberg } 214230dc78e1SJohan Hedberg 2143a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 2144a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 2145a3d4e20aSJohan Hedberg { 2146a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 2147a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 2148a3d4e20aSJohan Hedberg struct inquiry_entry *p; 2149a3d4e20aSJohan Hedberg 2150a3d4e20aSJohan Hedberg list_del(&ie->list); 2151a3d4e20aSJohan Hedberg 2152a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 2153a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 2154a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 2155a3d4e20aSJohan Hedberg break; 2156a3d4e20aSJohan Hedberg pos = &p->list; 2157a3d4e20aSJohan Hedberg } 2158a3d4e20aSJohan Hedberg 2159a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 2160a3d4e20aSJohan Hedberg } 2161a3d4e20aSJohan Hedberg 2162af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 2163af58925cSMarcel Holtmann bool name_known) 21641da177e4SLinus Torvalds { 216530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 216670f23020SAndrei Emeltchenko struct inquiry_entry *ie; 2167af58925cSMarcel Holtmann u32 flags = 0; 21681da177e4SLinus Torvalds 21696ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 21701da177e4SLinus Torvalds 21716928a924SJohan Hedberg hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR); 21722b2fec4dSSzymon Janc 2173af58925cSMarcel Holtmann if (!data->ssp_mode) 2174af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 2175388fc8faSJohan Hedberg 217670f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 2177a3d4e20aSJohan Hedberg if (ie) { 2178af58925cSMarcel Holtmann if (!ie->data.ssp_mode) 2179af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 2180388fc8faSJohan Hedberg 2181a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 2182a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 2183a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 2184a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 2185a3d4e20aSJohan Hedberg } 2186a3d4e20aSJohan Hedberg 2187561aafbcSJohan Hedberg goto update; 2188a3d4e20aSJohan Hedberg } 2189561aafbcSJohan Hedberg 21901da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 219127f70f3eSJohan Hedberg ie = kzalloc(sizeof(*ie), GFP_KERNEL); 2192af58925cSMarcel Holtmann if (!ie) { 2193af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 2194af58925cSMarcel Holtmann goto done; 2195af58925cSMarcel Holtmann } 219670f23020SAndrei Emeltchenko 2197561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 2198561aafbcSJohan Hedberg 2199561aafbcSJohan Hedberg if (name_known) { 2200561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 2201561aafbcSJohan Hedberg } else { 2202561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 2203561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 2204561aafbcSJohan Hedberg } 2205561aafbcSJohan Hedberg 2206561aafbcSJohan Hedberg update: 2207561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 2208561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 2209561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 2210561aafbcSJohan Hedberg list_del(&ie->list); 22111da177e4SLinus Torvalds } 22121da177e4SLinus Torvalds 221370f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 221470f23020SAndrei Emeltchenko ie->timestamp = jiffies; 22151da177e4SLinus Torvalds cache->timestamp = jiffies; 22163175405bSJohan Hedberg 22173175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 2218af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 22193175405bSJohan Hedberg 2220af58925cSMarcel Holtmann done: 2221af58925cSMarcel Holtmann return flags; 22221da177e4SLinus Torvalds } 22231da177e4SLinus Torvalds 22241da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 22251da177e4SLinus Torvalds { 222630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 22271da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 22281da177e4SLinus Torvalds struct inquiry_entry *e; 22291da177e4SLinus Torvalds int copied = 0; 22301da177e4SLinus Torvalds 2231561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 22321da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 2233b57c1a56SJohan Hedberg 2234b57c1a56SJohan Hedberg if (copied >= num) 2235b57c1a56SJohan Hedberg break; 2236b57c1a56SJohan Hedberg 22371da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 22381da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 22391da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 22401da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 22411da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 22421da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 2243b57c1a56SJohan Hedberg 22441da177e4SLinus Torvalds info++; 2245b57c1a56SJohan Hedberg copied++; 22461da177e4SLinus Torvalds } 22471da177e4SLinus Torvalds 22481da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 22491da177e4SLinus Torvalds return copied; 22501da177e4SLinus Torvalds } 22511da177e4SLinus Torvalds 225242c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 22531da177e4SLinus Torvalds { 22541da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 225542c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 22561da177e4SLinus Torvalds struct hci_cp_inquiry cp; 22571da177e4SLinus Torvalds 22581da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 22591da177e4SLinus Torvalds 22601da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 22611da177e4SLinus Torvalds return; 22621da177e4SLinus Torvalds 22631da177e4SLinus Torvalds /* Start Inquiry */ 22641da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 22651da177e4SLinus Torvalds cp.length = ir->length; 22661da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 226742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 22681da177e4SLinus Torvalds } 22691da177e4SLinus Torvalds 22701da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 22711da177e4SLinus Torvalds { 22721da177e4SLinus Torvalds __u8 __user *ptr = arg; 22731da177e4SLinus Torvalds struct hci_inquiry_req ir; 22741da177e4SLinus Torvalds struct hci_dev *hdev; 22751da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 22761da177e4SLinus Torvalds long timeo; 22771da177e4SLinus Torvalds __u8 *buf; 22781da177e4SLinus Torvalds 22791da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 22801da177e4SLinus Torvalds return -EFAULT; 22811da177e4SLinus Torvalds 22825a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 22835a08ecceSAndrei Emeltchenko if (!hdev) 22841da177e4SLinus Torvalds return -ENODEV; 22851da177e4SLinus Torvalds 22860736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22870736cfa8SMarcel Holtmann err = -EBUSY; 22880736cfa8SMarcel Holtmann goto done; 22890736cfa8SMarcel Holtmann } 22900736cfa8SMarcel Holtmann 22914a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 2292fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2293fee746b0SMarcel Holtmann goto done; 2294fee746b0SMarcel Holtmann } 2295fee746b0SMarcel Holtmann 22965b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 22975b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 22985b69bef5SMarcel Holtmann goto done; 22995b69bef5SMarcel Holtmann } 23005b69bef5SMarcel Holtmann 230156f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 230256f87901SJohan Hedberg err = -EOPNOTSUPP; 230356f87901SJohan Hedberg goto done; 230456f87901SJohan Hedberg } 230556f87901SJohan Hedberg 230609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 23071da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 2308a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 23091f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 23101da177e4SLinus Torvalds do_inquiry = 1; 23111da177e4SLinus Torvalds } 231209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 23131da177e4SLinus Torvalds 231404837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 231570f23020SAndrei Emeltchenko 231670f23020SAndrei Emeltchenko if (do_inquiry) { 231701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 231801178cd4SJohan Hedberg timeo); 231970f23020SAndrei Emeltchenko if (err < 0) 23201da177e4SLinus Torvalds goto done; 23213e13fa1eSAndre Guedes 23223e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 23233e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 23243e13fa1eSAndre Guedes */ 232574316201SNeilBrown if (wait_on_bit(&hdev->flags, HCI_INQUIRY, 23263e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 23273e13fa1eSAndre Guedes return -EINTR; 232870f23020SAndrei Emeltchenko } 23291da177e4SLinus Torvalds 23308fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 23318fc9ced3SGustavo Padovan * 255 entries 23328fc9ced3SGustavo Padovan */ 23331da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 23341da177e4SLinus Torvalds 23351da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 23361da177e4SLinus Torvalds * copy it to the user space. 23371da177e4SLinus Torvalds */ 233870f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 233970f23020SAndrei Emeltchenko if (!buf) { 23401da177e4SLinus Torvalds err = -ENOMEM; 23411da177e4SLinus Torvalds goto done; 23421da177e4SLinus Torvalds } 23431da177e4SLinus Torvalds 234409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 23451da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 234609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 23471da177e4SLinus Torvalds 23481da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 23491da177e4SLinus Torvalds 23501da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 23511da177e4SLinus Torvalds ptr += sizeof(ir); 23521da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 23531da177e4SLinus Torvalds ir.num_rsp)) 23541da177e4SLinus Torvalds err = -EFAULT; 23551da177e4SLinus Torvalds } else 23561da177e4SLinus Torvalds err = -EFAULT; 23571da177e4SLinus Torvalds 23581da177e4SLinus Torvalds kfree(buf); 23591da177e4SLinus Torvalds 23601da177e4SLinus Torvalds done: 23611da177e4SLinus Torvalds hci_dev_put(hdev); 23621da177e4SLinus Torvalds return err; 23631da177e4SLinus Torvalds } 23641da177e4SLinus Torvalds 2365cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 23661da177e4SLinus Torvalds { 23671da177e4SLinus Torvalds int ret = 0; 23681da177e4SLinus Torvalds 23691da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 23701da177e4SLinus Torvalds 23711da177e4SLinus Torvalds hci_req_lock(hdev); 23721da177e4SLinus Torvalds 237394324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 237494324962SJohan Hovold ret = -ENODEV; 237594324962SJohan Hovold goto done; 237694324962SJohan Hovold } 237794324962SJohan Hovold 2378d603b76bSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 2379d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags)) { 2380a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 2381a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 2382bf543036SJohan Hedberg */ 2383a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 2384611b30f7SMarcel Holtmann ret = -ERFKILL; 2385611b30f7SMarcel Holtmann goto done; 2386611b30f7SMarcel Holtmann } 2387611b30f7SMarcel Holtmann 2388a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 2389a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 2390a5c8f270SMarcel Holtmann * be able to determine if there is a public address 2391a5c8f270SMarcel Holtmann * or not. 2392a5c8f270SMarcel Holtmann * 2393c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 2394c6beca0eSMarcel Holtmann * if a public address or static random address is 2395c6beca0eSMarcel Holtmann * available. 2396c6beca0eSMarcel Holtmann * 2397a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 2398a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 2399a5c8f270SMarcel Holtmann */ 2400c6beca0eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 2401c6beca0eSMarcel Holtmann hdev->dev_type == HCI_BREDR && 2402a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2403a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 2404a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 2405a5c8f270SMarcel Holtmann goto done; 2406a5c8f270SMarcel Holtmann } 2407a5c8f270SMarcel Holtmann } 2408a5c8f270SMarcel Holtmann 24091da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 24101da177e4SLinus Torvalds ret = -EALREADY; 24111da177e4SLinus Torvalds goto done; 24121da177e4SLinus Torvalds } 24131da177e4SLinus Torvalds 24141da177e4SLinus Torvalds if (hdev->open(hdev)) { 24151da177e4SLinus Torvalds ret = -EIO; 24161da177e4SLinus Torvalds goto done; 24171da177e4SLinus Torvalds } 24181da177e4SLinus Torvalds 24191da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 24201da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 2421f41c70c4SMarcel Holtmann 2422af202f84SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 2423af202f84SMarcel Holtmann if (hdev->setup) 2424f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 2425f41c70c4SMarcel Holtmann 2426af202f84SMarcel Holtmann /* The transport driver can set these quirks before 2427af202f84SMarcel Holtmann * creating the HCI device or in its setup callback. 2428af202f84SMarcel Holtmann * 2429af202f84SMarcel Holtmann * In case any of them is set, the controller has to 2430af202f84SMarcel Holtmann * start up as unconfigured. 2431af202f84SMarcel Holtmann */ 2432eb1904f4SMarcel Holtmann if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) || 2433eb1904f4SMarcel Holtmann test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks)) 243489bc22d2SMarcel Holtmann set_bit(HCI_UNCONFIGURED, &hdev->dev_flags); 2435f41c70c4SMarcel Holtmann 24360ebca7d6SMarcel Holtmann /* For an unconfigured controller it is required to 24370ebca7d6SMarcel Holtmann * read at least the version information provided by 24380ebca7d6SMarcel Holtmann * the Read Local Version Information command. 24390ebca7d6SMarcel Holtmann * 24400ebca7d6SMarcel Holtmann * If the set_bdaddr driver callback is provided, then 24410ebca7d6SMarcel Holtmann * also the original Bluetooth public device address 24420ebca7d6SMarcel Holtmann * will be read using the Read BD Address command. 24430ebca7d6SMarcel Holtmann */ 24440ebca7d6SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) 24450ebca7d6SMarcel Holtmann ret = __hci_unconf_init(hdev); 244689bc22d2SMarcel Holtmann } 244789bc22d2SMarcel Holtmann 24489713c17bSMarcel Holtmann if (test_bit(HCI_CONFIG, &hdev->dev_flags)) { 24499713c17bSMarcel Holtmann /* If public address change is configured, ensure that 24509713c17bSMarcel Holtmann * the address gets programmed. If the driver does not 24519713c17bSMarcel Holtmann * support changing the public address, fail the power 24529713c17bSMarcel Holtmann * on procedure. 245324c457e2SMarcel Holtmann */ 24549713c17bSMarcel Holtmann if (bacmp(&hdev->public_addr, BDADDR_ANY) && 24559713c17bSMarcel Holtmann hdev->set_bdaddr) 245624c457e2SMarcel Holtmann ret = hdev->set_bdaddr(hdev, &hdev->public_addr); 245724c457e2SMarcel Holtmann else 245824c457e2SMarcel Holtmann ret = -EADDRNOTAVAIL; 245924c457e2SMarcel Holtmann } 246024c457e2SMarcel Holtmann 2461f41c70c4SMarcel Holtmann if (!ret) { 24624a964404SMarcel Holtmann if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 24630736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 24642177bab5SJohan Hedberg ret = __hci_init(hdev); 24651da177e4SLinus Torvalds } 24661da177e4SLinus Torvalds 2467f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 2468f41c70c4SMarcel Holtmann 24691da177e4SLinus Torvalds if (!ret) { 24701da177e4SLinus Torvalds hci_dev_hold(hdev); 2471d6bfd59cSJohan Hedberg set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); 24721da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 24731da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 2474bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 2475d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags) && 24764a964404SMarcel Holtmann !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 24770736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 24781514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 247909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2480744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 248109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 248256e5cb86SJohan Hedberg } 24831da177e4SLinus Torvalds } else { 24841da177e4SLinus Torvalds /* Init failed, cleanup */ 24853eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2486c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 2487b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 24881da177e4SLinus Torvalds 24891da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 24901da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 24911da177e4SLinus Torvalds 24921da177e4SLinus Torvalds if (hdev->flush) 24931da177e4SLinus Torvalds hdev->flush(hdev); 24941da177e4SLinus Torvalds 24951da177e4SLinus Torvalds if (hdev->sent_cmd) { 24961da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 24971da177e4SLinus Torvalds hdev->sent_cmd = NULL; 24981da177e4SLinus Torvalds } 24991da177e4SLinus Torvalds 25001da177e4SLinus Torvalds hdev->close(hdev); 2501fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 25021da177e4SLinus Torvalds } 25031da177e4SLinus Torvalds 25041da177e4SLinus Torvalds done: 25051da177e4SLinus Torvalds hci_req_unlock(hdev); 25061da177e4SLinus Torvalds return ret; 25071da177e4SLinus Torvalds } 25081da177e4SLinus Torvalds 2509cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 2510cbed0ca1SJohan Hedberg 2511cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 2512cbed0ca1SJohan Hedberg { 2513cbed0ca1SJohan Hedberg struct hci_dev *hdev; 2514cbed0ca1SJohan Hedberg int err; 2515cbed0ca1SJohan Hedberg 2516cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 2517cbed0ca1SJohan Hedberg if (!hdev) 2518cbed0ca1SJohan Hedberg return -ENODEV; 2519cbed0ca1SJohan Hedberg 25204a964404SMarcel Holtmann /* Devices that are marked as unconfigured can only be powered 2521fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices 2522fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is 2523fee746b0SMarcel Holtmann * possible. 2524fee746b0SMarcel Holtmann * 2525fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag 2526fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to 2527fee746b0SMarcel Holtmann * open the device. 2528fee746b0SMarcel Holtmann */ 25294a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 2530fee746b0SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 2531fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2532fee746b0SMarcel Holtmann goto done; 2533fee746b0SMarcel Holtmann } 2534fee746b0SMarcel Holtmann 2535e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 2536e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 2537e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 2538e1d08f40SJohan Hedberg * completed. 2539e1d08f40SJohan Hedberg */ 2540e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2541e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 2542e1d08f40SJohan Hedberg 2543a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 2544a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 2545a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 2546a5c8f270SMarcel Holtmann */ 2547e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 2548e1d08f40SJohan Hedberg 254912aa4f0aSMarcel Holtmann /* For controllers not using the management interface and that 2550b6ae8457SJohan Hedberg * are brought up using legacy ioctl, set the HCI_BONDABLE bit 255112aa4f0aSMarcel Holtmann * so that pairing works for them. Once the management interface 255212aa4f0aSMarcel Holtmann * is in use this bit will be cleared again and userspace has 255312aa4f0aSMarcel Holtmann * to explicitly enable it. 255412aa4f0aSMarcel Holtmann */ 255512aa4f0aSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 255612aa4f0aSMarcel Holtmann !test_bit(HCI_MGMT, &hdev->dev_flags)) 2557b6ae8457SJohan Hedberg set_bit(HCI_BONDABLE, &hdev->dev_flags); 255812aa4f0aSMarcel Holtmann 2559cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 2560cbed0ca1SJohan Hedberg 2561fee746b0SMarcel Holtmann done: 2562cbed0ca1SJohan Hedberg hci_dev_put(hdev); 2563cbed0ca1SJohan Hedberg return err; 2564cbed0ca1SJohan Hedberg } 2565cbed0ca1SJohan Hedberg 2566d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */ 2567d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev) 2568d7347f3cSJohan Hedberg { 2569d7347f3cSJohan Hedberg struct hci_conn_params *p; 2570d7347f3cSJohan Hedberg 2571f161dd41SJohan Hedberg list_for_each_entry(p, &hdev->le_conn_params, list) { 2572f161dd41SJohan Hedberg if (p->conn) { 2573f161dd41SJohan Hedberg hci_conn_drop(p->conn); 2574f8aaf9b6SJohan Hedberg hci_conn_put(p->conn); 2575f161dd41SJohan Hedberg p->conn = NULL; 2576f161dd41SJohan Hedberg } 2577d7347f3cSJohan Hedberg list_del_init(&p->action); 2578f161dd41SJohan Hedberg } 2579d7347f3cSJohan Hedberg 2580d7347f3cSJohan Hedberg BT_DBG("All LE pending actions cleared"); 2581d7347f3cSJohan Hedberg } 2582d7347f3cSJohan Hedberg 25831da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 25841da177e4SLinus Torvalds { 25851da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 25861da177e4SLinus Torvalds 258778c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 258878c04c0bSVinicius Costa Gomes 25891da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 25901da177e4SLinus Torvalds hci_req_lock(hdev); 25911da177e4SLinus Torvalds 25921da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 259365cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 25941da177e4SLinus Torvalds hci_req_unlock(hdev); 25951da177e4SLinus Torvalds return 0; 25961da177e4SLinus Torvalds } 25971da177e4SLinus Torvalds 25983eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 25993eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2600b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 26011da177e4SLinus Torvalds 260216ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 2603e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 260416ab91abSJohan Hedberg hdev->discov_timeout = 0; 26055e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 2606310a3d48SMarcel Holtmann clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 260716ab91abSJohan Hedberg } 260816ab91abSJohan Hedberg 2609a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 26107d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 26117d78525dSJohan Hedberg 26127ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 26134518bb0fSJohan Hedberg 26144518bb0fSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 2615d6bfd59cSJohan Hedberg cancel_delayed_work_sync(&hdev->rpa_expired); 26167ba8b4beSAndre Guedes 261776727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 261876727c02SJohan Hedberg * ensuring the workqueue is empty up front. 261976727c02SJohan Hedberg */ 262076727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 262176727c02SJohan Hedberg 262209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 26231f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 2624d7347f3cSJohan Hedberg hci_pend_le_actions_clear(hdev); 2625f161dd41SJohan Hedberg hci_conn_hash_flush(hdev); 262609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 26271da177e4SLinus Torvalds 26281da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 26291da177e4SLinus Torvalds 26301da177e4SLinus Torvalds if (hdev->flush) 26311da177e4SLinus Torvalds hdev->flush(hdev); 26321da177e4SLinus Torvalds 26331da177e4SLinus Torvalds /* Reset device */ 26341da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 26351da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 26364a964404SMarcel Holtmann if (!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 26374a964404SMarcel Holtmann !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 2638a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 26391da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 264001178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 26411da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 26421da177e4SLinus Torvalds } 26431da177e4SLinus Torvalds 2644c347b765SGustavo F. Padovan /* flush cmd work */ 2645c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 26461da177e4SLinus Torvalds 26471da177e4SLinus Torvalds /* Drop queues */ 26481da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 26491da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 26501da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 26511da177e4SLinus Torvalds 26521da177e4SLinus Torvalds /* Drop last sent command */ 26531da177e4SLinus Torvalds if (hdev->sent_cmd) { 265465cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 26551da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 26561da177e4SLinus Torvalds hdev->sent_cmd = NULL; 26571da177e4SLinus Torvalds } 26581da177e4SLinus Torvalds 2659b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 2660b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 2661b6ddb638SJohan Hedberg 26621da177e4SLinus Torvalds /* After this point our queues are empty 26631da177e4SLinus Torvalds * and no tasks are scheduled. */ 26641da177e4SLinus Torvalds hdev->close(hdev); 26651da177e4SLinus Torvalds 266635b973c9SJohan Hedberg /* Clear flags */ 2667fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 266835b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 266935b973c9SJohan Hedberg 267093c311a0SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 267193c311a0SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 267209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2673744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 267409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 26758ee56540SMarcel Holtmann } 267693c311a0SMarcel Holtmann } 26775add6af8SJohan Hedberg 2678ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 2679536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 2680ced5c338SAndrei Emeltchenko 2681e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 268209b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 26837a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, BDADDR_ANY); 2684e59fda8dSJohan Hedberg 26851da177e4SLinus Torvalds hci_req_unlock(hdev); 26861da177e4SLinus Torvalds 26871da177e4SLinus Torvalds hci_dev_put(hdev); 26881da177e4SLinus Torvalds return 0; 26891da177e4SLinus Torvalds } 26901da177e4SLinus Torvalds 26911da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 26921da177e4SLinus Torvalds { 26931da177e4SLinus Torvalds struct hci_dev *hdev; 26941da177e4SLinus Torvalds int err; 26951da177e4SLinus Torvalds 269670f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 269770f23020SAndrei Emeltchenko if (!hdev) 26981da177e4SLinus Torvalds return -ENODEV; 26998ee56540SMarcel Holtmann 27000736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 27010736cfa8SMarcel Holtmann err = -EBUSY; 27020736cfa8SMarcel Holtmann goto done; 27030736cfa8SMarcel Holtmann } 27040736cfa8SMarcel Holtmann 27058ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 27068ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 27078ee56540SMarcel Holtmann 27081da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 27098ee56540SMarcel Holtmann 27100736cfa8SMarcel Holtmann done: 27111da177e4SLinus Torvalds hci_dev_put(hdev); 27121da177e4SLinus Torvalds return err; 27131da177e4SLinus Torvalds } 27141da177e4SLinus Torvalds 27151da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 27161da177e4SLinus Torvalds { 27171da177e4SLinus Torvalds struct hci_dev *hdev; 27181da177e4SLinus Torvalds int ret = 0; 27191da177e4SLinus Torvalds 272070f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 272170f23020SAndrei Emeltchenko if (!hdev) 27221da177e4SLinus Torvalds return -ENODEV; 27231da177e4SLinus Torvalds 27241da177e4SLinus Torvalds hci_req_lock(hdev); 27251da177e4SLinus Torvalds 2726808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 2727808a049eSMarcel Holtmann ret = -ENETDOWN; 27281da177e4SLinus Torvalds goto done; 2729808a049eSMarcel Holtmann } 27301da177e4SLinus Torvalds 27310736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 27320736cfa8SMarcel Holtmann ret = -EBUSY; 27330736cfa8SMarcel Holtmann goto done; 27340736cfa8SMarcel Holtmann } 27350736cfa8SMarcel Holtmann 27364a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 2737fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 2738fee746b0SMarcel Holtmann goto done; 2739fee746b0SMarcel Holtmann } 2740fee746b0SMarcel Holtmann 27411da177e4SLinus Torvalds /* Drop queues */ 27421da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 27431da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 27441da177e4SLinus Torvalds 274576727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 274676727c02SJohan Hedberg * ensuring the workqueue is empty up front. 274776727c02SJohan Hedberg */ 274876727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 274976727c02SJohan Hedberg 275009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 27511f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 27521da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 275309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 27541da177e4SLinus Torvalds 27551da177e4SLinus Torvalds if (hdev->flush) 27561da177e4SLinus Torvalds hdev->flush(hdev); 27571da177e4SLinus Torvalds 27581da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 27596ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 27601da177e4SLinus Torvalds 276101178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 27621da177e4SLinus Torvalds 27631da177e4SLinus Torvalds done: 27641da177e4SLinus Torvalds hci_req_unlock(hdev); 27651da177e4SLinus Torvalds hci_dev_put(hdev); 27661da177e4SLinus Torvalds return ret; 27671da177e4SLinus Torvalds } 27681da177e4SLinus Torvalds 27691da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 27701da177e4SLinus Torvalds { 27711da177e4SLinus Torvalds struct hci_dev *hdev; 27721da177e4SLinus Torvalds int ret = 0; 27731da177e4SLinus Torvalds 277470f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 277570f23020SAndrei Emeltchenko if (!hdev) 27761da177e4SLinus Torvalds return -ENODEV; 27771da177e4SLinus Torvalds 27780736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 27790736cfa8SMarcel Holtmann ret = -EBUSY; 27800736cfa8SMarcel Holtmann goto done; 27810736cfa8SMarcel Holtmann } 27820736cfa8SMarcel Holtmann 27834a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 2784fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 2785fee746b0SMarcel Holtmann goto done; 2786fee746b0SMarcel Holtmann } 2787fee746b0SMarcel Holtmann 27881da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 27891da177e4SLinus Torvalds 27900736cfa8SMarcel Holtmann done: 27911da177e4SLinus Torvalds hci_dev_put(hdev); 27921da177e4SLinus Torvalds return ret; 27931da177e4SLinus Torvalds } 27941da177e4SLinus Torvalds 2795123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan) 2796123abc08SJohan Hedberg { 2797bc6d2d04SJohan Hedberg bool conn_changed, discov_changed; 2798123abc08SJohan Hedberg 2799123abc08SJohan Hedberg BT_DBG("%s scan 0x%02x", hdev->name, scan); 2800123abc08SJohan Hedberg 2801123abc08SJohan Hedberg if ((scan & SCAN_PAGE)) 2802123abc08SJohan Hedberg conn_changed = !test_and_set_bit(HCI_CONNECTABLE, 2803123abc08SJohan Hedberg &hdev->dev_flags); 2804123abc08SJohan Hedberg else 2805123abc08SJohan Hedberg conn_changed = test_and_clear_bit(HCI_CONNECTABLE, 2806123abc08SJohan Hedberg &hdev->dev_flags); 2807123abc08SJohan Hedberg 2808bc6d2d04SJohan Hedberg if ((scan & SCAN_INQUIRY)) { 2809bc6d2d04SJohan Hedberg discov_changed = !test_and_set_bit(HCI_DISCOVERABLE, 2810bc6d2d04SJohan Hedberg &hdev->dev_flags); 2811bc6d2d04SJohan Hedberg } else { 2812bc6d2d04SJohan Hedberg clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 2813bc6d2d04SJohan Hedberg discov_changed = test_and_clear_bit(HCI_DISCOVERABLE, 2814bc6d2d04SJohan Hedberg &hdev->dev_flags); 2815bc6d2d04SJohan Hedberg } 2816bc6d2d04SJohan Hedberg 2817123abc08SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2818123abc08SJohan Hedberg return; 2819123abc08SJohan Hedberg 2820bc6d2d04SJohan Hedberg if (conn_changed || discov_changed) { 2821bc6d2d04SJohan Hedberg /* In case this was disabled through mgmt */ 2822bc6d2d04SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 2823bc6d2d04SJohan Hedberg 2824bc6d2d04SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) 2825bc6d2d04SJohan Hedberg mgmt_update_adv_data(hdev); 2826bc6d2d04SJohan Hedberg 2827123abc08SJohan Hedberg mgmt_new_settings(hdev); 2828123abc08SJohan Hedberg } 2829bc6d2d04SJohan Hedberg } 2830123abc08SJohan Hedberg 28311da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 28321da177e4SLinus Torvalds { 28331da177e4SLinus Torvalds struct hci_dev *hdev; 28341da177e4SLinus Torvalds struct hci_dev_req dr; 28351da177e4SLinus Torvalds int err = 0; 28361da177e4SLinus Torvalds 28371da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 28381da177e4SLinus Torvalds return -EFAULT; 28391da177e4SLinus Torvalds 284070f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 284170f23020SAndrei Emeltchenko if (!hdev) 28421da177e4SLinus Torvalds return -ENODEV; 28431da177e4SLinus Torvalds 28440736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 28450736cfa8SMarcel Holtmann err = -EBUSY; 28460736cfa8SMarcel Holtmann goto done; 28470736cfa8SMarcel Holtmann } 28480736cfa8SMarcel Holtmann 28494a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 2850fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2851fee746b0SMarcel Holtmann goto done; 2852fee746b0SMarcel Holtmann } 2853fee746b0SMarcel Holtmann 28545b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 28555b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 28565b69bef5SMarcel Holtmann goto done; 28575b69bef5SMarcel Holtmann } 28585b69bef5SMarcel Holtmann 285956f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 286056f87901SJohan Hedberg err = -EOPNOTSUPP; 286156f87901SJohan Hedberg goto done; 286256f87901SJohan Hedberg } 286356f87901SJohan Hedberg 28641da177e4SLinus Torvalds switch (cmd) { 28651da177e4SLinus Torvalds case HCISETAUTH: 286601178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 28675f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 28681da177e4SLinus Torvalds break; 28691da177e4SLinus Torvalds 28701da177e4SLinus Torvalds case HCISETENCRYPT: 28711da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 28721da177e4SLinus Torvalds err = -EOPNOTSUPP; 28731da177e4SLinus Torvalds break; 28741da177e4SLinus Torvalds } 28751da177e4SLinus Torvalds 28761da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 28771da177e4SLinus Torvalds /* Auth must be enabled first */ 287801178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 28795f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 28801da177e4SLinus Torvalds if (err) 28811da177e4SLinus Torvalds break; 28821da177e4SLinus Torvalds } 28831da177e4SLinus Torvalds 288401178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 28855f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 28861da177e4SLinus Torvalds break; 28871da177e4SLinus Torvalds 28881da177e4SLinus Torvalds case HCISETSCAN: 288901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 28905f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 289191a668b0SJohan Hedberg 2892bc6d2d04SJohan Hedberg /* Ensure that the connectable and discoverable states 2893bc6d2d04SJohan Hedberg * get correctly modified as this was a non-mgmt change. 289491a668b0SJohan Hedberg */ 2895123abc08SJohan Hedberg if (!err) 2896123abc08SJohan Hedberg hci_update_scan_state(hdev, dr.dev_opt); 28971da177e4SLinus Torvalds break; 28981da177e4SLinus Torvalds 28991da177e4SLinus Torvalds case HCISETLINKPOL: 290001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 29015f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 29021da177e4SLinus Torvalds break; 29031da177e4SLinus Torvalds 29041da177e4SLinus Torvalds case HCISETLINKMODE: 2905e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2906e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2907e4e8e37cSMarcel Holtmann break; 2908e4e8e37cSMarcel Holtmann 2909e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2910e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 29111da177e4SLinus Torvalds break; 29121da177e4SLinus Torvalds 29131da177e4SLinus Torvalds case HCISETACLMTU: 29141da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 29151da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 29161da177e4SLinus Torvalds break; 29171da177e4SLinus Torvalds 29181da177e4SLinus Torvalds case HCISETSCOMTU: 29191da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 29201da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 29211da177e4SLinus Torvalds break; 29221da177e4SLinus Torvalds 29231da177e4SLinus Torvalds default: 29241da177e4SLinus Torvalds err = -EINVAL; 29251da177e4SLinus Torvalds break; 29261da177e4SLinus Torvalds } 2927e4e8e37cSMarcel Holtmann 29280736cfa8SMarcel Holtmann done: 29291da177e4SLinus Torvalds hci_dev_put(hdev); 29301da177e4SLinus Torvalds return err; 29311da177e4SLinus Torvalds } 29321da177e4SLinus Torvalds 29331da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 29341da177e4SLinus Torvalds { 29358035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 29361da177e4SLinus Torvalds struct hci_dev_list_req *dl; 29371da177e4SLinus Torvalds struct hci_dev_req *dr; 29381da177e4SLinus Torvalds int n = 0, size, err; 29391da177e4SLinus Torvalds __u16 dev_num; 29401da177e4SLinus Torvalds 29411da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 29421da177e4SLinus Torvalds return -EFAULT; 29431da177e4SLinus Torvalds 29441da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 29451da177e4SLinus Torvalds return -EINVAL; 29461da177e4SLinus Torvalds 29471da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 29481da177e4SLinus Torvalds 294970f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 295070f23020SAndrei Emeltchenko if (!dl) 29511da177e4SLinus Torvalds return -ENOMEM; 29521da177e4SLinus Torvalds 29531da177e4SLinus Torvalds dr = dl->dev_req; 29541da177e4SLinus Torvalds 2955f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 29568035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 29572e84d8dbSMarcel Holtmann unsigned long flags = hdev->flags; 2958c542a06cSJohan Hedberg 29592e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 29602e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 29612e84d8dbSMarcel Holtmann * device is actually down. 29622e84d8dbSMarcel Holtmann */ 29632e84d8dbSMarcel Holtmann if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 29642e84d8dbSMarcel Holtmann flags &= ~BIT(HCI_UP); 2965c542a06cSJohan Hedberg 29661da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 29672e84d8dbSMarcel Holtmann (dr + n)->dev_opt = flags; 2968c542a06cSJohan Hedberg 29691da177e4SLinus Torvalds if (++n >= dev_num) 29701da177e4SLinus Torvalds break; 29711da177e4SLinus Torvalds } 2972f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 29731da177e4SLinus Torvalds 29741da177e4SLinus Torvalds dl->dev_num = n; 29751da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 29761da177e4SLinus Torvalds 29771da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 29781da177e4SLinus Torvalds kfree(dl); 29791da177e4SLinus Torvalds 29801da177e4SLinus Torvalds return err ? -EFAULT : 0; 29811da177e4SLinus Torvalds } 29821da177e4SLinus Torvalds 29831da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 29841da177e4SLinus Torvalds { 29851da177e4SLinus Torvalds struct hci_dev *hdev; 29861da177e4SLinus Torvalds struct hci_dev_info di; 29872e84d8dbSMarcel Holtmann unsigned long flags; 29881da177e4SLinus Torvalds int err = 0; 29891da177e4SLinus Torvalds 29901da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 29911da177e4SLinus Torvalds return -EFAULT; 29921da177e4SLinus Torvalds 299370f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 299470f23020SAndrei Emeltchenko if (!hdev) 29951da177e4SLinus Torvalds return -ENODEV; 29961da177e4SLinus Torvalds 29972e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 29982e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 29992e84d8dbSMarcel Holtmann * device is actually down. 30002e84d8dbSMarcel Holtmann */ 30012e84d8dbSMarcel Holtmann if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 30022e84d8dbSMarcel Holtmann flags = hdev->flags & ~BIT(HCI_UP); 30032e84d8dbSMarcel Holtmann else 30042e84d8dbSMarcel Holtmann flags = hdev->flags; 3005c542a06cSJohan Hedberg 30061da177e4SLinus Torvalds strcpy(di.name, hdev->name); 30071da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 300860f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 30092e84d8dbSMarcel Holtmann di.flags = flags; 30101da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 3011572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 30121da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 30131da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 30141da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 30151da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 3016572c7f84SJohan Hedberg } else { 3017572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 3018572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 3019572c7f84SJohan Hedberg di.sco_mtu = 0; 3020572c7f84SJohan Hedberg di.sco_pkts = 0; 3021572c7f84SJohan Hedberg } 30221da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 30231da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 30241da177e4SLinus Torvalds 30251da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 30261da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 30271da177e4SLinus Torvalds 30281da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 30291da177e4SLinus Torvalds err = -EFAULT; 30301da177e4SLinus Torvalds 30311da177e4SLinus Torvalds hci_dev_put(hdev); 30321da177e4SLinus Torvalds 30331da177e4SLinus Torvalds return err; 30341da177e4SLinus Torvalds } 30351da177e4SLinus Torvalds 30361da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 30371da177e4SLinus Torvalds 3038611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 3039611b30f7SMarcel Holtmann { 3040611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 3041611b30f7SMarcel Holtmann 3042611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 3043611b30f7SMarcel Holtmann 30440736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 30450736cfa8SMarcel Holtmann return -EBUSY; 30460736cfa8SMarcel Holtmann 30475e130367SJohan Hedberg if (blocked) { 30485e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 3049d603b76bSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 3050d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags)) 3051611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 30525e130367SJohan Hedberg } else { 30535e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 30545e130367SJohan Hedberg } 3055611b30f7SMarcel Holtmann 3056611b30f7SMarcel Holtmann return 0; 3057611b30f7SMarcel Holtmann } 3058611b30f7SMarcel Holtmann 3059611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 3060611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 3061611b30f7SMarcel Holtmann }; 3062611b30f7SMarcel Holtmann 3063ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 3064ab81cbf9SJohan Hedberg { 3065ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 306696570ffcSJohan Hedberg int err; 3067ab81cbf9SJohan Hedberg 3068ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 3069ab81cbf9SJohan Hedberg 3070cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 307196570ffcSJohan Hedberg if (err < 0) { 307296570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 3073ab81cbf9SJohan Hedberg return; 307496570ffcSJohan Hedberg } 3075ab81cbf9SJohan Hedberg 3076a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 3077a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 3078a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 3079a5c8f270SMarcel Holtmann */ 3080a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 30814a964404SMarcel Holtmann test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) || 3082a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 3083a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 3084a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 3085bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 3086bf543036SJohan Hedberg hci_dev_do_close(hdev); 3087bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 308819202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 308919202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 3090bf543036SJohan Hedberg } 3091ab81cbf9SJohan Hedberg 3092fee746b0SMarcel Holtmann if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) { 30934a964404SMarcel Holtmann /* For unconfigured devices, set the HCI_RAW flag 30944a964404SMarcel Holtmann * so that userspace can easily identify them. 30954a964404SMarcel Holtmann */ 30964a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) 30974a964404SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 30980602a8adSMarcel Holtmann 30990602a8adSMarcel Holtmann /* For fully configured devices, this will send 31000602a8adSMarcel Holtmann * the Index Added event. For unconfigured devices, 31010602a8adSMarcel Holtmann * it will send Unconfigued Index Added event. 31020602a8adSMarcel Holtmann * 31030602a8adSMarcel Holtmann * Devices with HCI_QUIRK_RAW_DEVICE are ignored 31040602a8adSMarcel Holtmann * and no event will be send. 31050602a8adSMarcel Holtmann */ 3106744cf19eSJohan Hedberg mgmt_index_added(hdev); 3107d603b76bSMarcel Holtmann } else if (test_and_clear_bit(HCI_CONFIG, &hdev->dev_flags)) { 31085ea234d3SMarcel Holtmann /* When the controller is now configured, then it 31095ea234d3SMarcel Holtmann * is important to clear the HCI_RAW flag. 31105ea234d3SMarcel Holtmann */ 31115ea234d3SMarcel Holtmann if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) 31125ea234d3SMarcel Holtmann clear_bit(HCI_RAW, &hdev->flags); 31135ea234d3SMarcel Holtmann 3114d603b76bSMarcel Holtmann /* Powering on the controller with HCI_CONFIG set only 3115d603b76bSMarcel Holtmann * happens with the transition from unconfigured to 3116d603b76bSMarcel Holtmann * configured. This will send the Index Added event. 3117d603b76bSMarcel Holtmann */ 3118d603b76bSMarcel Holtmann mgmt_index_added(hdev); 3119ab81cbf9SJohan Hedberg } 3120ab81cbf9SJohan Hedberg } 3121ab81cbf9SJohan Hedberg 3122ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 3123ab81cbf9SJohan Hedberg { 31243243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 31253243553fSJohan Hedberg power_off.work); 3126ab81cbf9SJohan Hedberg 3127ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 3128ab81cbf9SJohan Hedberg 31298ee56540SMarcel Holtmann hci_dev_do_close(hdev); 3130ab81cbf9SJohan Hedberg } 3131ab81cbf9SJohan Hedberg 313216ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 313316ab91abSJohan Hedberg { 313416ab91abSJohan Hedberg struct hci_dev *hdev; 313516ab91abSJohan Hedberg 313616ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 313716ab91abSJohan Hedberg 313816ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 313916ab91abSJohan Hedberg 3140d1967ff8SMarcel Holtmann mgmt_discoverable_timeout(hdev); 314116ab91abSJohan Hedberg } 314216ab91abSJohan Hedberg 314335f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 31442aeb9a1aSJohan Hedberg { 31454821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 31462aeb9a1aSJohan Hedberg 31474821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 31484821002cSJohan Hedberg list_del(&uuid->list); 31492aeb9a1aSJohan Hedberg kfree(uuid); 31502aeb9a1aSJohan Hedberg } 31512aeb9a1aSJohan Hedberg } 31522aeb9a1aSJohan Hedberg 315335f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 315455ed8ca1SJohan Hedberg { 315555ed8ca1SJohan Hedberg struct link_key *key; 315655ed8ca1SJohan Hedberg 31570378b597SJohan Hedberg list_for_each_entry_rcu(key, &hdev->link_keys, list) { 31580378b597SJohan Hedberg list_del_rcu(&key->list); 31590378b597SJohan Hedberg kfree_rcu(key, rcu); 316055ed8ca1SJohan Hedberg } 316155ed8ca1SJohan Hedberg } 316255ed8ca1SJohan Hedberg 316335f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 3164b899efafSVinicius Costa Gomes { 3165970d0f1bSJohan Hedberg struct smp_ltk *k; 3166b899efafSVinicius Costa Gomes 3167970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 3168970d0f1bSJohan Hedberg list_del_rcu(&k->list); 3169970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 3170b899efafSVinicius Costa Gomes } 3171b899efafSVinicius Costa Gomes } 3172b899efafSVinicius Costa Gomes 3173970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 3174970c4e46SJohan Hedberg { 3175adae20cbSJohan Hedberg struct smp_irk *k; 3176970c4e46SJohan Hedberg 3177adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 3178adae20cbSJohan Hedberg list_del_rcu(&k->list); 3179adae20cbSJohan Hedberg kfree_rcu(k, rcu); 3180970c4e46SJohan Hedberg } 3181970c4e46SJohan Hedberg } 3182970c4e46SJohan Hedberg 318355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 318455ed8ca1SJohan Hedberg { 318555ed8ca1SJohan Hedberg struct link_key *k; 318655ed8ca1SJohan Hedberg 31870378b597SJohan Hedberg rcu_read_lock(); 31880378b597SJohan Hedberg list_for_each_entry_rcu(k, &hdev->link_keys, list) { 31890378b597SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) { 31900378b597SJohan Hedberg rcu_read_unlock(); 319155ed8ca1SJohan Hedberg return k; 31920378b597SJohan Hedberg } 31930378b597SJohan Hedberg } 31940378b597SJohan Hedberg rcu_read_unlock(); 319555ed8ca1SJohan Hedberg 319655ed8ca1SJohan Hedberg return NULL; 319755ed8ca1SJohan Hedberg } 319855ed8ca1SJohan Hedberg 3199745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 3200d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 3201d25e28abSJohan Hedberg { 3202d25e28abSJohan Hedberg /* Legacy key */ 3203d25e28abSJohan Hedberg if (key_type < 0x03) 3204745c0ce3SVishal Agarwal return true; 3205d25e28abSJohan Hedberg 3206d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 3207d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 3208745c0ce3SVishal Agarwal return false; 3209d25e28abSJohan Hedberg 3210d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 3211d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 3212745c0ce3SVishal Agarwal return false; 3213d25e28abSJohan Hedberg 3214d25e28abSJohan Hedberg /* Security mode 3 case */ 3215d25e28abSJohan Hedberg if (!conn) 3216745c0ce3SVishal Agarwal return true; 3217d25e28abSJohan Hedberg 3218e3befab9SJohan Hedberg /* BR/EDR key derived using SC from an LE link */ 3219e3befab9SJohan Hedberg if (conn->type == LE_LINK) 3220e3befab9SJohan Hedberg return true; 3221e3befab9SJohan Hedberg 3222d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 3223d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 3224745c0ce3SVishal Agarwal return true; 3225d25e28abSJohan Hedberg 3226d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 3227d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 3228745c0ce3SVishal Agarwal return true; 3229d25e28abSJohan Hedberg 3230d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 3231d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 3232745c0ce3SVishal Agarwal return true; 3233d25e28abSJohan Hedberg 3234d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 3235d25e28abSJohan Hedberg * persistently */ 3236745c0ce3SVishal Agarwal return false; 3237d25e28abSJohan Hedberg } 3238d25e28abSJohan Hedberg 3239e804d25dSJohan Hedberg static u8 ltk_role(u8 type) 324098a0b845SJohan Hedberg { 3241e804d25dSJohan Hedberg if (type == SMP_LTK) 3242e804d25dSJohan Hedberg return HCI_ROLE_MASTER; 324398a0b845SJohan Hedberg 3244e804d25dSJohan Hedberg return HCI_ROLE_SLAVE; 324598a0b845SJohan Hedberg } 324698a0b845SJohan Hedberg 3247f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 3248e804d25dSJohan Hedberg u8 addr_type, u8 role) 324975d262c2SVinicius Costa Gomes { 3250c9839a11SVinicius Costa Gomes struct smp_ltk *k; 325175d262c2SVinicius Costa Gomes 3252970d0f1bSJohan Hedberg rcu_read_lock(); 3253970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 32545378bc56SJohan Hedberg if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr)) 32555378bc56SJohan Hedberg continue; 32565378bc56SJohan Hedberg 3257923e2414SJohan Hedberg if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) { 3258970d0f1bSJohan Hedberg rcu_read_unlock(); 325975d262c2SVinicius Costa Gomes return k; 3260970d0f1bSJohan Hedberg } 3261970d0f1bSJohan Hedberg } 3262970d0f1bSJohan Hedberg rcu_read_unlock(); 326375d262c2SVinicius Costa Gomes 326475d262c2SVinicius Costa Gomes return NULL; 326575d262c2SVinicius Costa Gomes } 326675d262c2SVinicius Costa Gomes 3267970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 3268970c4e46SJohan Hedberg { 3269970c4e46SJohan Hedberg struct smp_irk *irk; 3270970c4e46SJohan Hedberg 3271adae20cbSJohan Hedberg rcu_read_lock(); 3272adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 3273adae20cbSJohan Hedberg if (!bacmp(&irk->rpa, rpa)) { 3274adae20cbSJohan Hedberg rcu_read_unlock(); 3275970c4e46SJohan Hedberg return irk; 3276970c4e46SJohan Hedberg } 3277adae20cbSJohan Hedberg } 3278970c4e46SJohan Hedberg 3279adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 3280defce9e8SJohan Hedberg if (smp_irk_matches(hdev, irk->val, rpa)) { 3281970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 3282adae20cbSJohan Hedberg rcu_read_unlock(); 3283970c4e46SJohan Hedberg return irk; 3284970c4e46SJohan Hedberg } 3285970c4e46SJohan Hedberg } 3286adae20cbSJohan Hedberg rcu_read_unlock(); 3287970c4e46SJohan Hedberg 3288970c4e46SJohan Hedberg return NULL; 3289970c4e46SJohan Hedberg } 3290970c4e46SJohan Hedberg 3291970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 3292970c4e46SJohan Hedberg u8 addr_type) 3293970c4e46SJohan Hedberg { 3294970c4e46SJohan Hedberg struct smp_irk *irk; 3295970c4e46SJohan Hedberg 32966cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 32976cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 32986cfc9988SJohan Hedberg return NULL; 32996cfc9988SJohan Hedberg 3300adae20cbSJohan Hedberg rcu_read_lock(); 3301adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 3302970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 3303adae20cbSJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) { 3304adae20cbSJohan Hedberg rcu_read_unlock(); 3305970c4e46SJohan Hedberg return irk; 3306970c4e46SJohan Hedberg } 3307adae20cbSJohan Hedberg } 3308adae20cbSJohan Hedberg rcu_read_unlock(); 3309970c4e46SJohan Hedberg 3310970c4e46SJohan Hedberg return NULL; 3311970c4e46SJohan Hedberg } 3312970c4e46SJohan Hedberg 3313567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 33147652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 33157652ff6aSJohan Hedberg u8 pin_len, bool *persistent) 331655ed8ca1SJohan Hedberg { 331755ed8ca1SJohan Hedberg struct link_key *key, *old_key; 3318745c0ce3SVishal Agarwal u8 old_key_type; 331955ed8ca1SJohan Hedberg 332055ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 332155ed8ca1SJohan Hedberg if (old_key) { 332255ed8ca1SJohan Hedberg old_key_type = old_key->type; 332355ed8ca1SJohan Hedberg key = old_key; 332455ed8ca1SJohan Hedberg } else { 332512adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 33260a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 332755ed8ca1SJohan Hedberg if (!key) 3328567fa2aaSJohan Hedberg return NULL; 33290378b597SJohan Hedberg list_add_rcu(&key->list, &hdev->link_keys); 333055ed8ca1SJohan Hedberg } 333155ed8ca1SJohan Hedberg 33326ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 333355ed8ca1SJohan Hedberg 3334d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 3335d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 3336d25e28abSJohan Hedberg * previous key */ 3337d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 3338a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 3339d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 3340655fe6ecSJohan Hedberg if (conn) 3341655fe6ecSJohan Hedberg conn->key_type = type; 3342655fe6ecSJohan Hedberg } 3343d25e28abSJohan Hedberg 334455ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 33459b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 334655ed8ca1SJohan Hedberg key->pin_len = pin_len; 334755ed8ca1SJohan Hedberg 3348b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 334955ed8ca1SJohan Hedberg key->type = old_key_type; 33504748fed2SJohan Hedberg else 33514748fed2SJohan Hedberg key->type = type; 33524748fed2SJohan Hedberg 33537652ff6aSJohan Hedberg if (persistent) 33547652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type, 33557652ff6aSJohan Hedberg old_key_type); 33564df378a1SJohan Hedberg 3357567fa2aaSJohan Hedberg return key; 335855ed8ca1SJohan Hedberg } 335955ed8ca1SJohan Hedberg 3360ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 336135d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 3362fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand) 336375d262c2SVinicius Costa Gomes { 3364c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 3365e804d25dSJohan Hedberg u8 role = ltk_role(type); 336675d262c2SVinicius Costa Gomes 3367f3a73d97SJohan Hedberg old_key = hci_find_ltk(hdev, bdaddr, addr_type, role); 3368c9839a11SVinicius Costa Gomes if (old_key) 336975d262c2SVinicius Costa Gomes key = old_key; 3370c9839a11SVinicius Costa Gomes else { 33710a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 337275d262c2SVinicius Costa Gomes if (!key) 3373ca9142b8SJohan Hedberg return NULL; 3374970d0f1bSJohan Hedberg list_add_rcu(&key->list, &hdev->long_term_keys); 337575d262c2SVinicius Costa Gomes } 337675d262c2SVinicius Costa Gomes 337775d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 3378c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 3379c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 3380c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 3381c9839a11SVinicius Costa Gomes key->ediv = ediv; 3382fe39c7b2SMarcel Holtmann key->rand = rand; 3383c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 3384c9839a11SVinicius Costa Gomes key->type = type; 338575d262c2SVinicius Costa Gomes 3386ca9142b8SJohan Hedberg return key; 338775d262c2SVinicius Costa Gomes } 338875d262c2SVinicius Costa Gomes 3389ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 3390ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 3391970c4e46SJohan Hedberg { 3392970c4e46SJohan Hedberg struct smp_irk *irk; 3393970c4e46SJohan Hedberg 3394970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 3395970c4e46SJohan Hedberg if (!irk) { 3396970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 3397970c4e46SJohan Hedberg if (!irk) 3398ca9142b8SJohan Hedberg return NULL; 3399970c4e46SJohan Hedberg 3400970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 3401970c4e46SJohan Hedberg irk->addr_type = addr_type; 3402970c4e46SJohan Hedberg 3403adae20cbSJohan Hedberg list_add_rcu(&irk->list, &hdev->identity_resolving_keys); 3404970c4e46SJohan Hedberg } 3405970c4e46SJohan Hedberg 3406970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 3407970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 3408970c4e46SJohan Hedberg 3409ca9142b8SJohan Hedberg return irk; 3410970c4e46SJohan Hedberg } 3411970c4e46SJohan Hedberg 341255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 341355ed8ca1SJohan Hedberg { 341455ed8ca1SJohan Hedberg struct link_key *key; 341555ed8ca1SJohan Hedberg 341655ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 341755ed8ca1SJohan Hedberg if (!key) 341855ed8ca1SJohan Hedberg return -ENOENT; 341955ed8ca1SJohan Hedberg 34206ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 342155ed8ca1SJohan Hedberg 34220378b597SJohan Hedberg list_del_rcu(&key->list); 34230378b597SJohan Hedberg kfree_rcu(key, rcu); 342455ed8ca1SJohan Hedberg 342555ed8ca1SJohan Hedberg return 0; 342655ed8ca1SJohan Hedberg } 342755ed8ca1SJohan Hedberg 3428e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 3429b899efafSVinicius Costa Gomes { 3430970d0f1bSJohan Hedberg struct smp_ltk *k; 3431c51ffa0bSJohan Hedberg int removed = 0; 3432b899efafSVinicius Costa Gomes 3433970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 3434e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 3435b899efafSVinicius Costa Gomes continue; 3436b899efafSVinicius Costa Gomes 34376ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 3438b899efafSVinicius Costa Gomes 3439970d0f1bSJohan Hedberg list_del_rcu(&k->list); 3440970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 3441c51ffa0bSJohan Hedberg removed++; 3442b899efafSVinicius Costa Gomes } 3443b899efafSVinicius Costa Gomes 3444c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 3445b899efafSVinicius Costa Gomes } 3446b899efafSVinicius Costa Gomes 3447a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 3448a7ec7338SJohan Hedberg { 3449adae20cbSJohan Hedberg struct smp_irk *k; 3450a7ec7338SJohan Hedberg 3451adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 3452a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 3453a7ec7338SJohan Hedberg continue; 3454a7ec7338SJohan Hedberg 3455a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 3456a7ec7338SJohan Hedberg 3457adae20cbSJohan Hedberg list_del_rcu(&k->list); 3458adae20cbSJohan Hedberg kfree_rcu(k, rcu); 3459a7ec7338SJohan Hedberg } 3460a7ec7338SJohan Hedberg } 3461a7ec7338SJohan Hedberg 34626bd32326SVille Tervo /* HCI command timer function */ 346365cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work) 34646bd32326SVille Tervo { 346565cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, 346665cc2b49SMarcel Holtmann cmd_timer.work); 34676bd32326SVille Tervo 3468bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 3469bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 3470bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 3471bda4f23aSAndrei Emeltchenko 3472bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 3473bda4f23aSAndrei Emeltchenko } else { 34746bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 3475bda4f23aSAndrei Emeltchenko } 3476bda4f23aSAndrei Emeltchenko 34776bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 3478c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 34796bd32326SVille Tervo } 34806bd32326SVille Tervo 34812763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 34826928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type) 34832763eda6SSzymon Janc { 34842763eda6SSzymon Janc struct oob_data *data; 34852763eda6SSzymon Janc 34866928a924SJohan Hedberg list_for_each_entry(data, &hdev->remote_oob_data, list) { 34876928a924SJohan Hedberg if (bacmp(bdaddr, &data->bdaddr) != 0) 34886928a924SJohan Hedberg continue; 34896928a924SJohan Hedberg if (data->bdaddr_type != bdaddr_type) 34906928a924SJohan Hedberg continue; 34912763eda6SSzymon Janc return data; 34926928a924SJohan Hedberg } 34932763eda6SSzymon Janc 34942763eda6SSzymon Janc return NULL; 34952763eda6SSzymon Janc } 34962763eda6SSzymon Janc 34976928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 34986928a924SJohan Hedberg u8 bdaddr_type) 34992763eda6SSzymon Janc { 35002763eda6SSzymon Janc struct oob_data *data; 35012763eda6SSzymon Janc 35026928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 35032763eda6SSzymon Janc if (!data) 35042763eda6SSzymon Janc return -ENOENT; 35052763eda6SSzymon Janc 35066928a924SJohan Hedberg BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type); 35072763eda6SSzymon Janc 35082763eda6SSzymon Janc list_del(&data->list); 35092763eda6SSzymon Janc kfree(data); 35102763eda6SSzymon Janc 35112763eda6SSzymon Janc return 0; 35122763eda6SSzymon Janc } 35132763eda6SSzymon Janc 351435f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 35152763eda6SSzymon Janc { 35162763eda6SSzymon Janc struct oob_data *data, *n; 35172763eda6SSzymon Janc 35182763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 35192763eda6SSzymon Janc list_del(&data->list); 35202763eda6SSzymon Janc kfree(data); 35212763eda6SSzymon Janc } 35222763eda6SSzymon Janc } 35232763eda6SSzymon Janc 35240798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 35256928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192, 352638da1703SJohan Hedberg u8 *hash256, u8 *rand256) 35270798872eSMarcel Holtmann { 35280798872eSMarcel Holtmann struct oob_data *data; 35290798872eSMarcel Holtmann 35306928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 35310798872eSMarcel Holtmann if (!data) { 35320a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 35330798872eSMarcel Holtmann if (!data) 35340798872eSMarcel Holtmann return -ENOMEM; 35350798872eSMarcel Holtmann 35360798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 35376928a924SJohan Hedberg data->bdaddr_type = bdaddr_type; 35380798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 35390798872eSMarcel Holtmann } 35400798872eSMarcel Holtmann 354181328d5cSJohan Hedberg if (hash192 && rand192) { 35420798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 354338da1703SJohan Hedberg memcpy(data->rand192, rand192, sizeof(data->rand192)); 354481328d5cSJohan Hedberg } else { 354581328d5cSJohan Hedberg memset(data->hash192, 0, sizeof(data->hash192)); 354681328d5cSJohan Hedberg memset(data->rand192, 0, sizeof(data->rand192)); 354781328d5cSJohan Hedberg } 35480798872eSMarcel Holtmann 354981328d5cSJohan Hedberg if (hash256 && rand256) { 35500798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 355138da1703SJohan Hedberg memcpy(data->rand256, rand256, sizeof(data->rand256)); 355281328d5cSJohan Hedberg } else { 355381328d5cSJohan Hedberg memset(data->hash256, 0, sizeof(data->hash256)); 355481328d5cSJohan Hedberg memset(data->rand256, 0, sizeof(data->rand256)); 355581328d5cSJohan Hedberg } 35560798872eSMarcel Holtmann 35576ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 35582763eda6SSzymon Janc 35592763eda6SSzymon Janc return 0; 35602763eda6SSzymon Janc } 35612763eda6SSzymon Janc 3562dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list, 3563b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 3564b2a66aadSAntti Julku { 3565b2a66aadSAntti Julku struct bdaddr_list *b; 3566b2a66aadSAntti Julku 3567dcc36c16SJohan Hedberg list_for_each_entry(b, bdaddr_list, list) { 3568b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3569b2a66aadSAntti Julku return b; 3570b9ee0a78SMarcel Holtmann } 3571b2a66aadSAntti Julku 3572b2a66aadSAntti Julku return NULL; 3573b2a66aadSAntti Julku } 3574b2a66aadSAntti Julku 3575dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list) 3576b2a66aadSAntti Julku { 3577b2a66aadSAntti Julku struct list_head *p, *n; 3578b2a66aadSAntti Julku 3579dcc36c16SJohan Hedberg list_for_each_safe(p, n, bdaddr_list) { 3580b9ee0a78SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 3581b2a66aadSAntti Julku 3582b2a66aadSAntti Julku list_del(p); 3583b2a66aadSAntti Julku kfree(b); 3584b2a66aadSAntti Julku } 3585b2a66aadSAntti Julku } 3586b2a66aadSAntti Julku 3587dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type) 3588b2a66aadSAntti Julku { 3589b2a66aadSAntti Julku struct bdaddr_list *entry; 3590b2a66aadSAntti Julku 3591b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3592b2a66aadSAntti Julku return -EBADF; 3593b2a66aadSAntti Julku 3594dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(list, bdaddr, type)) 35955e762444SAntti Julku return -EEXIST; 3596b2a66aadSAntti Julku 359727f70f3eSJohan Hedberg entry = kzalloc(sizeof(*entry), GFP_KERNEL); 35985e762444SAntti Julku if (!entry) 35995e762444SAntti Julku return -ENOMEM; 3600b2a66aadSAntti Julku 3601b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 3602b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 3603b2a66aadSAntti Julku 3604dcc36c16SJohan Hedberg list_add(&entry->list, list); 3605b2a66aadSAntti Julku 36062a8357f2SJohan Hedberg return 0; 3607b2a66aadSAntti Julku } 3608b2a66aadSAntti Julku 3609dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type) 3610b2a66aadSAntti Julku { 3611b2a66aadSAntti Julku struct bdaddr_list *entry; 3612b2a66aadSAntti Julku 361335f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 3614dcc36c16SJohan Hedberg hci_bdaddr_list_clear(list); 361535f7498aSJohan Hedberg return 0; 361635f7498aSJohan Hedberg } 3617b2a66aadSAntti Julku 3618dcc36c16SJohan Hedberg entry = hci_bdaddr_list_lookup(list, bdaddr, type); 3619d2ab0ac1SMarcel Holtmann if (!entry) 3620d2ab0ac1SMarcel Holtmann return -ENOENT; 3621d2ab0ac1SMarcel Holtmann 3622d2ab0ac1SMarcel Holtmann list_del(&entry->list); 3623d2ab0ac1SMarcel Holtmann kfree(entry); 3624d2ab0ac1SMarcel Holtmann 3625d2ab0ac1SMarcel Holtmann return 0; 3626d2ab0ac1SMarcel Holtmann } 3627d2ab0ac1SMarcel Holtmann 362815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 362915819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 363015819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 363115819a70SAndre Guedes { 363215819a70SAndre Guedes struct hci_conn_params *params; 363315819a70SAndre Guedes 3634738f6185SJohan Hedberg /* The conn params list only contains identity addresses */ 3635738f6185SJohan Hedberg if (!hci_is_identity_address(addr, addr_type)) 3636738f6185SJohan Hedberg return NULL; 3637738f6185SJohan Hedberg 363815819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 363915819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 364015819a70SAndre Guedes params->addr_type == addr_type) { 364115819a70SAndre Guedes return params; 364215819a70SAndre Guedes } 364315819a70SAndre Guedes } 364415819a70SAndre Guedes 364515819a70SAndre Guedes return NULL; 364615819a70SAndre Guedes } 364715819a70SAndre Guedes 3648cef952ceSAndre Guedes static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type) 3649cef952ceSAndre Guedes { 3650cef952ceSAndre Guedes struct hci_conn *conn; 3651cef952ceSAndre Guedes 3652cef952ceSAndre Guedes conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr); 3653cef952ceSAndre Guedes if (!conn) 3654cef952ceSAndre Guedes return false; 3655cef952ceSAndre Guedes 3656cef952ceSAndre Guedes if (conn->dst_type != type) 3657cef952ceSAndre Guedes return false; 3658cef952ceSAndre Guedes 3659cef952ceSAndre Guedes if (conn->state != BT_CONNECTED) 3660cef952ceSAndre Guedes return false; 3661cef952ceSAndre Guedes 3662cef952ceSAndre Guedes return true; 3663cef952ceSAndre Guedes } 3664cef952ceSAndre Guedes 366515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 3666501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 36674b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type) 366815819a70SAndre Guedes { 3669912b42efSJohan Hedberg struct hci_conn_params *param; 367015819a70SAndre Guedes 3671738f6185SJohan Hedberg /* The list only contains identity addresses */ 3672738f6185SJohan Hedberg if (!hci_is_identity_address(addr, addr_type)) 3673738f6185SJohan Hedberg return NULL; 367415819a70SAndre Guedes 3675501f8827SJohan Hedberg list_for_each_entry(param, list, action) { 3676912b42efSJohan Hedberg if (bacmp(¶m->addr, addr) == 0 && 3677912b42efSJohan Hedberg param->addr_type == addr_type) 3678912b42efSJohan Hedberg return param; 36794b10966fSMarcel Holtmann } 36804b10966fSMarcel Holtmann 36814b10966fSMarcel Holtmann return NULL; 368215819a70SAndre Guedes } 368315819a70SAndre Guedes 368415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 368551d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 368651d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type) 368715819a70SAndre Guedes { 368815819a70SAndre Guedes struct hci_conn_params *params; 368915819a70SAndre Guedes 3690c46245b3SJohan Hedberg if (!hci_is_identity_address(addr, addr_type)) 369151d167c0SMarcel Holtmann return NULL; 3692a9b0a04cSAndre Guedes 369315819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 3694cef952ceSAndre Guedes if (params) 369551d167c0SMarcel Holtmann return params; 369615819a70SAndre Guedes 369715819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 369815819a70SAndre Guedes if (!params) { 369915819a70SAndre Guedes BT_ERR("Out of memory"); 370051d167c0SMarcel Holtmann return NULL; 370115819a70SAndre Guedes } 370215819a70SAndre Guedes 370315819a70SAndre Guedes bacpy(¶ms->addr, addr); 370415819a70SAndre Guedes params->addr_type = addr_type; 3705cef952ceSAndre Guedes 3706cef952ceSAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 370793450c75SJohan Hedberg INIT_LIST_HEAD(¶ms->action); 3708cef952ceSAndre Guedes 3709bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval; 3710bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval; 3711bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency; 3712bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout; 3713bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED; 3714bf5b3c8bSMarcel Holtmann 3715bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 3716bf5b3c8bSMarcel Holtmann 371751d167c0SMarcel Holtmann return params; 3718bf5b3c8bSMarcel Holtmann } 3719bf5b3c8bSMarcel Holtmann 3720bf5b3c8bSMarcel Holtmann /* This function requires the caller holds hdev->lock */ 3721bf5b3c8bSMarcel Holtmann int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, 3722d06b50ceSMarcel Holtmann u8 auto_connect) 372315819a70SAndre Guedes { 372415819a70SAndre Guedes struct hci_conn_params *params; 372515819a70SAndre Guedes 37268c87aae1SMarcel Holtmann params = hci_conn_params_add(hdev, addr, addr_type); 37278c87aae1SMarcel Holtmann if (!params) 37288c87aae1SMarcel Holtmann return -EIO; 372915819a70SAndre Guedes 373042ce26deSJohan Hedberg if (params->auto_connect == auto_connect) 373142ce26deSJohan Hedberg return 0; 373242ce26deSJohan Hedberg 373366f8455aSJohan Hedberg list_del_init(¶ms->action); 373415819a70SAndre Guedes 3735cef952ceSAndre Guedes switch (auto_connect) { 3736cef952ceSAndre Guedes case HCI_AUTO_CONN_DISABLED: 3737cef952ceSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 373895305baaSJohan Hedberg hci_update_background_scan(hdev); 3739cef952ceSAndre Guedes break; 3740851efca8SJohan Hedberg case HCI_AUTO_CONN_REPORT: 374195305baaSJohan Hedberg list_add(¶ms->action, &hdev->pend_le_reports); 374295305baaSJohan Hedberg hci_update_background_scan(hdev); 3743851efca8SJohan Hedberg break; 37444b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 3745cef952ceSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 374695305baaSJohan Hedberg if (!is_connected(hdev, addr, addr_type)) { 374795305baaSJohan Hedberg list_add(¶ms->action, &hdev->pend_le_conns); 374895305baaSJohan Hedberg hci_update_background_scan(hdev); 374995305baaSJohan Hedberg } 3750cef952ceSAndre Guedes break; 3751cef952ceSAndre Guedes } 375215819a70SAndre Guedes 3753851efca8SJohan Hedberg params->auto_connect = auto_connect; 3754851efca8SJohan Hedberg 3755d06b50ceSMarcel Holtmann BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type, 3756d06b50ceSMarcel Holtmann auto_connect); 3757a9b0a04cSAndre Guedes 3758a9b0a04cSAndre Guedes return 0; 375915819a70SAndre Guedes } 376015819a70SAndre Guedes 3761f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params) 3762f6c63249SJohan Hedberg { 3763f6c63249SJohan Hedberg if (params->conn) { 3764f6c63249SJohan Hedberg hci_conn_drop(params->conn); 3765f6c63249SJohan Hedberg hci_conn_put(params->conn); 3766f6c63249SJohan Hedberg } 3767f6c63249SJohan Hedberg 3768f6c63249SJohan Hedberg list_del(¶ms->action); 3769f6c63249SJohan Hedberg list_del(¶ms->list); 3770f6c63249SJohan Hedberg kfree(params); 3771f6c63249SJohan Hedberg } 3772f6c63249SJohan Hedberg 377315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 377415819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 377515819a70SAndre Guedes { 377615819a70SAndre Guedes struct hci_conn_params *params; 377715819a70SAndre Guedes 377815819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 377915819a70SAndre Guedes if (!params) 378015819a70SAndre Guedes return; 378115819a70SAndre Guedes 3782f6c63249SJohan Hedberg hci_conn_params_free(params); 378315819a70SAndre Guedes 378495305baaSJohan Hedberg hci_update_background_scan(hdev); 378595305baaSJohan Hedberg 378615819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 378715819a70SAndre Guedes } 378815819a70SAndre Guedes 378915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 379055af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev) 379115819a70SAndre Guedes { 379215819a70SAndre Guedes struct hci_conn_params *params, *tmp; 379315819a70SAndre Guedes 379415819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 379555af49a8SJohan Hedberg if (params->auto_connect != HCI_AUTO_CONN_DISABLED) 379655af49a8SJohan Hedberg continue; 379715819a70SAndre Guedes list_del(¶ms->list); 379815819a70SAndre Guedes kfree(params); 379915819a70SAndre Guedes } 380015819a70SAndre Guedes 380155af49a8SJohan Hedberg BT_DBG("All LE disabled connection parameters were removed"); 380255af49a8SJohan Hedberg } 380355af49a8SJohan Hedberg 380455af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */ 3805373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev) 380615819a70SAndre Guedes { 380715819a70SAndre Guedes struct hci_conn_params *params, *tmp; 380815819a70SAndre Guedes 3809f6c63249SJohan Hedberg list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) 3810f6c63249SJohan Hedberg hci_conn_params_free(params); 381115819a70SAndre Guedes 3812a2f41a8fSJohan Hedberg hci_update_background_scan(hdev); 38131089b67dSMarcel Holtmann 381415819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 381515819a70SAndre Guedes } 381615819a70SAndre Guedes 38174c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 38187ba8b4beSAndre Guedes { 38194c87eaabSAndre Guedes if (status) { 38204c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 38217ba8b4beSAndre Guedes 38224c87eaabSAndre Guedes hci_dev_lock(hdev); 38234c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 38244c87eaabSAndre Guedes hci_dev_unlock(hdev); 38254c87eaabSAndre Guedes return; 38264c87eaabSAndre Guedes } 38277ba8b4beSAndre Guedes } 38287ba8b4beSAndre Guedes 38294c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 38307ba8b4beSAndre Guedes { 38314c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 38324c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 38334c87eaabSAndre Guedes struct hci_request req; 38344c87eaabSAndre Guedes struct hci_cp_inquiry cp; 38357ba8b4beSAndre Guedes int err; 38367ba8b4beSAndre Guedes 38374c87eaabSAndre Guedes if (status) { 38384c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 38394c87eaabSAndre Guedes return; 38407ba8b4beSAndre Guedes } 38417ba8b4beSAndre Guedes 38424c87eaabSAndre Guedes switch (hdev->discovery.type) { 38434c87eaabSAndre Guedes case DISCOV_TYPE_LE: 38444c87eaabSAndre Guedes hci_dev_lock(hdev); 38454c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 38464c87eaabSAndre Guedes hci_dev_unlock(hdev); 38474c87eaabSAndre Guedes break; 38487dbfac1dSAndre Guedes 38494c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 38504c87eaabSAndre Guedes hci_req_init(&req, hdev); 38517dbfac1dSAndre Guedes 38527dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 38534c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 38544c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 38554c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 38564c87eaabSAndre Guedes 38574c87eaabSAndre Guedes hci_dev_lock(hdev); 38584c87eaabSAndre Guedes 38594c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 38604c87eaabSAndre Guedes 38614c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 38624c87eaabSAndre Guedes if (err) { 38634c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 38644c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 38657dbfac1dSAndre Guedes } 38667dbfac1dSAndre Guedes 38674c87eaabSAndre Guedes hci_dev_unlock(hdev); 38684c87eaabSAndre Guedes break; 38694c87eaabSAndre Guedes } 38707dbfac1dSAndre Guedes } 38717dbfac1dSAndre Guedes 38727ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 38737ba8b4beSAndre Guedes { 38747ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 38757ba8b4beSAndre Guedes le_scan_disable.work); 38764c87eaabSAndre Guedes struct hci_request req; 38774c87eaabSAndre Guedes int err; 38787ba8b4beSAndre Guedes 38797ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 38807ba8b4beSAndre Guedes 38814c87eaabSAndre Guedes hci_req_init(&req, hdev); 38827ba8b4beSAndre Guedes 3883b1efcc28SAndre Guedes hci_req_add_le_scan_disable(&req); 38847ba8b4beSAndre Guedes 38854c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 38864c87eaabSAndre Guedes if (err) 38874c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 388828b75a89SAndre Guedes } 388928b75a89SAndre Guedes 38908d97250eSJohan Hedberg static void set_random_addr(struct hci_request *req, bdaddr_t *rpa) 38918d97250eSJohan Hedberg { 38928d97250eSJohan Hedberg struct hci_dev *hdev = req->hdev; 38938d97250eSJohan Hedberg 38948d97250eSJohan Hedberg /* If we're advertising or initiating an LE connection we can't 38958d97250eSJohan Hedberg * go ahead and change the random address at this time. This is 38968d97250eSJohan Hedberg * because the eventual initiator address used for the 38978d97250eSJohan Hedberg * subsequently created connection will be undefined (some 38988d97250eSJohan Hedberg * controllers use the new address and others the one we had 38998d97250eSJohan Hedberg * when the operation started). 39008d97250eSJohan Hedberg * 39018d97250eSJohan Hedberg * In this kind of scenario skip the update and let the random 39028d97250eSJohan Hedberg * address be updated at the next cycle. 39038d97250eSJohan Hedberg */ 39045ce194c4SJohan Hedberg if (test_bit(HCI_LE_ADV, &hdev->dev_flags) || 39058d97250eSJohan Hedberg hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { 39068d97250eSJohan Hedberg BT_DBG("Deferring random address update"); 39079a783a13SJohan Hedberg set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); 39088d97250eSJohan Hedberg return; 39098d97250eSJohan Hedberg } 39108d97250eSJohan Hedberg 39118d97250eSJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa); 39128d97250eSJohan Hedberg } 39138d97250eSJohan Hedberg 391494b1fc92SMarcel Holtmann int hci_update_random_address(struct hci_request *req, bool require_privacy, 391594b1fc92SMarcel Holtmann u8 *own_addr_type) 3916ebd3a747SJohan Hedberg { 3917ebd3a747SJohan Hedberg struct hci_dev *hdev = req->hdev; 3918ebd3a747SJohan Hedberg int err; 3919ebd3a747SJohan Hedberg 3920ebd3a747SJohan Hedberg /* If privacy is enabled use a resolvable private address. If 39212b5224dcSMarcel Holtmann * current RPA has expired or there is something else than 39222b5224dcSMarcel Holtmann * the current RPA in use, then generate a new one. 3923ebd3a747SJohan Hedberg */ 3924ebd3a747SJohan Hedberg if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) { 3925ebd3a747SJohan Hedberg int to; 3926ebd3a747SJohan Hedberg 3927ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_RANDOM; 3928ebd3a747SJohan Hedberg 3929ebd3a747SJohan Hedberg if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) && 39302b5224dcSMarcel Holtmann !bacmp(&hdev->random_addr, &hdev->rpa)) 3931ebd3a747SJohan Hedberg return 0; 3932ebd3a747SJohan Hedberg 3933defce9e8SJohan Hedberg err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa); 3934ebd3a747SJohan Hedberg if (err < 0) { 3935ebd3a747SJohan Hedberg BT_ERR("%s failed to generate new RPA", hdev->name); 3936ebd3a747SJohan Hedberg return err; 3937ebd3a747SJohan Hedberg } 3938ebd3a747SJohan Hedberg 39398d97250eSJohan Hedberg set_random_addr(req, &hdev->rpa); 3940ebd3a747SJohan Hedberg 3941ebd3a747SJohan Hedberg to = msecs_to_jiffies(hdev->rpa_timeout * 1000); 3942ebd3a747SJohan Hedberg queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to); 3943ebd3a747SJohan Hedberg 3944ebd3a747SJohan Hedberg return 0; 3945ebd3a747SJohan Hedberg } 3946ebd3a747SJohan Hedberg 394794b1fc92SMarcel Holtmann /* In case of required privacy without resolvable private address, 394894b1fc92SMarcel Holtmann * use an unresolvable private address. This is useful for active 394994b1fc92SMarcel Holtmann * scanning and non-connectable advertising. 395094b1fc92SMarcel Holtmann */ 395194b1fc92SMarcel Holtmann if (require_privacy) { 395294b1fc92SMarcel Holtmann bdaddr_t urpa; 395394b1fc92SMarcel Holtmann 395494b1fc92SMarcel Holtmann get_random_bytes(&urpa, 6); 395594b1fc92SMarcel Holtmann urpa.b[5] &= 0x3f; /* Clear two most significant bits */ 395694b1fc92SMarcel Holtmann 395794b1fc92SMarcel Holtmann *own_addr_type = ADDR_LE_DEV_RANDOM; 39588d97250eSJohan Hedberg set_random_addr(req, &urpa); 395994b1fc92SMarcel Holtmann return 0; 396094b1fc92SMarcel Holtmann } 396194b1fc92SMarcel Holtmann 3962ebd3a747SJohan Hedberg /* If forcing static address is in use or there is no public 3963ebd3a747SJohan Hedberg * address use the static address as random address (but skip 3964ebd3a747SJohan Hedberg * the HCI command if the current random address is already the 3965ebd3a747SJohan Hedberg * static one. 3966ebd3a747SJohan Hedberg */ 3967111902f7SMarcel Holtmann if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) || 3968ebd3a747SJohan Hedberg !bacmp(&hdev->bdaddr, BDADDR_ANY)) { 3969ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_RANDOM; 3970ebd3a747SJohan Hedberg if (bacmp(&hdev->static_addr, &hdev->random_addr)) 3971ebd3a747SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, 3972ebd3a747SJohan Hedberg &hdev->static_addr); 3973ebd3a747SJohan Hedberg return 0; 3974ebd3a747SJohan Hedberg } 3975ebd3a747SJohan Hedberg 3976ebd3a747SJohan Hedberg /* Neither privacy nor static address is being used so use a 3977ebd3a747SJohan Hedberg * public address. 3978ebd3a747SJohan Hedberg */ 3979ebd3a747SJohan Hedberg *own_addr_type = ADDR_LE_DEV_PUBLIC; 3980ebd3a747SJohan Hedberg 3981ebd3a747SJohan Hedberg return 0; 3982ebd3a747SJohan Hedberg } 3983ebd3a747SJohan Hedberg 3984a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 3985a1f4c318SJohan Hedberg * 3986a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 3987a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 3988a1f4c318SJohan Hedberg * the static random address. 3989a1f4c318SJohan Hedberg * 3990a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 3991a1f4c318SJohan Hedberg * public address to use the static random address instead. 3992a1f4c318SJohan Hedberg */ 3993a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 3994a1f4c318SJohan Hedberg u8 *bdaddr_type) 3995a1f4c318SJohan Hedberg { 3996111902f7SMarcel Holtmann if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) || 3997a1f4c318SJohan Hedberg !bacmp(&hdev->bdaddr, BDADDR_ANY)) { 3998a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 3999a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 4000a1f4c318SJohan Hedberg } else { 4001a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 4002a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 4003a1f4c318SJohan Hedberg } 4004a1f4c318SJohan Hedberg } 4005a1f4c318SJohan Hedberg 40069be0dab7SDavid Herrmann /* Alloc HCI device */ 40079be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 40089be0dab7SDavid Herrmann { 40099be0dab7SDavid Herrmann struct hci_dev *hdev; 40109be0dab7SDavid Herrmann 401127f70f3eSJohan Hedberg hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); 40129be0dab7SDavid Herrmann if (!hdev) 40139be0dab7SDavid Herrmann return NULL; 40149be0dab7SDavid Herrmann 4015b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 4016b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 4017b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 4018b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 4019b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 402096c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */ 4021bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 4022bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 4023b1b813d4SDavid Herrmann 4024b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 4025b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 4026b1b813d4SDavid Herrmann 40273f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 4028628531c9SGeorg Lukas hdev->le_adv_min_interval = 0x0800; 4029628531c9SGeorg Lukas hdev->le_adv_max_interval = 0x0800; 4030bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 4031bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 40324e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = 0x0028; 40334e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = 0x0038; 403404fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000; 403504fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a; 4036bef64738SMarcel Holtmann 4037d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 4038b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 403931ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 404031ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 4041d6bfd59cSJohan Hedberg 4042b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 4043b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 4044b1b813d4SDavid Herrmann 4045b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 4046b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 40476659358eSJohan Hedberg INIT_LIST_HEAD(&hdev->whitelist); 4048b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 4049b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 4050b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 4051970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 4052b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 4053d2ab0ac1SMarcel Holtmann INIT_LIST_HEAD(&hdev->le_white_list); 405415819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 405577a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 405666f8455aSJohan Hedberg INIT_LIST_HEAD(&hdev->pend_le_reports); 40576b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 4058b1b813d4SDavid Herrmann 4059b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 4060b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 4061b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 4062b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 4063b1b813d4SDavid Herrmann 4064b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 4065b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 4066b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 4067b1b813d4SDavid Herrmann 4068b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 4069b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 4070b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 4071b1b813d4SDavid Herrmann 4072b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 4073b1b813d4SDavid Herrmann 407465cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout); 4075b1b813d4SDavid Herrmann 4076b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 4077b1b813d4SDavid Herrmann discovery_init(hdev); 40789be0dab7SDavid Herrmann 40799be0dab7SDavid Herrmann return hdev; 40809be0dab7SDavid Herrmann } 40819be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 40829be0dab7SDavid Herrmann 40839be0dab7SDavid Herrmann /* Free HCI device */ 40849be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 40859be0dab7SDavid Herrmann { 40869be0dab7SDavid Herrmann /* will free via device release */ 40879be0dab7SDavid Herrmann put_device(&hdev->dev); 40889be0dab7SDavid Herrmann } 40899be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 40909be0dab7SDavid Herrmann 40911da177e4SLinus Torvalds /* Register HCI device */ 40921da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 40931da177e4SLinus Torvalds { 4094b1b813d4SDavid Herrmann int id, error; 40951da177e4SLinus Torvalds 409674292d5aSMarcel Holtmann if (!hdev->open || !hdev->close || !hdev->send) 40971da177e4SLinus Torvalds return -EINVAL; 40981da177e4SLinus Torvalds 409908add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 410008add513SMat Martineau * so the index can be used as the AMP controller ID. 410108add513SMat Martineau */ 41023df92b31SSasha Levin switch (hdev->dev_type) { 41033df92b31SSasha Levin case HCI_BREDR: 41043df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 41051da177e4SLinus Torvalds break; 41063df92b31SSasha Levin case HCI_AMP: 41073df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 41083df92b31SSasha Levin break; 41093df92b31SSasha Levin default: 41103df92b31SSasha Levin return -EINVAL; 41111da177e4SLinus Torvalds } 41121da177e4SLinus Torvalds 41133df92b31SSasha Levin if (id < 0) 41143df92b31SSasha Levin return id; 41153df92b31SSasha Levin 41161da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 41171da177e4SLinus Torvalds hdev->id = id; 41182d8b3a11SAndrei Emeltchenko 41192d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 41202d8b3a11SAndrei Emeltchenko 4121d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 4122d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 412333ca954dSDavid Herrmann if (!hdev->workqueue) { 412433ca954dSDavid Herrmann error = -ENOMEM; 412533ca954dSDavid Herrmann goto err; 412633ca954dSDavid Herrmann } 4127f48fd9c8SMarcel Holtmann 4128d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 4129d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 41306ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 41316ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 41326ead1bbcSJohan Hedberg error = -ENOMEM; 41336ead1bbcSJohan Hedberg goto err; 41346ead1bbcSJohan Hedberg } 41356ead1bbcSJohan Hedberg 41360153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 41370153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 41380153e2ecSMarcel Holtmann 4139bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 4140bdc3e0f1SMarcel Holtmann 4141bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 414233ca954dSDavid Herrmann if (error < 0) 414354506918SJohan Hedberg goto err_wqueue; 41441da177e4SLinus Torvalds 4145611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 4146a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 4147a8c5fb1aSGustavo Padovan hdev); 4148611b30f7SMarcel Holtmann if (hdev->rfkill) { 4149611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 4150611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 4151611b30f7SMarcel Holtmann hdev->rfkill = NULL; 4152611b30f7SMarcel Holtmann } 4153611b30f7SMarcel Holtmann } 4154611b30f7SMarcel Holtmann 41555e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 41565e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 41575e130367SJohan Hedberg 4158a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 4159004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 4160ce2be9acSAndrei Emeltchenko 416101cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 416256f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 416356f87901SJohan Hedberg * through reading supported features during init. 416456f87901SJohan Hedberg */ 416556f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 416656f87901SJohan Hedberg } 4167ce2be9acSAndrei Emeltchenko 4168fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 4169fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 4170fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 4171fcee3377SGustavo Padovan 41724a964404SMarcel Holtmann /* Devices that are marked for raw-only usage are unconfigured 41734a964404SMarcel Holtmann * and should not be included in normal operation. 4174fee746b0SMarcel Holtmann */ 4175fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 41764a964404SMarcel Holtmann set_bit(HCI_UNCONFIGURED, &hdev->dev_flags); 4177fee746b0SMarcel Holtmann 41781da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 4179dc946bd8SDavid Herrmann hci_dev_hold(hdev); 41801da177e4SLinus Torvalds 418119202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 4182fbe96d6fSMarcel Holtmann 41831da177e4SLinus Torvalds return id; 4184f48fd9c8SMarcel Holtmann 418533ca954dSDavid Herrmann err_wqueue: 418633ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 41876ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 418833ca954dSDavid Herrmann err: 41893df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 4190f48fd9c8SMarcel Holtmann 419133ca954dSDavid Herrmann return error; 41921da177e4SLinus Torvalds } 41931da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 41941da177e4SLinus Torvalds 41951da177e4SLinus Torvalds /* Unregister HCI device */ 419659735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 41971da177e4SLinus Torvalds { 41983df92b31SSasha Levin int i, id; 4199ef222013SMarcel Holtmann 4200c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 42011da177e4SLinus Torvalds 420294324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 420394324962SJohan Hovold 42043df92b31SSasha Levin id = hdev->id; 42053df92b31SSasha Levin 4206f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 42071da177e4SLinus Torvalds list_del(&hdev->list); 4208f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 42091da177e4SLinus Torvalds 42101da177e4SLinus Torvalds hci_dev_do_close(hdev); 42111da177e4SLinus Torvalds 4212cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 4213ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 4214ef222013SMarcel Holtmann 4215b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 4216b9b5ef18SGustavo Padovan 4217ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 4218d603b76bSMarcel Holtmann !test_bit(HCI_SETUP, &hdev->dev_flags) && 4219d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags)) { 422009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4221744cf19eSJohan Hedberg mgmt_index_removed(hdev); 422209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 422356e5cb86SJohan Hedberg } 4224ab81cbf9SJohan Hedberg 42252e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 42262e58ef3eSJohan Hedberg * pending list */ 42272e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 42282e58ef3eSJohan Hedberg 42291da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 42301da177e4SLinus Torvalds 4231611b30f7SMarcel Holtmann if (hdev->rfkill) { 4232611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 4233611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 4234611b30f7SMarcel Holtmann } 4235611b30f7SMarcel Holtmann 4236711eafe3SJohan Hedberg smp_unregister(hdev); 423799780a7bSJohan Hedberg 4238bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 4239147e2d59SDave Young 42400153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 42410153e2ecSMarcel Holtmann 4242f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 42436ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 4244f48fd9c8SMarcel Holtmann 424509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4246dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->blacklist); 42476659358eSJohan Hedberg hci_bdaddr_list_clear(&hdev->whitelist); 42482aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 424955ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 4250b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 4251970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 42522763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 4253dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->le_white_list); 4254373110c5SJohan Hedberg hci_conn_params_clear_all(hdev); 425522078800SMarcel Holtmann hci_discovery_filter_clear(hdev); 425609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 4257e2e0cacbSJohan Hedberg 4258dc946bd8SDavid Herrmann hci_dev_put(hdev); 42593df92b31SSasha Levin 42603df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 42611da177e4SLinus Torvalds } 42621da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 42631da177e4SLinus Torvalds 42641da177e4SLinus Torvalds /* Suspend HCI device */ 42651da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 42661da177e4SLinus Torvalds { 42671da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 42681da177e4SLinus Torvalds return 0; 42691da177e4SLinus Torvalds } 42701da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 42711da177e4SLinus Torvalds 42721da177e4SLinus Torvalds /* Resume HCI device */ 42731da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 42741da177e4SLinus Torvalds { 42751da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 42761da177e4SLinus Torvalds return 0; 42771da177e4SLinus Torvalds } 42781da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 42791da177e4SLinus Torvalds 428075e0569fSMarcel Holtmann /* Reset HCI device */ 428175e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev) 428275e0569fSMarcel Holtmann { 428375e0569fSMarcel Holtmann const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; 428475e0569fSMarcel Holtmann struct sk_buff *skb; 428575e0569fSMarcel Holtmann 428675e0569fSMarcel Holtmann skb = bt_skb_alloc(3, GFP_ATOMIC); 428775e0569fSMarcel Holtmann if (!skb) 428875e0569fSMarcel Holtmann return -ENOMEM; 428975e0569fSMarcel Holtmann 429075e0569fSMarcel Holtmann bt_cb(skb)->pkt_type = HCI_EVENT_PKT; 429175e0569fSMarcel Holtmann memcpy(skb_put(skb, 3), hw_err, 3); 429275e0569fSMarcel Holtmann 429375e0569fSMarcel Holtmann /* Send Hardware Error to upper stack */ 429475e0569fSMarcel Holtmann return hci_recv_frame(hdev, skb); 429575e0569fSMarcel Holtmann } 429675e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev); 429775e0569fSMarcel Holtmann 429876bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 4299e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 430076bca880SMarcel Holtmann { 430176bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 430276bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 430376bca880SMarcel Holtmann kfree_skb(skb); 430476bca880SMarcel Holtmann return -ENXIO; 430576bca880SMarcel Holtmann } 430676bca880SMarcel Holtmann 4307d82603c6SJorrit Schippers /* Incoming skb */ 430876bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 430976bca880SMarcel Holtmann 431076bca880SMarcel Holtmann /* Time stamp */ 431176bca880SMarcel Holtmann __net_timestamp(skb); 431276bca880SMarcel Holtmann 431376bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 4314b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 4315c78ae283SMarcel Holtmann 431676bca880SMarcel Holtmann return 0; 431776bca880SMarcel Holtmann } 431876bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 431976bca880SMarcel Holtmann 432033e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 43211e429f38SGustavo F. Padovan int count, __u8 index) 432233e882a5SSuraj Sumangala { 432333e882a5SSuraj Sumangala int len = 0; 432433e882a5SSuraj Sumangala int hlen = 0; 432533e882a5SSuraj Sumangala int remain = count; 432633e882a5SSuraj Sumangala struct sk_buff *skb; 432733e882a5SSuraj Sumangala struct bt_skb_cb *scb; 432833e882a5SSuraj Sumangala 432933e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 433033e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 433133e882a5SSuraj Sumangala return -EILSEQ; 433233e882a5SSuraj Sumangala 433333e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 433433e882a5SSuraj Sumangala 433533e882a5SSuraj Sumangala if (!skb) { 433633e882a5SSuraj Sumangala switch (type) { 433733e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 433833e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 433933e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 434033e882a5SSuraj Sumangala break; 434133e882a5SSuraj Sumangala case HCI_EVENT_PKT: 434233e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 434333e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 434433e882a5SSuraj Sumangala break; 434533e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 434633e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 434733e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 434833e882a5SSuraj Sumangala break; 434933e882a5SSuraj Sumangala } 435033e882a5SSuraj Sumangala 43511e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 435233e882a5SSuraj Sumangala if (!skb) 435333e882a5SSuraj Sumangala return -ENOMEM; 435433e882a5SSuraj Sumangala 435533e882a5SSuraj Sumangala scb = (void *) skb->cb; 435633e882a5SSuraj Sumangala scb->expect = hlen; 435733e882a5SSuraj Sumangala scb->pkt_type = type; 435833e882a5SSuraj Sumangala 435933e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 436033e882a5SSuraj Sumangala } 436133e882a5SSuraj Sumangala 436233e882a5SSuraj Sumangala while (count) { 436333e882a5SSuraj Sumangala scb = (void *) skb->cb; 436489bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 436533e882a5SSuraj Sumangala 436633e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 436733e882a5SSuraj Sumangala 436833e882a5SSuraj Sumangala count -= len; 436933e882a5SSuraj Sumangala data += len; 437033e882a5SSuraj Sumangala scb->expect -= len; 437133e882a5SSuraj Sumangala remain = count; 437233e882a5SSuraj Sumangala 437333e882a5SSuraj Sumangala switch (type) { 437433e882a5SSuraj Sumangala case HCI_EVENT_PKT: 437533e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 437633e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 437733e882a5SSuraj Sumangala scb->expect = h->plen; 437833e882a5SSuraj Sumangala 437933e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 438033e882a5SSuraj Sumangala kfree_skb(skb); 438133e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 438233e882a5SSuraj Sumangala return -ENOMEM; 438333e882a5SSuraj Sumangala } 438433e882a5SSuraj Sumangala } 438533e882a5SSuraj Sumangala break; 438633e882a5SSuraj Sumangala 438733e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 438833e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 438933e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 439033e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 439133e882a5SSuraj Sumangala 439233e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 439333e882a5SSuraj Sumangala kfree_skb(skb); 439433e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 439533e882a5SSuraj Sumangala return -ENOMEM; 439633e882a5SSuraj Sumangala } 439733e882a5SSuraj Sumangala } 439833e882a5SSuraj Sumangala break; 439933e882a5SSuraj Sumangala 440033e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 440133e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 440233e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 440333e882a5SSuraj Sumangala scb->expect = h->dlen; 440433e882a5SSuraj Sumangala 440533e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 440633e882a5SSuraj Sumangala kfree_skb(skb); 440733e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 440833e882a5SSuraj Sumangala return -ENOMEM; 440933e882a5SSuraj Sumangala } 441033e882a5SSuraj Sumangala } 441133e882a5SSuraj Sumangala break; 441233e882a5SSuraj Sumangala } 441333e882a5SSuraj Sumangala 441433e882a5SSuraj Sumangala if (scb->expect == 0) { 441533e882a5SSuraj Sumangala /* Complete frame */ 441633e882a5SSuraj Sumangala 441733e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 4418e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 441933e882a5SSuraj Sumangala 442033e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 442133e882a5SSuraj Sumangala return remain; 442233e882a5SSuraj Sumangala } 442333e882a5SSuraj Sumangala } 442433e882a5SSuraj Sumangala 442533e882a5SSuraj Sumangala return remain; 442633e882a5SSuraj Sumangala } 442733e882a5SSuraj Sumangala 442899811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 442999811510SSuraj Sumangala 443099811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 443199811510SSuraj Sumangala { 443299811510SSuraj Sumangala int type; 443399811510SSuraj Sumangala int rem = 0; 443499811510SSuraj Sumangala 4435da5f6c37SGustavo F. Padovan while (count) { 443699811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 443799811510SSuraj Sumangala 443899811510SSuraj Sumangala if (!skb) { 443999811510SSuraj Sumangala struct { char type; } *pkt; 444099811510SSuraj Sumangala 444199811510SSuraj Sumangala /* Start of the frame */ 444299811510SSuraj Sumangala pkt = data; 444399811510SSuraj Sumangala type = pkt->type; 444499811510SSuraj Sumangala 444599811510SSuraj Sumangala data++; 444699811510SSuraj Sumangala count--; 444799811510SSuraj Sumangala } else 444899811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 444999811510SSuraj Sumangala 44501e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 44511e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 445299811510SSuraj Sumangala if (rem < 0) 445399811510SSuraj Sumangala return rem; 445499811510SSuraj Sumangala 445599811510SSuraj Sumangala data += (count - rem); 445699811510SSuraj Sumangala count = rem; 4457f81c6224SJoe Perches } 445899811510SSuraj Sumangala 445999811510SSuraj Sumangala return rem; 446099811510SSuraj Sumangala } 446199811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 446299811510SSuraj Sumangala 44631da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 44641da177e4SLinus Torvalds 44651da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 44661da177e4SLinus Torvalds { 44671da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 44681da177e4SLinus Torvalds 4469f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 44701da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 4471f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 44721da177e4SLinus Torvalds 44731da177e4SLinus Torvalds return 0; 44741da177e4SLinus Torvalds } 44751da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 44761da177e4SLinus Torvalds 44771da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 44781da177e4SLinus Torvalds { 44791da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 44801da177e4SLinus Torvalds 4481f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 44821da177e4SLinus Torvalds list_del(&cb->list); 4483f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 44841da177e4SLinus Torvalds 44851da177e4SLinus Torvalds return 0; 44861da177e4SLinus Torvalds } 44871da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 44881da177e4SLinus Torvalds 448951086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 44901da177e4SLinus Torvalds { 4491cdc52faaSMarcel Holtmann int err; 4492cdc52faaSMarcel Holtmann 44930d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 44941da177e4SLinus Torvalds 44951da177e4SLinus Torvalds /* Time stamp */ 4496a61bbcf2SPatrick McHardy __net_timestamp(skb); 44971da177e4SLinus Torvalds 4498cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4499cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4500cd82e61cSMarcel Holtmann 4501cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 4502cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 4503470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 45041da177e4SLinus Torvalds } 45051da177e4SLinus Torvalds 45061da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 45071da177e4SLinus Torvalds skb_orphan(skb); 45081da177e4SLinus Torvalds 4509cdc52faaSMarcel Holtmann err = hdev->send(hdev, skb); 4510cdc52faaSMarcel Holtmann if (err < 0) { 4511cdc52faaSMarcel Holtmann BT_ERR("%s sending frame failed (%d)", hdev->name, err); 4512cdc52faaSMarcel Holtmann kfree_skb(skb); 4513cdc52faaSMarcel Holtmann } 45141da177e4SLinus Torvalds } 45151da177e4SLinus Torvalds 45163119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 45173119ae95SJohan Hedberg { 45183119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 45193119ae95SJohan Hedberg req->hdev = hdev; 45205d73e034SAndre Guedes req->err = 0; 45213119ae95SJohan Hedberg } 45223119ae95SJohan Hedberg 45233119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 45243119ae95SJohan Hedberg { 45253119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 45263119ae95SJohan Hedberg struct sk_buff *skb; 45273119ae95SJohan Hedberg unsigned long flags; 45283119ae95SJohan Hedberg 45293119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 45303119ae95SJohan Hedberg 453149c922bbSStephen Hemminger /* If an error occurred during request building, remove all HCI 45325d73e034SAndre Guedes * commands queued on the HCI request queue. 45335d73e034SAndre Guedes */ 45345d73e034SAndre Guedes if (req->err) { 45355d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 45365d73e034SAndre Guedes return req->err; 45375d73e034SAndre Guedes } 45385d73e034SAndre Guedes 45393119ae95SJohan Hedberg /* Do not allow empty requests */ 45403119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 4541382b0c39SAndre Guedes return -ENODATA; 45423119ae95SJohan Hedberg 45433119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 45443119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 45453119ae95SJohan Hedberg 45463119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 45473119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 45483119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 45493119ae95SJohan Hedberg 45503119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 45513119ae95SJohan Hedberg 45523119ae95SJohan Hedberg return 0; 45533119ae95SJohan Hedberg } 45543119ae95SJohan Hedberg 4555899de765SMarcel Holtmann bool hci_req_pending(struct hci_dev *hdev) 4556899de765SMarcel Holtmann { 4557899de765SMarcel Holtmann return (hdev->req_status == HCI_REQ_PEND); 4558899de765SMarcel Holtmann } 4559899de765SMarcel Holtmann 45601ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 456107dc93ddSJohan Hedberg u32 plen, const void *param) 45621da177e4SLinus Torvalds { 45631da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 45641da177e4SLinus Torvalds struct hci_command_hdr *hdr; 45651da177e4SLinus Torvalds struct sk_buff *skb; 45661da177e4SLinus Torvalds 45671da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 45681ca3a9d0SJohan Hedberg if (!skb) 45691ca3a9d0SJohan Hedberg return NULL; 45701da177e4SLinus Torvalds 45711da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 4572a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 45731da177e4SLinus Torvalds hdr->plen = plen; 45741da177e4SLinus Torvalds 45751da177e4SLinus Torvalds if (plen) 45761da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 45771da177e4SLinus Torvalds 45781da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 45791da177e4SLinus Torvalds 45800d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 458143e73e4eSMarcel Holtmann bt_cb(skb)->opcode = opcode; 4582c78ae283SMarcel Holtmann 45831ca3a9d0SJohan Hedberg return skb; 45841ca3a9d0SJohan Hedberg } 45851ca3a9d0SJohan Hedberg 45861ca3a9d0SJohan Hedberg /* Send HCI command */ 458707dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 458807dc93ddSJohan Hedberg const void *param) 45891ca3a9d0SJohan Hedberg { 45901ca3a9d0SJohan Hedberg struct sk_buff *skb; 45911ca3a9d0SJohan Hedberg 45921ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 45931ca3a9d0SJohan Hedberg 45941ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 45951ca3a9d0SJohan Hedberg if (!skb) { 45961ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 45971ca3a9d0SJohan Hedberg return -ENOMEM; 45981ca3a9d0SJohan Hedberg } 45991ca3a9d0SJohan Hedberg 460049c922bbSStephen Hemminger /* Stand-alone HCI commands must be flagged as 460111714b3dSJohan Hedberg * single-command requests. 460211714b3dSJohan Hedberg */ 460311714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 460411714b3dSJohan Hedberg 46051da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 4606c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 46071da177e4SLinus Torvalds 46081da177e4SLinus Torvalds return 0; 46091da177e4SLinus Torvalds } 46101da177e4SLinus Torvalds 461171c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 461207dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 461307dc93ddSJohan Hedberg const void *param, u8 event) 461471c76a17SJohan Hedberg { 461571c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 461671c76a17SJohan Hedberg struct sk_buff *skb; 461771c76a17SJohan Hedberg 461871c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 461971c76a17SJohan Hedberg 462049c922bbSStephen Hemminger /* If an error occurred during request building, there is no point in 462134739c1eSAndre Guedes * queueing the HCI command. We can simply return. 462234739c1eSAndre Guedes */ 462334739c1eSAndre Guedes if (req->err) 462434739c1eSAndre Guedes return; 462534739c1eSAndre Guedes 462671c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 462771c76a17SJohan Hedberg if (!skb) { 46285d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 46295d73e034SAndre Guedes hdev->name, opcode); 46305d73e034SAndre Guedes req->err = -ENOMEM; 4631e348fe6bSAndre Guedes return; 463271c76a17SJohan Hedberg } 463371c76a17SJohan Hedberg 463471c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 463571c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 463671c76a17SJohan Hedberg 463702350a72SJohan Hedberg bt_cb(skb)->req.event = event; 463802350a72SJohan Hedberg 463971c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 464071c76a17SJohan Hedberg } 464171c76a17SJohan Hedberg 464207dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 464307dc93ddSJohan Hedberg const void *param) 464402350a72SJohan Hedberg { 464502350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 464602350a72SJohan Hedberg } 464702350a72SJohan Hedberg 46481da177e4SLinus Torvalds /* Get data from the previously sent command */ 4649a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 46501da177e4SLinus Torvalds { 46511da177e4SLinus Torvalds struct hci_command_hdr *hdr; 46521da177e4SLinus Torvalds 46531da177e4SLinus Torvalds if (!hdev->sent_cmd) 46541da177e4SLinus Torvalds return NULL; 46551da177e4SLinus Torvalds 46561da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 46571da177e4SLinus Torvalds 4658a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 46591da177e4SLinus Torvalds return NULL; 46601da177e4SLinus Torvalds 4661f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 46621da177e4SLinus Torvalds 46631da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 46641da177e4SLinus Torvalds } 46651da177e4SLinus Torvalds 46661da177e4SLinus Torvalds /* Send ACL data */ 46671da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 46681da177e4SLinus Torvalds { 46691da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 46701da177e4SLinus Torvalds int len = skb->len; 46711da177e4SLinus Torvalds 4672badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 4673badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 46749c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 4675aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 4676aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 46771da177e4SLinus Torvalds } 46781da177e4SLinus Torvalds 4679ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 468073d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 46811da177e4SLinus Torvalds { 4682ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 46831da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 46841da177e4SLinus Torvalds struct sk_buff *list; 46851da177e4SLinus Torvalds 4686087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 4687087bfd99SGustavo Padovan skb->data_len = 0; 4688087bfd99SGustavo Padovan 4689087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 4690204a6e54SAndrei Emeltchenko 4691204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 4692204a6e54SAndrei Emeltchenko case HCI_BREDR: 4693087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 4694204a6e54SAndrei Emeltchenko break; 4695204a6e54SAndrei Emeltchenko case HCI_AMP: 4696204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 4697204a6e54SAndrei Emeltchenko break; 4698204a6e54SAndrei Emeltchenko default: 4699204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 4700204a6e54SAndrei Emeltchenko return; 4701204a6e54SAndrei Emeltchenko } 4702087bfd99SGustavo Padovan 470370f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 470470f23020SAndrei Emeltchenko if (!list) { 47051da177e4SLinus Torvalds /* Non fragmented */ 47061da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 47071da177e4SLinus Torvalds 470873d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 47091da177e4SLinus Torvalds } else { 47101da177e4SLinus Torvalds /* Fragmented */ 47111da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 47121da177e4SLinus Torvalds 47131da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 47141da177e4SLinus Torvalds 47159cfd5a23SJukka Rissanen /* Queue all fragments atomically. We need to use spin_lock_bh 47169cfd5a23SJukka Rissanen * here because of 6LoWPAN links, as there this function is 47179cfd5a23SJukka Rissanen * called from softirq and using normal spin lock could cause 47189cfd5a23SJukka Rissanen * deadlocks. 47199cfd5a23SJukka Rissanen */ 47209cfd5a23SJukka Rissanen spin_lock_bh(&queue->lock); 47211da177e4SLinus Torvalds 472273d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 4723e702112fSAndrei Emeltchenko 4724e702112fSAndrei Emeltchenko flags &= ~ACL_START; 4725e702112fSAndrei Emeltchenko flags |= ACL_CONT; 47261da177e4SLinus Torvalds do { 47271da177e4SLinus Torvalds skb = list; list = list->next; 47281da177e4SLinus Torvalds 47290d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 4730e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 47311da177e4SLinus Torvalds 47321da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 47331da177e4SLinus Torvalds 473473d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 47351da177e4SLinus Torvalds } while (list); 47361da177e4SLinus Torvalds 47379cfd5a23SJukka Rissanen spin_unlock_bh(&queue->lock); 47381da177e4SLinus Torvalds } 473973d80debSLuiz Augusto von Dentz } 474073d80debSLuiz Augusto von Dentz 474173d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 474273d80debSLuiz Augusto von Dentz { 4743ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 474473d80debSLuiz Augusto von Dentz 4745f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 474673d80debSLuiz Augusto von Dentz 4747ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 47481da177e4SLinus Torvalds 47493eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 47501da177e4SLinus Torvalds } 47511da177e4SLinus Torvalds 47521da177e4SLinus Torvalds /* Send SCO data */ 47530d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 47541da177e4SLinus Torvalds { 47551da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 47561da177e4SLinus Torvalds struct hci_sco_hdr hdr; 47571da177e4SLinus Torvalds 47581da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 47591da177e4SLinus Torvalds 4760aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 47611da177e4SLinus Torvalds hdr.dlen = skb->len; 47621da177e4SLinus Torvalds 4763badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 4764badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 47659c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 47661da177e4SLinus Torvalds 47670d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 4768c78ae283SMarcel Holtmann 47691da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 47703eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 47711da177e4SLinus Torvalds } 47721da177e4SLinus Torvalds 47731da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 47741da177e4SLinus Torvalds 47751da177e4SLinus Torvalds /* HCI Connection scheduler */ 47766039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 4777a8c5fb1aSGustavo Padovan int *quote) 47781da177e4SLinus Torvalds { 47791da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 47808035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 4781abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 47821da177e4SLinus Torvalds 47831da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 47841da177e4SLinus Torvalds * added and removed with TX task disabled. */ 4785bf4c6325SGustavo F. Padovan 4786bf4c6325SGustavo F. Padovan rcu_read_lock(); 4787bf4c6325SGustavo F. Padovan 4788bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4789769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 47901da177e4SLinus Torvalds continue; 4791769be974SMarcel Holtmann 4792769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 4793769be974SMarcel Holtmann continue; 4794769be974SMarcel Holtmann 47951da177e4SLinus Torvalds num++; 47961da177e4SLinus Torvalds 47971da177e4SLinus Torvalds if (c->sent < min) { 47981da177e4SLinus Torvalds min = c->sent; 47991da177e4SLinus Torvalds conn = c; 48001da177e4SLinus Torvalds } 480152087a79SLuiz Augusto von Dentz 480252087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 480352087a79SLuiz Augusto von Dentz break; 48041da177e4SLinus Torvalds } 48051da177e4SLinus Torvalds 4806bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4807bf4c6325SGustavo F. Padovan 48081da177e4SLinus Torvalds if (conn) { 48096ed58ec5SVille Tervo int cnt, q; 48106ed58ec5SVille Tervo 48116ed58ec5SVille Tervo switch (conn->type) { 48126ed58ec5SVille Tervo case ACL_LINK: 48136ed58ec5SVille Tervo cnt = hdev->acl_cnt; 48146ed58ec5SVille Tervo break; 48156ed58ec5SVille Tervo case SCO_LINK: 48166ed58ec5SVille Tervo case ESCO_LINK: 48176ed58ec5SVille Tervo cnt = hdev->sco_cnt; 48186ed58ec5SVille Tervo break; 48196ed58ec5SVille Tervo case LE_LINK: 48206ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 48216ed58ec5SVille Tervo break; 48226ed58ec5SVille Tervo default: 48236ed58ec5SVille Tervo cnt = 0; 48246ed58ec5SVille Tervo BT_ERR("Unknown link type"); 48256ed58ec5SVille Tervo } 48266ed58ec5SVille Tervo 48276ed58ec5SVille Tervo q = cnt / num; 48281da177e4SLinus Torvalds *quote = q ? q : 1; 48291da177e4SLinus Torvalds } else 48301da177e4SLinus Torvalds *quote = 0; 48311da177e4SLinus Torvalds 48321da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 48331da177e4SLinus Torvalds return conn; 48341da177e4SLinus Torvalds } 48351da177e4SLinus Torvalds 48366039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 48371da177e4SLinus Torvalds { 48381da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 48391da177e4SLinus Torvalds struct hci_conn *c; 48401da177e4SLinus Torvalds 4841bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 48421da177e4SLinus Torvalds 4843bf4c6325SGustavo F. Padovan rcu_read_lock(); 4844bf4c6325SGustavo F. Padovan 48451da177e4SLinus Torvalds /* Kill stalled connections */ 4846bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4847bae1f5d9SVille Tervo if (c->type == type && c->sent) { 48486ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 48496ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 4850bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 48511da177e4SLinus Torvalds } 48521da177e4SLinus Torvalds } 4853bf4c6325SGustavo F. Padovan 4854bf4c6325SGustavo F. Padovan rcu_read_unlock(); 48551da177e4SLinus Torvalds } 48561da177e4SLinus Torvalds 48576039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 485873d80debSLuiz Augusto von Dentz int *quote) 485973d80debSLuiz Augusto von Dentz { 486073d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 486173d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 4862abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 486373d80debSLuiz Augusto von Dentz struct hci_conn *conn; 486473d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 486573d80debSLuiz Augusto von Dentz 486673d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 486773d80debSLuiz Augusto von Dentz 4868bf4c6325SGustavo F. Padovan rcu_read_lock(); 4869bf4c6325SGustavo F. Padovan 4870bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 487173d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 487273d80debSLuiz Augusto von Dentz 487373d80debSLuiz Augusto von Dentz if (conn->type != type) 487473d80debSLuiz Augusto von Dentz continue; 487573d80debSLuiz Augusto von Dentz 487673d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 487773d80debSLuiz Augusto von Dentz continue; 487873d80debSLuiz Augusto von Dentz 487973d80debSLuiz Augusto von Dentz conn_num++; 488073d80debSLuiz Augusto von Dentz 48818192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 488273d80debSLuiz Augusto von Dentz struct sk_buff *skb; 488373d80debSLuiz Augusto von Dentz 488473d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 488573d80debSLuiz Augusto von Dentz continue; 488673d80debSLuiz Augusto von Dentz 488773d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 488873d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 488973d80debSLuiz Augusto von Dentz continue; 489073d80debSLuiz Augusto von Dentz 489173d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 489273d80debSLuiz Augusto von Dentz num = 0; 489373d80debSLuiz Augusto von Dentz min = ~0; 489473d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 489573d80debSLuiz Augusto von Dentz } 489673d80debSLuiz Augusto von Dentz 489773d80debSLuiz Augusto von Dentz num++; 489873d80debSLuiz Augusto von Dentz 489973d80debSLuiz Augusto von Dentz if (conn->sent < min) { 490073d80debSLuiz Augusto von Dentz min = conn->sent; 490173d80debSLuiz Augusto von Dentz chan = tmp; 490273d80debSLuiz Augusto von Dentz } 490373d80debSLuiz Augusto von Dentz } 490473d80debSLuiz Augusto von Dentz 490573d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 490673d80debSLuiz Augusto von Dentz break; 490773d80debSLuiz Augusto von Dentz } 490873d80debSLuiz Augusto von Dentz 4909bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4910bf4c6325SGustavo F. Padovan 491173d80debSLuiz Augusto von Dentz if (!chan) 491273d80debSLuiz Augusto von Dentz return NULL; 491373d80debSLuiz Augusto von Dentz 491473d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 491573d80debSLuiz Augusto von Dentz case ACL_LINK: 491673d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 491773d80debSLuiz Augusto von Dentz break; 4918bd1eb66bSAndrei Emeltchenko case AMP_LINK: 4919bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 4920bd1eb66bSAndrei Emeltchenko break; 492173d80debSLuiz Augusto von Dentz case SCO_LINK: 492273d80debSLuiz Augusto von Dentz case ESCO_LINK: 492373d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 492473d80debSLuiz Augusto von Dentz break; 492573d80debSLuiz Augusto von Dentz case LE_LINK: 492673d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 492773d80debSLuiz Augusto von Dentz break; 492873d80debSLuiz Augusto von Dentz default: 492973d80debSLuiz Augusto von Dentz cnt = 0; 493073d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 493173d80debSLuiz Augusto von Dentz } 493273d80debSLuiz Augusto von Dentz 493373d80debSLuiz Augusto von Dentz q = cnt / num; 493473d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 493573d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 493673d80debSLuiz Augusto von Dentz return chan; 493773d80debSLuiz Augusto von Dentz } 493873d80debSLuiz Augusto von Dentz 493902b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 494002b20f0bSLuiz Augusto von Dentz { 494102b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 494202b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 494302b20f0bSLuiz Augusto von Dentz int num = 0; 494402b20f0bSLuiz Augusto von Dentz 494502b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 494602b20f0bSLuiz Augusto von Dentz 4947bf4c6325SGustavo F. Padovan rcu_read_lock(); 4948bf4c6325SGustavo F. Padovan 4949bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 495002b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 495102b20f0bSLuiz Augusto von Dentz 495202b20f0bSLuiz Augusto von Dentz if (conn->type != type) 495302b20f0bSLuiz Augusto von Dentz continue; 495402b20f0bSLuiz Augusto von Dentz 495502b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 495602b20f0bSLuiz Augusto von Dentz continue; 495702b20f0bSLuiz Augusto von Dentz 495802b20f0bSLuiz Augusto von Dentz num++; 495902b20f0bSLuiz Augusto von Dentz 49608192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 496102b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 496202b20f0bSLuiz Augusto von Dentz 496302b20f0bSLuiz Augusto von Dentz if (chan->sent) { 496402b20f0bSLuiz Augusto von Dentz chan->sent = 0; 496502b20f0bSLuiz Augusto von Dentz continue; 496602b20f0bSLuiz Augusto von Dentz } 496702b20f0bSLuiz Augusto von Dentz 496802b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 496902b20f0bSLuiz Augusto von Dentz continue; 497002b20f0bSLuiz Augusto von Dentz 497102b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 497202b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 497302b20f0bSLuiz Augusto von Dentz continue; 497402b20f0bSLuiz Augusto von Dentz 497502b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 497602b20f0bSLuiz Augusto von Dentz 497702b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 497802b20f0bSLuiz Augusto von Dentz skb->priority); 497902b20f0bSLuiz Augusto von Dentz } 498002b20f0bSLuiz Augusto von Dentz 498102b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 498202b20f0bSLuiz Augusto von Dentz break; 498302b20f0bSLuiz Augusto von Dentz } 4984bf4c6325SGustavo F. Padovan 4985bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4986bf4c6325SGustavo F. Padovan 498702b20f0bSLuiz Augusto von Dentz } 498802b20f0bSLuiz Augusto von Dentz 4989b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4990b71d385aSAndrei Emeltchenko { 4991b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4992b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4993b71d385aSAndrei Emeltchenko } 4994b71d385aSAndrei Emeltchenko 49956039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 49961da177e4SLinus Torvalds { 49974a964404SMarcel Holtmann if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 49981da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 49991da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 500063d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 50015f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 5002bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 50031da177e4SLinus Torvalds } 500463d2bc1bSAndrei Emeltchenko } 50051da177e4SLinus Torvalds 50066039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 500763d2bc1bSAndrei Emeltchenko { 500863d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 500963d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 501063d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 501163d2bc1bSAndrei Emeltchenko int quote; 501263d2bc1bSAndrei Emeltchenko 501363d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 501404837f64SMarcel Holtmann 501573d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 501673d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 5017ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 5018ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 501973d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 502073d80debSLuiz Augusto von Dentz skb->len, skb->priority); 502173d80debSLuiz Augusto von Dentz 5022ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 5023ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 5024ec1cce24SLuiz Augusto von Dentz break; 5025ec1cce24SLuiz Augusto von Dentz 5026ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 5027ec1cce24SLuiz Augusto von Dentz 502873d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 502973d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 503004837f64SMarcel Holtmann 503157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 50321da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 50331da177e4SLinus Torvalds 50341da177e4SLinus Torvalds hdev->acl_cnt--; 503573d80debSLuiz Augusto von Dentz chan->sent++; 503673d80debSLuiz Augusto von Dentz chan->conn->sent++; 50371da177e4SLinus Torvalds } 50381da177e4SLinus Torvalds } 503902b20f0bSLuiz Augusto von Dentz 504002b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 504102b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 50421da177e4SLinus Torvalds } 50431da177e4SLinus Torvalds 50446039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 5045b71d385aSAndrei Emeltchenko { 504663d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 5047b71d385aSAndrei Emeltchenko struct hci_chan *chan; 5048b71d385aSAndrei Emeltchenko struct sk_buff *skb; 5049b71d385aSAndrei Emeltchenko int quote; 5050bd1eb66bSAndrei Emeltchenko u8 type; 5051b71d385aSAndrei Emeltchenko 505263d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 5053b71d385aSAndrei Emeltchenko 5054bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 5055bd1eb66bSAndrei Emeltchenko 5056bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 5057bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 5058bd1eb66bSAndrei Emeltchenko else 5059bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 5060bd1eb66bSAndrei Emeltchenko 5061b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 5062bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 5063b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 5064b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 5065b71d385aSAndrei Emeltchenko int blocks; 5066b71d385aSAndrei Emeltchenko 5067b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 5068b71d385aSAndrei Emeltchenko skb->len, skb->priority); 5069b71d385aSAndrei Emeltchenko 5070b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 5071b71d385aSAndrei Emeltchenko if (skb->priority < priority) 5072b71d385aSAndrei Emeltchenko break; 5073b71d385aSAndrei Emeltchenko 5074b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 5075b71d385aSAndrei Emeltchenko 5076b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 5077b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 5078b71d385aSAndrei Emeltchenko return; 5079b71d385aSAndrei Emeltchenko 5080b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 5081b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 5082b71d385aSAndrei Emeltchenko 508357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 5084b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 5085b71d385aSAndrei Emeltchenko 5086b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 5087b71d385aSAndrei Emeltchenko quote -= blocks; 5088b71d385aSAndrei Emeltchenko 5089b71d385aSAndrei Emeltchenko chan->sent += blocks; 5090b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 5091b71d385aSAndrei Emeltchenko } 5092b71d385aSAndrei Emeltchenko } 5093b71d385aSAndrei Emeltchenko 5094b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 5095bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 5096b71d385aSAndrei Emeltchenko } 5097b71d385aSAndrei Emeltchenko 50986039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 5099b71d385aSAndrei Emeltchenko { 5100b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 5101b71d385aSAndrei Emeltchenko 5102bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 5103bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 5104bd1eb66bSAndrei Emeltchenko return; 5105bd1eb66bSAndrei Emeltchenko 5106bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 5107bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 5108b71d385aSAndrei Emeltchenko return; 5109b71d385aSAndrei Emeltchenko 5110b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 5111b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 5112b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 5113b71d385aSAndrei Emeltchenko break; 5114b71d385aSAndrei Emeltchenko 5115b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 5116b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 5117b71d385aSAndrei Emeltchenko break; 5118b71d385aSAndrei Emeltchenko } 5119b71d385aSAndrei Emeltchenko } 5120b71d385aSAndrei Emeltchenko 51211da177e4SLinus Torvalds /* Schedule SCO */ 51226039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 51231da177e4SLinus Torvalds { 51241da177e4SLinus Torvalds struct hci_conn *conn; 51251da177e4SLinus Torvalds struct sk_buff *skb; 51261da177e4SLinus Torvalds int quote; 51271da177e4SLinus Torvalds 51281da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 51291da177e4SLinus Torvalds 513052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 513152087a79SLuiz Augusto von Dentz return; 513252087a79SLuiz Augusto von Dentz 51331da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 51341da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 51351da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 513657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 51371da177e4SLinus Torvalds 51381da177e4SLinus Torvalds conn->sent++; 51391da177e4SLinus Torvalds if (conn->sent == ~0) 51401da177e4SLinus Torvalds conn->sent = 0; 51411da177e4SLinus Torvalds } 51421da177e4SLinus Torvalds } 51431da177e4SLinus Torvalds } 51441da177e4SLinus Torvalds 51456039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 5146b6a0dc82SMarcel Holtmann { 5147b6a0dc82SMarcel Holtmann struct hci_conn *conn; 5148b6a0dc82SMarcel Holtmann struct sk_buff *skb; 5149b6a0dc82SMarcel Holtmann int quote; 5150b6a0dc82SMarcel Holtmann 5151b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 5152b6a0dc82SMarcel Holtmann 515352087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 515452087a79SLuiz Augusto von Dentz return; 515552087a79SLuiz Augusto von Dentz 51568fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 51578fc9ced3SGustavo Padovan "e))) { 5158b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 5159b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 516057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 5161b6a0dc82SMarcel Holtmann 5162b6a0dc82SMarcel Holtmann conn->sent++; 5163b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 5164b6a0dc82SMarcel Holtmann conn->sent = 0; 5165b6a0dc82SMarcel Holtmann } 5166b6a0dc82SMarcel Holtmann } 5167b6a0dc82SMarcel Holtmann } 5168b6a0dc82SMarcel Holtmann 51696039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 51706ed58ec5SVille Tervo { 517173d80debSLuiz Augusto von Dentz struct hci_chan *chan; 51726ed58ec5SVille Tervo struct sk_buff *skb; 517302b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 51746ed58ec5SVille Tervo 51756ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 51766ed58ec5SVille Tervo 517752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 517852087a79SLuiz Augusto von Dentz return; 517952087a79SLuiz Augusto von Dentz 51804a964404SMarcel Holtmann if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 51816ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 51826ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 5183bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 51846ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 5185bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 51866ed58ec5SVille Tervo } 51876ed58ec5SVille Tervo 51886ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 518902b20f0bSLuiz Augusto von Dentz tmp = cnt; 519073d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 5191ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 5192ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 519373d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 519473d80debSLuiz Augusto von Dentz skb->len, skb->priority); 51956ed58ec5SVille Tervo 5196ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 5197ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 5198ec1cce24SLuiz Augusto von Dentz break; 5199ec1cce24SLuiz Augusto von Dentz 5200ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 5201ec1cce24SLuiz Augusto von Dentz 520257d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 52036ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 52046ed58ec5SVille Tervo 52056ed58ec5SVille Tervo cnt--; 520673d80debSLuiz Augusto von Dentz chan->sent++; 520773d80debSLuiz Augusto von Dentz chan->conn->sent++; 52086ed58ec5SVille Tervo } 52096ed58ec5SVille Tervo } 521073d80debSLuiz Augusto von Dentz 52116ed58ec5SVille Tervo if (hdev->le_pkts) 52126ed58ec5SVille Tervo hdev->le_cnt = cnt; 52136ed58ec5SVille Tervo else 52146ed58ec5SVille Tervo hdev->acl_cnt = cnt; 521502b20f0bSLuiz Augusto von Dentz 521602b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 521702b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 52186ed58ec5SVille Tervo } 52196ed58ec5SVille Tervo 52203eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 52211da177e4SLinus Torvalds { 52223eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 52231da177e4SLinus Torvalds struct sk_buff *skb; 52241da177e4SLinus Torvalds 52256ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 52266ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 52271da177e4SLinus Torvalds 522852de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 52291da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 52301da177e4SLinus Torvalds hci_sched_acl(hdev); 52311da177e4SLinus Torvalds hci_sched_sco(hdev); 5232b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 52336ed58ec5SVille Tervo hci_sched_le(hdev); 523452de599eSMarcel Holtmann } 52356ed58ec5SVille Tervo 52361da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 52371da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 523857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 52391da177e4SLinus Torvalds } 52401da177e4SLinus Torvalds 524125985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 52421da177e4SLinus Torvalds 52431da177e4SLinus Torvalds /* ACL data packet */ 52446039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 52451da177e4SLinus Torvalds { 52461da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 52471da177e4SLinus Torvalds struct hci_conn *conn; 52481da177e4SLinus Torvalds __u16 handle, flags; 52491da177e4SLinus Torvalds 52501da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 52511da177e4SLinus Torvalds 52521da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 52531da177e4SLinus Torvalds flags = hci_flags(handle); 52541da177e4SLinus Torvalds handle = hci_handle(handle); 52551da177e4SLinus Torvalds 5256f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 5257a8c5fb1aSGustavo Padovan handle, flags); 52581da177e4SLinus Torvalds 52591da177e4SLinus Torvalds hdev->stat.acl_rx++; 52601da177e4SLinus Torvalds 52611da177e4SLinus Torvalds hci_dev_lock(hdev); 52621da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 52631da177e4SLinus Torvalds hci_dev_unlock(hdev); 52641da177e4SLinus Torvalds 52651da177e4SLinus Torvalds if (conn) { 526665983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 526704837f64SMarcel Holtmann 52681da177e4SLinus Torvalds /* Send to upper protocol */ 5269686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 52701da177e4SLinus Torvalds return; 52711da177e4SLinus Torvalds } else { 52721da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 52731da177e4SLinus Torvalds hdev->name, handle); 52741da177e4SLinus Torvalds } 52751da177e4SLinus Torvalds 52761da177e4SLinus Torvalds kfree_skb(skb); 52771da177e4SLinus Torvalds } 52781da177e4SLinus Torvalds 52791da177e4SLinus Torvalds /* SCO data packet */ 52806039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 52811da177e4SLinus Torvalds { 52821da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 52831da177e4SLinus Torvalds struct hci_conn *conn; 52841da177e4SLinus Torvalds __u16 handle; 52851da177e4SLinus Torvalds 52861da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 52871da177e4SLinus Torvalds 52881da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 52891da177e4SLinus Torvalds 5290f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 52911da177e4SLinus Torvalds 52921da177e4SLinus Torvalds hdev->stat.sco_rx++; 52931da177e4SLinus Torvalds 52941da177e4SLinus Torvalds hci_dev_lock(hdev); 52951da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 52961da177e4SLinus Torvalds hci_dev_unlock(hdev); 52971da177e4SLinus Torvalds 52981da177e4SLinus Torvalds if (conn) { 52991da177e4SLinus Torvalds /* Send to upper protocol */ 5300686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 53011da177e4SLinus Torvalds return; 53021da177e4SLinus Torvalds } else { 53031da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 53041da177e4SLinus Torvalds hdev->name, handle); 53051da177e4SLinus Torvalds } 53061da177e4SLinus Torvalds 53071da177e4SLinus Torvalds kfree_skb(skb); 53081da177e4SLinus Torvalds } 53091da177e4SLinus Torvalds 53109238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 53119238f36aSJohan Hedberg { 53129238f36aSJohan Hedberg struct sk_buff *skb; 53139238f36aSJohan Hedberg 53149238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 53159238f36aSJohan Hedberg if (!skb) 53169238f36aSJohan Hedberg return true; 53179238f36aSJohan Hedberg 53189238f36aSJohan Hedberg return bt_cb(skb)->req.start; 53199238f36aSJohan Hedberg } 53209238f36aSJohan Hedberg 532142c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 532242c6b129SJohan Hedberg { 532342c6b129SJohan Hedberg struct hci_command_hdr *sent; 532442c6b129SJohan Hedberg struct sk_buff *skb; 532542c6b129SJohan Hedberg u16 opcode; 532642c6b129SJohan Hedberg 532742c6b129SJohan Hedberg if (!hdev->sent_cmd) 532842c6b129SJohan Hedberg return; 532942c6b129SJohan Hedberg 533042c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 533142c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 533242c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 533342c6b129SJohan Hedberg return; 533442c6b129SJohan Hedberg 533542c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 533642c6b129SJohan Hedberg if (!skb) 533742c6b129SJohan Hedberg return; 533842c6b129SJohan Hedberg 533942c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 534042c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 534142c6b129SJohan Hedberg } 534242c6b129SJohan Hedberg 53439238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 53449238f36aSJohan Hedberg { 53459238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 53469238f36aSJohan Hedberg struct sk_buff *skb; 53479238f36aSJohan Hedberg unsigned long flags; 53489238f36aSJohan Hedberg 53499238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 53509238f36aSJohan Hedberg 535142c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 535242c6b129SJohan Hedberg * sent we need to do special handling of it. 53539238f36aSJohan Hedberg */ 535442c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 535542c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 535642c6b129SJohan Hedberg * reset complete event during init and any pending 535742c6b129SJohan Hedberg * command will never be completed. In such a case we 535842c6b129SJohan Hedberg * need to resend whatever was the last sent 535942c6b129SJohan Hedberg * command. 536042c6b129SJohan Hedberg */ 536142c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 536242c6b129SJohan Hedberg hci_resend_last(hdev); 536342c6b129SJohan Hedberg 53649238f36aSJohan Hedberg return; 536542c6b129SJohan Hedberg } 53669238f36aSJohan Hedberg 53679238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 53689238f36aSJohan Hedberg * this request the request is not yet complete. 53699238f36aSJohan Hedberg */ 53709238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 53719238f36aSJohan Hedberg return; 53729238f36aSJohan Hedberg 53739238f36aSJohan Hedberg /* If this was the last command in a request the complete 53749238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 53759238f36aSJohan Hedberg * command queue (hdev->cmd_q). 53769238f36aSJohan Hedberg */ 53779238f36aSJohan Hedberg if (hdev->sent_cmd) { 53789238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 537953e21fbcSJohan Hedberg 538053e21fbcSJohan Hedberg if (req_complete) { 538153e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 538253e21fbcSJohan Hedberg * avoid calling the callback more than once if 538353e21fbcSJohan Hedberg * this function gets called again. 538453e21fbcSJohan Hedberg */ 538553e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 538653e21fbcSJohan Hedberg 53879238f36aSJohan Hedberg goto call_complete; 53889238f36aSJohan Hedberg } 538953e21fbcSJohan Hedberg } 53909238f36aSJohan Hedberg 53919238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 53929238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 53939238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 53949238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 53959238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 53969238f36aSJohan Hedberg break; 53979238f36aSJohan Hedberg } 53989238f36aSJohan Hedberg 53999238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 54009238f36aSJohan Hedberg kfree_skb(skb); 54019238f36aSJohan Hedberg } 54029238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 54039238f36aSJohan Hedberg 54049238f36aSJohan Hedberg call_complete: 54059238f36aSJohan Hedberg if (req_complete) 54069238f36aSJohan Hedberg req_complete(hdev, status); 54079238f36aSJohan Hedberg } 54089238f36aSJohan Hedberg 5409b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 54101da177e4SLinus Torvalds { 5411b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 54121da177e4SLinus Torvalds struct sk_buff *skb; 54131da177e4SLinus Torvalds 54141da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 54151da177e4SLinus Torvalds 54161da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 5417cd82e61cSMarcel Holtmann /* Send copy to monitor */ 5418cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 5419cd82e61cSMarcel Holtmann 54201da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 54211da177e4SLinus Torvalds /* Send copy to the sockets */ 5422470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 54231da177e4SLinus Torvalds } 54241da177e4SLinus Torvalds 5425fee746b0SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 54261da177e4SLinus Torvalds kfree_skb(skb); 54271da177e4SLinus Torvalds continue; 54281da177e4SLinus Torvalds } 54291da177e4SLinus Torvalds 54301da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 54311da177e4SLinus Torvalds /* Don't process data packets in this states. */ 54320d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 54331da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 54341da177e4SLinus Torvalds case HCI_SCODATA_PKT: 54351da177e4SLinus Torvalds kfree_skb(skb); 54361da177e4SLinus Torvalds continue; 54373ff50b79SStephen Hemminger } 54381da177e4SLinus Torvalds } 54391da177e4SLinus Torvalds 54401da177e4SLinus Torvalds /* Process frame */ 54410d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 54421da177e4SLinus Torvalds case HCI_EVENT_PKT: 5443b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 54441da177e4SLinus Torvalds hci_event_packet(hdev, skb); 54451da177e4SLinus Torvalds break; 54461da177e4SLinus Torvalds 54471da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 54481da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 54491da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 54501da177e4SLinus Torvalds break; 54511da177e4SLinus Torvalds 54521da177e4SLinus Torvalds case HCI_SCODATA_PKT: 54531da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 54541da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 54551da177e4SLinus Torvalds break; 54561da177e4SLinus Torvalds 54571da177e4SLinus Torvalds default: 54581da177e4SLinus Torvalds kfree_skb(skb); 54591da177e4SLinus Torvalds break; 54601da177e4SLinus Torvalds } 54611da177e4SLinus Torvalds } 54621da177e4SLinus Torvalds } 54631da177e4SLinus Torvalds 5464c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 54651da177e4SLinus Torvalds { 5466c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 54671da177e4SLinus Torvalds struct sk_buff *skb; 54681da177e4SLinus Torvalds 54692104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 54702104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 54711da177e4SLinus Torvalds 54721da177e4SLinus Torvalds /* Send queued commands */ 54735a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 54745a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 54755a08ecceSAndrei Emeltchenko if (!skb) 54765a08ecceSAndrei Emeltchenko return; 54775a08ecceSAndrei Emeltchenko 54781da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 54791da177e4SLinus Torvalds 5480a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 548170f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 54821da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 548357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 54847bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 548565cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 54867bdb8a5cSSzymon Janc else 548765cc2b49SMarcel Holtmann schedule_delayed_work(&hdev->cmd_timer, 548865cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT); 54891da177e4SLinus Torvalds } else { 54901da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 5491c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 54921da177e4SLinus Torvalds } 54931da177e4SLinus Torvalds } 54941da177e4SLinus Torvalds } 5495b1efcc28SAndre Guedes 5496b1efcc28SAndre Guedes void hci_req_add_le_scan_disable(struct hci_request *req) 5497b1efcc28SAndre Guedes { 5498b1efcc28SAndre Guedes struct hci_cp_le_set_scan_enable cp; 5499b1efcc28SAndre Guedes 5500b1efcc28SAndre Guedes memset(&cp, 0, sizeof(cp)); 5501b1efcc28SAndre Guedes cp.enable = LE_SCAN_DISABLE; 5502b1efcc28SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 5503b1efcc28SAndre Guedes } 5504a4790dbdSAndre Guedes 55058540f6c0SMarcel Holtmann static void add_to_white_list(struct hci_request *req, 55068540f6c0SMarcel Holtmann struct hci_conn_params *params) 55078540f6c0SMarcel Holtmann { 55088540f6c0SMarcel Holtmann struct hci_cp_le_add_to_white_list cp; 55098540f6c0SMarcel Holtmann 55108540f6c0SMarcel Holtmann cp.bdaddr_type = params->addr_type; 55118540f6c0SMarcel Holtmann bacpy(&cp.bdaddr, ¶ms->addr); 55128540f6c0SMarcel Holtmann 55138540f6c0SMarcel Holtmann hci_req_add(req, HCI_OP_LE_ADD_TO_WHITE_LIST, sizeof(cp), &cp); 55148540f6c0SMarcel Holtmann } 55158540f6c0SMarcel Holtmann 55168540f6c0SMarcel Holtmann static u8 update_white_list(struct hci_request *req) 55178540f6c0SMarcel Holtmann { 55188540f6c0SMarcel Holtmann struct hci_dev *hdev = req->hdev; 55198540f6c0SMarcel Holtmann struct hci_conn_params *params; 55208540f6c0SMarcel Holtmann struct bdaddr_list *b; 55218540f6c0SMarcel Holtmann uint8_t white_list_entries = 0; 55228540f6c0SMarcel Holtmann 55238540f6c0SMarcel Holtmann /* Go through the current white list programmed into the 55248540f6c0SMarcel Holtmann * controller one by one and check if that address is still 55258540f6c0SMarcel Holtmann * in the list of pending connections or list of devices to 55268540f6c0SMarcel Holtmann * report. If not present in either list, then queue the 55278540f6c0SMarcel Holtmann * command to remove it from the controller. 55288540f6c0SMarcel Holtmann */ 55298540f6c0SMarcel Holtmann list_for_each_entry(b, &hdev->le_white_list, list) { 55308540f6c0SMarcel Holtmann struct hci_cp_le_del_from_white_list cp; 55318540f6c0SMarcel Holtmann 55328540f6c0SMarcel Holtmann if (hci_pend_le_action_lookup(&hdev->pend_le_conns, 55338540f6c0SMarcel Holtmann &b->bdaddr, b->bdaddr_type) || 55348540f6c0SMarcel Holtmann hci_pend_le_action_lookup(&hdev->pend_le_reports, 55358540f6c0SMarcel Holtmann &b->bdaddr, b->bdaddr_type)) { 55368540f6c0SMarcel Holtmann white_list_entries++; 55378540f6c0SMarcel Holtmann continue; 55388540f6c0SMarcel Holtmann } 55398540f6c0SMarcel Holtmann 55408540f6c0SMarcel Holtmann cp.bdaddr_type = b->bdaddr_type; 55418540f6c0SMarcel Holtmann bacpy(&cp.bdaddr, &b->bdaddr); 55428540f6c0SMarcel Holtmann 55438540f6c0SMarcel Holtmann hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST, 55448540f6c0SMarcel Holtmann sizeof(cp), &cp); 55458540f6c0SMarcel Holtmann } 55468540f6c0SMarcel Holtmann 55478540f6c0SMarcel Holtmann /* Since all no longer valid white list entries have been 55488540f6c0SMarcel Holtmann * removed, walk through the list of pending connections 55498540f6c0SMarcel Holtmann * and ensure that any new device gets programmed into 55508540f6c0SMarcel Holtmann * the controller. 55518540f6c0SMarcel Holtmann * 55528540f6c0SMarcel Holtmann * If the list of the devices is larger than the list of 55538540f6c0SMarcel Holtmann * available white list entries in the controller, then 55548540f6c0SMarcel Holtmann * just abort and return filer policy value to not use the 55558540f6c0SMarcel Holtmann * white list. 55568540f6c0SMarcel Holtmann */ 55578540f6c0SMarcel Holtmann list_for_each_entry(params, &hdev->pend_le_conns, action) { 55588540f6c0SMarcel Holtmann if (hci_bdaddr_list_lookup(&hdev->le_white_list, 55598540f6c0SMarcel Holtmann ¶ms->addr, params->addr_type)) 55608540f6c0SMarcel Holtmann continue; 55618540f6c0SMarcel Holtmann 55628540f6c0SMarcel Holtmann if (white_list_entries >= hdev->le_white_list_size) { 55638540f6c0SMarcel Holtmann /* Select filter policy to accept all advertising */ 55648540f6c0SMarcel Holtmann return 0x00; 55658540f6c0SMarcel Holtmann } 55668540f6c0SMarcel Holtmann 556766d8e837SMarcel Holtmann if (hci_find_irk_by_addr(hdev, ¶ms->addr, 556866d8e837SMarcel Holtmann params->addr_type)) { 556966d8e837SMarcel Holtmann /* White list can not be used with RPAs */ 557066d8e837SMarcel Holtmann return 0x00; 557166d8e837SMarcel Holtmann } 557266d8e837SMarcel Holtmann 55738540f6c0SMarcel Holtmann white_list_entries++; 55748540f6c0SMarcel Holtmann add_to_white_list(req, params); 55758540f6c0SMarcel Holtmann } 55768540f6c0SMarcel Holtmann 55778540f6c0SMarcel Holtmann /* After adding all new pending connections, walk through 55788540f6c0SMarcel Holtmann * the list of pending reports and also add these to the 55798540f6c0SMarcel Holtmann * white list if there is still space. 55808540f6c0SMarcel Holtmann */ 55818540f6c0SMarcel Holtmann list_for_each_entry(params, &hdev->pend_le_reports, action) { 55828540f6c0SMarcel Holtmann if (hci_bdaddr_list_lookup(&hdev->le_white_list, 55838540f6c0SMarcel Holtmann ¶ms->addr, params->addr_type)) 55848540f6c0SMarcel Holtmann continue; 55858540f6c0SMarcel Holtmann 55868540f6c0SMarcel Holtmann if (white_list_entries >= hdev->le_white_list_size) { 55878540f6c0SMarcel Holtmann /* Select filter policy to accept all advertising */ 55888540f6c0SMarcel Holtmann return 0x00; 55898540f6c0SMarcel Holtmann } 55908540f6c0SMarcel Holtmann 559166d8e837SMarcel Holtmann if (hci_find_irk_by_addr(hdev, ¶ms->addr, 559266d8e837SMarcel Holtmann params->addr_type)) { 559366d8e837SMarcel Holtmann /* White list can not be used with RPAs */ 559466d8e837SMarcel Holtmann return 0x00; 559566d8e837SMarcel Holtmann } 559666d8e837SMarcel Holtmann 55978540f6c0SMarcel Holtmann white_list_entries++; 55988540f6c0SMarcel Holtmann add_to_white_list(req, params); 55998540f6c0SMarcel Holtmann } 56008540f6c0SMarcel Holtmann 56018540f6c0SMarcel Holtmann /* Select filter policy to use white list */ 56028540f6c0SMarcel Holtmann return 0x01; 56038540f6c0SMarcel Holtmann } 56048540f6c0SMarcel Holtmann 56058ef30fd3SAndre Guedes void hci_req_add_le_passive_scan(struct hci_request *req) 56068ef30fd3SAndre Guedes { 56078ef30fd3SAndre Guedes struct hci_cp_le_set_scan_param param_cp; 56088ef30fd3SAndre Guedes struct hci_cp_le_set_scan_enable enable_cp; 56098ef30fd3SAndre Guedes struct hci_dev *hdev = req->hdev; 56108ef30fd3SAndre Guedes u8 own_addr_type; 56118540f6c0SMarcel Holtmann u8 filter_policy; 56128ef30fd3SAndre Guedes 56136ab535a7SMarcel Holtmann /* Set require_privacy to false since no SCAN_REQ are send 56146ab535a7SMarcel Holtmann * during passive scanning. Not using an unresolvable address 56156ab535a7SMarcel Holtmann * here is important so that peer devices using direct 56166ab535a7SMarcel Holtmann * advertising with our address will be correctly reported 56176ab535a7SMarcel Holtmann * by the controller. 56188ef30fd3SAndre Guedes */ 56196ab535a7SMarcel Holtmann if (hci_update_random_address(req, false, &own_addr_type)) 56208ef30fd3SAndre Guedes return; 56218ef30fd3SAndre Guedes 56228540f6c0SMarcel Holtmann /* Adding or removing entries from the white list must 56238540f6c0SMarcel Holtmann * happen before enabling scanning. The controller does 56248540f6c0SMarcel Holtmann * not allow white list modification while scanning. 56258540f6c0SMarcel Holtmann */ 56268540f6c0SMarcel Holtmann filter_policy = update_white_list(req); 56278540f6c0SMarcel Holtmann 56288ef30fd3SAndre Guedes memset(¶m_cp, 0, sizeof(param_cp)); 56298ef30fd3SAndre Guedes param_cp.type = LE_SCAN_PASSIVE; 56308ef30fd3SAndre Guedes param_cp.interval = cpu_to_le16(hdev->le_scan_interval); 56318ef30fd3SAndre Guedes param_cp.window = cpu_to_le16(hdev->le_scan_window); 56328ef30fd3SAndre Guedes param_cp.own_address_type = own_addr_type; 56338540f6c0SMarcel Holtmann param_cp.filter_policy = filter_policy; 56348ef30fd3SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), 56358ef30fd3SAndre Guedes ¶m_cp); 56368ef30fd3SAndre Guedes 56378ef30fd3SAndre Guedes memset(&enable_cp, 0, sizeof(enable_cp)); 56388ef30fd3SAndre Guedes enable_cp.enable = LE_SCAN_ENABLE; 56394340a124SAndre Guedes enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; 56408ef30fd3SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), 56418ef30fd3SAndre Guedes &enable_cp); 56428ef30fd3SAndre Guedes } 56438ef30fd3SAndre Guedes 5644a4790dbdSAndre Guedes static void update_background_scan_complete(struct hci_dev *hdev, u8 status) 5645a4790dbdSAndre Guedes { 5646a4790dbdSAndre Guedes if (status) 5647a4790dbdSAndre Guedes BT_DBG("HCI request failed to update background scanning: " 5648a4790dbdSAndre Guedes "status 0x%2.2x", status); 5649a4790dbdSAndre Guedes } 5650a4790dbdSAndre Guedes 5651a4790dbdSAndre Guedes /* This function controls the background scanning based on hdev->pend_le_conns 5652a4790dbdSAndre Guedes * list. If there are pending LE connection we start the background scanning, 5653a4790dbdSAndre Guedes * otherwise we stop it. 5654a4790dbdSAndre Guedes * 5655a4790dbdSAndre Guedes * This function requires the caller holds hdev->lock. 5656a4790dbdSAndre Guedes */ 5657a4790dbdSAndre Guedes void hci_update_background_scan(struct hci_dev *hdev) 5658a4790dbdSAndre Guedes { 5659a4790dbdSAndre Guedes struct hci_request req; 5660a4790dbdSAndre Guedes struct hci_conn *conn; 5661a4790dbdSAndre Guedes int err; 5662a4790dbdSAndre Guedes 5663c20c02d5SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags) || 5664c20c02d5SMarcel Holtmann test_bit(HCI_INIT, &hdev->flags) || 5665c20c02d5SMarcel Holtmann test_bit(HCI_SETUP, &hdev->dev_flags) || 5666d603b76bSMarcel Holtmann test_bit(HCI_CONFIG, &hdev->dev_flags) || 5667b8221770SMarcel Holtmann test_bit(HCI_AUTO_OFF, &hdev->dev_flags) || 5668c20c02d5SMarcel Holtmann test_bit(HCI_UNREGISTER, &hdev->dev_flags)) 56691c1697c0SMarcel Holtmann return; 56701c1697c0SMarcel Holtmann 5671a70f4b5fSJohan Hedberg /* No point in doing scanning if LE support hasn't been enabled */ 5672a70f4b5fSJohan Hedberg if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) 5673a70f4b5fSJohan Hedberg return; 5674a70f4b5fSJohan Hedberg 5675ae23ada4SJohan Hedberg /* If discovery is active don't interfere with it */ 5676ae23ada4SJohan Hedberg if (hdev->discovery.state != DISCOVERY_STOPPED) 5677ae23ada4SJohan Hedberg return; 5678ae23ada4SJohan Hedberg 5679ee3c3ca5SMarcel Holtmann /* Reset RSSI and UUID filters when starting background scanning 5680ee3c3ca5SMarcel Holtmann * since these filters are meant for service discovery only. 5681ee3c3ca5SMarcel Holtmann * 5682ee3c3ca5SMarcel Holtmann * The Start Discovery and Start Service Discovery operations 5683ee3c3ca5SMarcel Holtmann * ensure to set proper values for RSSI threshold and UUID 5684ee3c3ca5SMarcel Holtmann * filter list. So it is safe to just reset them here. 5685ee3c3ca5SMarcel Holtmann */ 5686ee3c3ca5SMarcel Holtmann hci_discovery_filter_clear(hdev); 5687ee3c3ca5SMarcel Holtmann 5688a4790dbdSAndre Guedes hci_req_init(&req, hdev); 5689a4790dbdSAndre Guedes 5690d1d588c1SJohan Hedberg if (list_empty(&hdev->pend_le_conns) && 569166f8455aSJohan Hedberg list_empty(&hdev->pend_le_reports)) { 56920d2bf134SJohan Hedberg /* If there is no pending LE connections or devices 56930d2bf134SJohan Hedberg * to be scanned for, we should stop the background 56940d2bf134SJohan Hedberg * scanning. 5695a4790dbdSAndre Guedes */ 5696a4790dbdSAndre Guedes 5697a4790dbdSAndre Guedes /* If controller is not scanning we are done. */ 5698a4790dbdSAndre Guedes if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 5699a4790dbdSAndre Guedes return; 5700a4790dbdSAndre Guedes 5701a4790dbdSAndre Guedes hci_req_add_le_scan_disable(&req); 5702a4790dbdSAndre Guedes 5703a4790dbdSAndre Guedes BT_DBG("%s stopping background scanning", hdev->name); 5704a4790dbdSAndre Guedes } else { 5705a4790dbdSAndre Guedes /* If there is at least one pending LE connection, we should 5706a4790dbdSAndre Guedes * keep the background scan running. 5707a4790dbdSAndre Guedes */ 5708a4790dbdSAndre Guedes 5709a4790dbdSAndre Guedes /* If controller is connecting, we should not start scanning 5710a4790dbdSAndre Guedes * since some controllers are not able to scan and connect at 5711a4790dbdSAndre Guedes * the same time. 5712a4790dbdSAndre Guedes */ 5713a4790dbdSAndre Guedes conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 5714a4790dbdSAndre Guedes if (conn) 5715a4790dbdSAndre Guedes return; 5716a4790dbdSAndre Guedes 57174340a124SAndre Guedes /* If controller is currently scanning, we stop it to ensure we 57184340a124SAndre Guedes * don't miss any advertising (due to duplicates filter). 57194340a124SAndre Guedes */ 57204340a124SAndre Guedes if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 57214340a124SAndre Guedes hci_req_add_le_scan_disable(&req); 57224340a124SAndre Guedes 57238ef30fd3SAndre Guedes hci_req_add_le_passive_scan(&req); 5724a4790dbdSAndre Guedes 5725a4790dbdSAndre Guedes BT_DBG("%s starting background scanning", hdev->name); 5726a4790dbdSAndre Guedes } 5727a4790dbdSAndre Guedes 5728a4790dbdSAndre Guedes err = hci_req_run(&req, update_background_scan_complete); 5729a4790dbdSAndre Guedes if (err) 5730a4790dbdSAndre Guedes BT_ERR("Failed to run HCI request: err %d", err); 5731a4790dbdSAndre Guedes } 5732432df05eSJohan Hedberg 573322f433dcSJohan Hedberg static bool disconnected_whitelist_entries(struct hci_dev *hdev) 573422f433dcSJohan Hedberg { 573522f433dcSJohan Hedberg struct bdaddr_list *b; 573622f433dcSJohan Hedberg 573722f433dcSJohan Hedberg list_for_each_entry(b, &hdev->whitelist, list) { 573822f433dcSJohan Hedberg struct hci_conn *conn; 573922f433dcSJohan Hedberg 574022f433dcSJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &b->bdaddr); 574122f433dcSJohan Hedberg if (!conn) 574222f433dcSJohan Hedberg return true; 574322f433dcSJohan Hedberg 574422f433dcSJohan Hedberg if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 574522f433dcSJohan Hedberg return true; 574622f433dcSJohan Hedberg } 574722f433dcSJohan Hedberg 574822f433dcSJohan Hedberg return false; 574922f433dcSJohan Hedberg } 575022f433dcSJohan Hedberg 5751432df05eSJohan Hedberg void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req) 5752432df05eSJohan Hedberg { 5753432df05eSJohan Hedberg u8 scan; 5754432df05eSJohan Hedberg 5755432df05eSJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) 5756432df05eSJohan Hedberg return; 5757432df05eSJohan Hedberg 5758432df05eSJohan Hedberg if (!hdev_is_powered(hdev)) 5759432df05eSJohan Hedberg return; 5760432df05eSJohan Hedberg 5761432df05eSJohan Hedberg if (mgmt_powering_down(hdev)) 5762432df05eSJohan Hedberg return; 5763432df05eSJohan Hedberg 5764432df05eSJohan Hedberg if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) || 576522f433dcSJohan Hedberg disconnected_whitelist_entries(hdev)) 5766432df05eSJohan Hedberg scan = SCAN_PAGE; 5767432df05eSJohan Hedberg else 5768432df05eSJohan Hedberg scan = SCAN_DISABLED; 5769432df05eSJohan Hedberg 5770432df05eSJohan Hedberg if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE)) 5771432df05eSJohan Hedberg return; 5772432df05eSJohan Hedberg 5773432df05eSJohan Hedberg if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) 5774432df05eSJohan Hedberg scan |= SCAN_INQUIRY; 5775432df05eSJohan Hedberg 5776432df05eSJohan Hedberg if (req) 5777432df05eSJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 5778432df05eSJohan Hedberg else 5779432df05eSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 5780432df05eSJohan Hedberg } 5781