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 400857dd3bSJohan Hedberg #include "hci_request.h" 4160c5f5fbSMarcel Holtmann #include "hci_debugfs.h" 42970c4e46SJohan Hedberg #include "smp.h" 43970c4e46SJohan Hedberg 44b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 45c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 463eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds /* HCI device list */ 491da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 501da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds /* HCI callback list */ 531da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 541da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 551da177e4SLinus Torvalds 563df92b31SSasha Levin /* HCI ID Numbering */ 573df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 583df92b31SSasha Levin 59899de765SMarcel Holtmann /* ----- HCI requests ----- */ 60899de765SMarcel Holtmann 61899de765SMarcel Holtmann #define HCI_REQ_DONE 0 62899de765SMarcel Holtmann #define HCI_REQ_PEND 1 63899de765SMarcel Holtmann #define HCI_REQ_CANCELED 2 64899de765SMarcel Holtmann 65899de765SMarcel Holtmann #define hci_req_lock(d) mutex_lock(&d->req_lock) 66899de765SMarcel Holtmann #define hci_req_unlock(d) mutex_unlock(&d->req_lock) 67899de765SMarcel Holtmann 681da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 691da177e4SLinus Torvalds 706516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 711da177e4SLinus Torvalds { 72040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 731da177e4SLinus Torvalds } 741da177e4SLinus Torvalds 75baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */ 76baf27f6eSMarcel Holtmann 774b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf, 784b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 794b4148e9SMarcel Holtmann { 804b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 814b4148e9SMarcel Holtmann char buf[3]; 824b4148e9SMarcel Holtmann 83111902f7SMarcel Holtmann buf[0] = test_bit(HCI_DUT_MODE, &hdev->dbg_flags) ? 'Y': 'N'; 844b4148e9SMarcel Holtmann buf[1] = '\n'; 854b4148e9SMarcel Holtmann buf[2] = '\0'; 864b4148e9SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 874b4148e9SMarcel Holtmann } 884b4148e9SMarcel Holtmann 894b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf, 904b4148e9SMarcel Holtmann size_t count, loff_t *ppos) 914b4148e9SMarcel Holtmann { 924b4148e9SMarcel Holtmann struct hci_dev *hdev = file->private_data; 934b4148e9SMarcel Holtmann struct sk_buff *skb; 944b4148e9SMarcel Holtmann char buf[32]; 954b4148e9SMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 964b4148e9SMarcel Holtmann bool enable; 974b4148e9SMarcel Holtmann int err; 984b4148e9SMarcel Holtmann 994b4148e9SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 1004b4148e9SMarcel Holtmann return -ENETDOWN; 1014b4148e9SMarcel Holtmann 1024b4148e9SMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 1034b4148e9SMarcel Holtmann return -EFAULT; 1044b4148e9SMarcel Holtmann 1054b4148e9SMarcel Holtmann buf[buf_size] = '\0'; 1064b4148e9SMarcel Holtmann if (strtobool(buf, &enable)) 1074b4148e9SMarcel Holtmann return -EINVAL; 1084b4148e9SMarcel Holtmann 109111902f7SMarcel Holtmann if (enable == test_bit(HCI_DUT_MODE, &hdev->dbg_flags)) 1104b4148e9SMarcel Holtmann return -EALREADY; 1114b4148e9SMarcel Holtmann 1124b4148e9SMarcel Holtmann hci_req_lock(hdev); 1134b4148e9SMarcel Holtmann if (enable) 1144b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL, 1154b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1164b4148e9SMarcel Holtmann else 1174b4148e9SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, 1184b4148e9SMarcel Holtmann HCI_CMD_TIMEOUT); 1194b4148e9SMarcel Holtmann hci_req_unlock(hdev); 1204b4148e9SMarcel Holtmann 1214b4148e9SMarcel Holtmann if (IS_ERR(skb)) 1224b4148e9SMarcel Holtmann return PTR_ERR(skb); 1234b4148e9SMarcel Holtmann 1244b4148e9SMarcel Holtmann err = -bt_to_errno(skb->data[0]); 1254b4148e9SMarcel Holtmann kfree_skb(skb); 1264b4148e9SMarcel Holtmann 1274b4148e9SMarcel Holtmann if (err < 0) 1284b4148e9SMarcel Holtmann return err; 1294b4148e9SMarcel Holtmann 130111902f7SMarcel Holtmann change_bit(HCI_DUT_MODE, &hdev->dbg_flags); 1314b4148e9SMarcel Holtmann 1324b4148e9SMarcel Holtmann return count; 1334b4148e9SMarcel Holtmann } 1344b4148e9SMarcel Holtmann 1354b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = { 1364b4148e9SMarcel Holtmann .open = simple_open, 1374b4148e9SMarcel Holtmann .read = dut_mode_read, 1384b4148e9SMarcel Holtmann .write = dut_mode_write, 1394b4148e9SMarcel Holtmann .llseek = default_llseek, 1404b4148e9SMarcel Holtmann }; 1414b4148e9SMarcel Holtmann 142c982b2eaSJohan Hedberg static int rpa_timeout_set(void *data, u64 val) 143c982b2eaSJohan Hedberg { 144c982b2eaSJohan Hedberg struct hci_dev *hdev = data; 145c982b2eaSJohan Hedberg 146c982b2eaSJohan Hedberg /* Require the RPA timeout to be at least 30 seconds and at most 147c982b2eaSJohan Hedberg * 24 hours. 148c982b2eaSJohan Hedberg */ 149c982b2eaSJohan Hedberg if (val < 30 || val > (60 * 60 * 24)) 150c982b2eaSJohan Hedberg return -EINVAL; 151c982b2eaSJohan Hedberg 152c982b2eaSJohan Hedberg hci_dev_lock(hdev); 153c982b2eaSJohan Hedberg hdev->rpa_timeout = val; 154c982b2eaSJohan Hedberg hci_dev_unlock(hdev); 155c982b2eaSJohan Hedberg 156c982b2eaSJohan Hedberg return 0; 157c982b2eaSJohan Hedberg } 158c982b2eaSJohan Hedberg 159c982b2eaSJohan Hedberg static int rpa_timeout_get(void *data, u64 *val) 160c982b2eaSJohan Hedberg { 161c982b2eaSJohan Hedberg struct hci_dev *hdev = data; 162c982b2eaSJohan Hedberg 163c982b2eaSJohan Hedberg hci_dev_lock(hdev); 164c982b2eaSJohan Hedberg *val = hdev->rpa_timeout; 165c982b2eaSJohan Hedberg hci_dev_unlock(hdev); 166c982b2eaSJohan Hedberg 167c982b2eaSJohan Hedberg return 0; 168c982b2eaSJohan Hedberg } 169c982b2eaSJohan Hedberg 170c982b2eaSJohan Hedberg DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get, 171c982b2eaSJohan Hedberg rpa_timeout_set, "%llu\n"); 172c982b2eaSJohan Hedberg 173ac345813SMarcel Holtmann static int identity_show(struct seq_file *f, void *p) 174ac345813SMarcel Holtmann { 175ac345813SMarcel Holtmann struct hci_dev *hdev = f->private; 176a1f4c318SJohan Hedberg bdaddr_t addr; 177ac345813SMarcel Holtmann u8 addr_type; 178ac345813SMarcel Holtmann 179ac345813SMarcel Holtmann hci_dev_lock(hdev); 180ac345813SMarcel Holtmann 181a1f4c318SJohan Hedberg hci_copy_identity_address(hdev, &addr, &addr_type); 182ac345813SMarcel Holtmann 183a1f4c318SJohan Hedberg seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type, 184473deef2SMarcel Holtmann 16, hdev->irk, &hdev->rpa); 185ac345813SMarcel Holtmann 186ac345813SMarcel Holtmann hci_dev_unlock(hdev); 187ac345813SMarcel Holtmann 188ac345813SMarcel Holtmann return 0; 189ac345813SMarcel Holtmann } 190ac345813SMarcel Holtmann 191ac345813SMarcel Holtmann static int identity_open(struct inode *inode, struct file *file) 192ac345813SMarcel Holtmann { 193ac345813SMarcel Holtmann return single_open(file, identity_show, inode->i_private); 194ac345813SMarcel Holtmann } 195ac345813SMarcel Holtmann 196ac345813SMarcel Holtmann static const struct file_operations identity_fops = { 197ac345813SMarcel Holtmann .open = identity_open, 198ac345813SMarcel Holtmann .read = seq_read, 199ac345813SMarcel Holtmann .llseek = seq_lseek, 200ac345813SMarcel Holtmann .release = single_release, 201ac345813SMarcel Holtmann }; 202ac345813SMarcel Holtmann 2037a4cd51dSMarcel Holtmann static int random_address_show(struct seq_file *f, void *p) 2047a4cd51dSMarcel Holtmann { 2057a4cd51dSMarcel Holtmann struct hci_dev *hdev = f->private; 2067a4cd51dSMarcel Holtmann 2077a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 2087a4cd51dSMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->random_addr); 2097a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 2107a4cd51dSMarcel Holtmann 2117a4cd51dSMarcel Holtmann return 0; 2127a4cd51dSMarcel Holtmann } 2137a4cd51dSMarcel Holtmann 2147a4cd51dSMarcel Holtmann static int random_address_open(struct inode *inode, struct file *file) 2157a4cd51dSMarcel Holtmann { 2167a4cd51dSMarcel Holtmann return single_open(file, random_address_show, inode->i_private); 2177a4cd51dSMarcel Holtmann } 2187a4cd51dSMarcel Holtmann 2197a4cd51dSMarcel Holtmann static const struct file_operations random_address_fops = { 2207a4cd51dSMarcel Holtmann .open = random_address_open, 2217a4cd51dSMarcel Holtmann .read = seq_read, 2227a4cd51dSMarcel Holtmann .llseek = seq_lseek, 2237a4cd51dSMarcel Holtmann .release = single_release, 2247a4cd51dSMarcel Holtmann }; 2257a4cd51dSMarcel Holtmann 226e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p) 227e7b8fc92SMarcel Holtmann { 228e7b8fc92SMarcel Holtmann struct hci_dev *hdev = f->private; 229e7b8fc92SMarcel Holtmann 230e7b8fc92SMarcel Holtmann hci_dev_lock(hdev); 231e7b8fc92SMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->static_addr); 232e7b8fc92SMarcel Holtmann hci_dev_unlock(hdev); 233e7b8fc92SMarcel Holtmann 234e7b8fc92SMarcel Holtmann return 0; 235e7b8fc92SMarcel Holtmann } 236e7b8fc92SMarcel Holtmann 237e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file) 238e7b8fc92SMarcel Holtmann { 239e7b8fc92SMarcel Holtmann return single_open(file, static_address_show, inode->i_private); 240e7b8fc92SMarcel Holtmann } 241e7b8fc92SMarcel Holtmann 242e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = { 243e7b8fc92SMarcel Holtmann .open = static_address_open, 244e7b8fc92SMarcel Holtmann .read = seq_read, 245e7b8fc92SMarcel Holtmann .llseek = seq_lseek, 246e7b8fc92SMarcel Holtmann .release = single_release, 247e7b8fc92SMarcel Holtmann }; 248e7b8fc92SMarcel Holtmann 249b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file, 250b32bba6cSMarcel Holtmann char __user *user_buf, 251b32bba6cSMarcel Holtmann size_t count, loff_t *ppos) 25292202185SMarcel Holtmann { 253b32bba6cSMarcel Holtmann struct hci_dev *hdev = file->private_data; 254b32bba6cSMarcel Holtmann char buf[3]; 25592202185SMarcel Holtmann 256111902f7SMarcel Holtmann buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N'; 257b32bba6cSMarcel Holtmann buf[1] = '\n'; 258b32bba6cSMarcel Holtmann buf[2] = '\0'; 259b32bba6cSMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 260b32bba6cSMarcel Holtmann } 261b32bba6cSMarcel Holtmann 262b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file, 263b32bba6cSMarcel Holtmann const char __user *user_buf, 264b32bba6cSMarcel Holtmann size_t count, loff_t *ppos) 265b32bba6cSMarcel Holtmann { 266b32bba6cSMarcel Holtmann struct hci_dev *hdev = file->private_data; 267b32bba6cSMarcel Holtmann char buf[32]; 268b32bba6cSMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 269b32bba6cSMarcel Holtmann bool enable; 270b32bba6cSMarcel Holtmann 271b32bba6cSMarcel Holtmann if (test_bit(HCI_UP, &hdev->flags)) 272b32bba6cSMarcel Holtmann return -EBUSY; 273b32bba6cSMarcel Holtmann 274b32bba6cSMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 275b32bba6cSMarcel Holtmann return -EFAULT; 276b32bba6cSMarcel Holtmann 277b32bba6cSMarcel Holtmann buf[buf_size] = '\0'; 278b32bba6cSMarcel Holtmann if (strtobool(buf, &enable)) 27992202185SMarcel Holtmann return -EINVAL; 28092202185SMarcel Holtmann 281111902f7SMarcel Holtmann if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags)) 282b32bba6cSMarcel Holtmann return -EALREADY; 28392202185SMarcel Holtmann 284111902f7SMarcel Holtmann change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags); 285b32bba6cSMarcel Holtmann 286b32bba6cSMarcel Holtmann return count; 28792202185SMarcel Holtmann } 28892202185SMarcel Holtmann 289b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = { 290b32bba6cSMarcel Holtmann .open = simple_open, 291b32bba6cSMarcel Holtmann .read = force_static_address_read, 292b32bba6cSMarcel Holtmann .write = force_static_address_write, 293b32bba6cSMarcel Holtmann .llseek = default_llseek, 294b32bba6cSMarcel Holtmann }; 29592202185SMarcel Holtmann 296d2ab0ac1SMarcel Holtmann static int white_list_show(struct seq_file *f, void *ptr) 297d2ab0ac1SMarcel Holtmann { 298d2ab0ac1SMarcel Holtmann struct hci_dev *hdev = f->private; 299d2ab0ac1SMarcel Holtmann struct bdaddr_list *b; 300d2ab0ac1SMarcel Holtmann 301d2ab0ac1SMarcel Holtmann hci_dev_lock(hdev); 302d2ab0ac1SMarcel Holtmann list_for_each_entry(b, &hdev->le_white_list, list) 303d2ab0ac1SMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 304d2ab0ac1SMarcel Holtmann hci_dev_unlock(hdev); 305d2ab0ac1SMarcel Holtmann 306d2ab0ac1SMarcel Holtmann return 0; 307d2ab0ac1SMarcel Holtmann } 308d2ab0ac1SMarcel Holtmann 309d2ab0ac1SMarcel Holtmann static int white_list_open(struct inode *inode, struct file *file) 310d2ab0ac1SMarcel Holtmann { 311d2ab0ac1SMarcel Holtmann return single_open(file, white_list_show, inode->i_private); 312d2ab0ac1SMarcel Holtmann } 313d2ab0ac1SMarcel Holtmann 314d2ab0ac1SMarcel Holtmann static const struct file_operations white_list_fops = { 315d2ab0ac1SMarcel Holtmann .open = white_list_open, 316d2ab0ac1SMarcel Holtmann .read = seq_read, 317d2ab0ac1SMarcel Holtmann .llseek = seq_lseek, 318d2ab0ac1SMarcel Holtmann .release = single_release, 319d2ab0ac1SMarcel Holtmann }; 320d2ab0ac1SMarcel Holtmann 3213698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr) 3223698d704SMarcel Holtmann { 3233698d704SMarcel Holtmann struct hci_dev *hdev = f->private; 324adae20cbSJohan Hedberg struct smp_irk *irk; 3253698d704SMarcel Holtmann 326adae20cbSJohan Hedberg rcu_read_lock(); 327adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 3283698d704SMarcel Holtmann seq_printf(f, "%pMR (type %u) %*phN %pMR\n", 3293698d704SMarcel Holtmann &irk->bdaddr, irk->addr_type, 3303698d704SMarcel Holtmann 16, irk->val, &irk->rpa); 3313698d704SMarcel Holtmann } 332adae20cbSJohan Hedberg rcu_read_unlock(); 3333698d704SMarcel Holtmann 3343698d704SMarcel Holtmann return 0; 3353698d704SMarcel Holtmann } 3363698d704SMarcel Holtmann 3373698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file) 3383698d704SMarcel Holtmann { 3393698d704SMarcel Holtmann return single_open(file, identity_resolving_keys_show, 3403698d704SMarcel Holtmann inode->i_private); 3413698d704SMarcel Holtmann } 3423698d704SMarcel Holtmann 3433698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = { 3443698d704SMarcel Holtmann .open = identity_resolving_keys_open, 3453698d704SMarcel Holtmann .read = seq_read, 3463698d704SMarcel Holtmann .llseek = seq_lseek, 3473698d704SMarcel Holtmann .release = single_release, 3483698d704SMarcel Holtmann }; 3493698d704SMarcel Holtmann 3508f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr) 3518f8625cdSMarcel Holtmann { 3528f8625cdSMarcel Holtmann struct hci_dev *hdev = f->private; 353970d0f1bSJohan Hedberg struct smp_ltk *ltk; 3548f8625cdSMarcel Holtmann 355970d0f1bSJohan Hedberg rcu_read_lock(); 356970d0f1bSJohan Hedberg list_for_each_entry_rcu(ltk, &hdev->long_term_keys, list) 357fe39c7b2SMarcel Holtmann seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n", 3588f8625cdSMarcel Holtmann <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, 3598f8625cdSMarcel Holtmann ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), 360fe39c7b2SMarcel Holtmann __le64_to_cpu(ltk->rand), 16, ltk->val); 361970d0f1bSJohan Hedberg rcu_read_unlock(); 3628f8625cdSMarcel Holtmann 3638f8625cdSMarcel Holtmann return 0; 3648f8625cdSMarcel Holtmann } 3658f8625cdSMarcel Holtmann 3668f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file) 3678f8625cdSMarcel Holtmann { 3688f8625cdSMarcel Holtmann return single_open(file, long_term_keys_show, inode->i_private); 3698f8625cdSMarcel Holtmann } 3708f8625cdSMarcel Holtmann 3718f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = { 3728f8625cdSMarcel Holtmann .open = long_term_keys_open, 3738f8625cdSMarcel Holtmann .read = seq_read, 3748f8625cdSMarcel Holtmann .llseek = seq_lseek, 3758f8625cdSMarcel Holtmann .release = single_release, 3768f8625cdSMarcel Holtmann }; 3778f8625cdSMarcel Holtmann 3784e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val) 3794e70c7e7SMarcel Holtmann { 3804e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 3814e70c7e7SMarcel Holtmann 3824e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval) 3834e70c7e7SMarcel Holtmann return -EINVAL; 3844e70c7e7SMarcel Holtmann 3854e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 3864e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = val; 3874e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 3884e70c7e7SMarcel Holtmann 3894e70c7e7SMarcel Holtmann return 0; 3904e70c7e7SMarcel Holtmann } 3914e70c7e7SMarcel Holtmann 3924e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val) 3934e70c7e7SMarcel Holtmann { 3944e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 3954e70c7e7SMarcel Holtmann 3964e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 3974e70c7e7SMarcel Holtmann *val = hdev->le_conn_min_interval; 3984e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 3994e70c7e7SMarcel Holtmann 4004e70c7e7SMarcel Holtmann return 0; 4014e70c7e7SMarcel Holtmann } 4024e70c7e7SMarcel Holtmann 4034e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get, 4044e70c7e7SMarcel Holtmann conn_min_interval_set, "%llu\n"); 4054e70c7e7SMarcel Holtmann 4064e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val) 4074e70c7e7SMarcel Holtmann { 4084e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 4094e70c7e7SMarcel Holtmann 4104e70c7e7SMarcel Holtmann if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval) 4114e70c7e7SMarcel Holtmann return -EINVAL; 4124e70c7e7SMarcel Holtmann 4134e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 4144e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = val; 4154e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 4164e70c7e7SMarcel Holtmann 4174e70c7e7SMarcel Holtmann return 0; 4184e70c7e7SMarcel Holtmann } 4194e70c7e7SMarcel Holtmann 4204e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val) 4214e70c7e7SMarcel Holtmann { 4224e70c7e7SMarcel Holtmann struct hci_dev *hdev = data; 4234e70c7e7SMarcel Holtmann 4244e70c7e7SMarcel Holtmann hci_dev_lock(hdev); 4254e70c7e7SMarcel Holtmann *val = hdev->le_conn_max_interval; 4264e70c7e7SMarcel Holtmann hci_dev_unlock(hdev); 4274e70c7e7SMarcel Holtmann 4284e70c7e7SMarcel Holtmann return 0; 4294e70c7e7SMarcel Holtmann } 4304e70c7e7SMarcel Holtmann 4314e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, 4324e70c7e7SMarcel Holtmann conn_max_interval_set, "%llu\n"); 4334e70c7e7SMarcel Holtmann 434816a93d1SMarcel Holtmann static int conn_latency_set(void *data, u64 val) 435816a93d1SMarcel Holtmann { 436816a93d1SMarcel Holtmann struct hci_dev *hdev = data; 437816a93d1SMarcel Holtmann 438816a93d1SMarcel Holtmann if (val > 0x01f3) 439816a93d1SMarcel Holtmann return -EINVAL; 440816a93d1SMarcel Holtmann 441816a93d1SMarcel Holtmann hci_dev_lock(hdev); 442816a93d1SMarcel Holtmann hdev->le_conn_latency = val; 443816a93d1SMarcel Holtmann hci_dev_unlock(hdev); 444816a93d1SMarcel Holtmann 445816a93d1SMarcel Holtmann return 0; 446816a93d1SMarcel Holtmann } 447816a93d1SMarcel Holtmann 448816a93d1SMarcel Holtmann static int conn_latency_get(void *data, u64 *val) 449816a93d1SMarcel Holtmann { 450816a93d1SMarcel Holtmann struct hci_dev *hdev = data; 451816a93d1SMarcel Holtmann 452816a93d1SMarcel Holtmann hci_dev_lock(hdev); 453816a93d1SMarcel Holtmann *val = hdev->le_conn_latency; 454816a93d1SMarcel Holtmann hci_dev_unlock(hdev); 455816a93d1SMarcel Holtmann 456816a93d1SMarcel Holtmann return 0; 457816a93d1SMarcel Holtmann } 458816a93d1SMarcel Holtmann 459816a93d1SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get, 460816a93d1SMarcel Holtmann conn_latency_set, "%llu\n"); 461816a93d1SMarcel Holtmann 462f1649577SMarcel Holtmann static int supervision_timeout_set(void *data, u64 val) 463f1649577SMarcel Holtmann { 464f1649577SMarcel Holtmann struct hci_dev *hdev = data; 465f1649577SMarcel Holtmann 466f1649577SMarcel Holtmann if (val < 0x000a || val > 0x0c80) 467f1649577SMarcel Holtmann return -EINVAL; 468f1649577SMarcel Holtmann 469f1649577SMarcel Holtmann hci_dev_lock(hdev); 470f1649577SMarcel Holtmann hdev->le_supv_timeout = val; 471f1649577SMarcel Holtmann hci_dev_unlock(hdev); 472f1649577SMarcel Holtmann 473f1649577SMarcel Holtmann return 0; 474f1649577SMarcel Holtmann } 475f1649577SMarcel Holtmann 476f1649577SMarcel Holtmann static int supervision_timeout_get(void *data, u64 *val) 477f1649577SMarcel Holtmann { 478f1649577SMarcel Holtmann struct hci_dev *hdev = data; 479f1649577SMarcel Holtmann 480f1649577SMarcel Holtmann hci_dev_lock(hdev); 481f1649577SMarcel Holtmann *val = hdev->le_supv_timeout; 482f1649577SMarcel Holtmann hci_dev_unlock(hdev); 483f1649577SMarcel Holtmann 484f1649577SMarcel Holtmann return 0; 485f1649577SMarcel Holtmann } 486f1649577SMarcel Holtmann 487f1649577SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get, 488f1649577SMarcel Holtmann supervision_timeout_set, "%llu\n"); 489f1649577SMarcel Holtmann 4903f959d46SMarcel Holtmann static int adv_channel_map_set(void *data, u64 val) 4913f959d46SMarcel Holtmann { 4923f959d46SMarcel Holtmann struct hci_dev *hdev = data; 4933f959d46SMarcel Holtmann 4943f959d46SMarcel Holtmann if (val < 0x01 || val > 0x07) 4953f959d46SMarcel Holtmann return -EINVAL; 4963f959d46SMarcel Holtmann 4973f959d46SMarcel Holtmann hci_dev_lock(hdev); 4983f959d46SMarcel Holtmann hdev->le_adv_channel_map = val; 4993f959d46SMarcel Holtmann hci_dev_unlock(hdev); 5003f959d46SMarcel Holtmann 5013f959d46SMarcel Holtmann return 0; 5023f959d46SMarcel Holtmann } 5033f959d46SMarcel Holtmann 5043f959d46SMarcel Holtmann static int adv_channel_map_get(void *data, u64 *val) 5053f959d46SMarcel Holtmann { 5063f959d46SMarcel Holtmann struct hci_dev *hdev = data; 5073f959d46SMarcel Holtmann 5083f959d46SMarcel Holtmann hci_dev_lock(hdev); 5093f959d46SMarcel Holtmann *val = hdev->le_adv_channel_map; 5103f959d46SMarcel Holtmann hci_dev_unlock(hdev); 5113f959d46SMarcel Holtmann 5123f959d46SMarcel Holtmann return 0; 5133f959d46SMarcel Holtmann } 5143f959d46SMarcel Holtmann 5153f959d46SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get, 5163f959d46SMarcel Holtmann adv_channel_map_set, "%llu\n"); 5173f959d46SMarcel Holtmann 518729a1051SGeorg Lukas static int adv_min_interval_set(void *data, u64 val) 51989863109SJukka Rissanen { 520729a1051SGeorg Lukas struct hci_dev *hdev = data; 52189863109SJukka Rissanen 522729a1051SGeorg Lukas if (val < 0x0020 || val > 0x4000 || val > hdev->le_adv_max_interval) 52389863109SJukka Rissanen return -EINVAL; 52489863109SJukka Rissanen 5257d474e06SAndre Guedes hci_dev_lock(hdev); 526729a1051SGeorg Lukas hdev->le_adv_min_interval = val; 5277d474e06SAndre Guedes hci_dev_unlock(hdev); 5287d474e06SAndre Guedes 5297d474e06SAndre Guedes return 0; 5307d474e06SAndre Guedes } 5317d474e06SAndre Guedes 532729a1051SGeorg Lukas static int adv_min_interval_get(void *data, u64 *val) 5337d474e06SAndre Guedes { 534729a1051SGeorg Lukas struct hci_dev *hdev = data; 535729a1051SGeorg Lukas 536729a1051SGeorg Lukas hci_dev_lock(hdev); 537729a1051SGeorg Lukas *val = hdev->le_adv_min_interval; 538729a1051SGeorg Lukas hci_dev_unlock(hdev); 539729a1051SGeorg Lukas 540729a1051SGeorg Lukas return 0; 5417d474e06SAndre Guedes } 5427d474e06SAndre Guedes 543729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_min_interval_fops, adv_min_interval_get, 544729a1051SGeorg Lukas adv_min_interval_set, "%llu\n"); 5457d474e06SAndre Guedes 546729a1051SGeorg Lukas static int adv_max_interval_set(void *data, u64 val) 547729a1051SGeorg Lukas { 548729a1051SGeorg Lukas struct hci_dev *hdev = data; 549729a1051SGeorg Lukas 550729a1051SGeorg Lukas if (val < 0x0020 || val > 0x4000 || val < hdev->le_adv_min_interval) 5517d474e06SAndre Guedes return -EINVAL; 5527d474e06SAndre Guedes 5537d474e06SAndre Guedes hci_dev_lock(hdev); 554729a1051SGeorg Lukas hdev->le_adv_max_interval = val; 5557d474e06SAndre Guedes hci_dev_unlock(hdev); 5567d474e06SAndre Guedes 557729a1051SGeorg Lukas return 0; 5587d474e06SAndre Guedes } 5597d474e06SAndre Guedes 560729a1051SGeorg Lukas static int adv_max_interval_get(void *data, u64 *val) 561729a1051SGeorg Lukas { 562729a1051SGeorg Lukas struct hci_dev *hdev = data; 563729a1051SGeorg Lukas 5647d474e06SAndre Guedes hci_dev_lock(hdev); 565729a1051SGeorg Lukas *val = hdev->le_adv_max_interval; 5667d474e06SAndre Guedes hci_dev_unlock(hdev); 567729a1051SGeorg Lukas 568729a1051SGeorg Lukas return 0; 569729a1051SGeorg Lukas } 570729a1051SGeorg Lukas 571729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get, 572729a1051SGeorg Lukas adv_max_interval_set, "%llu\n"); 573729a1051SGeorg Lukas 5741da177e4SLinus Torvalds /* ---- HCI requests ---- */ 5751da177e4SLinus Torvalds 57642c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 5771da177e4SLinus Torvalds { 57842c6b129SJohan Hedberg BT_DBG("%s result 0x%2.2x", hdev->name, result); 57975fb0e32SJohan Hedberg 5801da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 5811da177e4SLinus Torvalds hdev->req_result = result; 5821da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 5831da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 5841da177e4SLinus Torvalds } 5851da177e4SLinus Torvalds } 5861da177e4SLinus Torvalds 5871da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 5881da177e4SLinus Torvalds { 5891da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 5901da177e4SLinus Torvalds 5911da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 5921da177e4SLinus Torvalds hdev->req_result = err; 5931da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 5941da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 5951da177e4SLinus Torvalds } 5961da177e4SLinus Torvalds } 5971da177e4SLinus Torvalds 59877a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 59977a63e0aSFengguang Wu u8 event) 60075e84b7cSJohan Hedberg { 60175e84b7cSJohan Hedberg struct hci_ev_cmd_complete *ev; 60275e84b7cSJohan Hedberg struct hci_event_hdr *hdr; 60375e84b7cSJohan Hedberg struct sk_buff *skb; 60475e84b7cSJohan Hedberg 60575e84b7cSJohan Hedberg hci_dev_lock(hdev); 60675e84b7cSJohan Hedberg 60775e84b7cSJohan Hedberg skb = hdev->recv_evt; 60875e84b7cSJohan Hedberg hdev->recv_evt = NULL; 60975e84b7cSJohan Hedberg 61075e84b7cSJohan Hedberg hci_dev_unlock(hdev); 61175e84b7cSJohan Hedberg 61275e84b7cSJohan Hedberg if (!skb) 61375e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 61475e84b7cSJohan Hedberg 61575e84b7cSJohan Hedberg if (skb->len < sizeof(*hdr)) { 61675e84b7cSJohan Hedberg BT_ERR("Too short HCI event"); 61775e84b7cSJohan Hedberg goto failed; 61875e84b7cSJohan Hedberg } 61975e84b7cSJohan Hedberg 62075e84b7cSJohan Hedberg hdr = (void *) skb->data; 62175e84b7cSJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 62275e84b7cSJohan Hedberg 6237b1abbbeSJohan Hedberg if (event) { 6247b1abbbeSJohan Hedberg if (hdr->evt != event) 6257b1abbbeSJohan Hedberg goto failed; 6267b1abbbeSJohan Hedberg return skb; 6277b1abbbeSJohan Hedberg } 6287b1abbbeSJohan Hedberg 62975e84b7cSJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 63075e84b7cSJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 63175e84b7cSJohan Hedberg goto failed; 63275e84b7cSJohan Hedberg } 63375e84b7cSJohan Hedberg 63475e84b7cSJohan Hedberg if (skb->len < sizeof(*ev)) { 63575e84b7cSJohan Hedberg BT_ERR("Too short cmd_complete event"); 63675e84b7cSJohan Hedberg goto failed; 63775e84b7cSJohan Hedberg } 63875e84b7cSJohan Hedberg 63975e84b7cSJohan Hedberg ev = (void *) skb->data; 64075e84b7cSJohan Hedberg skb_pull(skb, sizeof(*ev)); 64175e84b7cSJohan Hedberg 64275e84b7cSJohan Hedberg if (opcode == __le16_to_cpu(ev->opcode)) 64375e84b7cSJohan Hedberg return skb; 64475e84b7cSJohan Hedberg 64575e84b7cSJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 64675e84b7cSJohan Hedberg __le16_to_cpu(ev->opcode)); 64775e84b7cSJohan Hedberg 64875e84b7cSJohan Hedberg failed: 64975e84b7cSJohan Hedberg kfree_skb(skb); 65075e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 65175e84b7cSJohan Hedberg } 65275e84b7cSJohan Hedberg 6537b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 65407dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout) 65575e84b7cSJohan Hedberg { 65675e84b7cSJohan Hedberg DECLARE_WAITQUEUE(wait, current); 65775e84b7cSJohan Hedberg struct hci_request req; 65875e84b7cSJohan Hedberg int err = 0; 65975e84b7cSJohan Hedberg 66075e84b7cSJohan Hedberg BT_DBG("%s", hdev->name); 66175e84b7cSJohan Hedberg 66275e84b7cSJohan Hedberg hci_req_init(&req, hdev); 66375e84b7cSJohan Hedberg 6647b1abbbeSJohan Hedberg hci_req_add_ev(&req, opcode, plen, param, event); 66575e84b7cSJohan Hedberg 66675e84b7cSJohan Hedberg hdev->req_status = HCI_REQ_PEND; 66775e84b7cSJohan Hedberg 66875e84b7cSJohan Hedberg add_wait_queue(&hdev->req_wait_q, &wait); 66975e84b7cSJohan Hedberg set_current_state(TASK_INTERRUPTIBLE); 67075e84b7cSJohan Hedberg 671039fada5SChan-yeol Park err = hci_req_run(&req, hci_req_sync_complete); 672039fada5SChan-yeol Park if (err < 0) { 673039fada5SChan-yeol Park remove_wait_queue(&hdev->req_wait_q, &wait); 67422a3ceabSJohan Hedberg set_current_state(TASK_RUNNING); 675039fada5SChan-yeol Park return ERR_PTR(err); 676039fada5SChan-yeol Park } 677039fada5SChan-yeol Park 67875e84b7cSJohan Hedberg schedule_timeout(timeout); 67975e84b7cSJohan Hedberg 68075e84b7cSJohan Hedberg remove_wait_queue(&hdev->req_wait_q, &wait); 68175e84b7cSJohan Hedberg 68275e84b7cSJohan Hedberg if (signal_pending(current)) 68375e84b7cSJohan Hedberg return ERR_PTR(-EINTR); 68475e84b7cSJohan Hedberg 68575e84b7cSJohan Hedberg switch (hdev->req_status) { 68675e84b7cSJohan Hedberg case HCI_REQ_DONE: 68775e84b7cSJohan Hedberg err = -bt_to_errno(hdev->req_result); 68875e84b7cSJohan Hedberg break; 68975e84b7cSJohan Hedberg 69075e84b7cSJohan Hedberg case HCI_REQ_CANCELED: 69175e84b7cSJohan Hedberg err = -hdev->req_result; 69275e84b7cSJohan Hedberg break; 69375e84b7cSJohan Hedberg 69475e84b7cSJohan Hedberg default: 69575e84b7cSJohan Hedberg err = -ETIMEDOUT; 69675e84b7cSJohan Hedberg break; 69775e84b7cSJohan Hedberg } 69875e84b7cSJohan Hedberg 69975e84b7cSJohan Hedberg hdev->req_status = hdev->req_result = 0; 70075e84b7cSJohan Hedberg 70175e84b7cSJohan Hedberg BT_DBG("%s end: err %d", hdev->name, err); 70275e84b7cSJohan Hedberg 70375e84b7cSJohan Hedberg if (err < 0) 70475e84b7cSJohan Hedberg return ERR_PTR(err); 70575e84b7cSJohan Hedberg 7067b1abbbeSJohan Hedberg return hci_get_cmd_complete(hdev, opcode, event); 7077b1abbbeSJohan Hedberg } 7087b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev); 7097b1abbbeSJohan Hedberg 7107b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 71107dc93ddSJohan Hedberg const void *param, u32 timeout) 7127b1abbbeSJohan Hedberg { 7137b1abbbeSJohan Hedberg return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); 71475e84b7cSJohan Hedberg } 71575e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync); 71675e84b7cSJohan Hedberg 7171da177e4SLinus Torvalds /* Execute request and wait for completion. */ 71801178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev, 71942c6b129SJohan Hedberg void (*func)(struct hci_request *req, 72042c6b129SJohan Hedberg unsigned long opt), 7211da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 7221da177e4SLinus Torvalds { 72342c6b129SJohan Hedberg struct hci_request req; 7241da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 7251da177e4SLinus Torvalds int err = 0; 7261da177e4SLinus Torvalds 7271da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 7281da177e4SLinus Torvalds 72942c6b129SJohan Hedberg hci_req_init(&req, hdev); 73042c6b129SJohan Hedberg 7311da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 7321da177e4SLinus Torvalds 73342c6b129SJohan Hedberg func(&req, opt); 73453cce22dSJohan Hedberg 735039fada5SChan-yeol Park add_wait_queue(&hdev->req_wait_q, &wait); 736039fada5SChan-yeol Park set_current_state(TASK_INTERRUPTIBLE); 737039fada5SChan-yeol Park 73842c6b129SJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 73942c6b129SJohan Hedberg if (err < 0) { 74053cce22dSJohan Hedberg hdev->req_status = 0; 741920c8300SAndre Guedes 742039fada5SChan-yeol Park remove_wait_queue(&hdev->req_wait_q, &wait); 74322a3ceabSJohan Hedberg set_current_state(TASK_RUNNING); 744039fada5SChan-yeol Park 745920c8300SAndre Guedes /* ENODATA means the HCI request command queue is empty. 746920c8300SAndre Guedes * This can happen when a request with conditionals doesn't 747920c8300SAndre Guedes * trigger any commands to be sent. This is normal behavior 748920c8300SAndre Guedes * and should not trigger an error return. 74942c6b129SJohan Hedberg */ 750920c8300SAndre Guedes if (err == -ENODATA) 75142c6b129SJohan Hedberg return 0; 752920c8300SAndre Guedes 753920c8300SAndre Guedes return err; 75453cce22dSJohan Hedberg } 75553cce22dSJohan Hedberg 7561da177e4SLinus Torvalds schedule_timeout(timeout); 7571da177e4SLinus Torvalds 7581da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 7591da177e4SLinus Torvalds 7601da177e4SLinus Torvalds if (signal_pending(current)) 7611da177e4SLinus Torvalds return -EINTR; 7621da177e4SLinus Torvalds 7631da177e4SLinus Torvalds switch (hdev->req_status) { 7641da177e4SLinus Torvalds case HCI_REQ_DONE: 765e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 7661da177e4SLinus Torvalds break; 7671da177e4SLinus Torvalds 7681da177e4SLinus Torvalds case HCI_REQ_CANCELED: 7691da177e4SLinus Torvalds err = -hdev->req_result; 7701da177e4SLinus Torvalds break; 7711da177e4SLinus Torvalds 7721da177e4SLinus Torvalds default: 7731da177e4SLinus Torvalds err = -ETIMEDOUT; 7741da177e4SLinus Torvalds break; 7753ff50b79SStephen Hemminger } 7761da177e4SLinus Torvalds 777a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 7781da177e4SLinus Torvalds 7791da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 7801da177e4SLinus Torvalds 7811da177e4SLinus Torvalds return err; 7821da177e4SLinus Torvalds } 7831da177e4SLinus Torvalds 78401178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev, 78542c6b129SJohan Hedberg void (*req)(struct hci_request *req, 78642c6b129SJohan Hedberg unsigned long opt), 7871da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 7881da177e4SLinus Torvalds { 7891da177e4SLinus Torvalds int ret; 7901da177e4SLinus Torvalds 7917c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 7927c6a329eSMarcel Holtmann return -ENETDOWN; 7937c6a329eSMarcel Holtmann 7941da177e4SLinus Torvalds /* Serialize all requests */ 7951da177e4SLinus Torvalds hci_req_lock(hdev); 79601178cd4SJohan Hedberg ret = __hci_req_sync(hdev, req, opt, timeout); 7971da177e4SLinus Torvalds hci_req_unlock(hdev); 7981da177e4SLinus Torvalds 7991da177e4SLinus Torvalds return ret; 8001da177e4SLinus Torvalds } 8011da177e4SLinus Torvalds 80242c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt) 8031da177e4SLinus Torvalds { 80442c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 8051da177e4SLinus Torvalds 8061da177e4SLinus Torvalds /* Reset device */ 80742c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 80842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 8091da177e4SLinus Torvalds } 8101da177e4SLinus Torvalds 81142c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 8121da177e4SLinus Torvalds { 81342c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 8142455a3eaSAndrei Emeltchenko 8151da177e4SLinus Torvalds /* Read Local Supported Features */ 81642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 8171da177e4SLinus Torvalds 8181143e5a6SMarcel Holtmann /* Read Local Version */ 81942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 8202177bab5SJohan Hedberg 8212177bab5SJohan Hedberg /* Read BD Address */ 82242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 8231da177e4SLinus Torvalds } 8241da177e4SLinus Torvalds 82542c6b129SJohan Hedberg static void amp_init(struct hci_request *req) 826e61ef499SAndrei Emeltchenko { 82742c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 8282455a3eaSAndrei Emeltchenko 829e61ef499SAndrei Emeltchenko /* Read Local Version */ 83042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 8316bcbc489SAndrei Emeltchenko 832f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 833f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 834f6996cfeSMarcel Holtmann 835f6996cfeSMarcel Holtmann /* Read Local Supported Features */ 836f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 837f6996cfeSMarcel Holtmann 8386bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 83942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 840e71dfabaSAndrei Emeltchenko 841e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 84242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 8437528ca1cSMarcel Holtmann 844f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 845f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 846f38ba941SMarcel Holtmann 8477528ca1cSMarcel Holtmann /* Read Location Data */ 8487528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 849e61ef499SAndrei Emeltchenko } 850e61ef499SAndrei Emeltchenko 85142c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 852e61ef499SAndrei Emeltchenko { 85342c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 854e61ef499SAndrei Emeltchenko 855e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 856e61ef499SAndrei Emeltchenko 85711778716SAndrei Emeltchenko /* Reset */ 85811778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 85942c6b129SJohan Hedberg hci_reset_req(req, 0); 86011778716SAndrei Emeltchenko 861e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 862e61ef499SAndrei Emeltchenko case HCI_BREDR: 86342c6b129SJohan Hedberg bredr_init(req); 864e61ef499SAndrei Emeltchenko break; 865e61ef499SAndrei Emeltchenko 866e61ef499SAndrei Emeltchenko case HCI_AMP: 86742c6b129SJohan Hedberg amp_init(req); 868e61ef499SAndrei Emeltchenko break; 869e61ef499SAndrei Emeltchenko 870e61ef499SAndrei Emeltchenko default: 871e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 872e61ef499SAndrei Emeltchenko break; 873e61ef499SAndrei Emeltchenko } 874e61ef499SAndrei Emeltchenko } 875e61ef499SAndrei Emeltchenko 87642c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 8772177bab5SJohan Hedberg { 8782177bab5SJohan Hedberg __le16 param; 8792177bab5SJohan Hedberg __u8 flt_type; 8802177bab5SJohan Hedberg 8812177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 88242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 8832177bab5SJohan Hedberg 8842177bab5SJohan Hedberg /* Read Class of Device */ 88542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 8862177bab5SJohan Hedberg 8872177bab5SJohan Hedberg /* Read Local Name */ 88842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 8892177bab5SJohan Hedberg 8902177bab5SJohan Hedberg /* Read Voice Setting */ 89142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 8922177bab5SJohan Hedberg 893b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 894b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 895b4cb9fb2SMarcel Holtmann 8964b836f39SMarcel Holtmann /* Read Current IAC LAP */ 8974b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 8984b836f39SMarcel Holtmann 8992177bab5SJohan Hedberg /* Clear Event Filters */ 9002177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 90142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 9022177bab5SJohan Hedberg 9032177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 904dcf4adbfSJoe Perches param = cpu_to_le16(0x7d00); 90542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 9062177bab5SJohan Hedberg } 9072177bab5SJohan Hedberg 90842c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 9092177bab5SJohan Hedberg { 910c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 911c73eee91SJohan Hedberg 9122177bab5SJohan Hedberg /* Read LE Buffer Size */ 91342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 9142177bab5SJohan Hedberg 9152177bab5SJohan Hedberg /* Read LE Local Supported Features */ 91642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 9172177bab5SJohan Hedberg 918747d3f03SMarcel Holtmann /* Read LE Supported States */ 919747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 920747d3f03SMarcel Holtmann 9212177bab5SJohan Hedberg /* Read LE White List Size */ 92242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 9232177bab5SJohan Hedberg 924747d3f03SMarcel Holtmann /* Clear LE White List */ 925747d3f03SMarcel Holtmann hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL); 926c73eee91SJohan Hedberg 927c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 928c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 929c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 9302177bab5SJohan Hedberg } 9312177bab5SJohan Hedberg 9322177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 9332177bab5SJohan Hedberg { 9342177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 9352177bab5SJohan Hedberg return 0x02; 9362177bab5SJohan Hedberg 9372177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 9382177bab5SJohan Hedberg return 0x01; 9392177bab5SJohan Hedberg 9402177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 9412177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 9422177bab5SJohan Hedberg return 0x01; 9432177bab5SJohan Hedberg 9442177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 9452177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 9462177bab5SJohan Hedberg return 0x01; 9472177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 9482177bab5SJohan Hedberg return 0x01; 9492177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 9502177bab5SJohan Hedberg return 0x01; 9512177bab5SJohan Hedberg } 9522177bab5SJohan Hedberg 9532177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 9542177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 9552177bab5SJohan Hedberg return 0x01; 9562177bab5SJohan Hedberg 9572177bab5SJohan Hedberg return 0x00; 9582177bab5SJohan Hedberg } 9592177bab5SJohan Hedberg 96042c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 9612177bab5SJohan Hedberg { 9622177bab5SJohan Hedberg u8 mode; 9632177bab5SJohan Hedberg 96442c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 9652177bab5SJohan Hedberg 96642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 9672177bab5SJohan Hedberg } 9682177bab5SJohan Hedberg 96942c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 9702177bab5SJohan Hedberg { 97142c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 97242c6b129SJohan Hedberg 9732177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 9742177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 9752177bab5SJohan Hedberg * command otherwise. 9762177bab5SJohan Hedberg */ 9772177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 9782177bab5SJohan Hedberg 9792177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 9802177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 9812177bab5SJohan Hedberg */ 9822177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 9832177bab5SJohan Hedberg return; 9842177bab5SJohan Hedberg 9852177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 9862177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 9872177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 9882177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 9892177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 9902177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 991c7882cbdSMarcel Holtmann } else { 992c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 993c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 994c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 995c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 996c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 997c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 998c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 999c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 1000c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 10010da71f1bSMarcel Holtmann 10020da71f1bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) { 10030da71f1bSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 1004c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 10052177bab5SJohan Hedberg } 10060da71f1bSMarcel Holtmann } 10072177bab5SJohan Hedberg 10082177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 10092177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 10102177bab5SJohan Hedberg 10112177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 10122177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 10132177bab5SJohan Hedberg 10142177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 10152177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 10162177bab5SJohan Hedberg 10172177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 10182177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 10192177bab5SJohan Hedberg 10202177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 10212177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 10222177bab5SJohan Hedberg 10232177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 10242177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 10252177bab5SJohan Hedberg 10262177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 10272177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 10282177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 10292177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 10302177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 10312177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 10322177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 10332177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 10342177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 10352177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 10362177bab5SJohan Hedberg * Features Notification 10372177bab5SJohan Hedberg */ 10382177bab5SJohan Hedberg } 10392177bab5SJohan Hedberg 10402177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 10412177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 10422177bab5SJohan Hedberg 104342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 10442177bab5SJohan Hedberg } 10452177bab5SJohan Hedberg 104642c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 10472177bab5SJohan Hedberg { 104842c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 104942c6b129SJohan Hedberg 10502177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 105142c6b129SJohan Hedberg bredr_setup(req); 105256f87901SJohan Hedberg else 105356f87901SJohan Hedberg clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 10542177bab5SJohan Hedberg 10552177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 105642c6b129SJohan Hedberg le_setup(req); 10572177bab5SJohan Hedberg 10583f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 10593f8e2d75SJohan Hedberg * local supported commands HCI command. 10603f8e2d75SJohan Hedberg */ 10613f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 106242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 10632177bab5SJohan Hedberg 10642177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 106557af75a8SMarcel Holtmann /* When SSP is available, then the host features page 106657af75a8SMarcel Holtmann * should also be available as well. However some 106757af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 106857af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 106957af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 107057af75a8SMarcel Holtmann */ 107157af75a8SMarcel Holtmann hdev->max_page = 0x01; 107257af75a8SMarcel Holtmann 10732177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 10742177bab5SJohan Hedberg u8 mode = 0x01; 107542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 10762177bab5SJohan Hedberg sizeof(mode), &mode); 10772177bab5SJohan Hedberg } else { 10782177bab5SJohan Hedberg struct hci_cp_write_eir cp; 10792177bab5SJohan Hedberg 10802177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 10812177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 10822177bab5SJohan Hedberg 108342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 10842177bab5SJohan Hedberg } 10852177bab5SJohan Hedberg } 10862177bab5SJohan Hedberg 10872177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 108842c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 10892177bab5SJohan Hedberg 10902177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 109142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 10922177bab5SJohan Hedberg 10932177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 10942177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 10952177bab5SJohan Hedberg 10962177bab5SJohan Hedberg cp.page = 0x01; 109742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 109842c6b129SJohan Hedberg sizeof(cp), &cp); 10992177bab5SJohan Hedberg } 11002177bab5SJohan Hedberg 11012177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 11022177bab5SJohan Hedberg u8 enable = 1; 110342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 11042177bab5SJohan Hedberg &enable); 11052177bab5SJohan Hedberg } 11062177bab5SJohan Hedberg } 11072177bab5SJohan Hedberg 110842c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 11092177bab5SJohan Hedberg { 111042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 11112177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 11122177bab5SJohan Hedberg u16 link_policy = 0; 11132177bab5SJohan Hedberg 11142177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 11152177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 11162177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 11172177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 11182177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 11192177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 11202177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 11212177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 11222177bab5SJohan Hedberg 11232177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 112442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 11252177bab5SJohan Hedberg } 11262177bab5SJohan Hedberg 112742c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 11282177bab5SJohan Hedberg { 112942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 11302177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 11312177bab5SJohan Hedberg 1132c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 1133c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1134c73eee91SJohan Hedberg return; 1135c73eee91SJohan Hedberg 11362177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 11372177bab5SJohan Hedberg 11382177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 11392177bab5SJohan Hedberg cp.le = 0x01; 114032226e4fSMarcel Holtmann cp.simul = 0x00; 11412177bab5SJohan Hedberg } 11422177bab5SJohan Hedberg 11432177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 114442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 11452177bab5SJohan Hedberg &cp); 11462177bab5SJohan Hedberg } 11472177bab5SJohan Hedberg 1148d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 1149d62e6d67SJohan Hedberg { 1150d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 1151d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1152d62e6d67SJohan Hedberg 1153d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 1154d62e6d67SJohan Hedberg * enable all necessary events for it. 1155d62e6d67SJohan Hedberg */ 115653b834d2SMarcel Holtmann if (lmp_csb_master_capable(hdev)) { 1157d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 1158d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 1159d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 1160d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 1161d62e6d67SJohan Hedberg } 1162d62e6d67SJohan Hedberg 1163d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 1164d62e6d67SJohan Hedberg * enable all necessary events for it. 1165d62e6d67SJohan Hedberg */ 116653b834d2SMarcel Holtmann if (lmp_csb_slave_capable(hdev)) { 1167d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 1168d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 1169d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 1170d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 1171d62e6d67SJohan Hedberg } 1172d62e6d67SJohan Hedberg 117340c59fcbSMarcel Holtmann /* Enable Authenticated Payload Timeout Expired event if supported */ 1174cd7ca0ecSMarcel Holtmann if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) 117540c59fcbSMarcel Holtmann events[2] |= 0x80; 117640c59fcbSMarcel Holtmann 1177d62e6d67SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 1178d62e6d67SJohan Hedberg } 1179d62e6d67SJohan Hedberg 118042c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 11812177bab5SJohan Hedberg { 118242c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1183d2c5d77fSJohan Hedberg u8 p; 118442c6b129SJohan Hedberg 11850da71f1bSMarcel Holtmann hci_setup_event_mask(req); 11860da71f1bSMarcel Holtmann 1187b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 1188b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 1189b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 1190b8f4e068SGustavo Padovan * 1191b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 1192b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 1193b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 1194b8f4e068SGustavo Padovan * command redundant anyway. 1195f9f462faSMarcel Holtmann * 1196f9f462faSMarcel Holtmann * Some controllers indicate that they support handling deleting 1197f9f462faSMarcel Holtmann * stored link keys, but they don't. The quirk lets a driver 1198f9f462faSMarcel Holtmann * just disable this command. 1199b8f4e068SGustavo Padovan */ 1200f9f462faSMarcel Holtmann if (hdev->commands[6] & 0x80 && 1201f9f462faSMarcel Holtmann !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { 120259f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 120359f45d57SJohan Hedberg 120459f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 120559f45d57SJohan Hedberg cp.delete_all = 0x01; 120659f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 120759f45d57SJohan Hedberg sizeof(cp), &cp); 120859f45d57SJohan Hedberg } 120959f45d57SJohan Hedberg 12102177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 121142c6b129SJohan Hedberg hci_setup_link_policy(req); 12122177bab5SJohan Hedberg 1213417287deSMarcel Holtmann if (hdev->commands[8] & 0x01) 1214417287deSMarcel Holtmann hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 1215417287deSMarcel Holtmann 1216417287deSMarcel Holtmann /* Some older Broadcom based Bluetooth 1.2 controllers do not 1217417287deSMarcel Holtmann * support the Read Page Scan Type command. Check support for 1218417287deSMarcel Holtmann * this command in the bit mask of supported commands. 1219417287deSMarcel Holtmann */ 1220417287deSMarcel Holtmann if (hdev->commands[13] & 0x01) 1221417287deSMarcel Holtmann hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 1222417287deSMarcel Holtmann 12239193c6e8SAndre Guedes if (lmp_le_capable(hdev)) { 12249193c6e8SAndre Guedes u8 events[8]; 12259193c6e8SAndre Guedes 12269193c6e8SAndre Guedes memset(events, 0, sizeof(events)); 12274d6c705bSMarcel Holtmann events[0] = 0x0f; 12284d6c705bSMarcel Holtmann 12294d6c705bSMarcel Holtmann if (hdev->le_features[0] & HCI_LE_ENCRYPTION) 12304d6c705bSMarcel Holtmann events[0] |= 0x10; /* LE Long Term Key Request */ 1231662bc2e6SAndre Guedes 1232662bc2e6SAndre Guedes /* If controller supports the Connection Parameters Request 1233662bc2e6SAndre Guedes * Link Layer Procedure, enable the corresponding event. 1234662bc2e6SAndre Guedes */ 1235662bc2e6SAndre Guedes if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC) 1236662bc2e6SAndre Guedes events[0] |= 0x20; /* LE Remote Connection 1237662bc2e6SAndre Guedes * Parameter Request 1238662bc2e6SAndre Guedes */ 1239662bc2e6SAndre Guedes 12404b71bba4SMarcel Holtmann /* If the controller supports Extended Scanner Filter 12414b71bba4SMarcel Holtmann * Policies, enable the correspondig event. 12424b71bba4SMarcel Holtmann */ 12434b71bba4SMarcel Holtmann if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY) 12444b71bba4SMarcel Holtmann events[1] |= 0x04; /* LE Direct Advertising 12454b71bba4SMarcel Holtmann * Report 12464b71bba4SMarcel Holtmann */ 12474b71bba4SMarcel Holtmann 12485a34bd5fSMarcel Holtmann /* If the controller supports the LE Read Local P-256 12495a34bd5fSMarcel Holtmann * Public Key command, enable the corresponding event. 12505a34bd5fSMarcel Holtmann */ 12515a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x02) 12525a34bd5fSMarcel Holtmann events[0] |= 0x80; /* LE Read Local P-256 12535a34bd5fSMarcel Holtmann * Public Key Complete 12545a34bd5fSMarcel Holtmann */ 12555a34bd5fSMarcel Holtmann 12565a34bd5fSMarcel Holtmann /* If the controller supports the LE Generate DHKey 12575a34bd5fSMarcel Holtmann * command, enable the corresponding event. 12585a34bd5fSMarcel Holtmann */ 12595a34bd5fSMarcel Holtmann if (hdev->commands[34] & 0x04) 12605a34bd5fSMarcel Holtmann events[1] |= 0x01; /* LE Generate DHKey Complete */ 12615a34bd5fSMarcel Holtmann 12629193c6e8SAndre Guedes hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), 12639193c6e8SAndre Guedes events); 12649193c6e8SAndre Guedes 126515a49ccaSMarcel Holtmann if (hdev->commands[25] & 0x40) { 126615a49ccaSMarcel Holtmann /* Read LE Advertising Channel TX Power */ 126715a49ccaSMarcel Holtmann hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 126815a49ccaSMarcel Holtmann } 126915a49ccaSMarcel Holtmann 127042c6b129SJohan Hedberg hci_set_le_support(req); 12719193c6e8SAndre Guedes } 1272d2c5d77fSJohan Hedberg 1273d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 1274d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 1275d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 1276d2c5d77fSJohan Hedberg 1277d2c5d77fSJohan Hedberg cp.page = p; 1278d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 1279d2c5d77fSJohan Hedberg sizeof(cp), &cp); 1280d2c5d77fSJohan Hedberg } 12812177bab5SJohan Hedberg } 12822177bab5SJohan Hedberg 12835d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt) 12845d4e7e8dSJohan Hedberg { 12855d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 12865d4e7e8dSJohan Hedberg 1287d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 1288d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 1289d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 1290d62e6d67SJohan Hedberg 1291109e3191SMarcel Holtmann /* Read local codec list if the HCI command is supported */ 1292109e3191SMarcel Holtmann if (hdev->commands[29] & 0x20) 1293109e3191SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL); 1294109e3191SMarcel Holtmann 1295f4fe73edSMarcel Holtmann /* Get MWS transport configuration if the HCI command is supported */ 1296f4fe73edSMarcel Holtmann if (hdev->commands[30] & 0x08) 1297f4fe73edSMarcel Holtmann hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL); 1298f4fe73edSMarcel Holtmann 12995d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 130053b834d2SMarcel Holtmann if (lmp_sync_train_capable(hdev)) 13015d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 1302a6d0d690SMarcel Holtmann 1303a6d0d690SMarcel Holtmann /* Enable Secure Connections if supported and configured */ 1304710f11c0SJohan Hedberg if (bredr_sc_enabled(hdev)) { 1305a6d0d690SMarcel Holtmann u8 support = 0x01; 1306a6d0d690SMarcel Holtmann hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, 1307a6d0d690SMarcel Holtmann sizeof(support), &support); 1308a6d0d690SMarcel Holtmann } 13095d4e7e8dSJohan Hedberg } 13105d4e7e8dSJohan Hedberg 13112177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 13122177bab5SJohan Hedberg { 13132177bab5SJohan Hedberg int err; 13142177bab5SJohan Hedberg 13152177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 13162177bab5SJohan Hedberg if (err < 0) 13172177bab5SJohan Hedberg return err; 13182177bab5SJohan Hedberg 13194b4148e9SMarcel Holtmann /* The Device Under Test (DUT) mode is special and available for 13204b4148e9SMarcel Holtmann * all controller types. So just create it early on. 13214b4148e9SMarcel Holtmann */ 13224b4148e9SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 13234b4148e9SMarcel Holtmann debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, 13244b4148e9SMarcel Holtmann &dut_mode_fops); 13254b4148e9SMarcel Holtmann } 13264b4148e9SMarcel Holtmann 13272177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 13282177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 13292177bab5SJohan Hedberg * first stage init. 13302177bab5SJohan Hedberg */ 13312177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 13322177bab5SJohan Hedberg return 0; 13332177bab5SJohan Hedberg 13342177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 13352177bab5SJohan Hedberg if (err < 0) 13362177bab5SJohan Hedberg return err; 13372177bab5SJohan Hedberg 13385d4e7e8dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 13395d4e7e8dSJohan Hedberg if (err < 0) 13405d4e7e8dSJohan Hedberg return err; 13415d4e7e8dSJohan Hedberg 1342baf27f6eSMarcel Holtmann err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 1343baf27f6eSMarcel Holtmann if (err < 0) 1344baf27f6eSMarcel Holtmann return err; 1345baf27f6eSMarcel Holtmann 1346baf27f6eSMarcel Holtmann /* Only create debugfs entries during the initial setup 1347baf27f6eSMarcel Holtmann * phase and not every time the controller gets powered on. 1348baf27f6eSMarcel Holtmann */ 1349baf27f6eSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 1350baf27f6eSMarcel Holtmann return 0; 1351baf27f6eSMarcel Holtmann 135260c5f5fbSMarcel Holtmann hci_debugfs_create_common(hdev); 135360c5f5fbSMarcel Holtmann 135471c3b60eSMarcel Holtmann if (lmp_bredr_capable(hdev)) 135560c5f5fbSMarcel Holtmann hci_debugfs_create_bredr(hdev); 13562bfa3531SMarcel Holtmann 1357d0f729b8SMarcel Holtmann if (lmp_le_capable(hdev)) { 1358ac345813SMarcel Holtmann debugfs_create_file("identity", 0400, hdev->debugfs, 1359ac345813SMarcel Holtmann hdev, &identity_fops); 1360ac345813SMarcel Holtmann debugfs_create_file("rpa_timeout", 0644, hdev->debugfs, 1361ac345813SMarcel Holtmann hdev, &rpa_timeout_fops); 13627a4cd51dSMarcel Holtmann debugfs_create_file("random_address", 0444, hdev->debugfs, 13637a4cd51dSMarcel Holtmann hdev, &random_address_fops); 1364e7b8fc92SMarcel Holtmann debugfs_create_file("static_address", 0444, hdev->debugfs, 1365e7b8fc92SMarcel Holtmann hdev, &static_address_fops); 1366b32bba6cSMarcel Holtmann 1367b32bba6cSMarcel Holtmann /* For controllers with a public address, provide a debug 1368b32bba6cSMarcel Holtmann * option to force the usage of the configured static 1369b32bba6cSMarcel Holtmann * address. By default the public address is used. 1370b32bba6cSMarcel Holtmann */ 1371b32bba6cSMarcel Holtmann if (bacmp(&hdev->bdaddr, BDADDR_ANY)) 1372b32bba6cSMarcel Holtmann debugfs_create_file("force_static_address", 0644, 1373b32bba6cSMarcel Holtmann hdev->debugfs, hdev, 1374b32bba6cSMarcel Holtmann &force_static_address_fops); 1375b32bba6cSMarcel Holtmann 1376b32bba6cSMarcel Holtmann debugfs_create_u8("white_list_size", 0444, hdev->debugfs, 1377b32bba6cSMarcel Holtmann &hdev->le_white_list_size); 1378d2ab0ac1SMarcel Holtmann debugfs_create_file("white_list", 0444, hdev->debugfs, hdev, 1379d2ab0ac1SMarcel Holtmann &white_list_fops); 13803698d704SMarcel Holtmann debugfs_create_file("identity_resolving_keys", 0400, 13813698d704SMarcel Holtmann hdev->debugfs, hdev, 13823698d704SMarcel Holtmann &identity_resolving_keys_fops); 13838f8625cdSMarcel Holtmann debugfs_create_file("long_term_keys", 0400, hdev->debugfs, 13848f8625cdSMarcel Holtmann hdev, &long_term_keys_fops); 13854e70c7e7SMarcel Holtmann debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, 13864e70c7e7SMarcel Holtmann hdev, &conn_min_interval_fops); 13874e70c7e7SMarcel Holtmann debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, 13884e70c7e7SMarcel Holtmann hdev, &conn_max_interval_fops); 1389816a93d1SMarcel Holtmann debugfs_create_file("conn_latency", 0644, hdev->debugfs, 1390816a93d1SMarcel Holtmann hdev, &conn_latency_fops); 1391f1649577SMarcel Holtmann debugfs_create_file("supervision_timeout", 0644, hdev->debugfs, 1392f1649577SMarcel Holtmann hdev, &supervision_timeout_fops); 13933f959d46SMarcel Holtmann debugfs_create_file("adv_channel_map", 0644, hdev->debugfs, 13943f959d46SMarcel Holtmann hdev, &adv_channel_map_fops); 1395729a1051SGeorg Lukas debugfs_create_file("adv_min_interval", 0644, hdev->debugfs, 1396729a1051SGeorg Lukas hdev, &adv_min_interval_fops); 1397729a1051SGeorg Lukas debugfs_create_file("adv_max_interval", 0644, hdev->debugfs, 1398729a1051SGeorg Lukas hdev, &adv_max_interval_fops); 1399b9a7a61eSLukasz Rymanowski debugfs_create_u16("discov_interleaved_timeout", 0644, 1400b9a7a61eSLukasz Rymanowski hdev->debugfs, 1401b9a7a61eSLukasz Rymanowski &hdev->discov_interleaved_timeout); 140254506918SJohan Hedberg 140360c5f5fbSMarcel Holtmann hci_debugfs_create_le(hdev); 140460c5f5fbSMarcel Holtmann 1405711eafe3SJohan Hedberg smp_register(hdev); 1406d0f729b8SMarcel Holtmann } 1407e7b8fc92SMarcel Holtmann 1408baf27f6eSMarcel Holtmann return 0; 14092177bab5SJohan Hedberg } 14102177bab5SJohan Hedberg 14110ebca7d6SMarcel Holtmann static void hci_init0_req(struct hci_request *req, unsigned long opt) 14120ebca7d6SMarcel Holtmann { 14130ebca7d6SMarcel Holtmann struct hci_dev *hdev = req->hdev; 14140ebca7d6SMarcel Holtmann 14150ebca7d6SMarcel Holtmann BT_DBG("%s %ld", hdev->name, opt); 14160ebca7d6SMarcel Holtmann 14170ebca7d6SMarcel Holtmann /* Reset */ 14180ebca7d6SMarcel Holtmann if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 14190ebca7d6SMarcel Holtmann hci_reset_req(req, 0); 14200ebca7d6SMarcel Holtmann 14210ebca7d6SMarcel Holtmann /* Read Local Version */ 14220ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 14230ebca7d6SMarcel Holtmann 14240ebca7d6SMarcel Holtmann /* Read BD Address */ 14250ebca7d6SMarcel Holtmann if (hdev->set_bdaddr) 14260ebca7d6SMarcel Holtmann hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 14270ebca7d6SMarcel Holtmann } 14280ebca7d6SMarcel Holtmann 14290ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev) 14300ebca7d6SMarcel Holtmann { 14310ebca7d6SMarcel Holtmann int err; 14320ebca7d6SMarcel Holtmann 1433cc78b44bSMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 1434cc78b44bSMarcel Holtmann return 0; 1435cc78b44bSMarcel Holtmann 14360ebca7d6SMarcel Holtmann err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT); 14370ebca7d6SMarcel Holtmann if (err < 0) 14380ebca7d6SMarcel Holtmann return err; 14390ebca7d6SMarcel Holtmann 14400ebca7d6SMarcel Holtmann return 0; 14410ebca7d6SMarcel Holtmann } 14420ebca7d6SMarcel Holtmann 144342c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 14441da177e4SLinus Torvalds { 14451da177e4SLinus Torvalds __u8 scan = opt; 14461da177e4SLinus Torvalds 144742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 14481da177e4SLinus Torvalds 14491da177e4SLinus Torvalds /* Inquiry and Page scans */ 145042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 14511da177e4SLinus Torvalds } 14521da177e4SLinus Torvalds 145342c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 14541da177e4SLinus Torvalds { 14551da177e4SLinus Torvalds __u8 auth = opt; 14561da177e4SLinus Torvalds 145742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 14581da177e4SLinus Torvalds 14591da177e4SLinus Torvalds /* Authentication */ 146042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 14611da177e4SLinus Torvalds } 14621da177e4SLinus Torvalds 146342c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 14641da177e4SLinus Torvalds { 14651da177e4SLinus Torvalds __u8 encrypt = opt; 14661da177e4SLinus Torvalds 146742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 14681da177e4SLinus Torvalds 1469e4e8e37cSMarcel Holtmann /* Encryption */ 147042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 14711da177e4SLinus Torvalds } 14721da177e4SLinus Torvalds 147342c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 1474e4e8e37cSMarcel Holtmann { 1475e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1476e4e8e37cSMarcel Holtmann 147742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1478e4e8e37cSMarcel Holtmann 1479e4e8e37cSMarcel Holtmann /* Default link policy */ 148042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1481e4e8e37cSMarcel Holtmann } 1482e4e8e37cSMarcel Holtmann 14831da177e4SLinus Torvalds /* Get HCI device by index. 14841da177e4SLinus Torvalds * Device is held on return. */ 14851da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 14861da177e4SLinus Torvalds { 14878035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 14881da177e4SLinus Torvalds 14891da177e4SLinus Torvalds BT_DBG("%d", index); 14901da177e4SLinus Torvalds 14911da177e4SLinus Torvalds if (index < 0) 14921da177e4SLinus Torvalds return NULL; 14931da177e4SLinus Torvalds 14941da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 14958035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 14961da177e4SLinus Torvalds if (d->id == index) { 14971da177e4SLinus Torvalds hdev = hci_dev_hold(d); 14981da177e4SLinus Torvalds break; 14991da177e4SLinus Torvalds } 15001da177e4SLinus Torvalds } 15011da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 15021da177e4SLinus Torvalds return hdev; 15031da177e4SLinus Torvalds } 15041da177e4SLinus Torvalds 15051da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1506ff9ef578SJohan Hedberg 150730dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 150830dc78e1SJohan Hedberg { 150930dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 151030dc78e1SJohan Hedberg 15116fbe195dSAndre Guedes switch (discov->state) { 1512343f935bSAndre Guedes case DISCOVERY_FINDING: 15136fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 151430dc78e1SJohan Hedberg return true; 151530dc78e1SJohan Hedberg 15166fbe195dSAndre Guedes default: 151730dc78e1SJohan Hedberg return false; 151830dc78e1SJohan Hedberg } 15196fbe195dSAndre Guedes } 152030dc78e1SJohan Hedberg 1521ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1522ff9ef578SJohan Hedberg { 1523bb3e0a33SJohan Hedberg int old_state = hdev->discovery.state; 1524bb3e0a33SJohan Hedberg 1525ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1526ff9ef578SJohan Hedberg 1527bb3e0a33SJohan Hedberg if (old_state == state) 1528ff9ef578SJohan Hedberg return; 1529ff9ef578SJohan Hedberg 1530bb3e0a33SJohan Hedberg hdev->discovery.state = state; 1531bb3e0a33SJohan Hedberg 1532ff9ef578SJohan Hedberg switch (state) { 1533ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 1534c54c3860SAndre Guedes hci_update_background_scan(hdev); 1535c54c3860SAndre Guedes 1536bb3e0a33SJohan Hedberg if (old_state != DISCOVERY_STARTING) 1537ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1538ff9ef578SJohan Hedberg break; 1539ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1540ff9ef578SJohan Hedberg break; 1541343f935bSAndre Guedes case DISCOVERY_FINDING: 1542ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1543ff9ef578SJohan Hedberg break; 154430dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 154530dc78e1SJohan Hedberg break; 1546ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1547ff9ef578SJohan Hedberg break; 1548ff9ef578SJohan Hedberg } 1549ff9ef578SJohan Hedberg } 1550ff9ef578SJohan Hedberg 15511f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 15521da177e4SLinus Torvalds { 155330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1554b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 15551da177e4SLinus Torvalds 1556561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1557561aafbcSJohan Hedberg list_del(&p->all); 1558b57c1a56SJohan Hedberg kfree(p); 15591da177e4SLinus Torvalds } 1560561aafbcSJohan Hedberg 1561561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1562561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 15631da177e4SLinus Torvalds } 15641da177e4SLinus Torvalds 1565a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1566a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 15671da177e4SLinus Torvalds { 156830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 15691da177e4SLinus Torvalds struct inquiry_entry *e; 15701da177e4SLinus Torvalds 15716ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 15721da177e4SLinus Torvalds 1573561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 15741da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 15751da177e4SLinus Torvalds return e; 15761da177e4SLinus Torvalds } 15771da177e4SLinus Torvalds 1578b57c1a56SJohan Hedberg return NULL; 1579b57c1a56SJohan Hedberg } 1580b57c1a56SJohan Hedberg 1581561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1582561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1583561aafbcSJohan Hedberg { 158430883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1585561aafbcSJohan Hedberg struct inquiry_entry *e; 1586561aafbcSJohan Hedberg 15876ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1588561aafbcSJohan Hedberg 1589561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1590561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1591561aafbcSJohan Hedberg return e; 1592561aafbcSJohan Hedberg } 1593561aafbcSJohan Hedberg 1594561aafbcSJohan Hedberg return NULL; 1595561aafbcSJohan Hedberg } 1596561aafbcSJohan Hedberg 159730dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 159830dc78e1SJohan Hedberg bdaddr_t *bdaddr, 159930dc78e1SJohan Hedberg int state) 160030dc78e1SJohan Hedberg { 160130dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 160230dc78e1SJohan Hedberg struct inquiry_entry *e; 160330dc78e1SJohan Hedberg 16046ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 160530dc78e1SJohan Hedberg 160630dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 160730dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 160830dc78e1SJohan Hedberg return e; 160930dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 161030dc78e1SJohan Hedberg return e; 161130dc78e1SJohan Hedberg } 161230dc78e1SJohan Hedberg 161330dc78e1SJohan Hedberg return NULL; 161430dc78e1SJohan Hedberg } 161530dc78e1SJohan Hedberg 1616a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1617a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1618a3d4e20aSJohan Hedberg { 1619a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1620a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1621a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1622a3d4e20aSJohan Hedberg 1623a3d4e20aSJohan Hedberg list_del(&ie->list); 1624a3d4e20aSJohan Hedberg 1625a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1626a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1627a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1628a3d4e20aSJohan Hedberg break; 1629a3d4e20aSJohan Hedberg pos = &p->list; 1630a3d4e20aSJohan Hedberg } 1631a3d4e20aSJohan Hedberg 1632a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1633a3d4e20aSJohan Hedberg } 1634a3d4e20aSJohan Hedberg 1635af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1636af58925cSMarcel Holtmann bool name_known) 16371da177e4SLinus Torvalds { 163830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 163970f23020SAndrei Emeltchenko struct inquiry_entry *ie; 1640af58925cSMarcel Holtmann u32 flags = 0; 16411da177e4SLinus Torvalds 16426ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 16431da177e4SLinus Torvalds 16446928a924SJohan Hedberg hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR); 16452b2fec4dSSzymon Janc 1646af58925cSMarcel Holtmann if (!data->ssp_mode) 1647af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1648388fc8faSJohan Hedberg 164970f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1650a3d4e20aSJohan Hedberg if (ie) { 1651af58925cSMarcel Holtmann if (!ie->data.ssp_mode) 1652af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 1653388fc8faSJohan Hedberg 1654a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1655a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1656a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1657a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1658a3d4e20aSJohan Hedberg } 1659a3d4e20aSJohan Hedberg 1660561aafbcSJohan Hedberg goto update; 1661a3d4e20aSJohan Hedberg } 1662561aafbcSJohan Hedberg 16631da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 166427f70f3eSJohan Hedberg ie = kzalloc(sizeof(*ie), GFP_KERNEL); 1665af58925cSMarcel Holtmann if (!ie) { 1666af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 1667af58925cSMarcel Holtmann goto done; 1668af58925cSMarcel Holtmann } 166970f23020SAndrei Emeltchenko 1670561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1671561aafbcSJohan Hedberg 1672561aafbcSJohan Hedberg if (name_known) { 1673561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1674561aafbcSJohan Hedberg } else { 1675561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1676561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1677561aafbcSJohan Hedberg } 1678561aafbcSJohan Hedberg 1679561aafbcSJohan Hedberg update: 1680561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1681561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1682561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1683561aafbcSJohan Hedberg list_del(&ie->list); 16841da177e4SLinus Torvalds } 16851da177e4SLinus Torvalds 168670f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 168770f23020SAndrei Emeltchenko ie->timestamp = jiffies; 16881da177e4SLinus Torvalds cache->timestamp = jiffies; 16893175405bSJohan Hedberg 16903175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 1691af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 16923175405bSJohan Hedberg 1693af58925cSMarcel Holtmann done: 1694af58925cSMarcel Holtmann return flags; 16951da177e4SLinus Torvalds } 16961da177e4SLinus Torvalds 16971da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 16981da177e4SLinus Torvalds { 169930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 17001da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 17011da177e4SLinus Torvalds struct inquiry_entry *e; 17021da177e4SLinus Torvalds int copied = 0; 17031da177e4SLinus Torvalds 1704561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 17051da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1706b57c1a56SJohan Hedberg 1707b57c1a56SJohan Hedberg if (copied >= num) 1708b57c1a56SJohan Hedberg break; 1709b57c1a56SJohan Hedberg 17101da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 17111da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 17121da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 17131da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 17141da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 17151da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1716b57c1a56SJohan Hedberg 17171da177e4SLinus Torvalds info++; 1718b57c1a56SJohan Hedberg copied++; 17191da177e4SLinus Torvalds } 17201da177e4SLinus Torvalds 17211da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 17221da177e4SLinus Torvalds return copied; 17231da177e4SLinus Torvalds } 17241da177e4SLinus Torvalds 172542c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 17261da177e4SLinus Torvalds { 17271da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 172842c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 17291da177e4SLinus Torvalds struct hci_cp_inquiry cp; 17301da177e4SLinus Torvalds 17311da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 17321da177e4SLinus Torvalds 17331da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 17341da177e4SLinus Torvalds return; 17351da177e4SLinus Torvalds 17361da177e4SLinus Torvalds /* Start Inquiry */ 17371da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 17381da177e4SLinus Torvalds cp.length = ir->length; 17391da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 174042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 17411da177e4SLinus Torvalds } 17421da177e4SLinus Torvalds 17431da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 17441da177e4SLinus Torvalds { 17451da177e4SLinus Torvalds __u8 __user *ptr = arg; 17461da177e4SLinus Torvalds struct hci_inquiry_req ir; 17471da177e4SLinus Torvalds struct hci_dev *hdev; 17481da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 17491da177e4SLinus Torvalds long timeo; 17501da177e4SLinus Torvalds __u8 *buf; 17511da177e4SLinus Torvalds 17521da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 17531da177e4SLinus Torvalds return -EFAULT; 17541da177e4SLinus Torvalds 17555a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 17565a08ecceSAndrei Emeltchenko if (!hdev) 17571da177e4SLinus Torvalds return -ENODEV; 17581da177e4SLinus Torvalds 17590736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 17600736cfa8SMarcel Holtmann err = -EBUSY; 17610736cfa8SMarcel Holtmann goto done; 17620736cfa8SMarcel Holtmann } 17630736cfa8SMarcel Holtmann 17644a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 1765fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 1766fee746b0SMarcel Holtmann goto done; 1767fee746b0SMarcel Holtmann } 1768fee746b0SMarcel Holtmann 17695b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 17705b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 17715b69bef5SMarcel Holtmann goto done; 17725b69bef5SMarcel Holtmann } 17735b69bef5SMarcel Holtmann 177456f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 177556f87901SJohan Hedberg err = -EOPNOTSUPP; 177656f87901SJohan Hedberg goto done; 177756f87901SJohan Hedberg } 177856f87901SJohan Hedberg 177909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 17801da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1781a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 17821f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 17831da177e4SLinus Torvalds do_inquiry = 1; 17841da177e4SLinus Torvalds } 178509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 17861da177e4SLinus Torvalds 178704837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 178870f23020SAndrei Emeltchenko 178970f23020SAndrei Emeltchenko if (do_inquiry) { 179001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 179101178cd4SJohan Hedberg timeo); 179270f23020SAndrei Emeltchenko if (err < 0) 17931da177e4SLinus Torvalds goto done; 17943e13fa1eSAndre Guedes 17953e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 17963e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 17973e13fa1eSAndre Guedes */ 179874316201SNeilBrown if (wait_on_bit(&hdev->flags, HCI_INQUIRY, 17993e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 18003e13fa1eSAndre Guedes return -EINTR; 180170f23020SAndrei Emeltchenko } 18021da177e4SLinus Torvalds 18038fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 18048fc9ced3SGustavo Padovan * 255 entries 18058fc9ced3SGustavo Padovan */ 18061da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 18071da177e4SLinus Torvalds 18081da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 18091da177e4SLinus Torvalds * copy it to the user space. 18101da177e4SLinus Torvalds */ 181170f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 181270f23020SAndrei Emeltchenko if (!buf) { 18131da177e4SLinus Torvalds err = -ENOMEM; 18141da177e4SLinus Torvalds goto done; 18151da177e4SLinus Torvalds } 18161da177e4SLinus Torvalds 181709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 18181da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 181909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18201da177e4SLinus Torvalds 18211da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 18221da177e4SLinus Torvalds 18231da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 18241da177e4SLinus Torvalds ptr += sizeof(ir); 18251da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 18261da177e4SLinus Torvalds ir.num_rsp)) 18271da177e4SLinus Torvalds err = -EFAULT; 18281da177e4SLinus Torvalds } else 18291da177e4SLinus Torvalds err = -EFAULT; 18301da177e4SLinus Torvalds 18311da177e4SLinus Torvalds kfree(buf); 18321da177e4SLinus Torvalds 18331da177e4SLinus Torvalds done: 18341da177e4SLinus Torvalds hci_dev_put(hdev); 18351da177e4SLinus Torvalds return err; 18361da177e4SLinus Torvalds } 18371da177e4SLinus Torvalds 1838cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 18391da177e4SLinus Torvalds { 18401da177e4SLinus Torvalds int ret = 0; 18411da177e4SLinus Torvalds 18421da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 18431da177e4SLinus Torvalds 18441da177e4SLinus Torvalds hci_req_lock(hdev); 18451da177e4SLinus Torvalds 184694324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 184794324962SJohan Hovold ret = -ENODEV; 184894324962SJohan Hovold goto done; 184994324962SJohan Hovold } 185094324962SJohan Hovold 1851d603b76bSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 1852d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags)) { 1853a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1854a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1855bf543036SJohan Hedberg */ 1856a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 1857611b30f7SMarcel Holtmann ret = -ERFKILL; 1858611b30f7SMarcel Holtmann goto done; 1859611b30f7SMarcel Holtmann } 1860611b30f7SMarcel Holtmann 1861a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 1862a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 1863a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1864a5c8f270SMarcel Holtmann * or not. 1865a5c8f270SMarcel Holtmann * 1866c6beca0eSMarcel Holtmann * In case of user channel usage, it is not important 1867c6beca0eSMarcel Holtmann * if a public address or static random address is 1868c6beca0eSMarcel Holtmann * available. 1869c6beca0eSMarcel Holtmann * 1870a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1871a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1872a5c8f270SMarcel Holtmann */ 1873c6beca0eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 1874c6beca0eSMarcel Holtmann hdev->dev_type == HCI_BREDR && 1875a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1876a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1877a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1878a5c8f270SMarcel Holtmann goto done; 1879a5c8f270SMarcel Holtmann } 1880a5c8f270SMarcel Holtmann } 1881a5c8f270SMarcel Holtmann 18821da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 18831da177e4SLinus Torvalds ret = -EALREADY; 18841da177e4SLinus Torvalds goto done; 18851da177e4SLinus Torvalds } 18861da177e4SLinus Torvalds 18871da177e4SLinus Torvalds if (hdev->open(hdev)) { 18881da177e4SLinus Torvalds ret = -EIO; 18891da177e4SLinus Torvalds goto done; 18901da177e4SLinus Torvalds } 18911da177e4SLinus Torvalds 18921da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 18931da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1894f41c70c4SMarcel Holtmann 1895af202f84SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 1896af202f84SMarcel Holtmann if (hdev->setup) 1897f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1898f41c70c4SMarcel Holtmann 1899af202f84SMarcel Holtmann /* The transport driver can set these quirks before 1900af202f84SMarcel Holtmann * creating the HCI device or in its setup callback. 1901af202f84SMarcel Holtmann * 1902af202f84SMarcel Holtmann * In case any of them is set, the controller has to 1903af202f84SMarcel Holtmann * start up as unconfigured. 1904af202f84SMarcel Holtmann */ 1905eb1904f4SMarcel Holtmann if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) || 1906eb1904f4SMarcel Holtmann test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks)) 190789bc22d2SMarcel Holtmann set_bit(HCI_UNCONFIGURED, &hdev->dev_flags); 1908f41c70c4SMarcel Holtmann 19090ebca7d6SMarcel Holtmann /* For an unconfigured controller it is required to 19100ebca7d6SMarcel Holtmann * read at least the version information provided by 19110ebca7d6SMarcel Holtmann * the Read Local Version Information command. 19120ebca7d6SMarcel Holtmann * 19130ebca7d6SMarcel Holtmann * If the set_bdaddr driver callback is provided, then 19140ebca7d6SMarcel Holtmann * also the original Bluetooth public device address 19150ebca7d6SMarcel Holtmann * will be read using the Read BD Address command. 19160ebca7d6SMarcel Holtmann */ 19170ebca7d6SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) 19180ebca7d6SMarcel Holtmann ret = __hci_unconf_init(hdev); 191989bc22d2SMarcel Holtmann } 192089bc22d2SMarcel Holtmann 19219713c17bSMarcel Holtmann if (test_bit(HCI_CONFIG, &hdev->dev_flags)) { 19229713c17bSMarcel Holtmann /* If public address change is configured, ensure that 19239713c17bSMarcel Holtmann * the address gets programmed. If the driver does not 19249713c17bSMarcel Holtmann * support changing the public address, fail the power 19259713c17bSMarcel Holtmann * on procedure. 192624c457e2SMarcel Holtmann */ 19279713c17bSMarcel Holtmann if (bacmp(&hdev->public_addr, BDADDR_ANY) && 19289713c17bSMarcel Holtmann hdev->set_bdaddr) 192924c457e2SMarcel Holtmann ret = hdev->set_bdaddr(hdev, &hdev->public_addr); 193024c457e2SMarcel Holtmann else 193124c457e2SMarcel Holtmann ret = -EADDRNOTAVAIL; 193224c457e2SMarcel Holtmann } 193324c457e2SMarcel Holtmann 1934f41c70c4SMarcel Holtmann if (!ret) { 19354a964404SMarcel Holtmann if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 19360736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 19372177bab5SJohan Hedberg ret = __hci_init(hdev); 19381da177e4SLinus Torvalds } 19391da177e4SLinus Torvalds 1940f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1941f41c70c4SMarcel Holtmann 19421da177e4SLinus Torvalds if (!ret) { 19431da177e4SLinus Torvalds hci_dev_hold(hdev); 1944d6bfd59cSJohan Hedberg set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); 19451da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 19461da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 1947bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 1948d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags) && 19494a964404SMarcel Holtmann !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 19500736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 19511514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 195209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1953744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 195409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 195556e5cb86SJohan Hedberg } 19561da177e4SLinus Torvalds } else { 19571da177e4SLinus Torvalds /* Init failed, cleanup */ 19583eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1959c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 1960b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 19611da177e4SLinus Torvalds 19621da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 19631da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 19641da177e4SLinus Torvalds 19651da177e4SLinus Torvalds if (hdev->flush) 19661da177e4SLinus Torvalds hdev->flush(hdev); 19671da177e4SLinus Torvalds 19681da177e4SLinus Torvalds if (hdev->sent_cmd) { 19691da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 19701da177e4SLinus Torvalds hdev->sent_cmd = NULL; 19711da177e4SLinus Torvalds } 19721da177e4SLinus Torvalds 19731da177e4SLinus Torvalds hdev->close(hdev); 1974fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 19751da177e4SLinus Torvalds } 19761da177e4SLinus Torvalds 19771da177e4SLinus Torvalds done: 19781da177e4SLinus Torvalds hci_req_unlock(hdev); 19791da177e4SLinus Torvalds return ret; 19801da177e4SLinus Torvalds } 19811da177e4SLinus Torvalds 1982cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 1983cbed0ca1SJohan Hedberg 1984cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 1985cbed0ca1SJohan Hedberg { 1986cbed0ca1SJohan Hedberg struct hci_dev *hdev; 1987cbed0ca1SJohan Hedberg int err; 1988cbed0ca1SJohan Hedberg 1989cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 1990cbed0ca1SJohan Hedberg if (!hdev) 1991cbed0ca1SJohan Hedberg return -ENODEV; 1992cbed0ca1SJohan Hedberg 19934a964404SMarcel Holtmann /* Devices that are marked as unconfigured can only be powered 1994fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices 1995fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is 1996fee746b0SMarcel Holtmann * possible. 1997fee746b0SMarcel Holtmann * 1998fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag 1999fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to 2000fee746b0SMarcel Holtmann * open the device. 2001fee746b0SMarcel Holtmann */ 20024a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 2003fee746b0SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 2004fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2005fee746b0SMarcel Holtmann goto done; 2006fee746b0SMarcel Holtmann } 2007fee746b0SMarcel Holtmann 2008e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 2009e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 2010e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 2011e1d08f40SJohan Hedberg * completed. 2012e1d08f40SJohan Hedberg */ 2013e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2014e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 2015e1d08f40SJohan Hedberg 2016a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 2017a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 2018a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 2019a5c8f270SMarcel Holtmann */ 2020e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 2021e1d08f40SJohan Hedberg 202212aa4f0aSMarcel Holtmann /* For controllers not using the management interface and that 2023b6ae8457SJohan Hedberg * are brought up using legacy ioctl, set the HCI_BONDABLE bit 202412aa4f0aSMarcel Holtmann * so that pairing works for them. Once the management interface 202512aa4f0aSMarcel Holtmann * is in use this bit will be cleared again and userspace has 202612aa4f0aSMarcel Holtmann * to explicitly enable it. 202712aa4f0aSMarcel Holtmann */ 202812aa4f0aSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 202912aa4f0aSMarcel Holtmann !test_bit(HCI_MGMT, &hdev->dev_flags)) 2030b6ae8457SJohan Hedberg set_bit(HCI_BONDABLE, &hdev->dev_flags); 203112aa4f0aSMarcel Holtmann 2032cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 2033cbed0ca1SJohan Hedberg 2034fee746b0SMarcel Holtmann done: 2035cbed0ca1SJohan Hedberg hci_dev_put(hdev); 2036cbed0ca1SJohan Hedberg return err; 2037cbed0ca1SJohan Hedberg } 2038cbed0ca1SJohan Hedberg 2039d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */ 2040d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev) 2041d7347f3cSJohan Hedberg { 2042d7347f3cSJohan Hedberg struct hci_conn_params *p; 2043d7347f3cSJohan Hedberg 2044f161dd41SJohan Hedberg list_for_each_entry(p, &hdev->le_conn_params, list) { 2045f161dd41SJohan Hedberg if (p->conn) { 2046f161dd41SJohan Hedberg hci_conn_drop(p->conn); 2047f8aaf9b6SJohan Hedberg hci_conn_put(p->conn); 2048f161dd41SJohan Hedberg p->conn = NULL; 2049f161dd41SJohan Hedberg } 2050d7347f3cSJohan Hedberg list_del_init(&p->action); 2051f161dd41SJohan Hedberg } 2052d7347f3cSJohan Hedberg 2053d7347f3cSJohan Hedberg BT_DBG("All LE pending actions cleared"); 2054d7347f3cSJohan Hedberg } 2055d7347f3cSJohan Hedberg 20561da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 20571da177e4SLinus Torvalds { 20581da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 20591da177e4SLinus Torvalds 206078c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 206178c04c0bSVinicius Costa Gomes 20621da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 20631da177e4SLinus Torvalds hci_req_lock(hdev); 20641da177e4SLinus Torvalds 20651da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 206665cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 20671da177e4SLinus Torvalds hci_req_unlock(hdev); 20681da177e4SLinus Torvalds return 0; 20691da177e4SLinus Torvalds } 20701da177e4SLinus Torvalds 20713eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 20723eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 2073b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 20741da177e4SLinus Torvalds 207516ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 2076e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 207716ab91abSJohan Hedberg hdev->discov_timeout = 0; 20785e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 2079310a3d48SMarcel Holtmann clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 208016ab91abSJohan Hedberg } 208116ab91abSJohan Hedberg 2082a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 20837d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 20847d78525dSJohan Hedberg 20857ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 20864518bb0fSJohan Hedberg 20874518bb0fSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 2088d6bfd59cSJohan Hedberg cancel_delayed_work_sync(&hdev->rpa_expired); 20897ba8b4beSAndre Guedes 209076727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 209176727c02SJohan Hedberg * ensuring the workqueue is empty up front. 209276727c02SJohan Hedberg */ 209376727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 209476727c02SJohan Hedberg 209509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 20961aeb9c65SJohan Hedberg 20971aeb9c65SJohan Hedberg if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 20981aeb9c65SJohan Hedberg if (hdev->dev_type == HCI_BREDR) 20991aeb9c65SJohan Hedberg mgmt_powered(hdev, 0); 21001aeb9c65SJohan Hedberg } 21011aeb9c65SJohan Hedberg 21021f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 2103d7347f3cSJohan Hedberg hci_pend_le_actions_clear(hdev); 2104f161dd41SJohan Hedberg hci_conn_hash_flush(hdev); 210509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 21061da177e4SLinus Torvalds 21071da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 21081da177e4SLinus Torvalds 21091da177e4SLinus Torvalds if (hdev->flush) 21101da177e4SLinus Torvalds hdev->flush(hdev); 21111da177e4SLinus Torvalds 21121da177e4SLinus Torvalds /* Reset device */ 21131da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 21141da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 21154a964404SMarcel Holtmann if (!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 21164a964404SMarcel Holtmann !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && 2117a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 21181da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 211901178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 21201da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 21211da177e4SLinus Torvalds } 21221da177e4SLinus Torvalds 2123c347b765SGustavo F. Padovan /* flush cmd work */ 2124c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 21251da177e4SLinus Torvalds 21261da177e4SLinus Torvalds /* Drop queues */ 21271da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 21281da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 21291da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 21301da177e4SLinus Torvalds 21311da177e4SLinus Torvalds /* Drop last sent command */ 21321da177e4SLinus Torvalds if (hdev->sent_cmd) { 213365cc2b49SMarcel Holtmann cancel_delayed_work_sync(&hdev->cmd_timer); 21341da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 21351da177e4SLinus Torvalds hdev->sent_cmd = NULL; 21361da177e4SLinus Torvalds } 21371da177e4SLinus Torvalds 2138b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 2139b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 2140b6ddb638SJohan Hedberg 21411da177e4SLinus Torvalds /* After this point our queues are empty 21421da177e4SLinus Torvalds * and no tasks are scheduled. */ 21431da177e4SLinus Torvalds hdev->close(hdev); 21441da177e4SLinus Torvalds 214535b973c9SJohan Hedberg /* Clear flags */ 2146fee746b0SMarcel Holtmann hdev->flags &= BIT(HCI_RAW); 214735b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 214835b973c9SJohan Hedberg 2149ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 2150536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 2151ced5c338SAndrei Emeltchenko 2152e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 215309b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 21547a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, BDADDR_ANY); 2155e59fda8dSJohan Hedberg 21561da177e4SLinus Torvalds hci_req_unlock(hdev); 21571da177e4SLinus Torvalds 21581da177e4SLinus Torvalds hci_dev_put(hdev); 21591da177e4SLinus Torvalds return 0; 21601da177e4SLinus Torvalds } 21611da177e4SLinus Torvalds 21621da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 21631da177e4SLinus Torvalds { 21641da177e4SLinus Torvalds struct hci_dev *hdev; 21651da177e4SLinus Torvalds int err; 21661da177e4SLinus Torvalds 216770f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 216870f23020SAndrei Emeltchenko if (!hdev) 21691da177e4SLinus Torvalds return -ENODEV; 21708ee56540SMarcel Holtmann 21710736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 21720736cfa8SMarcel Holtmann err = -EBUSY; 21730736cfa8SMarcel Holtmann goto done; 21740736cfa8SMarcel Holtmann } 21750736cfa8SMarcel Holtmann 21768ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 21778ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 21788ee56540SMarcel Holtmann 21791da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 21808ee56540SMarcel Holtmann 21810736cfa8SMarcel Holtmann done: 21821da177e4SLinus Torvalds hci_dev_put(hdev); 21831da177e4SLinus Torvalds return err; 21841da177e4SLinus Torvalds } 21851da177e4SLinus Torvalds 21861da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 21871da177e4SLinus Torvalds { 21881da177e4SLinus Torvalds struct hci_dev *hdev; 21891da177e4SLinus Torvalds int ret = 0; 21901da177e4SLinus Torvalds 219170f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 219270f23020SAndrei Emeltchenko if (!hdev) 21931da177e4SLinus Torvalds return -ENODEV; 21941da177e4SLinus Torvalds 21951da177e4SLinus Torvalds hci_req_lock(hdev); 21961da177e4SLinus Torvalds 2197808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 2198808a049eSMarcel Holtmann ret = -ENETDOWN; 21991da177e4SLinus Torvalds goto done; 2200808a049eSMarcel Holtmann } 22011da177e4SLinus Torvalds 22020736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22030736cfa8SMarcel Holtmann ret = -EBUSY; 22040736cfa8SMarcel Holtmann goto done; 22050736cfa8SMarcel Holtmann } 22060736cfa8SMarcel Holtmann 22074a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 2208fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 2209fee746b0SMarcel Holtmann goto done; 2210fee746b0SMarcel Holtmann } 2211fee746b0SMarcel Holtmann 22121da177e4SLinus Torvalds /* Drop queues */ 22131da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 22141da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 22151da177e4SLinus Torvalds 221676727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 221776727c02SJohan Hedberg * ensuring the workqueue is empty up front. 221876727c02SJohan Hedberg */ 221976727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 222076727c02SJohan Hedberg 222109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 22221f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 22231da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 222409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 22251da177e4SLinus Torvalds 22261da177e4SLinus Torvalds if (hdev->flush) 22271da177e4SLinus Torvalds hdev->flush(hdev); 22281da177e4SLinus Torvalds 22291da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 22306ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 22311da177e4SLinus Torvalds 223201178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 22331da177e4SLinus Torvalds 22341da177e4SLinus Torvalds done: 22351da177e4SLinus Torvalds hci_req_unlock(hdev); 22361da177e4SLinus Torvalds hci_dev_put(hdev); 22371da177e4SLinus Torvalds return ret; 22381da177e4SLinus Torvalds } 22391da177e4SLinus Torvalds 22401da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 22411da177e4SLinus Torvalds { 22421da177e4SLinus Torvalds struct hci_dev *hdev; 22431da177e4SLinus Torvalds int ret = 0; 22441da177e4SLinus Torvalds 224570f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 224670f23020SAndrei Emeltchenko if (!hdev) 22471da177e4SLinus Torvalds return -ENODEV; 22481da177e4SLinus Torvalds 22490736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 22500736cfa8SMarcel Holtmann ret = -EBUSY; 22510736cfa8SMarcel Holtmann goto done; 22520736cfa8SMarcel Holtmann } 22530736cfa8SMarcel Holtmann 22544a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 2255fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 2256fee746b0SMarcel Holtmann goto done; 2257fee746b0SMarcel Holtmann } 2258fee746b0SMarcel Holtmann 22591da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 22601da177e4SLinus Torvalds 22610736cfa8SMarcel Holtmann done: 22621da177e4SLinus Torvalds hci_dev_put(hdev); 22631da177e4SLinus Torvalds return ret; 22641da177e4SLinus Torvalds } 22651da177e4SLinus Torvalds 2266123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan) 2267123abc08SJohan Hedberg { 2268bc6d2d04SJohan Hedberg bool conn_changed, discov_changed; 2269123abc08SJohan Hedberg 2270123abc08SJohan Hedberg BT_DBG("%s scan 0x%02x", hdev->name, scan); 2271123abc08SJohan Hedberg 2272123abc08SJohan Hedberg if ((scan & SCAN_PAGE)) 2273123abc08SJohan Hedberg conn_changed = !test_and_set_bit(HCI_CONNECTABLE, 2274123abc08SJohan Hedberg &hdev->dev_flags); 2275123abc08SJohan Hedberg else 2276123abc08SJohan Hedberg conn_changed = test_and_clear_bit(HCI_CONNECTABLE, 2277123abc08SJohan Hedberg &hdev->dev_flags); 2278123abc08SJohan Hedberg 2279bc6d2d04SJohan Hedberg if ((scan & SCAN_INQUIRY)) { 2280bc6d2d04SJohan Hedberg discov_changed = !test_and_set_bit(HCI_DISCOVERABLE, 2281bc6d2d04SJohan Hedberg &hdev->dev_flags); 2282bc6d2d04SJohan Hedberg } else { 2283bc6d2d04SJohan Hedberg clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 2284bc6d2d04SJohan Hedberg discov_changed = test_and_clear_bit(HCI_DISCOVERABLE, 2285bc6d2d04SJohan Hedberg &hdev->dev_flags); 2286bc6d2d04SJohan Hedberg } 2287bc6d2d04SJohan Hedberg 2288123abc08SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2289123abc08SJohan Hedberg return; 2290123abc08SJohan Hedberg 2291bc6d2d04SJohan Hedberg if (conn_changed || discov_changed) { 2292bc6d2d04SJohan Hedberg /* In case this was disabled through mgmt */ 2293bc6d2d04SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 2294bc6d2d04SJohan Hedberg 2295bc6d2d04SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) 2296bc6d2d04SJohan Hedberg mgmt_update_adv_data(hdev); 2297bc6d2d04SJohan Hedberg 2298123abc08SJohan Hedberg mgmt_new_settings(hdev); 2299123abc08SJohan Hedberg } 2300bc6d2d04SJohan Hedberg } 2301123abc08SJohan Hedberg 23021da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 23031da177e4SLinus Torvalds { 23041da177e4SLinus Torvalds struct hci_dev *hdev; 23051da177e4SLinus Torvalds struct hci_dev_req dr; 23061da177e4SLinus Torvalds int err = 0; 23071da177e4SLinus Torvalds 23081da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 23091da177e4SLinus Torvalds return -EFAULT; 23101da177e4SLinus Torvalds 231170f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 231270f23020SAndrei Emeltchenko if (!hdev) 23131da177e4SLinus Torvalds return -ENODEV; 23141da177e4SLinus Torvalds 23150736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 23160736cfa8SMarcel Holtmann err = -EBUSY; 23170736cfa8SMarcel Holtmann goto done; 23180736cfa8SMarcel Holtmann } 23190736cfa8SMarcel Holtmann 23204a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 2321fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 2322fee746b0SMarcel Holtmann goto done; 2323fee746b0SMarcel Holtmann } 2324fee746b0SMarcel Holtmann 23255b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 23265b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 23275b69bef5SMarcel Holtmann goto done; 23285b69bef5SMarcel Holtmann } 23295b69bef5SMarcel Holtmann 233056f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 233156f87901SJohan Hedberg err = -EOPNOTSUPP; 233256f87901SJohan Hedberg goto done; 233356f87901SJohan Hedberg } 233456f87901SJohan Hedberg 23351da177e4SLinus Torvalds switch (cmd) { 23361da177e4SLinus Torvalds case HCISETAUTH: 233701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 23385f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23391da177e4SLinus Torvalds break; 23401da177e4SLinus Torvalds 23411da177e4SLinus Torvalds case HCISETENCRYPT: 23421da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 23431da177e4SLinus Torvalds err = -EOPNOTSUPP; 23441da177e4SLinus Torvalds break; 23451da177e4SLinus Torvalds } 23461da177e4SLinus Torvalds 23471da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 23481da177e4SLinus Torvalds /* Auth must be enabled first */ 234901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 23505f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23511da177e4SLinus Torvalds if (err) 23521da177e4SLinus Torvalds break; 23531da177e4SLinus Torvalds } 23541da177e4SLinus Torvalds 235501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 23565f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23571da177e4SLinus Torvalds break; 23581da177e4SLinus Torvalds 23591da177e4SLinus Torvalds case HCISETSCAN: 236001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 23615f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 236291a668b0SJohan Hedberg 2363bc6d2d04SJohan Hedberg /* Ensure that the connectable and discoverable states 2364bc6d2d04SJohan Hedberg * get correctly modified as this was a non-mgmt change. 236591a668b0SJohan Hedberg */ 2366123abc08SJohan Hedberg if (!err) 2367123abc08SJohan Hedberg hci_update_scan_state(hdev, dr.dev_opt); 23681da177e4SLinus Torvalds break; 23691da177e4SLinus Torvalds 23701da177e4SLinus Torvalds case HCISETLINKPOL: 237101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 23725f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 23731da177e4SLinus Torvalds break; 23741da177e4SLinus Torvalds 23751da177e4SLinus Torvalds case HCISETLINKMODE: 2376e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2377e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2378e4e8e37cSMarcel Holtmann break; 2379e4e8e37cSMarcel Holtmann 2380e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2381e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 23821da177e4SLinus Torvalds break; 23831da177e4SLinus Torvalds 23841da177e4SLinus Torvalds case HCISETACLMTU: 23851da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 23861da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 23871da177e4SLinus Torvalds break; 23881da177e4SLinus Torvalds 23891da177e4SLinus Torvalds case HCISETSCOMTU: 23901da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 23911da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 23921da177e4SLinus Torvalds break; 23931da177e4SLinus Torvalds 23941da177e4SLinus Torvalds default: 23951da177e4SLinus Torvalds err = -EINVAL; 23961da177e4SLinus Torvalds break; 23971da177e4SLinus Torvalds } 2398e4e8e37cSMarcel Holtmann 23990736cfa8SMarcel Holtmann done: 24001da177e4SLinus Torvalds hci_dev_put(hdev); 24011da177e4SLinus Torvalds return err; 24021da177e4SLinus Torvalds } 24031da177e4SLinus Torvalds 24041da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 24051da177e4SLinus Torvalds { 24068035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 24071da177e4SLinus Torvalds struct hci_dev_list_req *dl; 24081da177e4SLinus Torvalds struct hci_dev_req *dr; 24091da177e4SLinus Torvalds int n = 0, size, err; 24101da177e4SLinus Torvalds __u16 dev_num; 24111da177e4SLinus Torvalds 24121da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 24131da177e4SLinus Torvalds return -EFAULT; 24141da177e4SLinus Torvalds 24151da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 24161da177e4SLinus Torvalds return -EINVAL; 24171da177e4SLinus Torvalds 24181da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 24191da177e4SLinus Torvalds 242070f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 242170f23020SAndrei Emeltchenko if (!dl) 24221da177e4SLinus Torvalds return -ENOMEM; 24231da177e4SLinus Torvalds 24241da177e4SLinus Torvalds dr = dl->dev_req; 24251da177e4SLinus Torvalds 2426f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 24278035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 24282e84d8dbSMarcel Holtmann unsigned long flags = hdev->flags; 2429c542a06cSJohan Hedberg 24302e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 24312e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 24322e84d8dbSMarcel Holtmann * device is actually down. 24332e84d8dbSMarcel Holtmann */ 24342e84d8dbSMarcel Holtmann if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 24352e84d8dbSMarcel Holtmann flags &= ~BIT(HCI_UP); 2436c542a06cSJohan Hedberg 24371da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 24382e84d8dbSMarcel Holtmann (dr + n)->dev_opt = flags; 2439c542a06cSJohan Hedberg 24401da177e4SLinus Torvalds if (++n >= dev_num) 24411da177e4SLinus Torvalds break; 24421da177e4SLinus Torvalds } 2443f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 24441da177e4SLinus Torvalds 24451da177e4SLinus Torvalds dl->dev_num = n; 24461da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 24471da177e4SLinus Torvalds 24481da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 24491da177e4SLinus Torvalds kfree(dl); 24501da177e4SLinus Torvalds 24511da177e4SLinus Torvalds return err ? -EFAULT : 0; 24521da177e4SLinus Torvalds } 24531da177e4SLinus Torvalds 24541da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 24551da177e4SLinus Torvalds { 24561da177e4SLinus Torvalds struct hci_dev *hdev; 24571da177e4SLinus Torvalds struct hci_dev_info di; 24582e84d8dbSMarcel Holtmann unsigned long flags; 24591da177e4SLinus Torvalds int err = 0; 24601da177e4SLinus Torvalds 24611da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 24621da177e4SLinus Torvalds return -EFAULT; 24631da177e4SLinus Torvalds 246470f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 246570f23020SAndrei Emeltchenko if (!hdev) 24661da177e4SLinus Torvalds return -ENODEV; 24671da177e4SLinus Torvalds 24682e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 24692e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 24702e84d8dbSMarcel Holtmann * device is actually down. 24712e84d8dbSMarcel Holtmann */ 24722e84d8dbSMarcel Holtmann if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 24732e84d8dbSMarcel Holtmann flags = hdev->flags & ~BIT(HCI_UP); 24742e84d8dbSMarcel Holtmann else 24752e84d8dbSMarcel Holtmann flags = hdev->flags; 2476c542a06cSJohan Hedberg 24771da177e4SLinus Torvalds strcpy(di.name, hdev->name); 24781da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 247960f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 24802e84d8dbSMarcel Holtmann di.flags = flags; 24811da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2482572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 24831da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 24841da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 24851da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 24861da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2487572c7f84SJohan Hedberg } else { 2488572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2489572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2490572c7f84SJohan Hedberg di.sco_mtu = 0; 2491572c7f84SJohan Hedberg di.sco_pkts = 0; 2492572c7f84SJohan Hedberg } 24931da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 24941da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 24951da177e4SLinus Torvalds 24961da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 24971da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 24981da177e4SLinus Torvalds 24991da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 25001da177e4SLinus Torvalds err = -EFAULT; 25011da177e4SLinus Torvalds 25021da177e4SLinus Torvalds hci_dev_put(hdev); 25031da177e4SLinus Torvalds 25041da177e4SLinus Torvalds return err; 25051da177e4SLinus Torvalds } 25061da177e4SLinus Torvalds 25071da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 25081da177e4SLinus Torvalds 2509611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2510611b30f7SMarcel Holtmann { 2511611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2512611b30f7SMarcel Holtmann 2513611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2514611b30f7SMarcel Holtmann 25150736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 25160736cfa8SMarcel Holtmann return -EBUSY; 25170736cfa8SMarcel Holtmann 25185e130367SJohan Hedberg if (blocked) { 25195e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 2520d603b76bSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 2521d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags)) 2522611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 25235e130367SJohan Hedberg } else { 25245e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 25255e130367SJohan Hedberg } 2526611b30f7SMarcel Holtmann 2527611b30f7SMarcel Holtmann return 0; 2528611b30f7SMarcel Holtmann } 2529611b30f7SMarcel Holtmann 2530611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2531611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2532611b30f7SMarcel Holtmann }; 2533611b30f7SMarcel Holtmann 2534ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2535ab81cbf9SJohan Hedberg { 2536ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 253796570ffcSJohan Hedberg int err; 2538ab81cbf9SJohan Hedberg 2539ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2540ab81cbf9SJohan Hedberg 2541cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 254296570ffcSJohan Hedberg if (err < 0) { 25433ad67582SJaganath Kanakkassery hci_dev_lock(hdev); 254496570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 25453ad67582SJaganath Kanakkassery hci_dev_unlock(hdev); 2546ab81cbf9SJohan Hedberg return; 254796570ffcSJohan Hedberg } 2548ab81cbf9SJohan Hedberg 2549a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2550a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2551a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2552a5c8f270SMarcel Holtmann */ 2553a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 25544a964404SMarcel Holtmann test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) || 2555a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 2556a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2557a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2558bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2559bf543036SJohan Hedberg hci_dev_do_close(hdev); 2560bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 256119202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 256219202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2563bf543036SJohan Hedberg } 2564ab81cbf9SJohan Hedberg 2565fee746b0SMarcel Holtmann if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) { 25664a964404SMarcel Holtmann /* For unconfigured devices, set the HCI_RAW flag 25674a964404SMarcel Holtmann * so that userspace can easily identify them. 25684a964404SMarcel Holtmann */ 25694a964404SMarcel Holtmann if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) 25704a964404SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 25710602a8adSMarcel Holtmann 25720602a8adSMarcel Holtmann /* For fully configured devices, this will send 25730602a8adSMarcel Holtmann * the Index Added event. For unconfigured devices, 25740602a8adSMarcel Holtmann * it will send Unconfigued Index Added event. 25750602a8adSMarcel Holtmann * 25760602a8adSMarcel Holtmann * Devices with HCI_QUIRK_RAW_DEVICE are ignored 25770602a8adSMarcel Holtmann * and no event will be send. 25780602a8adSMarcel Holtmann */ 2579744cf19eSJohan Hedberg mgmt_index_added(hdev); 2580d603b76bSMarcel Holtmann } else if (test_and_clear_bit(HCI_CONFIG, &hdev->dev_flags)) { 25815ea234d3SMarcel Holtmann /* When the controller is now configured, then it 25825ea234d3SMarcel Holtmann * is important to clear the HCI_RAW flag. 25835ea234d3SMarcel Holtmann */ 25845ea234d3SMarcel Holtmann if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) 25855ea234d3SMarcel Holtmann clear_bit(HCI_RAW, &hdev->flags); 25865ea234d3SMarcel Holtmann 2587d603b76bSMarcel Holtmann /* Powering on the controller with HCI_CONFIG set only 2588d603b76bSMarcel Holtmann * happens with the transition from unconfigured to 2589d603b76bSMarcel Holtmann * configured. This will send the Index Added event. 2590d603b76bSMarcel Holtmann */ 2591d603b76bSMarcel Holtmann mgmt_index_added(hdev); 2592ab81cbf9SJohan Hedberg } 2593ab81cbf9SJohan Hedberg } 2594ab81cbf9SJohan Hedberg 2595ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2596ab81cbf9SJohan Hedberg { 25973243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 25983243553fSJohan Hedberg power_off.work); 2599ab81cbf9SJohan Hedberg 2600ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2601ab81cbf9SJohan Hedberg 26028ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2603ab81cbf9SJohan Hedberg } 2604ab81cbf9SJohan Hedberg 260516ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 260616ab91abSJohan Hedberg { 260716ab91abSJohan Hedberg struct hci_dev *hdev; 260816ab91abSJohan Hedberg 260916ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 261016ab91abSJohan Hedberg 261116ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 261216ab91abSJohan Hedberg 2613d1967ff8SMarcel Holtmann mgmt_discoverable_timeout(hdev); 261416ab91abSJohan Hedberg } 261516ab91abSJohan Hedberg 261635f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 26172aeb9a1aSJohan Hedberg { 26184821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 26192aeb9a1aSJohan Hedberg 26204821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 26214821002cSJohan Hedberg list_del(&uuid->list); 26222aeb9a1aSJohan Hedberg kfree(uuid); 26232aeb9a1aSJohan Hedberg } 26242aeb9a1aSJohan Hedberg } 26252aeb9a1aSJohan Hedberg 262635f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 262755ed8ca1SJohan Hedberg { 262855ed8ca1SJohan Hedberg struct link_key *key; 262955ed8ca1SJohan Hedberg 26300378b597SJohan Hedberg list_for_each_entry_rcu(key, &hdev->link_keys, list) { 26310378b597SJohan Hedberg list_del_rcu(&key->list); 26320378b597SJohan Hedberg kfree_rcu(key, rcu); 263355ed8ca1SJohan Hedberg } 263455ed8ca1SJohan Hedberg } 263555ed8ca1SJohan Hedberg 263635f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 2637b899efafSVinicius Costa Gomes { 2638970d0f1bSJohan Hedberg struct smp_ltk *k; 2639b899efafSVinicius Costa Gomes 2640970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 2641970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2642970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2643b899efafSVinicius Costa Gomes } 2644b899efafSVinicius Costa Gomes } 2645b899efafSVinicius Costa Gomes 2646970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 2647970c4e46SJohan Hedberg { 2648adae20cbSJohan Hedberg struct smp_irk *k; 2649970c4e46SJohan Hedberg 2650adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 2651adae20cbSJohan Hedberg list_del_rcu(&k->list); 2652adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2653970c4e46SJohan Hedberg } 2654970c4e46SJohan Hedberg } 2655970c4e46SJohan Hedberg 265655ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 265755ed8ca1SJohan Hedberg { 265855ed8ca1SJohan Hedberg struct link_key *k; 265955ed8ca1SJohan Hedberg 26600378b597SJohan Hedberg rcu_read_lock(); 26610378b597SJohan Hedberg list_for_each_entry_rcu(k, &hdev->link_keys, list) { 26620378b597SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) { 26630378b597SJohan Hedberg rcu_read_unlock(); 266455ed8ca1SJohan Hedberg return k; 26650378b597SJohan Hedberg } 26660378b597SJohan Hedberg } 26670378b597SJohan Hedberg rcu_read_unlock(); 266855ed8ca1SJohan Hedberg 266955ed8ca1SJohan Hedberg return NULL; 267055ed8ca1SJohan Hedberg } 267155ed8ca1SJohan Hedberg 2672745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2673d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2674d25e28abSJohan Hedberg { 2675d25e28abSJohan Hedberg /* Legacy key */ 2676d25e28abSJohan Hedberg if (key_type < 0x03) 2677745c0ce3SVishal Agarwal return true; 2678d25e28abSJohan Hedberg 2679d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2680d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2681745c0ce3SVishal Agarwal return false; 2682d25e28abSJohan Hedberg 2683d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2684d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2685745c0ce3SVishal Agarwal return false; 2686d25e28abSJohan Hedberg 2687d25e28abSJohan Hedberg /* Security mode 3 case */ 2688d25e28abSJohan Hedberg if (!conn) 2689745c0ce3SVishal Agarwal return true; 2690d25e28abSJohan Hedberg 2691e3befab9SJohan Hedberg /* BR/EDR key derived using SC from an LE link */ 2692e3befab9SJohan Hedberg if (conn->type == LE_LINK) 2693e3befab9SJohan Hedberg return true; 2694e3befab9SJohan Hedberg 2695d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2696d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2697745c0ce3SVishal Agarwal return true; 2698d25e28abSJohan Hedberg 2699d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2700d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2701745c0ce3SVishal Agarwal return true; 2702d25e28abSJohan Hedberg 2703d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2704d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2705745c0ce3SVishal Agarwal return true; 2706d25e28abSJohan Hedberg 2707d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2708d25e28abSJohan Hedberg * persistently */ 2709745c0ce3SVishal Agarwal return false; 2710d25e28abSJohan Hedberg } 2711d25e28abSJohan Hedberg 2712e804d25dSJohan Hedberg static u8 ltk_role(u8 type) 271398a0b845SJohan Hedberg { 2714e804d25dSJohan Hedberg if (type == SMP_LTK) 2715e804d25dSJohan Hedberg return HCI_ROLE_MASTER; 271698a0b845SJohan Hedberg 2717e804d25dSJohan Hedberg return HCI_ROLE_SLAVE; 271898a0b845SJohan Hedberg } 271998a0b845SJohan Hedberg 2720f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2721e804d25dSJohan Hedberg u8 addr_type, u8 role) 272275d262c2SVinicius Costa Gomes { 2723c9839a11SVinicius Costa Gomes struct smp_ltk *k; 272475d262c2SVinicius Costa Gomes 2725970d0f1bSJohan Hedberg rcu_read_lock(); 2726970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 27275378bc56SJohan Hedberg if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr)) 27285378bc56SJohan Hedberg continue; 27295378bc56SJohan Hedberg 2730923e2414SJohan Hedberg if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) { 2731970d0f1bSJohan Hedberg rcu_read_unlock(); 273275d262c2SVinicius Costa Gomes return k; 2733970d0f1bSJohan Hedberg } 2734970d0f1bSJohan Hedberg } 2735970d0f1bSJohan Hedberg rcu_read_unlock(); 273675d262c2SVinicius Costa Gomes 273775d262c2SVinicius Costa Gomes return NULL; 273875d262c2SVinicius Costa Gomes } 273975d262c2SVinicius Costa Gomes 2740970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 2741970c4e46SJohan Hedberg { 2742970c4e46SJohan Hedberg struct smp_irk *irk; 2743970c4e46SJohan Hedberg 2744adae20cbSJohan Hedberg rcu_read_lock(); 2745adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2746adae20cbSJohan Hedberg if (!bacmp(&irk->rpa, rpa)) { 2747adae20cbSJohan Hedberg rcu_read_unlock(); 2748970c4e46SJohan Hedberg return irk; 2749970c4e46SJohan Hedberg } 2750adae20cbSJohan Hedberg } 2751970c4e46SJohan Hedberg 2752adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2753defce9e8SJohan Hedberg if (smp_irk_matches(hdev, irk->val, rpa)) { 2754970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2755adae20cbSJohan Hedberg rcu_read_unlock(); 2756970c4e46SJohan Hedberg return irk; 2757970c4e46SJohan Hedberg } 2758970c4e46SJohan Hedberg } 2759adae20cbSJohan Hedberg rcu_read_unlock(); 2760970c4e46SJohan Hedberg 2761970c4e46SJohan Hedberg return NULL; 2762970c4e46SJohan Hedberg } 2763970c4e46SJohan Hedberg 2764970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2765970c4e46SJohan Hedberg u8 addr_type) 2766970c4e46SJohan Hedberg { 2767970c4e46SJohan Hedberg struct smp_irk *irk; 2768970c4e46SJohan Hedberg 27696cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 27706cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 27716cfc9988SJohan Hedberg return NULL; 27726cfc9988SJohan Hedberg 2773adae20cbSJohan Hedberg rcu_read_lock(); 2774adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 2775970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 2776adae20cbSJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) { 2777adae20cbSJohan Hedberg rcu_read_unlock(); 2778970c4e46SJohan Hedberg return irk; 2779970c4e46SJohan Hedberg } 2780adae20cbSJohan Hedberg } 2781adae20cbSJohan Hedberg rcu_read_unlock(); 2782970c4e46SJohan Hedberg 2783970c4e46SJohan Hedberg return NULL; 2784970c4e46SJohan Hedberg } 2785970c4e46SJohan Hedberg 2786567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 27877652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 27887652ff6aSJohan Hedberg u8 pin_len, bool *persistent) 278955ed8ca1SJohan Hedberg { 279055ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2791745c0ce3SVishal Agarwal u8 old_key_type; 279255ed8ca1SJohan Hedberg 279355ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 279455ed8ca1SJohan Hedberg if (old_key) { 279555ed8ca1SJohan Hedberg old_key_type = old_key->type; 279655ed8ca1SJohan Hedberg key = old_key; 279755ed8ca1SJohan Hedberg } else { 279812adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 27990a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 280055ed8ca1SJohan Hedberg if (!key) 2801567fa2aaSJohan Hedberg return NULL; 28020378b597SJohan Hedberg list_add_rcu(&key->list, &hdev->link_keys); 280355ed8ca1SJohan Hedberg } 280455ed8ca1SJohan Hedberg 28056ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 280655ed8ca1SJohan Hedberg 2807d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2808d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2809d25e28abSJohan Hedberg * previous key */ 2810d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2811a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2812d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2813655fe6ecSJohan Hedberg if (conn) 2814655fe6ecSJohan Hedberg conn->key_type = type; 2815655fe6ecSJohan Hedberg } 2816d25e28abSJohan Hedberg 281755ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 28189b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 281955ed8ca1SJohan Hedberg key->pin_len = pin_len; 282055ed8ca1SJohan Hedberg 2821b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 282255ed8ca1SJohan Hedberg key->type = old_key_type; 28234748fed2SJohan Hedberg else 28244748fed2SJohan Hedberg key->type = type; 28254748fed2SJohan Hedberg 28267652ff6aSJohan Hedberg if (persistent) 28277652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type, 28287652ff6aSJohan Hedberg old_key_type); 28294df378a1SJohan Hedberg 2830567fa2aaSJohan Hedberg return key; 283155ed8ca1SJohan Hedberg } 283255ed8ca1SJohan Hedberg 2833ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 283435d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 2835fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand) 283675d262c2SVinicius Costa Gomes { 2837c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 2838e804d25dSJohan Hedberg u8 role = ltk_role(type); 283975d262c2SVinicius Costa Gomes 2840f3a73d97SJohan Hedberg old_key = hci_find_ltk(hdev, bdaddr, addr_type, role); 2841c9839a11SVinicius Costa Gomes if (old_key) 284275d262c2SVinicius Costa Gomes key = old_key; 2843c9839a11SVinicius Costa Gomes else { 28440a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 284575d262c2SVinicius Costa Gomes if (!key) 2846ca9142b8SJohan Hedberg return NULL; 2847970d0f1bSJohan Hedberg list_add_rcu(&key->list, &hdev->long_term_keys); 284875d262c2SVinicius Costa Gomes } 284975d262c2SVinicius Costa Gomes 285075d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2851c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2852c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2853c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2854c9839a11SVinicius Costa Gomes key->ediv = ediv; 2855fe39c7b2SMarcel Holtmann key->rand = rand; 2856c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2857c9839a11SVinicius Costa Gomes key->type = type; 285875d262c2SVinicius Costa Gomes 2859ca9142b8SJohan Hedberg return key; 286075d262c2SVinicius Costa Gomes } 286175d262c2SVinicius Costa Gomes 2862ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 2863ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 2864970c4e46SJohan Hedberg { 2865970c4e46SJohan Hedberg struct smp_irk *irk; 2866970c4e46SJohan Hedberg 2867970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 2868970c4e46SJohan Hedberg if (!irk) { 2869970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 2870970c4e46SJohan Hedberg if (!irk) 2871ca9142b8SJohan Hedberg return NULL; 2872970c4e46SJohan Hedberg 2873970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 2874970c4e46SJohan Hedberg irk->addr_type = addr_type; 2875970c4e46SJohan Hedberg 2876adae20cbSJohan Hedberg list_add_rcu(&irk->list, &hdev->identity_resolving_keys); 2877970c4e46SJohan Hedberg } 2878970c4e46SJohan Hedberg 2879970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 2880970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 2881970c4e46SJohan Hedberg 2882ca9142b8SJohan Hedberg return irk; 2883970c4e46SJohan Hedberg } 2884970c4e46SJohan Hedberg 288555ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 288655ed8ca1SJohan Hedberg { 288755ed8ca1SJohan Hedberg struct link_key *key; 288855ed8ca1SJohan Hedberg 288955ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 289055ed8ca1SJohan Hedberg if (!key) 289155ed8ca1SJohan Hedberg return -ENOENT; 289255ed8ca1SJohan Hedberg 28936ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 289455ed8ca1SJohan Hedberg 28950378b597SJohan Hedberg list_del_rcu(&key->list); 28960378b597SJohan Hedberg kfree_rcu(key, rcu); 289755ed8ca1SJohan Hedberg 289855ed8ca1SJohan Hedberg return 0; 289955ed8ca1SJohan Hedberg } 290055ed8ca1SJohan Hedberg 2901e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 2902b899efafSVinicius Costa Gomes { 2903970d0f1bSJohan Hedberg struct smp_ltk *k; 2904c51ffa0bSJohan Hedberg int removed = 0; 2905b899efafSVinicius Costa Gomes 2906970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 2907e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 2908b899efafSVinicius Costa Gomes continue; 2909b899efafSVinicius Costa Gomes 29106ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2911b899efafSVinicius Costa Gomes 2912970d0f1bSJohan Hedberg list_del_rcu(&k->list); 2913970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 2914c51ffa0bSJohan Hedberg removed++; 2915b899efafSVinicius Costa Gomes } 2916b899efafSVinicius Costa Gomes 2917c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 2918b899efafSVinicius Costa Gomes } 2919b899efafSVinicius Costa Gomes 2920a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 2921a7ec7338SJohan Hedberg { 2922adae20cbSJohan Hedberg struct smp_irk *k; 2923a7ec7338SJohan Hedberg 2924adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 2925a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 2926a7ec7338SJohan Hedberg continue; 2927a7ec7338SJohan Hedberg 2928a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2929a7ec7338SJohan Hedberg 2930adae20cbSJohan Hedberg list_del_rcu(&k->list); 2931adae20cbSJohan Hedberg kfree_rcu(k, rcu); 2932a7ec7338SJohan Hedberg } 2933a7ec7338SJohan Hedberg } 2934a7ec7338SJohan Hedberg 29356bd32326SVille Tervo /* HCI command timer function */ 293665cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work) 29376bd32326SVille Tervo { 293865cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, 293965cc2b49SMarcel Holtmann cmd_timer.work); 29406bd32326SVille Tervo 2941bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2942bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2943bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2944bda4f23aSAndrei Emeltchenko 2945bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 2946bda4f23aSAndrei Emeltchenko } else { 29476bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 2948bda4f23aSAndrei Emeltchenko } 2949bda4f23aSAndrei Emeltchenko 29506bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2951c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 29526bd32326SVille Tervo } 29536bd32326SVille Tervo 29542763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 29556928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type) 29562763eda6SSzymon Janc { 29572763eda6SSzymon Janc struct oob_data *data; 29582763eda6SSzymon Janc 29596928a924SJohan Hedberg list_for_each_entry(data, &hdev->remote_oob_data, list) { 29606928a924SJohan Hedberg if (bacmp(bdaddr, &data->bdaddr) != 0) 29616928a924SJohan Hedberg continue; 29626928a924SJohan Hedberg if (data->bdaddr_type != bdaddr_type) 29636928a924SJohan Hedberg continue; 29642763eda6SSzymon Janc return data; 29656928a924SJohan Hedberg } 29662763eda6SSzymon Janc 29672763eda6SSzymon Janc return NULL; 29682763eda6SSzymon Janc } 29692763eda6SSzymon Janc 29706928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 29716928a924SJohan Hedberg u8 bdaddr_type) 29722763eda6SSzymon Janc { 29732763eda6SSzymon Janc struct oob_data *data; 29742763eda6SSzymon Janc 29756928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 29762763eda6SSzymon Janc if (!data) 29772763eda6SSzymon Janc return -ENOENT; 29782763eda6SSzymon Janc 29796928a924SJohan Hedberg BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type); 29802763eda6SSzymon Janc 29812763eda6SSzymon Janc list_del(&data->list); 29822763eda6SSzymon Janc kfree(data); 29832763eda6SSzymon Janc 29842763eda6SSzymon Janc return 0; 29852763eda6SSzymon Janc } 29862763eda6SSzymon Janc 298735f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 29882763eda6SSzymon Janc { 29892763eda6SSzymon Janc struct oob_data *data, *n; 29902763eda6SSzymon Janc 29912763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 29922763eda6SSzymon Janc list_del(&data->list); 29932763eda6SSzymon Janc kfree(data); 29942763eda6SSzymon Janc } 29952763eda6SSzymon Janc } 29962763eda6SSzymon Janc 29970798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 29986928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192, 299938da1703SJohan Hedberg u8 *hash256, u8 *rand256) 30000798872eSMarcel Holtmann { 30010798872eSMarcel Holtmann struct oob_data *data; 30020798872eSMarcel Holtmann 30036928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 30040798872eSMarcel Holtmann if (!data) { 30050a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 30060798872eSMarcel Holtmann if (!data) 30070798872eSMarcel Holtmann return -ENOMEM; 30080798872eSMarcel Holtmann 30090798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 30106928a924SJohan Hedberg data->bdaddr_type = bdaddr_type; 30110798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 30120798872eSMarcel Holtmann } 30130798872eSMarcel Holtmann 301481328d5cSJohan Hedberg if (hash192 && rand192) { 30150798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 301638da1703SJohan Hedberg memcpy(data->rand192, rand192, sizeof(data->rand192)); 301781328d5cSJohan Hedberg } else { 301881328d5cSJohan Hedberg memset(data->hash192, 0, sizeof(data->hash192)); 301981328d5cSJohan Hedberg memset(data->rand192, 0, sizeof(data->rand192)); 302081328d5cSJohan Hedberg } 30210798872eSMarcel Holtmann 302281328d5cSJohan Hedberg if (hash256 && rand256) { 30230798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 302438da1703SJohan Hedberg memcpy(data->rand256, rand256, sizeof(data->rand256)); 302581328d5cSJohan Hedberg } else { 302681328d5cSJohan Hedberg memset(data->hash256, 0, sizeof(data->hash256)); 302781328d5cSJohan Hedberg memset(data->rand256, 0, sizeof(data->rand256)); 302881328d5cSJohan Hedberg } 30290798872eSMarcel Holtmann 30306ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 30312763eda6SSzymon Janc 30322763eda6SSzymon Janc return 0; 30332763eda6SSzymon Janc } 30342763eda6SSzymon Janc 3035dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list, 3036b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 3037b2a66aadSAntti Julku { 3038b2a66aadSAntti Julku struct bdaddr_list *b; 3039b2a66aadSAntti Julku 3040dcc36c16SJohan Hedberg list_for_each_entry(b, bdaddr_list, list) { 3041b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 3042b2a66aadSAntti Julku return b; 3043b9ee0a78SMarcel Holtmann } 3044b2a66aadSAntti Julku 3045b2a66aadSAntti Julku return NULL; 3046b2a66aadSAntti Julku } 3047b2a66aadSAntti Julku 3048dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list) 3049b2a66aadSAntti Julku { 3050b2a66aadSAntti Julku struct list_head *p, *n; 3051b2a66aadSAntti Julku 3052dcc36c16SJohan Hedberg list_for_each_safe(p, n, bdaddr_list) { 3053b9ee0a78SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 3054b2a66aadSAntti Julku 3055b2a66aadSAntti Julku list_del(p); 3056b2a66aadSAntti Julku kfree(b); 3057b2a66aadSAntti Julku } 3058b2a66aadSAntti Julku } 3059b2a66aadSAntti Julku 3060dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type) 3061b2a66aadSAntti Julku { 3062b2a66aadSAntti Julku struct bdaddr_list *entry; 3063b2a66aadSAntti Julku 3064b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 3065b2a66aadSAntti Julku return -EBADF; 3066b2a66aadSAntti Julku 3067dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(list, bdaddr, type)) 30685e762444SAntti Julku return -EEXIST; 3069b2a66aadSAntti Julku 307027f70f3eSJohan Hedberg entry = kzalloc(sizeof(*entry), GFP_KERNEL); 30715e762444SAntti Julku if (!entry) 30725e762444SAntti Julku return -ENOMEM; 3073b2a66aadSAntti Julku 3074b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 3075b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 3076b2a66aadSAntti Julku 3077dcc36c16SJohan Hedberg list_add(&entry->list, list); 3078b2a66aadSAntti Julku 30792a8357f2SJohan Hedberg return 0; 3080b2a66aadSAntti Julku } 3081b2a66aadSAntti Julku 3082dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type) 3083b2a66aadSAntti Julku { 3084b2a66aadSAntti Julku struct bdaddr_list *entry; 3085b2a66aadSAntti Julku 308635f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 3087dcc36c16SJohan Hedberg hci_bdaddr_list_clear(list); 308835f7498aSJohan Hedberg return 0; 308935f7498aSJohan Hedberg } 3090b2a66aadSAntti Julku 3091dcc36c16SJohan Hedberg entry = hci_bdaddr_list_lookup(list, bdaddr, type); 3092d2ab0ac1SMarcel Holtmann if (!entry) 3093d2ab0ac1SMarcel Holtmann return -ENOENT; 3094d2ab0ac1SMarcel Holtmann 3095d2ab0ac1SMarcel Holtmann list_del(&entry->list); 3096d2ab0ac1SMarcel Holtmann kfree(entry); 3097d2ab0ac1SMarcel Holtmann 3098d2ab0ac1SMarcel Holtmann return 0; 3099d2ab0ac1SMarcel Holtmann } 3100d2ab0ac1SMarcel Holtmann 310115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 310215819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 310315819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 310415819a70SAndre Guedes { 310515819a70SAndre Guedes struct hci_conn_params *params; 310615819a70SAndre Guedes 3107738f6185SJohan Hedberg /* The conn params list only contains identity addresses */ 3108738f6185SJohan Hedberg if (!hci_is_identity_address(addr, addr_type)) 3109738f6185SJohan Hedberg return NULL; 3110738f6185SJohan Hedberg 311115819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 311215819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 311315819a70SAndre Guedes params->addr_type == addr_type) { 311415819a70SAndre Guedes return params; 311515819a70SAndre Guedes } 311615819a70SAndre Guedes } 311715819a70SAndre Guedes 311815819a70SAndre Guedes return NULL; 311915819a70SAndre Guedes } 312015819a70SAndre Guedes 312115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 3122501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 31234b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type) 312415819a70SAndre Guedes { 3125912b42efSJohan Hedberg struct hci_conn_params *param; 312615819a70SAndre Guedes 3127738f6185SJohan Hedberg /* The list only contains identity addresses */ 3128738f6185SJohan Hedberg if (!hci_is_identity_address(addr, addr_type)) 3129738f6185SJohan Hedberg return NULL; 313015819a70SAndre Guedes 3131501f8827SJohan Hedberg list_for_each_entry(param, list, action) { 3132912b42efSJohan Hedberg if (bacmp(¶m->addr, addr) == 0 && 3133912b42efSJohan Hedberg param->addr_type == addr_type) 3134912b42efSJohan Hedberg return param; 31354b10966fSMarcel Holtmann } 31364b10966fSMarcel Holtmann 31374b10966fSMarcel Holtmann return NULL; 313815819a70SAndre Guedes } 313915819a70SAndre Guedes 314015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 314151d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 314251d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type) 314315819a70SAndre Guedes { 314415819a70SAndre Guedes struct hci_conn_params *params; 314515819a70SAndre Guedes 3146c46245b3SJohan Hedberg if (!hci_is_identity_address(addr, addr_type)) 314751d167c0SMarcel Holtmann return NULL; 3148a9b0a04cSAndre Guedes 314915819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 3150cef952ceSAndre Guedes if (params) 315151d167c0SMarcel Holtmann return params; 315215819a70SAndre Guedes 315315819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 315415819a70SAndre Guedes if (!params) { 315515819a70SAndre Guedes BT_ERR("Out of memory"); 315651d167c0SMarcel Holtmann return NULL; 315715819a70SAndre Guedes } 315815819a70SAndre Guedes 315915819a70SAndre Guedes bacpy(¶ms->addr, addr); 316015819a70SAndre Guedes params->addr_type = addr_type; 3161cef952ceSAndre Guedes 3162cef952ceSAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 316393450c75SJohan Hedberg INIT_LIST_HEAD(¶ms->action); 3164cef952ceSAndre Guedes 3165bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval; 3166bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval; 3167bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency; 3168bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout; 3169bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED; 3170bf5b3c8bSMarcel Holtmann 3171bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 3172bf5b3c8bSMarcel Holtmann 317351d167c0SMarcel Holtmann return params; 3174bf5b3c8bSMarcel Holtmann } 3175bf5b3c8bSMarcel Holtmann 3176f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params) 3177f6c63249SJohan Hedberg { 3178f6c63249SJohan Hedberg if (params->conn) { 3179f6c63249SJohan Hedberg hci_conn_drop(params->conn); 3180f6c63249SJohan Hedberg hci_conn_put(params->conn); 3181f6c63249SJohan Hedberg } 3182f6c63249SJohan Hedberg 3183f6c63249SJohan Hedberg list_del(¶ms->action); 3184f6c63249SJohan Hedberg list_del(¶ms->list); 3185f6c63249SJohan Hedberg kfree(params); 3186f6c63249SJohan Hedberg } 3187f6c63249SJohan Hedberg 318815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 318915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 319015819a70SAndre Guedes { 319115819a70SAndre Guedes struct hci_conn_params *params; 319215819a70SAndre Guedes 319315819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 319415819a70SAndre Guedes if (!params) 319515819a70SAndre Guedes return; 319615819a70SAndre Guedes 3197f6c63249SJohan Hedberg hci_conn_params_free(params); 319815819a70SAndre Guedes 319995305baaSJohan Hedberg hci_update_background_scan(hdev); 320095305baaSJohan Hedberg 320115819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 320215819a70SAndre Guedes } 320315819a70SAndre Guedes 320415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 320555af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev) 320615819a70SAndre Guedes { 320715819a70SAndre Guedes struct hci_conn_params *params, *tmp; 320815819a70SAndre Guedes 320915819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 321055af49a8SJohan Hedberg if (params->auto_connect != HCI_AUTO_CONN_DISABLED) 321155af49a8SJohan Hedberg continue; 321215819a70SAndre Guedes list_del(¶ms->list); 321315819a70SAndre Guedes kfree(params); 321415819a70SAndre Guedes } 321515819a70SAndre Guedes 321655af49a8SJohan Hedberg BT_DBG("All LE disabled connection parameters were removed"); 321755af49a8SJohan Hedberg } 321855af49a8SJohan Hedberg 321955af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */ 3220373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev) 322115819a70SAndre Guedes { 322215819a70SAndre Guedes struct hci_conn_params *params, *tmp; 322315819a70SAndre Guedes 3224f6c63249SJohan Hedberg list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) 3225f6c63249SJohan Hedberg hci_conn_params_free(params); 322615819a70SAndre Guedes 3227a2f41a8fSJohan Hedberg hci_update_background_scan(hdev); 32281089b67dSMarcel Holtmann 322915819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 323015819a70SAndre Guedes } 323115819a70SAndre Guedes 32324c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 32337ba8b4beSAndre Guedes { 32344c87eaabSAndre Guedes if (status) { 32354c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 32367ba8b4beSAndre Guedes 32374c87eaabSAndre Guedes hci_dev_lock(hdev); 32384c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 32394c87eaabSAndre Guedes hci_dev_unlock(hdev); 32404c87eaabSAndre Guedes return; 32414c87eaabSAndre Guedes } 32427ba8b4beSAndre Guedes } 32437ba8b4beSAndre Guedes 32444c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 32457ba8b4beSAndre Guedes { 32464c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 32474c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 32484c87eaabSAndre Guedes struct hci_request req; 32494c87eaabSAndre Guedes struct hci_cp_inquiry cp; 32507ba8b4beSAndre Guedes int err; 32517ba8b4beSAndre Guedes 32524c87eaabSAndre Guedes if (status) { 32534c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 32544c87eaabSAndre Guedes return; 32557ba8b4beSAndre Guedes } 32567ba8b4beSAndre Guedes 32574c87eaabSAndre Guedes switch (hdev->discovery.type) { 32584c87eaabSAndre Guedes case DISCOV_TYPE_LE: 32594c87eaabSAndre Guedes hci_dev_lock(hdev); 32604c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 32614c87eaabSAndre Guedes hci_dev_unlock(hdev); 32624c87eaabSAndre Guedes break; 32637dbfac1dSAndre Guedes 32644c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 32654c87eaabSAndre Guedes hci_req_init(&req, hdev); 32667dbfac1dSAndre Guedes 32677dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 32684c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 32694c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 32704c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 32714c87eaabSAndre Guedes 32724c87eaabSAndre Guedes hci_dev_lock(hdev); 32734c87eaabSAndre Guedes 32744c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 32754c87eaabSAndre Guedes 32764c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 32774c87eaabSAndre Guedes if (err) { 32784c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 32794c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 32807dbfac1dSAndre Guedes } 32817dbfac1dSAndre Guedes 32824c87eaabSAndre Guedes hci_dev_unlock(hdev); 32834c87eaabSAndre Guedes break; 32844c87eaabSAndre Guedes } 32857dbfac1dSAndre Guedes } 32867dbfac1dSAndre Guedes 32877ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 32887ba8b4beSAndre Guedes { 32897ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 32907ba8b4beSAndre Guedes le_scan_disable.work); 32914c87eaabSAndre Guedes struct hci_request req; 32924c87eaabSAndre Guedes int err; 32937ba8b4beSAndre Guedes 32947ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 32957ba8b4beSAndre Guedes 32964c87eaabSAndre Guedes hci_req_init(&req, hdev); 32977ba8b4beSAndre Guedes 3298b1efcc28SAndre Guedes hci_req_add_le_scan_disable(&req); 32997ba8b4beSAndre Guedes 33004c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 33014c87eaabSAndre Guedes if (err) 33024c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 330328b75a89SAndre Guedes } 330428b75a89SAndre Guedes 3305a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 3306a1f4c318SJohan Hedberg * 3307a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 3308a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 3309a1f4c318SJohan Hedberg * the static random address. 3310a1f4c318SJohan Hedberg * 3311a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 3312a1f4c318SJohan Hedberg * public address to use the static random address instead. 331350b5b952SMarcel Holtmann * 331450b5b952SMarcel Holtmann * In case BR/EDR has been disabled on a dual-mode controller and 331550b5b952SMarcel Holtmann * userspace has configured a static address, then that address 331650b5b952SMarcel Holtmann * becomes the identity address instead of the public BR/EDR address. 3317a1f4c318SJohan Hedberg */ 3318a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 3319a1f4c318SJohan Hedberg u8 *bdaddr_type) 3320a1f4c318SJohan Hedberg { 3321111902f7SMarcel Holtmann if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) || 332250b5b952SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) || 332350b5b952SMarcel Holtmann (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) && 332450b5b952SMarcel Holtmann bacmp(&hdev->static_addr, BDADDR_ANY))) { 3325a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 3326a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 3327a1f4c318SJohan Hedberg } else { 3328a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 3329a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 3330a1f4c318SJohan Hedberg } 3331a1f4c318SJohan Hedberg } 3332a1f4c318SJohan Hedberg 33339be0dab7SDavid Herrmann /* Alloc HCI device */ 33349be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 33359be0dab7SDavid Herrmann { 33369be0dab7SDavid Herrmann struct hci_dev *hdev; 33379be0dab7SDavid Herrmann 333827f70f3eSJohan Hedberg hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); 33399be0dab7SDavid Herrmann if (!hdev) 33409be0dab7SDavid Herrmann return NULL; 33419be0dab7SDavid Herrmann 3342b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 3343b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 3344b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 3345b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 3346b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 334796c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */ 3348bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 3349bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 3350b1b813d4SDavid Herrmann 3351b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 3352b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 3353b1b813d4SDavid Herrmann 33543f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 3355628531c9SGeorg Lukas hdev->le_adv_min_interval = 0x0800; 3356628531c9SGeorg Lukas hdev->le_adv_max_interval = 0x0800; 3357bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 3358bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 33594e70c7e7SMarcel Holtmann hdev->le_conn_min_interval = 0x0028; 33604e70c7e7SMarcel Holtmann hdev->le_conn_max_interval = 0x0038; 336104fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000; 336204fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a; 3363bef64738SMarcel Holtmann 3364d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 3365b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 336631ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 336731ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 3368d6bfd59cSJohan Hedberg 3369b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 3370b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 3371b1b813d4SDavid Herrmann 3372b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 3373b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 33746659358eSJohan Hedberg INIT_LIST_HEAD(&hdev->whitelist); 3375b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 3376b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 3377b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 3378970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 3379b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 3380d2ab0ac1SMarcel Holtmann INIT_LIST_HEAD(&hdev->le_white_list); 338115819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 338277a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 338366f8455aSJohan Hedberg INIT_LIST_HEAD(&hdev->pend_le_reports); 33846b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 3385b1b813d4SDavid Herrmann 3386b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 3387b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 3388b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 3389b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 3390b1b813d4SDavid Herrmann 3391b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 3392b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 3393b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 3394b1b813d4SDavid Herrmann 3395b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 3396b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 3397b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 3398b1b813d4SDavid Herrmann 3399b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 3400b1b813d4SDavid Herrmann 340165cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout); 3402b1b813d4SDavid Herrmann 3403b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 3404b1b813d4SDavid Herrmann discovery_init(hdev); 34059be0dab7SDavid Herrmann 34069be0dab7SDavid Herrmann return hdev; 34079be0dab7SDavid Herrmann } 34089be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 34099be0dab7SDavid Herrmann 34109be0dab7SDavid Herrmann /* Free HCI device */ 34119be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 34129be0dab7SDavid Herrmann { 34139be0dab7SDavid Herrmann /* will free via device release */ 34149be0dab7SDavid Herrmann put_device(&hdev->dev); 34159be0dab7SDavid Herrmann } 34169be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 34179be0dab7SDavid Herrmann 34181da177e4SLinus Torvalds /* Register HCI device */ 34191da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 34201da177e4SLinus Torvalds { 3421b1b813d4SDavid Herrmann int id, error; 34221da177e4SLinus Torvalds 342374292d5aSMarcel Holtmann if (!hdev->open || !hdev->close || !hdev->send) 34241da177e4SLinus Torvalds return -EINVAL; 34251da177e4SLinus Torvalds 342608add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 342708add513SMat Martineau * so the index can be used as the AMP controller ID. 342808add513SMat Martineau */ 34293df92b31SSasha Levin switch (hdev->dev_type) { 34303df92b31SSasha Levin case HCI_BREDR: 34313df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 34321da177e4SLinus Torvalds break; 34333df92b31SSasha Levin case HCI_AMP: 34343df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 34353df92b31SSasha Levin break; 34363df92b31SSasha Levin default: 34373df92b31SSasha Levin return -EINVAL; 34381da177e4SLinus Torvalds } 34391da177e4SLinus Torvalds 34403df92b31SSasha Levin if (id < 0) 34413df92b31SSasha Levin return id; 34423df92b31SSasha Levin 34431da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 34441da177e4SLinus Torvalds hdev->id = id; 34452d8b3a11SAndrei Emeltchenko 34462d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 34472d8b3a11SAndrei Emeltchenko 3448d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3449d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 345033ca954dSDavid Herrmann if (!hdev->workqueue) { 345133ca954dSDavid Herrmann error = -ENOMEM; 345233ca954dSDavid Herrmann goto err; 345333ca954dSDavid Herrmann } 3454f48fd9c8SMarcel Holtmann 3455d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 3456d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 34576ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 34586ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 34596ead1bbcSJohan Hedberg error = -ENOMEM; 34606ead1bbcSJohan Hedberg goto err; 34616ead1bbcSJohan Hedberg } 34626ead1bbcSJohan Hedberg 34630153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 34640153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 34650153e2ecSMarcel Holtmann 3466bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 3467bdc3e0f1SMarcel Holtmann 3468bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 346933ca954dSDavid Herrmann if (error < 0) 347054506918SJohan Hedberg goto err_wqueue; 34711da177e4SLinus Torvalds 3472611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 3473a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 3474a8c5fb1aSGustavo Padovan hdev); 3475611b30f7SMarcel Holtmann if (hdev->rfkill) { 3476611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 3477611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3478611b30f7SMarcel Holtmann hdev->rfkill = NULL; 3479611b30f7SMarcel Holtmann } 3480611b30f7SMarcel Holtmann } 3481611b30f7SMarcel Holtmann 34825e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 34835e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 34845e130367SJohan Hedberg 3485a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 3486004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 3487ce2be9acSAndrei Emeltchenko 348801cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 348956f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 349056f87901SJohan Hedberg * through reading supported features during init. 349156f87901SJohan Hedberg */ 349256f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 349356f87901SJohan Hedberg } 3494ce2be9acSAndrei Emeltchenko 3495fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 3496fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 3497fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 3498fcee3377SGustavo Padovan 34994a964404SMarcel Holtmann /* Devices that are marked for raw-only usage are unconfigured 35004a964404SMarcel Holtmann * and should not be included in normal operation. 3501fee746b0SMarcel Holtmann */ 3502fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 35034a964404SMarcel Holtmann set_bit(HCI_UNCONFIGURED, &hdev->dev_flags); 3504fee746b0SMarcel Holtmann 35051da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 3506dc946bd8SDavid Herrmann hci_dev_hold(hdev); 35071da177e4SLinus Torvalds 350819202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 3509fbe96d6fSMarcel Holtmann 35101da177e4SLinus Torvalds return id; 3511f48fd9c8SMarcel Holtmann 351233ca954dSDavid Herrmann err_wqueue: 351333ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 35146ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 351533ca954dSDavid Herrmann err: 35163df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 3517f48fd9c8SMarcel Holtmann 351833ca954dSDavid Herrmann return error; 35191da177e4SLinus Torvalds } 35201da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 35211da177e4SLinus Torvalds 35221da177e4SLinus Torvalds /* Unregister HCI device */ 352359735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 35241da177e4SLinus Torvalds { 35253df92b31SSasha Levin int i, id; 3526ef222013SMarcel Holtmann 3527c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 35281da177e4SLinus Torvalds 352994324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 353094324962SJohan Hovold 35313df92b31SSasha Levin id = hdev->id; 35323df92b31SSasha Levin 3533f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 35341da177e4SLinus Torvalds list_del(&hdev->list); 3535f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 35361da177e4SLinus Torvalds 35371da177e4SLinus Torvalds hci_dev_do_close(hdev); 35381da177e4SLinus Torvalds 3539cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 3540ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 3541ef222013SMarcel Holtmann 3542b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 3543b9b5ef18SGustavo Padovan 3544ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 3545d603b76bSMarcel Holtmann !test_bit(HCI_SETUP, &hdev->dev_flags) && 3546d603b76bSMarcel Holtmann !test_bit(HCI_CONFIG, &hdev->dev_flags)) { 354709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3548744cf19eSJohan Hedberg mgmt_index_removed(hdev); 354909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 355056e5cb86SJohan Hedberg } 3551ab81cbf9SJohan Hedberg 35522e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 35532e58ef3eSJohan Hedberg * pending list */ 35542e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 35552e58ef3eSJohan Hedberg 35561da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 35571da177e4SLinus Torvalds 3558611b30f7SMarcel Holtmann if (hdev->rfkill) { 3559611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 3560611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 3561611b30f7SMarcel Holtmann } 3562611b30f7SMarcel Holtmann 3563711eafe3SJohan Hedberg smp_unregister(hdev); 356499780a7bSJohan Hedberg 3565bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 3566147e2d59SDave Young 35670153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 35680153e2ecSMarcel Holtmann 3569f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 35706ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 3571f48fd9c8SMarcel Holtmann 357209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 3573dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->blacklist); 35746659358eSJohan Hedberg hci_bdaddr_list_clear(&hdev->whitelist); 35752aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 357655ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 3577b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 3578970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 35792763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 3580dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->le_white_list); 3581373110c5SJohan Hedberg hci_conn_params_clear_all(hdev); 358222078800SMarcel Holtmann hci_discovery_filter_clear(hdev); 358309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 3584e2e0cacbSJohan Hedberg 3585dc946bd8SDavid Herrmann hci_dev_put(hdev); 35863df92b31SSasha Levin 35873df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 35881da177e4SLinus Torvalds } 35891da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 35901da177e4SLinus Torvalds 35911da177e4SLinus Torvalds /* Suspend HCI device */ 35921da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 35931da177e4SLinus Torvalds { 35941da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 35951da177e4SLinus Torvalds return 0; 35961da177e4SLinus Torvalds } 35971da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 35981da177e4SLinus Torvalds 35991da177e4SLinus Torvalds /* Resume HCI device */ 36001da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 36011da177e4SLinus Torvalds { 36021da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 36031da177e4SLinus Torvalds return 0; 36041da177e4SLinus Torvalds } 36051da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 36061da177e4SLinus Torvalds 360775e0569fSMarcel Holtmann /* Reset HCI device */ 360875e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev) 360975e0569fSMarcel Holtmann { 361075e0569fSMarcel Holtmann const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; 361175e0569fSMarcel Holtmann struct sk_buff *skb; 361275e0569fSMarcel Holtmann 361375e0569fSMarcel Holtmann skb = bt_skb_alloc(3, GFP_ATOMIC); 361475e0569fSMarcel Holtmann if (!skb) 361575e0569fSMarcel Holtmann return -ENOMEM; 361675e0569fSMarcel Holtmann 361775e0569fSMarcel Holtmann bt_cb(skb)->pkt_type = HCI_EVENT_PKT; 361875e0569fSMarcel Holtmann memcpy(skb_put(skb, 3), hw_err, 3); 361975e0569fSMarcel Holtmann 362075e0569fSMarcel Holtmann /* Send Hardware Error to upper stack */ 362175e0569fSMarcel Holtmann return hci_recv_frame(hdev, skb); 362275e0569fSMarcel Holtmann } 362375e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev); 362475e0569fSMarcel Holtmann 362576bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 3626e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 362776bca880SMarcel Holtmann { 362876bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 362976bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 363076bca880SMarcel Holtmann kfree_skb(skb); 363176bca880SMarcel Holtmann return -ENXIO; 363276bca880SMarcel Holtmann } 363376bca880SMarcel Holtmann 3634d82603c6SJorrit Schippers /* Incoming skb */ 363576bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 363676bca880SMarcel Holtmann 363776bca880SMarcel Holtmann /* Time stamp */ 363876bca880SMarcel Holtmann __net_timestamp(skb); 363976bca880SMarcel Holtmann 364076bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 3641b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 3642c78ae283SMarcel Holtmann 364376bca880SMarcel Holtmann return 0; 364476bca880SMarcel Holtmann } 364576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 364676bca880SMarcel Holtmann 364733e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 36481e429f38SGustavo F. Padovan int count, __u8 index) 364933e882a5SSuraj Sumangala { 365033e882a5SSuraj Sumangala int len = 0; 365133e882a5SSuraj Sumangala int hlen = 0; 365233e882a5SSuraj Sumangala int remain = count; 365333e882a5SSuraj Sumangala struct sk_buff *skb; 365433e882a5SSuraj Sumangala struct bt_skb_cb *scb; 365533e882a5SSuraj Sumangala 365633e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 365733e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 365833e882a5SSuraj Sumangala return -EILSEQ; 365933e882a5SSuraj Sumangala 366033e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 366133e882a5SSuraj Sumangala 366233e882a5SSuraj Sumangala if (!skb) { 366333e882a5SSuraj Sumangala switch (type) { 366433e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 366533e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 366633e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 366733e882a5SSuraj Sumangala break; 366833e882a5SSuraj Sumangala case HCI_EVENT_PKT: 366933e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 367033e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 367133e882a5SSuraj Sumangala break; 367233e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 367333e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 367433e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 367533e882a5SSuraj Sumangala break; 367633e882a5SSuraj Sumangala } 367733e882a5SSuraj Sumangala 36781e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 367933e882a5SSuraj Sumangala if (!skb) 368033e882a5SSuraj Sumangala return -ENOMEM; 368133e882a5SSuraj Sumangala 368233e882a5SSuraj Sumangala scb = (void *) skb->cb; 368333e882a5SSuraj Sumangala scb->expect = hlen; 368433e882a5SSuraj Sumangala scb->pkt_type = type; 368533e882a5SSuraj Sumangala 368633e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 368733e882a5SSuraj Sumangala } 368833e882a5SSuraj Sumangala 368933e882a5SSuraj Sumangala while (count) { 369033e882a5SSuraj Sumangala scb = (void *) skb->cb; 369189bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 369233e882a5SSuraj Sumangala 369333e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 369433e882a5SSuraj Sumangala 369533e882a5SSuraj Sumangala count -= len; 369633e882a5SSuraj Sumangala data += len; 369733e882a5SSuraj Sumangala scb->expect -= len; 369833e882a5SSuraj Sumangala remain = count; 369933e882a5SSuraj Sumangala 370033e882a5SSuraj Sumangala switch (type) { 370133e882a5SSuraj Sumangala case HCI_EVENT_PKT: 370233e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 370333e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 370433e882a5SSuraj Sumangala scb->expect = h->plen; 370533e882a5SSuraj Sumangala 370633e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 370733e882a5SSuraj Sumangala kfree_skb(skb); 370833e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 370933e882a5SSuraj Sumangala return -ENOMEM; 371033e882a5SSuraj Sumangala } 371133e882a5SSuraj Sumangala } 371233e882a5SSuraj Sumangala break; 371333e882a5SSuraj Sumangala 371433e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 371533e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 371633e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 371733e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 371833e882a5SSuraj Sumangala 371933e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 372033e882a5SSuraj Sumangala kfree_skb(skb); 372133e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 372233e882a5SSuraj Sumangala return -ENOMEM; 372333e882a5SSuraj Sumangala } 372433e882a5SSuraj Sumangala } 372533e882a5SSuraj Sumangala break; 372633e882a5SSuraj Sumangala 372733e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 372833e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 372933e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 373033e882a5SSuraj Sumangala scb->expect = h->dlen; 373133e882a5SSuraj Sumangala 373233e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 373333e882a5SSuraj Sumangala kfree_skb(skb); 373433e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 373533e882a5SSuraj Sumangala return -ENOMEM; 373633e882a5SSuraj Sumangala } 373733e882a5SSuraj Sumangala } 373833e882a5SSuraj Sumangala break; 373933e882a5SSuraj Sumangala } 374033e882a5SSuraj Sumangala 374133e882a5SSuraj Sumangala if (scb->expect == 0) { 374233e882a5SSuraj Sumangala /* Complete frame */ 374333e882a5SSuraj Sumangala 374433e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 3745e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 374633e882a5SSuraj Sumangala 374733e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 374833e882a5SSuraj Sumangala return remain; 374933e882a5SSuraj Sumangala } 375033e882a5SSuraj Sumangala } 375133e882a5SSuraj Sumangala 375233e882a5SSuraj Sumangala return remain; 375333e882a5SSuraj Sumangala } 375433e882a5SSuraj Sumangala 375599811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 375699811510SSuraj Sumangala 375799811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 375899811510SSuraj Sumangala { 375999811510SSuraj Sumangala int type; 376099811510SSuraj Sumangala int rem = 0; 376199811510SSuraj Sumangala 3762da5f6c37SGustavo F. Padovan while (count) { 376399811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 376499811510SSuraj Sumangala 376599811510SSuraj Sumangala if (!skb) { 376699811510SSuraj Sumangala struct { char type; } *pkt; 376799811510SSuraj Sumangala 376899811510SSuraj Sumangala /* Start of the frame */ 376999811510SSuraj Sumangala pkt = data; 377099811510SSuraj Sumangala type = pkt->type; 377199811510SSuraj Sumangala 377299811510SSuraj Sumangala data++; 377399811510SSuraj Sumangala count--; 377499811510SSuraj Sumangala } else 377599811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 377699811510SSuraj Sumangala 37771e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 37781e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 377999811510SSuraj Sumangala if (rem < 0) 378099811510SSuraj Sumangala return rem; 378199811510SSuraj Sumangala 378299811510SSuraj Sumangala data += (count - rem); 378399811510SSuraj Sumangala count = rem; 3784f81c6224SJoe Perches } 378599811510SSuraj Sumangala 378699811510SSuraj Sumangala return rem; 378799811510SSuraj Sumangala } 378899811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 378999811510SSuraj Sumangala 37901da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 37911da177e4SLinus Torvalds 37921da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 37931da177e4SLinus Torvalds { 37941da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 37951da177e4SLinus Torvalds 3796f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 37971da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 3798f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 37991da177e4SLinus Torvalds 38001da177e4SLinus Torvalds return 0; 38011da177e4SLinus Torvalds } 38021da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 38031da177e4SLinus Torvalds 38041da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 38051da177e4SLinus Torvalds { 38061da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 38071da177e4SLinus Torvalds 3808f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 38091da177e4SLinus Torvalds list_del(&cb->list); 3810f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 38111da177e4SLinus Torvalds 38121da177e4SLinus Torvalds return 0; 38131da177e4SLinus Torvalds } 38141da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 38151da177e4SLinus Torvalds 381651086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 38171da177e4SLinus Torvalds { 3818cdc52faaSMarcel Holtmann int err; 3819cdc52faaSMarcel Holtmann 38200d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 38211da177e4SLinus Torvalds 38221da177e4SLinus Torvalds /* Time stamp */ 3823a61bbcf2SPatrick McHardy __net_timestamp(skb); 38241da177e4SLinus Torvalds 3825cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3826cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3827cd82e61cSMarcel Holtmann 3828cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3829cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3830470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 38311da177e4SLinus Torvalds } 38321da177e4SLinus Torvalds 38331da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 38341da177e4SLinus Torvalds skb_orphan(skb); 38351da177e4SLinus Torvalds 3836cdc52faaSMarcel Holtmann err = hdev->send(hdev, skb); 3837cdc52faaSMarcel Holtmann if (err < 0) { 3838cdc52faaSMarcel Holtmann BT_ERR("%s sending frame failed (%d)", hdev->name, err); 3839cdc52faaSMarcel Holtmann kfree_skb(skb); 3840cdc52faaSMarcel Holtmann } 38411da177e4SLinus Torvalds } 38421da177e4SLinus Torvalds 3843899de765SMarcel Holtmann bool hci_req_pending(struct hci_dev *hdev) 3844899de765SMarcel Holtmann { 3845899de765SMarcel Holtmann return (hdev->req_status == HCI_REQ_PEND); 3846899de765SMarcel Holtmann } 3847899de765SMarcel Holtmann 38481ca3a9d0SJohan Hedberg /* Send HCI command */ 384907dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 385007dc93ddSJohan Hedberg const void *param) 38511ca3a9d0SJohan Hedberg { 38521ca3a9d0SJohan Hedberg struct sk_buff *skb; 38531ca3a9d0SJohan Hedberg 38541ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 38551ca3a9d0SJohan Hedberg 38561ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 38571ca3a9d0SJohan Hedberg if (!skb) { 38581ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 38591ca3a9d0SJohan Hedberg return -ENOMEM; 38601ca3a9d0SJohan Hedberg } 38611ca3a9d0SJohan Hedberg 386249c922bbSStephen Hemminger /* Stand-alone HCI commands must be flagged as 386311714b3dSJohan Hedberg * single-command requests. 386411714b3dSJohan Hedberg */ 386511714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 386611714b3dSJohan Hedberg 38671da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3868c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 38691da177e4SLinus Torvalds 38701da177e4SLinus Torvalds return 0; 38711da177e4SLinus Torvalds } 38721da177e4SLinus Torvalds 38731da177e4SLinus Torvalds /* Get data from the previously sent command */ 3874a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 38751da177e4SLinus Torvalds { 38761da177e4SLinus Torvalds struct hci_command_hdr *hdr; 38771da177e4SLinus Torvalds 38781da177e4SLinus Torvalds if (!hdev->sent_cmd) 38791da177e4SLinus Torvalds return NULL; 38801da177e4SLinus Torvalds 38811da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 38821da177e4SLinus Torvalds 3883a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 38841da177e4SLinus Torvalds return NULL; 38851da177e4SLinus Torvalds 3886f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 38871da177e4SLinus Torvalds 38881da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 38891da177e4SLinus Torvalds } 38901da177e4SLinus Torvalds 38911da177e4SLinus Torvalds /* Send ACL data */ 38921da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 38931da177e4SLinus Torvalds { 38941da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 38951da177e4SLinus Torvalds int len = skb->len; 38961da177e4SLinus Torvalds 3897badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3898badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 38999c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3900aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3901aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 39021da177e4SLinus Torvalds } 39031da177e4SLinus Torvalds 3904ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 390573d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 39061da177e4SLinus Torvalds { 3907ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 39081da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 39091da177e4SLinus Torvalds struct sk_buff *list; 39101da177e4SLinus Torvalds 3911087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3912087bfd99SGustavo Padovan skb->data_len = 0; 3913087bfd99SGustavo Padovan 3914087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3915204a6e54SAndrei Emeltchenko 3916204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3917204a6e54SAndrei Emeltchenko case HCI_BREDR: 3918087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3919204a6e54SAndrei Emeltchenko break; 3920204a6e54SAndrei Emeltchenko case HCI_AMP: 3921204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3922204a6e54SAndrei Emeltchenko break; 3923204a6e54SAndrei Emeltchenko default: 3924204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 3925204a6e54SAndrei Emeltchenko return; 3926204a6e54SAndrei Emeltchenko } 3927087bfd99SGustavo Padovan 392870f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 392970f23020SAndrei Emeltchenko if (!list) { 39301da177e4SLinus Torvalds /* Non fragmented */ 39311da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 39321da177e4SLinus Torvalds 393373d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 39341da177e4SLinus Torvalds } else { 39351da177e4SLinus Torvalds /* Fragmented */ 39361da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 39371da177e4SLinus Torvalds 39381da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 39391da177e4SLinus Torvalds 39409cfd5a23SJukka Rissanen /* Queue all fragments atomically. We need to use spin_lock_bh 39419cfd5a23SJukka Rissanen * here because of 6LoWPAN links, as there this function is 39429cfd5a23SJukka Rissanen * called from softirq and using normal spin lock could cause 39439cfd5a23SJukka Rissanen * deadlocks. 39449cfd5a23SJukka Rissanen */ 39459cfd5a23SJukka Rissanen spin_lock_bh(&queue->lock); 39461da177e4SLinus Torvalds 394773d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3948e702112fSAndrei Emeltchenko 3949e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3950e702112fSAndrei Emeltchenko flags |= ACL_CONT; 39511da177e4SLinus Torvalds do { 39521da177e4SLinus Torvalds skb = list; list = list->next; 39531da177e4SLinus Torvalds 39540d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3955e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 39561da177e4SLinus Torvalds 39571da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 39581da177e4SLinus Torvalds 395973d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 39601da177e4SLinus Torvalds } while (list); 39611da177e4SLinus Torvalds 39629cfd5a23SJukka Rissanen spin_unlock_bh(&queue->lock); 39631da177e4SLinus Torvalds } 396473d80debSLuiz Augusto von Dentz } 396573d80debSLuiz Augusto von Dentz 396673d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 396773d80debSLuiz Augusto von Dentz { 3968ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 396973d80debSLuiz Augusto von Dentz 3970f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 397173d80debSLuiz Augusto von Dentz 3972ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 39731da177e4SLinus Torvalds 39743eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 39751da177e4SLinus Torvalds } 39761da177e4SLinus Torvalds 39771da177e4SLinus Torvalds /* Send SCO data */ 39780d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 39791da177e4SLinus Torvalds { 39801da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 39811da177e4SLinus Torvalds struct hci_sco_hdr hdr; 39821da177e4SLinus Torvalds 39831da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 39841da177e4SLinus Torvalds 3985aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 39861da177e4SLinus Torvalds hdr.dlen = skb->len; 39871da177e4SLinus Torvalds 3988badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 3989badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 39909c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 39911da177e4SLinus Torvalds 39920d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 3993c78ae283SMarcel Holtmann 39941da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 39953eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 39961da177e4SLinus Torvalds } 39971da177e4SLinus Torvalds 39981da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 39991da177e4SLinus Torvalds 40001da177e4SLinus Torvalds /* HCI Connection scheduler */ 40016039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 4002a8c5fb1aSGustavo Padovan int *quote) 40031da177e4SLinus Torvalds { 40041da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 40058035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 4006abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 40071da177e4SLinus Torvalds 40081da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 40091da177e4SLinus Torvalds * added and removed with TX task disabled. */ 4010bf4c6325SGustavo F. Padovan 4011bf4c6325SGustavo F. Padovan rcu_read_lock(); 4012bf4c6325SGustavo F. Padovan 4013bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4014769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 40151da177e4SLinus Torvalds continue; 4016769be974SMarcel Holtmann 4017769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 4018769be974SMarcel Holtmann continue; 4019769be974SMarcel Holtmann 40201da177e4SLinus Torvalds num++; 40211da177e4SLinus Torvalds 40221da177e4SLinus Torvalds if (c->sent < min) { 40231da177e4SLinus Torvalds min = c->sent; 40241da177e4SLinus Torvalds conn = c; 40251da177e4SLinus Torvalds } 402652087a79SLuiz Augusto von Dentz 402752087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 402852087a79SLuiz Augusto von Dentz break; 40291da177e4SLinus Torvalds } 40301da177e4SLinus Torvalds 4031bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4032bf4c6325SGustavo F. Padovan 40331da177e4SLinus Torvalds if (conn) { 40346ed58ec5SVille Tervo int cnt, q; 40356ed58ec5SVille Tervo 40366ed58ec5SVille Tervo switch (conn->type) { 40376ed58ec5SVille Tervo case ACL_LINK: 40386ed58ec5SVille Tervo cnt = hdev->acl_cnt; 40396ed58ec5SVille Tervo break; 40406ed58ec5SVille Tervo case SCO_LINK: 40416ed58ec5SVille Tervo case ESCO_LINK: 40426ed58ec5SVille Tervo cnt = hdev->sco_cnt; 40436ed58ec5SVille Tervo break; 40446ed58ec5SVille Tervo case LE_LINK: 40456ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 40466ed58ec5SVille Tervo break; 40476ed58ec5SVille Tervo default: 40486ed58ec5SVille Tervo cnt = 0; 40496ed58ec5SVille Tervo BT_ERR("Unknown link type"); 40506ed58ec5SVille Tervo } 40516ed58ec5SVille Tervo 40526ed58ec5SVille Tervo q = cnt / num; 40531da177e4SLinus Torvalds *quote = q ? q : 1; 40541da177e4SLinus Torvalds } else 40551da177e4SLinus Torvalds *quote = 0; 40561da177e4SLinus Torvalds 40571da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 40581da177e4SLinus Torvalds return conn; 40591da177e4SLinus Torvalds } 40601da177e4SLinus Torvalds 40616039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 40621da177e4SLinus Torvalds { 40631da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 40641da177e4SLinus Torvalds struct hci_conn *c; 40651da177e4SLinus Torvalds 4066bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 40671da177e4SLinus Torvalds 4068bf4c6325SGustavo F. Padovan rcu_read_lock(); 4069bf4c6325SGustavo F. Padovan 40701da177e4SLinus Torvalds /* Kill stalled connections */ 4071bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 4072bae1f5d9SVille Tervo if (c->type == type && c->sent) { 40736ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 40746ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 4075bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 40761da177e4SLinus Torvalds } 40771da177e4SLinus Torvalds } 4078bf4c6325SGustavo F. Padovan 4079bf4c6325SGustavo F. Padovan rcu_read_unlock(); 40801da177e4SLinus Torvalds } 40811da177e4SLinus Torvalds 40826039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 408373d80debSLuiz Augusto von Dentz int *quote) 408473d80debSLuiz Augusto von Dentz { 408573d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 408673d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 4087abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 408873d80debSLuiz Augusto von Dentz struct hci_conn *conn; 408973d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 409073d80debSLuiz Augusto von Dentz 409173d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 409273d80debSLuiz Augusto von Dentz 4093bf4c6325SGustavo F. Padovan rcu_read_lock(); 4094bf4c6325SGustavo F. Padovan 4095bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 409673d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 409773d80debSLuiz Augusto von Dentz 409873d80debSLuiz Augusto von Dentz if (conn->type != type) 409973d80debSLuiz Augusto von Dentz continue; 410073d80debSLuiz Augusto von Dentz 410173d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 410273d80debSLuiz Augusto von Dentz continue; 410373d80debSLuiz Augusto von Dentz 410473d80debSLuiz Augusto von Dentz conn_num++; 410573d80debSLuiz Augusto von Dentz 41068192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 410773d80debSLuiz Augusto von Dentz struct sk_buff *skb; 410873d80debSLuiz Augusto von Dentz 410973d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 411073d80debSLuiz Augusto von Dentz continue; 411173d80debSLuiz Augusto von Dentz 411273d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 411373d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 411473d80debSLuiz Augusto von Dentz continue; 411573d80debSLuiz Augusto von Dentz 411673d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 411773d80debSLuiz Augusto von Dentz num = 0; 411873d80debSLuiz Augusto von Dentz min = ~0; 411973d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 412073d80debSLuiz Augusto von Dentz } 412173d80debSLuiz Augusto von Dentz 412273d80debSLuiz Augusto von Dentz num++; 412373d80debSLuiz Augusto von Dentz 412473d80debSLuiz Augusto von Dentz if (conn->sent < min) { 412573d80debSLuiz Augusto von Dentz min = conn->sent; 412673d80debSLuiz Augusto von Dentz chan = tmp; 412773d80debSLuiz Augusto von Dentz } 412873d80debSLuiz Augusto von Dentz } 412973d80debSLuiz Augusto von Dentz 413073d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 413173d80debSLuiz Augusto von Dentz break; 413273d80debSLuiz Augusto von Dentz } 413373d80debSLuiz Augusto von Dentz 4134bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4135bf4c6325SGustavo F. Padovan 413673d80debSLuiz Augusto von Dentz if (!chan) 413773d80debSLuiz Augusto von Dentz return NULL; 413873d80debSLuiz Augusto von Dentz 413973d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 414073d80debSLuiz Augusto von Dentz case ACL_LINK: 414173d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 414273d80debSLuiz Augusto von Dentz break; 4143bd1eb66bSAndrei Emeltchenko case AMP_LINK: 4144bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 4145bd1eb66bSAndrei Emeltchenko break; 414673d80debSLuiz Augusto von Dentz case SCO_LINK: 414773d80debSLuiz Augusto von Dentz case ESCO_LINK: 414873d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 414973d80debSLuiz Augusto von Dentz break; 415073d80debSLuiz Augusto von Dentz case LE_LINK: 415173d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 415273d80debSLuiz Augusto von Dentz break; 415373d80debSLuiz Augusto von Dentz default: 415473d80debSLuiz Augusto von Dentz cnt = 0; 415573d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 415673d80debSLuiz Augusto von Dentz } 415773d80debSLuiz Augusto von Dentz 415873d80debSLuiz Augusto von Dentz q = cnt / num; 415973d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 416073d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 416173d80debSLuiz Augusto von Dentz return chan; 416273d80debSLuiz Augusto von Dentz } 416373d80debSLuiz Augusto von Dentz 416402b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 416502b20f0bSLuiz Augusto von Dentz { 416602b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 416702b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 416802b20f0bSLuiz Augusto von Dentz int num = 0; 416902b20f0bSLuiz Augusto von Dentz 417002b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 417102b20f0bSLuiz Augusto von Dentz 4172bf4c6325SGustavo F. Padovan rcu_read_lock(); 4173bf4c6325SGustavo F. Padovan 4174bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 417502b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 417602b20f0bSLuiz Augusto von Dentz 417702b20f0bSLuiz Augusto von Dentz if (conn->type != type) 417802b20f0bSLuiz Augusto von Dentz continue; 417902b20f0bSLuiz Augusto von Dentz 418002b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 418102b20f0bSLuiz Augusto von Dentz continue; 418202b20f0bSLuiz Augusto von Dentz 418302b20f0bSLuiz Augusto von Dentz num++; 418402b20f0bSLuiz Augusto von Dentz 41858192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 418602b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 418702b20f0bSLuiz Augusto von Dentz 418802b20f0bSLuiz Augusto von Dentz if (chan->sent) { 418902b20f0bSLuiz Augusto von Dentz chan->sent = 0; 419002b20f0bSLuiz Augusto von Dentz continue; 419102b20f0bSLuiz Augusto von Dentz } 419202b20f0bSLuiz Augusto von Dentz 419302b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 419402b20f0bSLuiz Augusto von Dentz continue; 419502b20f0bSLuiz Augusto von Dentz 419602b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 419702b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 419802b20f0bSLuiz Augusto von Dentz continue; 419902b20f0bSLuiz Augusto von Dentz 420002b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 420102b20f0bSLuiz Augusto von Dentz 420202b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 420302b20f0bSLuiz Augusto von Dentz skb->priority); 420402b20f0bSLuiz Augusto von Dentz } 420502b20f0bSLuiz Augusto von Dentz 420602b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 420702b20f0bSLuiz Augusto von Dentz break; 420802b20f0bSLuiz Augusto von Dentz } 4209bf4c6325SGustavo F. Padovan 4210bf4c6325SGustavo F. Padovan rcu_read_unlock(); 4211bf4c6325SGustavo F. Padovan 421202b20f0bSLuiz Augusto von Dentz } 421302b20f0bSLuiz Augusto von Dentz 4214b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 4215b71d385aSAndrei Emeltchenko { 4216b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 4217b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 4218b71d385aSAndrei Emeltchenko } 4219b71d385aSAndrei Emeltchenko 42206039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 42211da177e4SLinus Torvalds { 42224a964404SMarcel Holtmann if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 42231da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 42241da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 422563d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 42265f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 4227bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 42281da177e4SLinus Torvalds } 422963d2bc1bSAndrei Emeltchenko } 42301da177e4SLinus Torvalds 42316039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 423263d2bc1bSAndrei Emeltchenko { 423363d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 423463d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 423563d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 423663d2bc1bSAndrei Emeltchenko int quote; 423763d2bc1bSAndrei Emeltchenko 423863d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 423904837f64SMarcel Holtmann 424073d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 424173d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 4242ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4243ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 424473d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 424573d80debSLuiz Augusto von Dentz skb->len, skb->priority); 424673d80debSLuiz Augusto von Dentz 4247ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4248ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4249ec1cce24SLuiz Augusto von Dentz break; 4250ec1cce24SLuiz Augusto von Dentz 4251ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4252ec1cce24SLuiz Augusto von Dentz 425373d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 425473d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 425504837f64SMarcel Holtmann 425657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 42571da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 42581da177e4SLinus Torvalds 42591da177e4SLinus Torvalds hdev->acl_cnt--; 426073d80debSLuiz Augusto von Dentz chan->sent++; 426173d80debSLuiz Augusto von Dentz chan->conn->sent++; 42621da177e4SLinus Torvalds } 42631da177e4SLinus Torvalds } 426402b20f0bSLuiz Augusto von Dentz 426502b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 426602b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 42671da177e4SLinus Torvalds } 42681da177e4SLinus Torvalds 42696039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 4270b71d385aSAndrei Emeltchenko { 427163d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 4272b71d385aSAndrei Emeltchenko struct hci_chan *chan; 4273b71d385aSAndrei Emeltchenko struct sk_buff *skb; 4274b71d385aSAndrei Emeltchenko int quote; 4275bd1eb66bSAndrei Emeltchenko u8 type; 4276b71d385aSAndrei Emeltchenko 427763d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 4278b71d385aSAndrei Emeltchenko 4279bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4280bd1eb66bSAndrei Emeltchenko 4281bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 4282bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 4283bd1eb66bSAndrei Emeltchenko else 4284bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 4285bd1eb66bSAndrei Emeltchenko 4286b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 4287bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 4288b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 4289b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 4290b71d385aSAndrei Emeltchenko int blocks; 4291b71d385aSAndrei Emeltchenko 4292b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 4293b71d385aSAndrei Emeltchenko skb->len, skb->priority); 4294b71d385aSAndrei Emeltchenko 4295b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 4296b71d385aSAndrei Emeltchenko if (skb->priority < priority) 4297b71d385aSAndrei Emeltchenko break; 4298b71d385aSAndrei Emeltchenko 4299b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 4300b71d385aSAndrei Emeltchenko 4301b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 4302b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 4303b71d385aSAndrei Emeltchenko return; 4304b71d385aSAndrei Emeltchenko 4305b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 4306b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 4307b71d385aSAndrei Emeltchenko 430857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4309b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 4310b71d385aSAndrei Emeltchenko 4311b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 4312b71d385aSAndrei Emeltchenko quote -= blocks; 4313b71d385aSAndrei Emeltchenko 4314b71d385aSAndrei Emeltchenko chan->sent += blocks; 4315b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 4316b71d385aSAndrei Emeltchenko } 4317b71d385aSAndrei Emeltchenko } 4318b71d385aSAndrei Emeltchenko 4319b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 4320bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 4321b71d385aSAndrei Emeltchenko } 4322b71d385aSAndrei Emeltchenko 43236039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 4324b71d385aSAndrei Emeltchenko { 4325b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 4326b71d385aSAndrei Emeltchenko 4327bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 4328bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 4329bd1eb66bSAndrei Emeltchenko return; 4330bd1eb66bSAndrei Emeltchenko 4331bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 4332bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 4333b71d385aSAndrei Emeltchenko return; 4334b71d385aSAndrei Emeltchenko 4335b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 4336b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 4337b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 4338b71d385aSAndrei Emeltchenko break; 4339b71d385aSAndrei Emeltchenko 4340b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 4341b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 4342b71d385aSAndrei Emeltchenko break; 4343b71d385aSAndrei Emeltchenko } 4344b71d385aSAndrei Emeltchenko } 4345b71d385aSAndrei Emeltchenko 43461da177e4SLinus Torvalds /* Schedule SCO */ 43476039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 43481da177e4SLinus Torvalds { 43491da177e4SLinus Torvalds struct hci_conn *conn; 43501da177e4SLinus Torvalds struct sk_buff *skb; 43511da177e4SLinus Torvalds int quote; 43521da177e4SLinus Torvalds 43531da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 43541da177e4SLinus Torvalds 435552087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 435652087a79SLuiz Augusto von Dentz return; 435752087a79SLuiz Augusto von Dentz 43581da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 43591da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 43601da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 436157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 43621da177e4SLinus Torvalds 43631da177e4SLinus Torvalds conn->sent++; 43641da177e4SLinus Torvalds if (conn->sent == ~0) 43651da177e4SLinus Torvalds conn->sent = 0; 43661da177e4SLinus Torvalds } 43671da177e4SLinus Torvalds } 43681da177e4SLinus Torvalds } 43691da177e4SLinus Torvalds 43706039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 4371b6a0dc82SMarcel Holtmann { 4372b6a0dc82SMarcel Holtmann struct hci_conn *conn; 4373b6a0dc82SMarcel Holtmann struct sk_buff *skb; 4374b6a0dc82SMarcel Holtmann int quote; 4375b6a0dc82SMarcel Holtmann 4376b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 4377b6a0dc82SMarcel Holtmann 437852087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 437952087a79SLuiz Augusto von Dentz return; 438052087a79SLuiz Augusto von Dentz 43818fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 43828fc9ced3SGustavo Padovan "e))) { 4383b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 4384b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 438557d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 4386b6a0dc82SMarcel Holtmann 4387b6a0dc82SMarcel Holtmann conn->sent++; 4388b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 4389b6a0dc82SMarcel Holtmann conn->sent = 0; 4390b6a0dc82SMarcel Holtmann } 4391b6a0dc82SMarcel Holtmann } 4392b6a0dc82SMarcel Holtmann } 4393b6a0dc82SMarcel Holtmann 43946039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 43956ed58ec5SVille Tervo { 439673d80debSLuiz Augusto von Dentz struct hci_chan *chan; 43976ed58ec5SVille Tervo struct sk_buff *skb; 439802b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 43996ed58ec5SVille Tervo 44006ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 44016ed58ec5SVille Tervo 440252087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 440352087a79SLuiz Augusto von Dentz return; 440452087a79SLuiz Augusto von Dentz 44054a964404SMarcel Holtmann if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) { 44066ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 44076ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 4408bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 44096ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 4410bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 44116ed58ec5SVille Tervo } 44126ed58ec5SVille Tervo 44136ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 441402b20f0bSLuiz Augusto von Dentz tmp = cnt; 441573d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 4416ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 4417ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 441873d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 441973d80debSLuiz Augusto von Dentz skb->len, skb->priority); 44206ed58ec5SVille Tervo 4421ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 4422ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 4423ec1cce24SLuiz Augusto von Dentz break; 4424ec1cce24SLuiz Augusto von Dentz 4425ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 4426ec1cce24SLuiz Augusto von Dentz 442757d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 44286ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 44296ed58ec5SVille Tervo 44306ed58ec5SVille Tervo cnt--; 443173d80debSLuiz Augusto von Dentz chan->sent++; 443273d80debSLuiz Augusto von Dentz chan->conn->sent++; 44336ed58ec5SVille Tervo } 44346ed58ec5SVille Tervo } 443573d80debSLuiz Augusto von Dentz 44366ed58ec5SVille Tervo if (hdev->le_pkts) 44376ed58ec5SVille Tervo hdev->le_cnt = cnt; 44386ed58ec5SVille Tervo else 44396ed58ec5SVille Tervo hdev->acl_cnt = cnt; 444002b20f0bSLuiz Augusto von Dentz 444102b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 444202b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 44436ed58ec5SVille Tervo } 44446ed58ec5SVille Tervo 44453eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 44461da177e4SLinus Torvalds { 44473eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 44481da177e4SLinus Torvalds struct sk_buff *skb; 44491da177e4SLinus Torvalds 44506ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 44516ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 44521da177e4SLinus Torvalds 445352de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 44541da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 44551da177e4SLinus Torvalds hci_sched_acl(hdev); 44561da177e4SLinus Torvalds hci_sched_sco(hdev); 4457b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 44586ed58ec5SVille Tervo hci_sched_le(hdev); 445952de599eSMarcel Holtmann } 44606ed58ec5SVille Tervo 44611da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 44621da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 446357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 44641da177e4SLinus Torvalds } 44651da177e4SLinus Torvalds 446625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 44671da177e4SLinus Torvalds 44681da177e4SLinus Torvalds /* ACL data packet */ 44696039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 44701da177e4SLinus Torvalds { 44711da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 44721da177e4SLinus Torvalds struct hci_conn *conn; 44731da177e4SLinus Torvalds __u16 handle, flags; 44741da177e4SLinus Torvalds 44751da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 44761da177e4SLinus Torvalds 44771da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 44781da177e4SLinus Torvalds flags = hci_flags(handle); 44791da177e4SLinus Torvalds handle = hci_handle(handle); 44801da177e4SLinus Torvalds 4481f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 4482a8c5fb1aSGustavo Padovan handle, flags); 44831da177e4SLinus Torvalds 44841da177e4SLinus Torvalds hdev->stat.acl_rx++; 44851da177e4SLinus Torvalds 44861da177e4SLinus Torvalds hci_dev_lock(hdev); 44871da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 44881da177e4SLinus Torvalds hci_dev_unlock(hdev); 44891da177e4SLinus Torvalds 44901da177e4SLinus Torvalds if (conn) { 449165983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 449204837f64SMarcel Holtmann 44931da177e4SLinus Torvalds /* Send to upper protocol */ 4494686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 44951da177e4SLinus Torvalds return; 44961da177e4SLinus Torvalds } else { 44971da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 44981da177e4SLinus Torvalds hdev->name, handle); 44991da177e4SLinus Torvalds } 45001da177e4SLinus Torvalds 45011da177e4SLinus Torvalds kfree_skb(skb); 45021da177e4SLinus Torvalds } 45031da177e4SLinus Torvalds 45041da177e4SLinus Torvalds /* SCO data packet */ 45056039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 45061da177e4SLinus Torvalds { 45071da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 45081da177e4SLinus Torvalds struct hci_conn *conn; 45091da177e4SLinus Torvalds __u16 handle; 45101da177e4SLinus Torvalds 45111da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 45121da177e4SLinus Torvalds 45131da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 45141da177e4SLinus Torvalds 4515f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 45161da177e4SLinus Torvalds 45171da177e4SLinus Torvalds hdev->stat.sco_rx++; 45181da177e4SLinus Torvalds 45191da177e4SLinus Torvalds hci_dev_lock(hdev); 45201da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 45211da177e4SLinus Torvalds hci_dev_unlock(hdev); 45221da177e4SLinus Torvalds 45231da177e4SLinus Torvalds if (conn) { 45241da177e4SLinus Torvalds /* Send to upper protocol */ 4525686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 45261da177e4SLinus Torvalds return; 45271da177e4SLinus Torvalds } else { 45281da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 45291da177e4SLinus Torvalds hdev->name, handle); 45301da177e4SLinus Torvalds } 45311da177e4SLinus Torvalds 45321da177e4SLinus Torvalds kfree_skb(skb); 45331da177e4SLinus Torvalds } 45341da177e4SLinus Torvalds 45359238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 45369238f36aSJohan Hedberg { 45379238f36aSJohan Hedberg struct sk_buff *skb; 45389238f36aSJohan Hedberg 45399238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 45409238f36aSJohan Hedberg if (!skb) 45419238f36aSJohan Hedberg return true; 45429238f36aSJohan Hedberg 45439238f36aSJohan Hedberg return bt_cb(skb)->req.start; 45449238f36aSJohan Hedberg } 45459238f36aSJohan Hedberg 454642c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 454742c6b129SJohan Hedberg { 454842c6b129SJohan Hedberg struct hci_command_hdr *sent; 454942c6b129SJohan Hedberg struct sk_buff *skb; 455042c6b129SJohan Hedberg u16 opcode; 455142c6b129SJohan Hedberg 455242c6b129SJohan Hedberg if (!hdev->sent_cmd) 455342c6b129SJohan Hedberg return; 455442c6b129SJohan Hedberg 455542c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 455642c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 455742c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 455842c6b129SJohan Hedberg return; 455942c6b129SJohan Hedberg 456042c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 456142c6b129SJohan Hedberg if (!skb) 456242c6b129SJohan Hedberg return; 456342c6b129SJohan Hedberg 456442c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 456542c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 456642c6b129SJohan Hedberg } 456742c6b129SJohan Hedberg 45689238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 45699238f36aSJohan Hedberg { 45709238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 45719238f36aSJohan Hedberg struct sk_buff *skb; 45729238f36aSJohan Hedberg unsigned long flags; 45739238f36aSJohan Hedberg 45749238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 45759238f36aSJohan Hedberg 457642c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 457742c6b129SJohan Hedberg * sent we need to do special handling of it. 45789238f36aSJohan Hedberg */ 457942c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 458042c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 458142c6b129SJohan Hedberg * reset complete event during init and any pending 458242c6b129SJohan Hedberg * command will never be completed. In such a case we 458342c6b129SJohan Hedberg * need to resend whatever was the last sent 458442c6b129SJohan Hedberg * command. 458542c6b129SJohan Hedberg */ 458642c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 458742c6b129SJohan Hedberg hci_resend_last(hdev); 458842c6b129SJohan Hedberg 45899238f36aSJohan Hedberg return; 459042c6b129SJohan Hedberg } 45919238f36aSJohan Hedberg 45929238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 45939238f36aSJohan Hedberg * this request the request is not yet complete. 45949238f36aSJohan Hedberg */ 45959238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 45969238f36aSJohan Hedberg return; 45979238f36aSJohan Hedberg 45989238f36aSJohan Hedberg /* If this was the last command in a request the complete 45999238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 46009238f36aSJohan Hedberg * command queue (hdev->cmd_q). 46019238f36aSJohan Hedberg */ 46029238f36aSJohan Hedberg if (hdev->sent_cmd) { 46039238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 460453e21fbcSJohan Hedberg 460553e21fbcSJohan Hedberg if (req_complete) { 460653e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 460753e21fbcSJohan Hedberg * avoid calling the callback more than once if 460853e21fbcSJohan Hedberg * this function gets called again. 460953e21fbcSJohan Hedberg */ 461053e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 461153e21fbcSJohan Hedberg 46129238f36aSJohan Hedberg goto call_complete; 46139238f36aSJohan Hedberg } 461453e21fbcSJohan Hedberg } 46159238f36aSJohan Hedberg 46169238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 46179238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 46189238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 46199238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 46209238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 46219238f36aSJohan Hedberg break; 46229238f36aSJohan Hedberg } 46239238f36aSJohan Hedberg 46249238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 46259238f36aSJohan Hedberg kfree_skb(skb); 46269238f36aSJohan Hedberg } 46279238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 46289238f36aSJohan Hedberg 46299238f36aSJohan Hedberg call_complete: 46309238f36aSJohan Hedberg if (req_complete) 46319238f36aSJohan Hedberg req_complete(hdev, status); 46329238f36aSJohan Hedberg } 46339238f36aSJohan Hedberg 4634b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 46351da177e4SLinus Torvalds { 4636b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 46371da177e4SLinus Torvalds struct sk_buff *skb; 46381da177e4SLinus Torvalds 46391da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 46401da177e4SLinus Torvalds 46411da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 4642cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4643cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4644cd82e61cSMarcel Holtmann 46451da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 46461da177e4SLinus Torvalds /* Send copy to the sockets */ 4647470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 46481da177e4SLinus Torvalds } 46491da177e4SLinus Torvalds 4650fee746b0SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 46511da177e4SLinus Torvalds kfree_skb(skb); 46521da177e4SLinus Torvalds continue; 46531da177e4SLinus Torvalds } 46541da177e4SLinus Torvalds 46551da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 46561da177e4SLinus Torvalds /* Don't process data packets in this states. */ 46570d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 46581da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 46591da177e4SLinus Torvalds case HCI_SCODATA_PKT: 46601da177e4SLinus Torvalds kfree_skb(skb); 46611da177e4SLinus Torvalds continue; 46623ff50b79SStephen Hemminger } 46631da177e4SLinus Torvalds } 46641da177e4SLinus Torvalds 46651da177e4SLinus Torvalds /* Process frame */ 46660d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 46671da177e4SLinus Torvalds case HCI_EVENT_PKT: 4668b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 46691da177e4SLinus Torvalds hci_event_packet(hdev, skb); 46701da177e4SLinus Torvalds break; 46711da177e4SLinus Torvalds 46721da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 46731da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 46741da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 46751da177e4SLinus Torvalds break; 46761da177e4SLinus Torvalds 46771da177e4SLinus Torvalds case HCI_SCODATA_PKT: 46781da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 46791da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 46801da177e4SLinus Torvalds break; 46811da177e4SLinus Torvalds 46821da177e4SLinus Torvalds default: 46831da177e4SLinus Torvalds kfree_skb(skb); 46841da177e4SLinus Torvalds break; 46851da177e4SLinus Torvalds } 46861da177e4SLinus Torvalds } 46871da177e4SLinus Torvalds } 46881da177e4SLinus Torvalds 4689c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 46901da177e4SLinus Torvalds { 4691c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 46921da177e4SLinus Torvalds struct sk_buff *skb; 46931da177e4SLinus Torvalds 46942104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 46952104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 46961da177e4SLinus Torvalds 46971da177e4SLinus Torvalds /* Send queued commands */ 46985a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 46995a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 47005a08ecceSAndrei Emeltchenko if (!skb) 47015a08ecceSAndrei Emeltchenko return; 47025a08ecceSAndrei Emeltchenko 47031da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 47041da177e4SLinus Torvalds 4705a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 470670f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 47071da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 470857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 47097bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 471065cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 47117bdb8a5cSSzymon Janc else 471265cc2b49SMarcel Holtmann schedule_delayed_work(&hdev->cmd_timer, 471365cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT); 47141da177e4SLinus Torvalds } else { 47151da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4716c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 47171da177e4SLinus Torvalds } 47181da177e4SLinus Torvalds } 47191da177e4SLinus Torvalds } 4720