11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 31da177e4SLinus Torvalds Copyright (C) 2000-2001 Qualcomm Incorporated 4590051deSGustavo F. Padovan Copyright (C) 2011 ProFUSION Embedded Systems 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 91da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 101da177e4SLinus Torvalds published by the Free Software Foundation; 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 131da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 141da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 151da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 161da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 171da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 181da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 191da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 221da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 231da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 241da177e4SLinus Torvalds */ 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds /* Bluetooth HCI core. */ 271da177e4SLinus Torvalds 288c520a59SGustavo Padovan #include <linux/export.h> 293df92b31SSasha Levin #include <linux/idr.h> 30611b30f7SMarcel Holtmann #include <linux/rfkill.h> 31baf27f6eSMarcel Holtmann #include <linux/debugfs.h> 3247219839SMarcel Holtmann #include <asm/unaligned.h> 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 351da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 361da177e4SLinus Torvalds 37b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 38c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 393eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds /* HCI device list */ 421da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 431da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds /* HCI callback list */ 461da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 471da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 481da177e4SLinus Torvalds 493df92b31SSasha Levin /* HCI ID Numbering */ 503df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 513df92b31SSasha Levin 521da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 531da177e4SLinus Torvalds 546516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 551da177e4SLinus Torvalds { 56040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 571da177e4SLinus Torvalds } 581da177e4SLinus Torvalds 59baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */ 60baf27f6eSMarcel Holtmann 61dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr) 62dfb826a8SMarcel Holtmann { 63dfb826a8SMarcel Holtmann struct hci_dev *hdev = f->private; 64dfb826a8SMarcel Holtmann u8 p; 65dfb826a8SMarcel Holtmann 66dfb826a8SMarcel Holtmann hci_dev_lock(hdev); 67dfb826a8SMarcel Holtmann for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 68cfbb2b5bSMarcel Holtmann seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 69dfb826a8SMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p, 70dfb826a8SMarcel Holtmann hdev->features[p][0], hdev->features[p][1], 71dfb826a8SMarcel Holtmann hdev->features[p][2], hdev->features[p][3], 72dfb826a8SMarcel Holtmann hdev->features[p][4], hdev->features[p][5], 73dfb826a8SMarcel Holtmann hdev->features[p][6], hdev->features[p][7]); 74dfb826a8SMarcel Holtmann } 75cfbb2b5bSMarcel Holtmann if (lmp_le_capable(hdev)) 76cfbb2b5bSMarcel Holtmann seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 77cfbb2b5bSMarcel Holtmann "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", 78cfbb2b5bSMarcel Holtmann hdev->le_features[0], hdev->le_features[1], 79cfbb2b5bSMarcel Holtmann hdev->le_features[2], hdev->le_features[3], 80cfbb2b5bSMarcel Holtmann hdev->le_features[4], hdev->le_features[5], 81cfbb2b5bSMarcel Holtmann hdev->le_features[6], hdev->le_features[7]); 82dfb826a8SMarcel Holtmann hci_dev_unlock(hdev); 83dfb826a8SMarcel Holtmann 84dfb826a8SMarcel Holtmann return 0; 85dfb826a8SMarcel Holtmann } 86dfb826a8SMarcel Holtmann 87dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file) 88dfb826a8SMarcel Holtmann { 89dfb826a8SMarcel Holtmann return single_open(file, features_show, inode->i_private); 90dfb826a8SMarcel Holtmann } 91dfb826a8SMarcel Holtmann 92dfb826a8SMarcel Holtmann static const struct file_operations features_fops = { 93dfb826a8SMarcel Holtmann .open = features_open, 94dfb826a8SMarcel Holtmann .read = seq_read, 95dfb826a8SMarcel Holtmann .llseek = seq_lseek, 96dfb826a8SMarcel Holtmann .release = single_release, 97dfb826a8SMarcel Holtmann }; 98dfb826a8SMarcel Holtmann 9970afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p) 10070afe0b8SMarcel Holtmann { 10170afe0b8SMarcel Holtmann struct hci_dev *hdev = f->private; 10270afe0b8SMarcel Holtmann struct bdaddr_list *b; 10370afe0b8SMarcel Holtmann 10470afe0b8SMarcel Holtmann hci_dev_lock(hdev); 10570afe0b8SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) 106b25f0785SMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 10770afe0b8SMarcel Holtmann hci_dev_unlock(hdev); 10870afe0b8SMarcel Holtmann 10970afe0b8SMarcel Holtmann return 0; 11070afe0b8SMarcel Holtmann } 11170afe0b8SMarcel Holtmann 11270afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file) 11370afe0b8SMarcel Holtmann { 11470afe0b8SMarcel Holtmann return single_open(file, blacklist_show, inode->i_private); 11570afe0b8SMarcel Holtmann } 11670afe0b8SMarcel Holtmann 11770afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = { 11870afe0b8SMarcel Holtmann .open = blacklist_open, 11970afe0b8SMarcel Holtmann .read = seq_read, 12070afe0b8SMarcel Holtmann .llseek = seq_lseek, 12170afe0b8SMarcel Holtmann .release = single_release, 12270afe0b8SMarcel Holtmann }; 12370afe0b8SMarcel Holtmann 12447219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p) 12547219839SMarcel Holtmann { 12647219839SMarcel Holtmann struct hci_dev *hdev = f->private; 12747219839SMarcel Holtmann struct bt_uuid *uuid; 12847219839SMarcel Holtmann 12947219839SMarcel Holtmann hci_dev_lock(hdev); 13047219839SMarcel Holtmann list_for_each_entry(uuid, &hdev->uuids, list) { 13147219839SMarcel Holtmann u32 data0, data5; 13247219839SMarcel Holtmann u16 data1, data2, data3, data4; 13347219839SMarcel Holtmann 13447219839SMarcel Holtmann data5 = get_unaligned_le32(uuid); 13547219839SMarcel Holtmann data4 = get_unaligned_le16(uuid + 4); 13647219839SMarcel Holtmann data3 = get_unaligned_le16(uuid + 6); 13747219839SMarcel Holtmann data2 = get_unaligned_le16(uuid + 8); 13847219839SMarcel Holtmann data1 = get_unaligned_le16(uuid + 10); 13947219839SMarcel Holtmann data0 = get_unaligned_le32(uuid + 12); 14047219839SMarcel Holtmann 14147219839SMarcel Holtmann seq_printf(f, "%.8x-%.4x-%.4x-%.4x-%.4x%.8x\n", 14247219839SMarcel Holtmann data0, data1, data2, data3, data4, data5); 14347219839SMarcel Holtmann } 14447219839SMarcel Holtmann hci_dev_unlock(hdev); 14547219839SMarcel Holtmann 14647219839SMarcel Holtmann return 0; 14747219839SMarcel Holtmann } 14847219839SMarcel Holtmann 14947219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file) 15047219839SMarcel Holtmann { 15147219839SMarcel Holtmann return single_open(file, uuids_show, inode->i_private); 15247219839SMarcel Holtmann } 15347219839SMarcel Holtmann 15447219839SMarcel Holtmann static const struct file_operations uuids_fops = { 15547219839SMarcel Holtmann .open = uuids_open, 15647219839SMarcel Holtmann .read = seq_read, 15747219839SMarcel Holtmann .llseek = seq_lseek, 15847219839SMarcel Holtmann .release = single_release, 15947219839SMarcel Holtmann }; 16047219839SMarcel Holtmann 161baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p) 162baf27f6eSMarcel Holtmann { 163baf27f6eSMarcel Holtmann struct hci_dev *hdev = f->private; 164baf27f6eSMarcel Holtmann struct discovery_state *cache = &hdev->discovery; 165baf27f6eSMarcel Holtmann struct inquiry_entry *e; 166baf27f6eSMarcel Holtmann 167baf27f6eSMarcel Holtmann hci_dev_lock(hdev); 168baf27f6eSMarcel Holtmann 169baf27f6eSMarcel Holtmann list_for_each_entry(e, &cache->all, all) { 170baf27f6eSMarcel Holtmann struct inquiry_data *data = &e->data; 171baf27f6eSMarcel Holtmann seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", 172baf27f6eSMarcel Holtmann &data->bdaddr, 173baf27f6eSMarcel Holtmann data->pscan_rep_mode, data->pscan_period_mode, 174baf27f6eSMarcel Holtmann data->pscan_mode, data->dev_class[2], 175baf27f6eSMarcel Holtmann data->dev_class[1], data->dev_class[0], 176baf27f6eSMarcel Holtmann __le16_to_cpu(data->clock_offset), 177baf27f6eSMarcel Holtmann data->rssi, data->ssp_mode, e->timestamp); 178baf27f6eSMarcel Holtmann } 179baf27f6eSMarcel Holtmann 180baf27f6eSMarcel Holtmann hci_dev_unlock(hdev); 181baf27f6eSMarcel Holtmann 182baf27f6eSMarcel Holtmann return 0; 183baf27f6eSMarcel Holtmann } 184baf27f6eSMarcel Holtmann 185baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file) 186baf27f6eSMarcel Holtmann { 187baf27f6eSMarcel Holtmann return single_open(file, inquiry_cache_show, inode->i_private); 188baf27f6eSMarcel Holtmann } 189baf27f6eSMarcel Holtmann 190baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = { 191baf27f6eSMarcel Holtmann .open = inquiry_cache_open, 192baf27f6eSMarcel Holtmann .read = seq_read, 193baf27f6eSMarcel Holtmann .llseek = seq_lseek, 194baf27f6eSMarcel Holtmann .release = single_release, 195baf27f6eSMarcel Holtmann }; 196baf27f6eSMarcel Holtmann 19702d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr) 19802d08d15SMarcel Holtmann { 19902d08d15SMarcel Holtmann struct hci_dev *hdev = f->private; 20002d08d15SMarcel Holtmann struct list_head *p, *n; 20102d08d15SMarcel Holtmann 20202d08d15SMarcel Holtmann hci_dev_lock(hdev); 20302d08d15SMarcel Holtmann list_for_each_safe(p, n, &hdev->link_keys) { 20402d08d15SMarcel Holtmann struct link_key *key = list_entry(p, struct link_key, list); 20502d08d15SMarcel Holtmann seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type, 20602d08d15SMarcel Holtmann HCI_LINK_KEY_SIZE, key->val, key->pin_len); 20702d08d15SMarcel Holtmann } 20802d08d15SMarcel Holtmann hci_dev_unlock(hdev); 20902d08d15SMarcel Holtmann 21002d08d15SMarcel Holtmann return 0; 21102d08d15SMarcel Holtmann } 21202d08d15SMarcel Holtmann 21302d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file) 21402d08d15SMarcel Holtmann { 21502d08d15SMarcel Holtmann return single_open(file, link_keys_show, inode->i_private); 21602d08d15SMarcel Holtmann } 21702d08d15SMarcel Holtmann 21802d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = { 21902d08d15SMarcel Holtmann .open = link_keys_open, 22002d08d15SMarcel Holtmann .read = seq_read, 22102d08d15SMarcel Holtmann .llseek = seq_lseek, 22202d08d15SMarcel Holtmann .release = single_release, 22302d08d15SMarcel Holtmann }; 22402d08d15SMarcel Holtmann 22512c269d7SMarcel Holtmann static ssize_t use_debug_keys_read(struct file *file, char __user *user_buf, 22612c269d7SMarcel Holtmann size_t count, loff_t *ppos) 22712c269d7SMarcel Holtmann { 22812c269d7SMarcel Holtmann struct hci_dev *hdev = file->private_data; 22912c269d7SMarcel Holtmann char buf[3]; 23012c269d7SMarcel Holtmann 23112c269d7SMarcel Holtmann buf[0] = test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) ? 'Y': 'N'; 23212c269d7SMarcel Holtmann buf[1] = '\n'; 23312c269d7SMarcel Holtmann buf[2] = '\0'; 23412c269d7SMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 23512c269d7SMarcel Holtmann } 23612c269d7SMarcel Holtmann 23712c269d7SMarcel Holtmann static const struct file_operations use_debug_keys_fops = { 23812c269d7SMarcel Holtmann .open = simple_open, 23912c269d7SMarcel Holtmann .read = use_debug_keys_read, 24012c269d7SMarcel Holtmann .llseek = default_llseek, 24112c269d7SMarcel Holtmann }; 24212c269d7SMarcel Holtmann 243babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr) 244babdbb3cSMarcel Holtmann { 245babdbb3cSMarcel Holtmann struct hci_dev *hdev = f->private; 246babdbb3cSMarcel Holtmann 247babdbb3cSMarcel Holtmann hci_dev_lock(hdev); 248babdbb3cSMarcel Holtmann seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], 249babdbb3cSMarcel Holtmann hdev->dev_class[1], hdev->dev_class[0]); 250babdbb3cSMarcel Holtmann hci_dev_unlock(hdev); 251babdbb3cSMarcel Holtmann 252babdbb3cSMarcel Holtmann return 0; 253babdbb3cSMarcel Holtmann } 254babdbb3cSMarcel Holtmann 255babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file) 256babdbb3cSMarcel Holtmann { 257babdbb3cSMarcel Holtmann return single_open(file, dev_class_show, inode->i_private); 258babdbb3cSMarcel Holtmann } 259babdbb3cSMarcel Holtmann 260babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = { 261babdbb3cSMarcel Holtmann .open = dev_class_open, 262babdbb3cSMarcel Holtmann .read = seq_read, 263babdbb3cSMarcel Holtmann .llseek = seq_lseek, 264babdbb3cSMarcel Holtmann .release = single_release, 265babdbb3cSMarcel Holtmann }; 266babdbb3cSMarcel Holtmann 267041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val) 268041000b9SMarcel Holtmann { 269041000b9SMarcel Holtmann struct hci_dev *hdev = data; 270041000b9SMarcel Holtmann 271041000b9SMarcel Holtmann hci_dev_lock(hdev); 272041000b9SMarcel Holtmann *val = hdev->voice_setting; 273041000b9SMarcel Holtmann hci_dev_unlock(hdev); 274041000b9SMarcel Holtmann 275041000b9SMarcel Holtmann return 0; 276041000b9SMarcel Holtmann } 277041000b9SMarcel Holtmann 278041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get, 279041000b9SMarcel Holtmann NULL, "0x%4.4llx\n"); 280041000b9SMarcel Holtmann 281ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val) 282ebd1e33bSMarcel Holtmann { 283ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 284ebd1e33bSMarcel Holtmann 285ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 286ebd1e33bSMarcel Holtmann hdev->auto_accept_delay = val; 287ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 288ebd1e33bSMarcel Holtmann 289ebd1e33bSMarcel Holtmann return 0; 290ebd1e33bSMarcel Holtmann } 291ebd1e33bSMarcel Holtmann 292ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val) 293ebd1e33bSMarcel Holtmann { 294ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 295ebd1e33bSMarcel Holtmann 296ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 297ebd1e33bSMarcel Holtmann *val = hdev->auto_accept_delay; 298ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 299ebd1e33bSMarcel Holtmann 300ebd1e33bSMarcel Holtmann return 0; 301ebd1e33bSMarcel Holtmann } 302ebd1e33bSMarcel Holtmann 303ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, 304ebd1e33bSMarcel Holtmann auto_accept_delay_set, "%llu\n"); 305ebd1e33bSMarcel Holtmann 30606f5b778SMarcel Holtmann static int ssp_debug_mode_set(void *data, u64 val) 30706f5b778SMarcel Holtmann { 30806f5b778SMarcel Holtmann struct hci_dev *hdev = data; 30906f5b778SMarcel Holtmann struct sk_buff *skb; 31006f5b778SMarcel Holtmann __u8 mode; 31106f5b778SMarcel Holtmann int err; 31206f5b778SMarcel Holtmann 31306f5b778SMarcel Holtmann if (val != 0 && val != 1) 31406f5b778SMarcel Holtmann return -EINVAL; 31506f5b778SMarcel Holtmann 31606f5b778SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 31706f5b778SMarcel Holtmann return -ENETDOWN; 31806f5b778SMarcel Holtmann 31906f5b778SMarcel Holtmann hci_req_lock(hdev); 32006f5b778SMarcel Holtmann mode = val; 32106f5b778SMarcel Holtmann skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode), 32206f5b778SMarcel Holtmann &mode, HCI_CMD_TIMEOUT); 32306f5b778SMarcel Holtmann hci_req_unlock(hdev); 32406f5b778SMarcel Holtmann 32506f5b778SMarcel Holtmann if (IS_ERR(skb)) 32606f5b778SMarcel Holtmann return PTR_ERR(skb); 32706f5b778SMarcel Holtmann 32806f5b778SMarcel Holtmann err = -bt_to_errno(skb->data[0]); 32906f5b778SMarcel Holtmann kfree_skb(skb); 33006f5b778SMarcel Holtmann 33106f5b778SMarcel Holtmann if (err < 0) 33206f5b778SMarcel Holtmann return err; 33306f5b778SMarcel Holtmann 33406f5b778SMarcel Holtmann hci_dev_lock(hdev); 33506f5b778SMarcel Holtmann hdev->ssp_debug_mode = val; 33606f5b778SMarcel Holtmann hci_dev_unlock(hdev); 33706f5b778SMarcel Holtmann 33806f5b778SMarcel Holtmann return 0; 33906f5b778SMarcel Holtmann } 34006f5b778SMarcel Holtmann 34106f5b778SMarcel Holtmann static int ssp_debug_mode_get(void *data, u64 *val) 34206f5b778SMarcel Holtmann { 34306f5b778SMarcel Holtmann struct hci_dev *hdev = data; 34406f5b778SMarcel Holtmann 34506f5b778SMarcel Holtmann hci_dev_lock(hdev); 34606f5b778SMarcel Holtmann *val = hdev->ssp_debug_mode; 34706f5b778SMarcel Holtmann hci_dev_unlock(hdev); 34806f5b778SMarcel Holtmann 34906f5b778SMarcel Holtmann return 0; 35006f5b778SMarcel Holtmann } 35106f5b778SMarcel Holtmann 35206f5b778SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get, 35306f5b778SMarcel Holtmann ssp_debug_mode_set, "%llu\n"); 35406f5b778SMarcel Holtmann 3552bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val) 3562bfa3531SMarcel Holtmann { 3572bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 3582bfa3531SMarcel Holtmann 3592bfa3531SMarcel Holtmann if (val != 0 && (val < 500 || val > 3600000)) 3602bfa3531SMarcel Holtmann return -EINVAL; 3612bfa3531SMarcel Holtmann 3622bfa3531SMarcel Holtmann hci_dev_lock(hdev); 3632bfa3531SMarcel Holtmann hdev->idle_timeout= val; 3642bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 3652bfa3531SMarcel Holtmann 3662bfa3531SMarcel Holtmann return 0; 3672bfa3531SMarcel Holtmann } 3682bfa3531SMarcel Holtmann 3692bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val) 3702bfa3531SMarcel Holtmann { 3712bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 3722bfa3531SMarcel Holtmann 3732bfa3531SMarcel Holtmann hci_dev_lock(hdev); 3742bfa3531SMarcel Holtmann *val = hdev->idle_timeout; 3752bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 3762bfa3531SMarcel Holtmann 3772bfa3531SMarcel Holtmann return 0; 3782bfa3531SMarcel Holtmann } 3792bfa3531SMarcel Holtmann 3802bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get, 3812bfa3531SMarcel Holtmann idle_timeout_set, "%llu\n"); 3822bfa3531SMarcel Holtmann 3832bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val) 3842bfa3531SMarcel Holtmann { 3852bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 3862bfa3531SMarcel Holtmann 3872bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val > hdev->sniff_max_interval) 3882bfa3531SMarcel Holtmann return -EINVAL; 3892bfa3531SMarcel Holtmann 3902bfa3531SMarcel Holtmann hci_dev_lock(hdev); 3912bfa3531SMarcel Holtmann hdev->sniff_min_interval= val; 3922bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 3932bfa3531SMarcel Holtmann 3942bfa3531SMarcel Holtmann return 0; 3952bfa3531SMarcel Holtmann } 3962bfa3531SMarcel Holtmann 3972bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val) 3982bfa3531SMarcel Holtmann { 3992bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4002bfa3531SMarcel Holtmann 4012bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4022bfa3531SMarcel Holtmann *val = hdev->sniff_min_interval; 4032bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4042bfa3531SMarcel Holtmann 4052bfa3531SMarcel Holtmann return 0; 4062bfa3531SMarcel Holtmann } 4072bfa3531SMarcel Holtmann 4082bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get, 4092bfa3531SMarcel Holtmann sniff_min_interval_set, "%llu\n"); 4102bfa3531SMarcel Holtmann 4112bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val) 4122bfa3531SMarcel Holtmann { 4132bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4142bfa3531SMarcel Holtmann 4152bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val < hdev->sniff_min_interval) 4162bfa3531SMarcel Holtmann return -EINVAL; 4172bfa3531SMarcel Holtmann 4182bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4192bfa3531SMarcel Holtmann hdev->sniff_max_interval= val; 4202bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4212bfa3531SMarcel Holtmann 4222bfa3531SMarcel Holtmann return 0; 4232bfa3531SMarcel Holtmann } 4242bfa3531SMarcel Holtmann 4252bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val) 4262bfa3531SMarcel Holtmann { 4272bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 4282bfa3531SMarcel Holtmann 4292bfa3531SMarcel Holtmann hci_dev_lock(hdev); 4302bfa3531SMarcel Holtmann *val = hdev->sniff_max_interval; 4312bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 4322bfa3531SMarcel Holtmann 4332bfa3531SMarcel Holtmann return 0; 4342bfa3531SMarcel Holtmann } 4352bfa3531SMarcel Holtmann 4362bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, 4372bfa3531SMarcel Holtmann sniff_max_interval_set, "%llu\n"); 4382bfa3531SMarcel Holtmann 439e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p) 440e7b8fc92SMarcel Holtmann { 441e7b8fc92SMarcel Holtmann struct hci_dev *hdev = f->private; 442e7b8fc92SMarcel Holtmann 443e7b8fc92SMarcel Holtmann hci_dev_lock(hdev); 444e7b8fc92SMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->static_addr); 445e7b8fc92SMarcel Holtmann hci_dev_unlock(hdev); 446e7b8fc92SMarcel Holtmann 447e7b8fc92SMarcel Holtmann return 0; 448e7b8fc92SMarcel Holtmann } 449e7b8fc92SMarcel Holtmann 450e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file) 451e7b8fc92SMarcel Holtmann { 452e7b8fc92SMarcel Holtmann return single_open(file, static_address_show, inode->i_private); 453e7b8fc92SMarcel Holtmann } 454e7b8fc92SMarcel Holtmann 455e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = { 456e7b8fc92SMarcel Holtmann .open = static_address_open, 457e7b8fc92SMarcel Holtmann .read = seq_read, 458e7b8fc92SMarcel Holtmann .llseek = seq_lseek, 459e7b8fc92SMarcel Holtmann .release = single_release, 460e7b8fc92SMarcel Holtmann }; 461e7b8fc92SMarcel Holtmann 46292202185SMarcel Holtmann static int own_address_type_set(void *data, u64 val) 46392202185SMarcel Holtmann { 46492202185SMarcel Holtmann struct hci_dev *hdev = data; 46592202185SMarcel Holtmann 46692202185SMarcel Holtmann if (val != 0 && val != 1) 46792202185SMarcel Holtmann return -EINVAL; 46892202185SMarcel Holtmann 46992202185SMarcel Holtmann hci_dev_lock(hdev); 47092202185SMarcel Holtmann hdev->own_addr_type = val; 47192202185SMarcel Holtmann hci_dev_unlock(hdev); 47292202185SMarcel Holtmann 47392202185SMarcel Holtmann return 0; 47492202185SMarcel Holtmann } 47592202185SMarcel Holtmann 47692202185SMarcel Holtmann static int own_address_type_get(void *data, u64 *val) 47792202185SMarcel Holtmann { 47892202185SMarcel Holtmann struct hci_dev *hdev = data; 47992202185SMarcel Holtmann 48092202185SMarcel Holtmann hci_dev_lock(hdev); 48192202185SMarcel Holtmann *val = hdev->own_addr_type; 48292202185SMarcel Holtmann hci_dev_unlock(hdev); 48392202185SMarcel Holtmann 48492202185SMarcel Holtmann return 0; 48592202185SMarcel Holtmann } 48692202185SMarcel Holtmann 48792202185SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get, 48892202185SMarcel Holtmann own_address_type_set, "%llu\n"); 48992202185SMarcel Holtmann 4908f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr) 4918f8625cdSMarcel Holtmann { 4928f8625cdSMarcel Holtmann struct hci_dev *hdev = f->private; 4938f8625cdSMarcel Holtmann struct list_head *p, *n; 4948f8625cdSMarcel Holtmann 4958f8625cdSMarcel Holtmann hci_dev_lock(hdev); 4968f8625cdSMarcel Holtmann list_for_each_safe(p, n, &hdev->link_keys) { 4978f8625cdSMarcel Holtmann struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list); 4988f8625cdSMarcel Holtmann seq_printf(f, "%pMR (type %u) %u %u %u %.4x %*phN %*phN\\n", 4998f8625cdSMarcel Holtmann <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, 5008f8625cdSMarcel Holtmann ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), 5018f8625cdSMarcel Holtmann 8, ltk->rand, 16, ltk->val); 5028f8625cdSMarcel Holtmann } 5038f8625cdSMarcel Holtmann hci_dev_unlock(hdev); 5048f8625cdSMarcel Holtmann 5058f8625cdSMarcel Holtmann return 0; 5068f8625cdSMarcel Holtmann } 5078f8625cdSMarcel Holtmann 5088f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file) 5098f8625cdSMarcel Holtmann { 5108f8625cdSMarcel Holtmann return single_open(file, long_term_keys_show, inode->i_private); 5118f8625cdSMarcel Holtmann } 5128f8625cdSMarcel Holtmann 5138f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = { 5148f8625cdSMarcel Holtmann .open = long_term_keys_open, 5158f8625cdSMarcel Holtmann .read = seq_read, 5168f8625cdSMarcel Holtmann .llseek = seq_lseek, 5178f8625cdSMarcel Holtmann .release = single_release, 5188f8625cdSMarcel Holtmann }; 5198f8625cdSMarcel Holtmann 5201da177e4SLinus Torvalds /* ---- HCI requests ---- */ 5211da177e4SLinus Torvalds 52242c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 5231da177e4SLinus Torvalds { 52442c6b129SJohan Hedberg BT_DBG("%s result 0x%2.2x", hdev->name, result); 52575fb0e32SJohan Hedberg 5261da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 5271da177e4SLinus Torvalds hdev->req_result = result; 5281da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 5291da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 5301da177e4SLinus Torvalds } 5311da177e4SLinus Torvalds } 5321da177e4SLinus Torvalds 5331da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 5341da177e4SLinus Torvalds { 5351da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 5361da177e4SLinus Torvalds 5371da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 5381da177e4SLinus Torvalds hdev->req_result = err; 5391da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 5401da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 5411da177e4SLinus Torvalds } 5421da177e4SLinus Torvalds } 5431da177e4SLinus Torvalds 54477a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 54577a63e0aSFengguang Wu u8 event) 54675e84b7cSJohan Hedberg { 54775e84b7cSJohan Hedberg struct hci_ev_cmd_complete *ev; 54875e84b7cSJohan Hedberg struct hci_event_hdr *hdr; 54975e84b7cSJohan Hedberg struct sk_buff *skb; 55075e84b7cSJohan Hedberg 55175e84b7cSJohan Hedberg hci_dev_lock(hdev); 55275e84b7cSJohan Hedberg 55375e84b7cSJohan Hedberg skb = hdev->recv_evt; 55475e84b7cSJohan Hedberg hdev->recv_evt = NULL; 55575e84b7cSJohan Hedberg 55675e84b7cSJohan Hedberg hci_dev_unlock(hdev); 55775e84b7cSJohan Hedberg 55875e84b7cSJohan Hedberg if (!skb) 55975e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 56075e84b7cSJohan Hedberg 56175e84b7cSJohan Hedberg if (skb->len < sizeof(*hdr)) { 56275e84b7cSJohan Hedberg BT_ERR("Too short HCI event"); 56375e84b7cSJohan Hedberg goto failed; 56475e84b7cSJohan Hedberg } 56575e84b7cSJohan Hedberg 56675e84b7cSJohan Hedberg hdr = (void *) skb->data; 56775e84b7cSJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 56875e84b7cSJohan Hedberg 5697b1abbbeSJohan Hedberg if (event) { 5707b1abbbeSJohan Hedberg if (hdr->evt != event) 5717b1abbbeSJohan Hedberg goto failed; 5727b1abbbeSJohan Hedberg return skb; 5737b1abbbeSJohan Hedberg } 5747b1abbbeSJohan Hedberg 57575e84b7cSJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 57675e84b7cSJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 57775e84b7cSJohan Hedberg goto failed; 57875e84b7cSJohan Hedberg } 57975e84b7cSJohan Hedberg 58075e84b7cSJohan Hedberg if (skb->len < sizeof(*ev)) { 58175e84b7cSJohan Hedberg BT_ERR("Too short cmd_complete event"); 58275e84b7cSJohan Hedberg goto failed; 58375e84b7cSJohan Hedberg } 58475e84b7cSJohan Hedberg 58575e84b7cSJohan Hedberg ev = (void *) skb->data; 58675e84b7cSJohan Hedberg skb_pull(skb, sizeof(*ev)); 58775e84b7cSJohan Hedberg 58875e84b7cSJohan Hedberg if (opcode == __le16_to_cpu(ev->opcode)) 58975e84b7cSJohan Hedberg return skb; 59075e84b7cSJohan Hedberg 59175e84b7cSJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 59275e84b7cSJohan Hedberg __le16_to_cpu(ev->opcode)); 59375e84b7cSJohan Hedberg 59475e84b7cSJohan Hedberg failed: 59575e84b7cSJohan Hedberg kfree_skb(skb); 59675e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 59775e84b7cSJohan Hedberg } 59875e84b7cSJohan Hedberg 5997b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 60007dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout) 60175e84b7cSJohan Hedberg { 60275e84b7cSJohan Hedberg DECLARE_WAITQUEUE(wait, current); 60375e84b7cSJohan Hedberg struct hci_request req; 60475e84b7cSJohan Hedberg int err = 0; 60575e84b7cSJohan Hedberg 60675e84b7cSJohan Hedberg BT_DBG("%s", hdev->name); 60775e84b7cSJohan Hedberg 60875e84b7cSJohan Hedberg hci_req_init(&req, hdev); 60975e84b7cSJohan Hedberg 6107b1abbbeSJohan Hedberg hci_req_add_ev(&req, opcode, plen, param, event); 61175e84b7cSJohan Hedberg 61275e84b7cSJohan Hedberg hdev->req_status = HCI_REQ_PEND; 61375e84b7cSJohan Hedberg 61475e84b7cSJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 61575e84b7cSJohan Hedberg if (err < 0) 61675e84b7cSJohan Hedberg return ERR_PTR(err); 61775e84b7cSJohan Hedberg 61875e84b7cSJohan Hedberg add_wait_queue(&hdev->req_wait_q, &wait); 61975e84b7cSJohan Hedberg set_current_state(TASK_INTERRUPTIBLE); 62075e84b7cSJohan Hedberg 62175e84b7cSJohan Hedberg schedule_timeout(timeout); 62275e84b7cSJohan Hedberg 62375e84b7cSJohan Hedberg remove_wait_queue(&hdev->req_wait_q, &wait); 62475e84b7cSJohan Hedberg 62575e84b7cSJohan Hedberg if (signal_pending(current)) 62675e84b7cSJohan Hedberg return ERR_PTR(-EINTR); 62775e84b7cSJohan Hedberg 62875e84b7cSJohan Hedberg switch (hdev->req_status) { 62975e84b7cSJohan Hedberg case HCI_REQ_DONE: 63075e84b7cSJohan Hedberg err = -bt_to_errno(hdev->req_result); 63175e84b7cSJohan Hedberg break; 63275e84b7cSJohan Hedberg 63375e84b7cSJohan Hedberg case HCI_REQ_CANCELED: 63475e84b7cSJohan Hedberg err = -hdev->req_result; 63575e84b7cSJohan Hedberg break; 63675e84b7cSJohan Hedberg 63775e84b7cSJohan Hedberg default: 63875e84b7cSJohan Hedberg err = -ETIMEDOUT; 63975e84b7cSJohan Hedberg break; 64075e84b7cSJohan Hedberg } 64175e84b7cSJohan Hedberg 64275e84b7cSJohan Hedberg hdev->req_status = hdev->req_result = 0; 64375e84b7cSJohan Hedberg 64475e84b7cSJohan Hedberg BT_DBG("%s end: err %d", hdev->name, err); 64575e84b7cSJohan Hedberg 64675e84b7cSJohan Hedberg if (err < 0) 64775e84b7cSJohan Hedberg return ERR_PTR(err); 64875e84b7cSJohan Hedberg 6497b1abbbeSJohan Hedberg return hci_get_cmd_complete(hdev, opcode, event); 6507b1abbbeSJohan Hedberg } 6517b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev); 6527b1abbbeSJohan Hedberg 6537b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 65407dc93ddSJohan Hedberg const void *param, u32 timeout) 6557b1abbbeSJohan Hedberg { 6567b1abbbeSJohan Hedberg return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); 65775e84b7cSJohan Hedberg } 65875e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync); 65975e84b7cSJohan Hedberg 6601da177e4SLinus Torvalds /* Execute request and wait for completion. */ 66101178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev, 66242c6b129SJohan Hedberg void (*func)(struct hci_request *req, 66342c6b129SJohan Hedberg unsigned long opt), 6641da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 6651da177e4SLinus Torvalds { 66642c6b129SJohan Hedberg struct hci_request req; 6671da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 6681da177e4SLinus Torvalds int err = 0; 6691da177e4SLinus Torvalds 6701da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 6711da177e4SLinus Torvalds 67242c6b129SJohan Hedberg hci_req_init(&req, hdev); 67342c6b129SJohan Hedberg 6741da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 6751da177e4SLinus Torvalds 67642c6b129SJohan Hedberg func(&req, opt); 67753cce22dSJohan Hedberg 67842c6b129SJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 67942c6b129SJohan Hedberg if (err < 0) { 68053cce22dSJohan Hedberg hdev->req_status = 0; 681920c8300SAndre Guedes 682920c8300SAndre Guedes /* ENODATA means the HCI request command queue is empty. 683920c8300SAndre Guedes * This can happen when a request with conditionals doesn't 684920c8300SAndre Guedes * trigger any commands to be sent. This is normal behavior 685920c8300SAndre Guedes * and should not trigger an error return. 68642c6b129SJohan Hedberg */ 687920c8300SAndre Guedes if (err == -ENODATA) 68842c6b129SJohan Hedberg return 0; 689920c8300SAndre Guedes 690920c8300SAndre Guedes return err; 69153cce22dSJohan Hedberg } 69253cce22dSJohan Hedberg 693bc4445c7SAndre Guedes add_wait_queue(&hdev->req_wait_q, &wait); 694bc4445c7SAndre Guedes set_current_state(TASK_INTERRUPTIBLE); 695bc4445c7SAndre Guedes 6961da177e4SLinus Torvalds schedule_timeout(timeout); 6971da177e4SLinus Torvalds 6981da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 6991da177e4SLinus Torvalds 7001da177e4SLinus Torvalds if (signal_pending(current)) 7011da177e4SLinus Torvalds return -EINTR; 7021da177e4SLinus Torvalds 7031da177e4SLinus Torvalds switch (hdev->req_status) { 7041da177e4SLinus Torvalds case HCI_REQ_DONE: 705e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 7061da177e4SLinus Torvalds break; 7071da177e4SLinus Torvalds 7081da177e4SLinus Torvalds case HCI_REQ_CANCELED: 7091da177e4SLinus Torvalds err = -hdev->req_result; 7101da177e4SLinus Torvalds break; 7111da177e4SLinus Torvalds 7121da177e4SLinus Torvalds default: 7131da177e4SLinus Torvalds err = -ETIMEDOUT; 7141da177e4SLinus Torvalds break; 7153ff50b79SStephen Hemminger } 7161da177e4SLinus Torvalds 717a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 7181da177e4SLinus Torvalds 7191da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 7201da177e4SLinus Torvalds 7211da177e4SLinus Torvalds return err; 7221da177e4SLinus Torvalds } 7231da177e4SLinus Torvalds 72401178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev, 72542c6b129SJohan Hedberg void (*req)(struct hci_request *req, 72642c6b129SJohan Hedberg unsigned long opt), 7271da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 7281da177e4SLinus Torvalds { 7291da177e4SLinus Torvalds int ret; 7301da177e4SLinus Torvalds 7317c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 7327c6a329eSMarcel Holtmann return -ENETDOWN; 7337c6a329eSMarcel Holtmann 7341da177e4SLinus Torvalds /* Serialize all requests */ 7351da177e4SLinus Torvalds hci_req_lock(hdev); 73601178cd4SJohan Hedberg ret = __hci_req_sync(hdev, req, opt, timeout); 7371da177e4SLinus Torvalds hci_req_unlock(hdev); 7381da177e4SLinus Torvalds 7391da177e4SLinus Torvalds return ret; 7401da177e4SLinus Torvalds } 7411da177e4SLinus Torvalds 74242c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt) 7431da177e4SLinus Torvalds { 74442c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 7451da177e4SLinus Torvalds 7461da177e4SLinus Torvalds /* Reset device */ 74742c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 74842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 7491da177e4SLinus Torvalds } 7501da177e4SLinus Torvalds 75142c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 7521da177e4SLinus Torvalds { 75342c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 7542455a3eaSAndrei Emeltchenko 7551da177e4SLinus Torvalds /* Read Local Supported Features */ 75642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 7571da177e4SLinus Torvalds 7581143e5a6SMarcel Holtmann /* Read Local Version */ 75942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 7602177bab5SJohan Hedberg 7612177bab5SJohan Hedberg /* Read BD Address */ 76242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 7631da177e4SLinus Torvalds } 7641da177e4SLinus Torvalds 76542c6b129SJohan Hedberg static void amp_init(struct hci_request *req) 766e61ef499SAndrei Emeltchenko { 76742c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 7682455a3eaSAndrei Emeltchenko 769e61ef499SAndrei Emeltchenko /* Read Local Version */ 77042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 7716bcbc489SAndrei Emeltchenko 772f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 773f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 774f6996cfeSMarcel Holtmann 775f6996cfeSMarcel Holtmann /* Read Local Supported Features */ 776f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 777f6996cfeSMarcel Holtmann 7786bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 77942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 780e71dfabaSAndrei Emeltchenko 781e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 78242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 7837528ca1cSMarcel Holtmann 784f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 785f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 786f38ba941SMarcel Holtmann 7877528ca1cSMarcel Holtmann /* Read Location Data */ 7887528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 789e61ef499SAndrei Emeltchenko } 790e61ef499SAndrei Emeltchenko 79142c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 792e61ef499SAndrei Emeltchenko { 79342c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 794e61ef499SAndrei Emeltchenko 795e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 796e61ef499SAndrei Emeltchenko 79711778716SAndrei Emeltchenko /* Reset */ 79811778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 79942c6b129SJohan Hedberg hci_reset_req(req, 0); 80011778716SAndrei Emeltchenko 801e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 802e61ef499SAndrei Emeltchenko case HCI_BREDR: 80342c6b129SJohan Hedberg bredr_init(req); 804e61ef499SAndrei Emeltchenko break; 805e61ef499SAndrei Emeltchenko 806e61ef499SAndrei Emeltchenko case HCI_AMP: 80742c6b129SJohan Hedberg amp_init(req); 808e61ef499SAndrei Emeltchenko break; 809e61ef499SAndrei Emeltchenko 810e61ef499SAndrei Emeltchenko default: 811e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 812e61ef499SAndrei Emeltchenko break; 813e61ef499SAndrei Emeltchenko } 814e61ef499SAndrei Emeltchenko } 815e61ef499SAndrei Emeltchenko 81642c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 8172177bab5SJohan Hedberg { 8184ca048e3SMarcel Holtmann struct hci_dev *hdev = req->hdev; 8194ca048e3SMarcel Holtmann 8202177bab5SJohan Hedberg __le16 param; 8212177bab5SJohan Hedberg __u8 flt_type; 8222177bab5SJohan Hedberg 8232177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 82442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 8252177bab5SJohan Hedberg 8262177bab5SJohan Hedberg /* Read Class of Device */ 82742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 8282177bab5SJohan Hedberg 8292177bab5SJohan Hedberg /* Read Local Name */ 83042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 8312177bab5SJohan Hedberg 8322177bab5SJohan Hedberg /* Read Voice Setting */ 83342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 8342177bab5SJohan Hedberg 835b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 836b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 837b4cb9fb2SMarcel Holtmann 8384b836f39SMarcel Holtmann /* Read Current IAC LAP */ 8394b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 8404b836f39SMarcel Holtmann 8412177bab5SJohan Hedberg /* Clear Event Filters */ 8422177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 84342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 8442177bab5SJohan Hedberg 8452177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 8462177bab5SJohan Hedberg param = __constant_cpu_to_le16(0x7d00); 84742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 8482177bab5SJohan Hedberg 8494ca048e3SMarcel Holtmann /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, 8504ca048e3SMarcel Holtmann * but it does not support page scan related HCI commands. 8514ca048e3SMarcel Holtmann */ 8524ca048e3SMarcel Holtmann if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) { 853f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 854f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 855f332ec66SJohan Hedberg } 8562177bab5SJohan Hedberg } 8572177bab5SJohan Hedberg 85842c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 8592177bab5SJohan Hedberg { 860c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 861c73eee91SJohan Hedberg 8622177bab5SJohan Hedberg /* Read LE Buffer Size */ 86342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 8642177bab5SJohan Hedberg 8652177bab5SJohan Hedberg /* Read LE Local Supported Features */ 86642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 8672177bab5SJohan Hedberg 8682177bab5SJohan Hedberg /* Read LE Advertising Channel TX Power */ 86942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 8702177bab5SJohan Hedberg 8712177bab5SJohan Hedberg /* Read LE White List Size */ 87242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 8732177bab5SJohan Hedberg 8742177bab5SJohan Hedberg /* Read LE Supported States */ 87542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 876c73eee91SJohan Hedberg 877c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 878c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 879c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 8802177bab5SJohan Hedberg } 8812177bab5SJohan Hedberg 8822177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 8832177bab5SJohan Hedberg { 8842177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 8852177bab5SJohan Hedberg return 0x02; 8862177bab5SJohan Hedberg 8872177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 8882177bab5SJohan Hedberg return 0x01; 8892177bab5SJohan Hedberg 8902177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 8912177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 8922177bab5SJohan Hedberg return 0x01; 8932177bab5SJohan Hedberg 8942177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 8952177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 8962177bab5SJohan Hedberg return 0x01; 8972177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 8982177bab5SJohan Hedberg return 0x01; 8992177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 9002177bab5SJohan Hedberg return 0x01; 9012177bab5SJohan Hedberg } 9022177bab5SJohan Hedberg 9032177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 9042177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 9052177bab5SJohan Hedberg return 0x01; 9062177bab5SJohan Hedberg 9072177bab5SJohan Hedberg return 0x00; 9082177bab5SJohan Hedberg } 9092177bab5SJohan Hedberg 91042c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 9112177bab5SJohan Hedberg { 9122177bab5SJohan Hedberg u8 mode; 9132177bab5SJohan Hedberg 91442c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 9152177bab5SJohan Hedberg 91642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 9172177bab5SJohan Hedberg } 9182177bab5SJohan Hedberg 91942c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 9202177bab5SJohan Hedberg { 92142c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 92242c6b129SJohan Hedberg 9232177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 9242177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 9252177bab5SJohan Hedberg * command otherwise. 9262177bab5SJohan Hedberg */ 9272177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 9282177bab5SJohan Hedberg 9292177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 9302177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 9312177bab5SJohan Hedberg */ 9322177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 9332177bab5SJohan Hedberg return; 9342177bab5SJohan Hedberg 9352177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 9362177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 9372177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 9382177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 9392177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 9402177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 941c7882cbdSMarcel Holtmann } else { 942c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 943c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 944c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 945c7882cbdSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 946c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 947c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 948c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 949c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 950c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 951c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 952c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 9532177bab5SJohan Hedberg } 9542177bab5SJohan Hedberg 9552177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 9562177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 9572177bab5SJohan Hedberg 9582177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 9592177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 9602177bab5SJohan Hedberg 9612177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 9622177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 9632177bab5SJohan Hedberg 9642177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 9652177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 9662177bab5SJohan Hedberg 9672177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 9682177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 9692177bab5SJohan Hedberg 9702177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 9712177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 9722177bab5SJohan Hedberg 9732177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 9742177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 9752177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 9762177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 9772177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 9782177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 9792177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 9802177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 9812177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 9822177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 9832177bab5SJohan Hedberg * Features Notification 9842177bab5SJohan Hedberg */ 9852177bab5SJohan Hedberg } 9862177bab5SJohan Hedberg 9872177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 9882177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 9892177bab5SJohan Hedberg 99042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 9912177bab5SJohan Hedberg 9922177bab5SJohan Hedberg if (lmp_le_capable(hdev)) { 9932177bab5SJohan Hedberg memset(events, 0, sizeof(events)); 9942177bab5SJohan Hedberg events[0] = 0x1f; 99542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, 9962177bab5SJohan Hedberg sizeof(events), events); 9972177bab5SJohan Hedberg } 9982177bab5SJohan Hedberg } 9992177bab5SJohan Hedberg 100042c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 10012177bab5SJohan Hedberg { 100242c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 100342c6b129SJohan Hedberg 10042177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 100542c6b129SJohan Hedberg bredr_setup(req); 100656f87901SJohan Hedberg else 100756f87901SJohan Hedberg clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 10082177bab5SJohan Hedberg 10092177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 101042c6b129SJohan Hedberg le_setup(req); 10112177bab5SJohan Hedberg 101242c6b129SJohan Hedberg hci_setup_event_mask(req); 10132177bab5SJohan Hedberg 10143f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 10153f8e2d75SJohan Hedberg * local supported commands HCI command. 10163f8e2d75SJohan Hedberg */ 10173f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 101842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 10192177bab5SJohan Hedberg 10202177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 102157af75a8SMarcel Holtmann /* When SSP is available, then the host features page 102257af75a8SMarcel Holtmann * should also be available as well. However some 102357af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 102457af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 102557af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 102657af75a8SMarcel Holtmann */ 102757af75a8SMarcel Holtmann hdev->max_page = 0x01; 102857af75a8SMarcel Holtmann 10292177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 10302177bab5SJohan Hedberg u8 mode = 0x01; 103142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 10322177bab5SJohan Hedberg sizeof(mode), &mode); 10332177bab5SJohan Hedberg } else { 10342177bab5SJohan Hedberg struct hci_cp_write_eir cp; 10352177bab5SJohan Hedberg 10362177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 10372177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 10382177bab5SJohan Hedberg 103942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 10402177bab5SJohan Hedberg } 10412177bab5SJohan Hedberg } 10422177bab5SJohan Hedberg 10432177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 104442c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 10452177bab5SJohan Hedberg 10462177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 104742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 10482177bab5SJohan Hedberg 10492177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 10502177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 10512177bab5SJohan Hedberg 10522177bab5SJohan Hedberg cp.page = 0x01; 105342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 105442c6b129SJohan Hedberg sizeof(cp), &cp); 10552177bab5SJohan Hedberg } 10562177bab5SJohan Hedberg 10572177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 10582177bab5SJohan Hedberg u8 enable = 1; 105942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 10602177bab5SJohan Hedberg &enable); 10612177bab5SJohan Hedberg } 10622177bab5SJohan Hedberg } 10632177bab5SJohan Hedberg 106442c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 10652177bab5SJohan Hedberg { 106642c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 10672177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 10682177bab5SJohan Hedberg u16 link_policy = 0; 10692177bab5SJohan Hedberg 10702177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 10712177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 10722177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 10732177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 10742177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 10752177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 10762177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 10772177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 10782177bab5SJohan Hedberg 10792177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 108042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 10812177bab5SJohan Hedberg } 10822177bab5SJohan Hedberg 108342c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 10842177bab5SJohan Hedberg { 108542c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 10862177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 10872177bab5SJohan Hedberg 1088c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 1089c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1090c73eee91SJohan Hedberg return; 1091c73eee91SJohan Hedberg 10922177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 10932177bab5SJohan Hedberg 10942177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 10952177bab5SJohan Hedberg cp.le = 0x01; 10962177bab5SJohan Hedberg cp.simul = lmp_le_br_capable(hdev); 10972177bab5SJohan Hedberg } 10982177bab5SJohan Hedberg 10992177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 110042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 11012177bab5SJohan Hedberg &cp); 11022177bab5SJohan Hedberg } 11032177bab5SJohan Hedberg 1104d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 1105d62e6d67SJohan Hedberg { 1106d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 1107d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1108d62e6d67SJohan Hedberg 1109d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 1110d62e6d67SJohan Hedberg * enable all necessary events for it. 1111d62e6d67SJohan Hedberg */ 1112d62e6d67SJohan Hedberg if (hdev->features[2][0] & 0x01) { 1113d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 1114d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 1115d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 1116d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 1117d62e6d67SJohan Hedberg } 1118d62e6d67SJohan Hedberg 1119d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 1120d62e6d67SJohan Hedberg * enable all necessary events for it. 1121d62e6d67SJohan Hedberg */ 1122d62e6d67SJohan Hedberg if (hdev->features[2][0] & 0x02) { 1123d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 1124d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 1125d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 1126d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 1127d62e6d67SJohan Hedberg } 1128d62e6d67SJohan Hedberg 1129d62e6d67SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 1130d62e6d67SJohan Hedberg } 1131d62e6d67SJohan Hedberg 113242c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 11332177bab5SJohan Hedberg { 113442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1135d2c5d77fSJohan Hedberg u8 p; 113642c6b129SJohan Hedberg 1137b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 1138b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 1139b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 1140b8f4e068SGustavo Padovan * 1141b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 1142b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 1143b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 1144b8f4e068SGustavo Padovan * command redundant anyway. 1145b8f4e068SGustavo Padovan */ 114659f45d57SJohan Hedberg if (hdev->commands[6] & 0x80) { 114759f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 114859f45d57SJohan Hedberg 114959f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 115059f45d57SJohan Hedberg cp.delete_all = 0x01; 115159f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 115259f45d57SJohan Hedberg sizeof(cp), &cp); 115359f45d57SJohan Hedberg } 115459f45d57SJohan Hedberg 11552177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 115642c6b129SJohan Hedberg hci_setup_link_policy(req); 11572177bab5SJohan Hedberg 115879830f66SMarcel Holtmann if (lmp_le_capable(hdev)) { 115979830f66SMarcel Holtmann /* If the controller has a public BD_ADDR, then by 116079830f66SMarcel Holtmann * default use that one. If this is a LE only 116179830f66SMarcel Holtmann * controller without one, default to the random 116279830f66SMarcel Holtmann * address. 116379830f66SMarcel Holtmann */ 116479830f66SMarcel Holtmann if (bacmp(&hdev->bdaddr, BDADDR_ANY)) 116579830f66SMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_PUBLIC; 116679830f66SMarcel Holtmann else 116779830f66SMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_RANDOM; 116879830f66SMarcel Holtmann 116942c6b129SJohan Hedberg hci_set_le_support(req); 117079830f66SMarcel Holtmann } 1171d2c5d77fSJohan Hedberg 1172d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 1173d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 1174d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 1175d2c5d77fSJohan Hedberg 1176d2c5d77fSJohan Hedberg cp.page = p; 1177d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 1178d2c5d77fSJohan Hedberg sizeof(cp), &cp); 1179d2c5d77fSJohan Hedberg } 11802177bab5SJohan Hedberg } 11812177bab5SJohan Hedberg 11825d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt) 11835d4e7e8dSJohan Hedberg { 11845d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 11855d4e7e8dSJohan Hedberg 1186d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 1187d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 1188d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 1189d62e6d67SJohan Hedberg 11905d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 11915d4e7e8dSJohan Hedberg if (hdev->features[2][0] & 0x04) 11925d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 11935d4e7e8dSJohan Hedberg } 11945d4e7e8dSJohan Hedberg 11952177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 11962177bab5SJohan Hedberg { 11972177bab5SJohan Hedberg int err; 11982177bab5SJohan Hedberg 11992177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 12002177bab5SJohan Hedberg if (err < 0) 12012177bab5SJohan Hedberg return err; 12022177bab5SJohan Hedberg 12032177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 12042177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 12052177bab5SJohan Hedberg * first stage init. 12062177bab5SJohan Hedberg */ 12072177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 12082177bab5SJohan Hedberg return 0; 12092177bab5SJohan Hedberg 12102177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 12112177bab5SJohan Hedberg if (err < 0) 12122177bab5SJohan Hedberg return err; 12132177bab5SJohan Hedberg 12145d4e7e8dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 12155d4e7e8dSJohan Hedberg if (err < 0) 12165d4e7e8dSJohan Hedberg return err; 12175d4e7e8dSJohan Hedberg 1218baf27f6eSMarcel Holtmann err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 1219baf27f6eSMarcel Holtmann if (err < 0) 1220baf27f6eSMarcel Holtmann return err; 1221baf27f6eSMarcel Holtmann 1222baf27f6eSMarcel Holtmann /* Only create debugfs entries during the initial setup 1223baf27f6eSMarcel Holtmann * phase and not every time the controller gets powered on. 1224baf27f6eSMarcel Holtmann */ 1225baf27f6eSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 1226baf27f6eSMarcel Holtmann return 0; 1227baf27f6eSMarcel Holtmann 1228dfb826a8SMarcel Holtmann debugfs_create_file("features", 0444, hdev->debugfs, hdev, 1229dfb826a8SMarcel Holtmann &features_fops); 1230ceeb3bc0SMarcel Holtmann debugfs_create_u16("manufacturer", 0444, hdev->debugfs, 1231ceeb3bc0SMarcel Holtmann &hdev->manufacturer); 1232ceeb3bc0SMarcel Holtmann debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); 1233ceeb3bc0SMarcel Holtmann debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); 123470afe0b8SMarcel Holtmann debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, 123570afe0b8SMarcel Holtmann &blacklist_fops); 123647219839SMarcel Holtmann debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); 123747219839SMarcel Holtmann 1238baf27f6eSMarcel Holtmann if (lmp_bredr_capable(hdev)) { 1239baf27f6eSMarcel Holtmann debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, 1240baf27f6eSMarcel Holtmann hdev, &inquiry_cache_fops); 124102d08d15SMarcel Holtmann debugfs_create_file("link_keys", 0400, hdev->debugfs, 124202d08d15SMarcel Holtmann hdev, &link_keys_fops); 124312c269d7SMarcel Holtmann debugfs_create_file("use_debug_keys", 0444, hdev->debugfs, 124412c269d7SMarcel Holtmann hdev, &use_debug_keys_fops); 1245babdbb3cSMarcel Holtmann debugfs_create_file("dev_class", 0444, hdev->debugfs, 1246babdbb3cSMarcel Holtmann hdev, &dev_class_fops); 1247041000b9SMarcel Holtmann debugfs_create_file("voice_setting", 0444, hdev->debugfs, 1248041000b9SMarcel Holtmann hdev, &voice_setting_fops); 1249baf27f6eSMarcel Holtmann } 1250baf27f6eSMarcel Holtmann 125106f5b778SMarcel Holtmann if (lmp_ssp_capable(hdev)) { 1252ebd1e33bSMarcel Holtmann debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, 1253ebd1e33bSMarcel Holtmann hdev, &auto_accept_delay_fops); 125406f5b778SMarcel Holtmann debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs, 125506f5b778SMarcel Holtmann hdev, &ssp_debug_mode_fops); 125606f5b778SMarcel Holtmann } 1257ebd1e33bSMarcel Holtmann 12582bfa3531SMarcel Holtmann if (lmp_sniff_capable(hdev)) { 12592bfa3531SMarcel Holtmann debugfs_create_file("idle_timeout", 0644, hdev->debugfs, 12602bfa3531SMarcel Holtmann hdev, &idle_timeout_fops); 12612bfa3531SMarcel Holtmann debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs, 12622bfa3531SMarcel Holtmann hdev, &sniff_min_interval_fops); 12632bfa3531SMarcel Holtmann debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs, 12642bfa3531SMarcel Holtmann hdev, &sniff_max_interval_fops); 12652bfa3531SMarcel Holtmann } 12662bfa3531SMarcel Holtmann 1267d0f729b8SMarcel Holtmann if (lmp_le_capable(hdev)) { 1268d0f729b8SMarcel Holtmann debugfs_create_u8("white_list_size", 0444, hdev->debugfs, 1269d0f729b8SMarcel Holtmann &hdev->le_white_list_size); 1270e7b8fc92SMarcel Holtmann debugfs_create_file("static_address", 0444, hdev->debugfs, 1271e7b8fc92SMarcel Holtmann hdev, &static_address_fops); 127292202185SMarcel Holtmann debugfs_create_file("own_address_type", 0644, hdev->debugfs, 127392202185SMarcel Holtmann hdev, &own_address_type_fops); 12748f8625cdSMarcel Holtmann debugfs_create_file("long_term_keys", 0400, hdev->debugfs, 12758f8625cdSMarcel Holtmann hdev, &long_term_keys_fops); 1276d0f729b8SMarcel Holtmann } 1277e7b8fc92SMarcel Holtmann 1278baf27f6eSMarcel Holtmann return 0; 12792177bab5SJohan Hedberg } 12802177bab5SJohan Hedberg 128142c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 12821da177e4SLinus Torvalds { 12831da177e4SLinus Torvalds __u8 scan = opt; 12841da177e4SLinus Torvalds 128542c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 12861da177e4SLinus Torvalds 12871da177e4SLinus Torvalds /* Inquiry and Page scans */ 128842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 12891da177e4SLinus Torvalds } 12901da177e4SLinus Torvalds 129142c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 12921da177e4SLinus Torvalds { 12931da177e4SLinus Torvalds __u8 auth = opt; 12941da177e4SLinus Torvalds 129542c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 12961da177e4SLinus Torvalds 12971da177e4SLinus Torvalds /* Authentication */ 129842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 12991da177e4SLinus Torvalds } 13001da177e4SLinus Torvalds 130142c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 13021da177e4SLinus Torvalds { 13031da177e4SLinus Torvalds __u8 encrypt = opt; 13041da177e4SLinus Torvalds 130542c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 13061da177e4SLinus Torvalds 1307e4e8e37cSMarcel Holtmann /* Encryption */ 130842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 13091da177e4SLinus Torvalds } 13101da177e4SLinus Torvalds 131142c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 1312e4e8e37cSMarcel Holtmann { 1313e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1314e4e8e37cSMarcel Holtmann 131542c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1316e4e8e37cSMarcel Holtmann 1317e4e8e37cSMarcel Holtmann /* Default link policy */ 131842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1319e4e8e37cSMarcel Holtmann } 1320e4e8e37cSMarcel Holtmann 13211da177e4SLinus Torvalds /* Get HCI device by index. 13221da177e4SLinus Torvalds * Device is held on return. */ 13231da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 13241da177e4SLinus Torvalds { 13258035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 13261da177e4SLinus Torvalds 13271da177e4SLinus Torvalds BT_DBG("%d", index); 13281da177e4SLinus Torvalds 13291da177e4SLinus Torvalds if (index < 0) 13301da177e4SLinus Torvalds return NULL; 13311da177e4SLinus Torvalds 13321da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 13338035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 13341da177e4SLinus Torvalds if (d->id == index) { 13351da177e4SLinus Torvalds hdev = hci_dev_hold(d); 13361da177e4SLinus Torvalds break; 13371da177e4SLinus Torvalds } 13381da177e4SLinus Torvalds } 13391da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 13401da177e4SLinus Torvalds return hdev; 13411da177e4SLinus Torvalds } 13421da177e4SLinus Torvalds 13431da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1344ff9ef578SJohan Hedberg 134530dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 134630dc78e1SJohan Hedberg { 134730dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 134830dc78e1SJohan Hedberg 13496fbe195dSAndre Guedes switch (discov->state) { 1350343f935bSAndre Guedes case DISCOVERY_FINDING: 13516fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 135230dc78e1SJohan Hedberg return true; 135330dc78e1SJohan Hedberg 13546fbe195dSAndre Guedes default: 135530dc78e1SJohan Hedberg return false; 135630dc78e1SJohan Hedberg } 13576fbe195dSAndre Guedes } 135830dc78e1SJohan Hedberg 1359ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1360ff9ef578SJohan Hedberg { 1361ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1362ff9ef578SJohan Hedberg 1363ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 1364ff9ef578SJohan Hedberg return; 1365ff9ef578SJohan Hedberg 1366ff9ef578SJohan Hedberg switch (state) { 1367ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 13687b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 1369ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1370ff9ef578SJohan Hedberg break; 1371ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1372ff9ef578SJohan Hedberg break; 1373343f935bSAndre Guedes case DISCOVERY_FINDING: 1374ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1375ff9ef578SJohan Hedberg break; 137630dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 137730dc78e1SJohan Hedberg break; 1378ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1379ff9ef578SJohan Hedberg break; 1380ff9ef578SJohan Hedberg } 1381ff9ef578SJohan Hedberg 1382ff9ef578SJohan Hedberg hdev->discovery.state = state; 1383ff9ef578SJohan Hedberg } 1384ff9ef578SJohan Hedberg 13851f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 13861da177e4SLinus Torvalds { 138730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1388b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 13891da177e4SLinus Torvalds 1390561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1391561aafbcSJohan Hedberg list_del(&p->all); 1392b57c1a56SJohan Hedberg kfree(p); 13931da177e4SLinus Torvalds } 1394561aafbcSJohan Hedberg 1395561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1396561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 13971da177e4SLinus Torvalds } 13981da177e4SLinus Torvalds 1399a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1400a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 14011da177e4SLinus Torvalds { 140230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 14031da177e4SLinus Torvalds struct inquiry_entry *e; 14041da177e4SLinus Torvalds 14056ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 14061da177e4SLinus Torvalds 1407561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 14081da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 14091da177e4SLinus Torvalds return e; 14101da177e4SLinus Torvalds } 14111da177e4SLinus Torvalds 1412b57c1a56SJohan Hedberg return NULL; 1413b57c1a56SJohan Hedberg } 1414b57c1a56SJohan Hedberg 1415561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1416561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1417561aafbcSJohan Hedberg { 141830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1419561aafbcSJohan Hedberg struct inquiry_entry *e; 1420561aafbcSJohan Hedberg 14216ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1422561aafbcSJohan Hedberg 1423561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1424561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1425561aafbcSJohan Hedberg return e; 1426561aafbcSJohan Hedberg } 1427561aafbcSJohan Hedberg 1428561aafbcSJohan Hedberg return NULL; 1429561aafbcSJohan Hedberg } 1430561aafbcSJohan Hedberg 143130dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 143230dc78e1SJohan Hedberg bdaddr_t *bdaddr, 143330dc78e1SJohan Hedberg int state) 143430dc78e1SJohan Hedberg { 143530dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 143630dc78e1SJohan Hedberg struct inquiry_entry *e; 143730dc78e1SJohan Hedberg 14386ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 143930dc78e1SJohan Hedberg 144030dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 144130dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 144230dc78e1SJohan Hedberg return e; 144330dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 144430dc78e1SJohan Hedberg return e; 144530dc78e1SJohan Hedberg } 144630dc78e1SJohan Hedberg 144730dc78e1SJohan Hedberg return NULL; 144830dc78e1SJohan Hedberg } 144930dc78e1SJohan Hedberg 1450a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1451a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1452a3d4e20aSJohan Hedberg { 1453a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1454a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1455a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1456a3d4e20aSJohan Hedberg 1457a3d4e20aSJohan Hedberg list_del(&ie->list); 1458a3d4e20aSJohan Hedberg 1459a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1460a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1461a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1462a3d4e20aSJohan Hedberg break; 1463a3d4e20aSJohan Hedberg pos = &p->list; 1464a3d4e20aSJohan Hedberg } 1465a3d4e20aSJohan Hedberg 1466a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1467a3d4e20aSJohan Hedberg } 1468a3d4e20aSJohan Hedberg 14693175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1470388fc8faSJohan Hedberg bool name_known, bool *ssp) 14711da177e4SLinus Torvalds { 147230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 147370f23020SAndrei Emeltchenko struct inquiry_entry *ie; 14741da177e4SLinus Torvalds 14756ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 14761da177e4SLinus Torvalds 14772b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 14782b2fec4dSSzymon Janc 1479388fc8faSJohan Hedberg if (ssp) 1480388fc8faSJohan Hedberg *ssp = data->ssp_mode; 1481388fc8faSJohan Hedberg 148270f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1483a3d4e20aSJohan Hedberg if (ie) { 1484388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 1485388fc8faSJohan Hedberg *ssp = true; 1486388fc8faSJohan Hedberg 1487a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1488a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1489a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1490a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1491a3d4e20aSJohan Hedberg } 1492a3d4e20aSJohan Hedberg 1493561aafbcSJohan Hedberg goto update; 1494a3d4e20aSJohan Hedberg } 1495561aafbcSJohan Hedberg 14961da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 149770f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 149870f23020SAndrei Emeltchenko if (!ie) 14993175405bSJohan Hedberg return false; 150070f23020SAndrei Emeltchenko 1501561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1502561aafbcSJohan Hedberg 1503561aafbcSJohan Hedberg if (name_known) { 1504561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1505561aafbcSJohan Hedberg } else { 1506561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1507561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1508561aafbcSJohan Hedberg } 1509561aafbcSJohan Hedberg 1510561aafbcSJohan Hedberg update: 1511561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1512561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1513561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1514561aafbcSJohan Hedberg list_del(&ie->list); 15151da177e4SLinus Torvalds } 15161da177e4SLinus Torvalds 151770f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 151870f23020SAndrei Emeltchenko ie->timestamp = jiffies; 15191da177e4SLinus Torvalds cache->timestamp = jiffies; 15203175405bSJohan Hedberg 15213175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 15223175405bSJohan Hedberg return false; 15233175405bSJohan Hedberg 15243175405bSJohan Hedberg return true; 15251da177e4SLinus Torvalds } 15261da177e4SLinus Torvalds 15271da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 15281da177e4SLinus Torvalds { 152930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 15301da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 15311da177e4SLinus Torvalds struct inquiry_entry *e; 15321da177e4SLinus Torvalds int copied = 0; 15331da177e4SLinus Torvalds 1534561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 15351da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1536b57c1a56SJohan Hedberg 1537b57c1a56SJohan Hedberg if (copied >= num) 1538b57c1a56SJohan Hedberg break; 1539b57c1a56SJohan Hedberg 15401da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 15411da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 15421da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 15431da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 15441da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 15451da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1546b57c1a56SJohan Hedberg 15471da177e4SLinus Torvalds info++; 1548b57c1a56SJohan Hedberg copied++; 15491da177e4SLinus Torvalds } 15501da177e4SLinus Torvalds 15511da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 15521da177e4SLinus Torvalds return copied; 15531da177e4SLinus Torvalds } 15541da177e4SLinus Torvalds 155542c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 15561da177e4SLinus Torvalds { 15571da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 155842c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 15591da177e4SLinus Torvalds struct hci_cp_inquiry cp; 15601da177e4SLinus Torvalds 15611da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 15621da177e4SLinus Torvalds 15631da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 15641da177e4SLinus Torvalds return; 15651da177e4SLinus Torvalds 15661da177e4SLinus Torvalds /* Start Inquiry */ 15671da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 15681da177e4SLinus Torvalds cp.length = ir->length; 15691da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 157042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 15711da177e4SLinus Torvalds } 15721da177e4SLinus Torvalds 15733e13fa1eSAndre Guedes static int wait_inquiry(void *word) 15743e13fa1eSAndre Guedes { 15753e13fa1eSAndre Guedes schedule(); 15763e13fa1eSAndre Guedes return signal_pending(current); 15773e13fa1eSAndre Guedes } 15783e13fa1eSAndre Guedes 15791da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 15801da177e4SLinus Torvalds { 15811da177e4SLinus Torvalds __u8 __user *ptr = arg; 15821da177e4SLinus Torvalds struct hci_inquiry_req ir; 15831da177e4SLinus Torvalds struct hci_dev *hdev; 15841da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 15851da177e4SLinus Torvalds long timeo; 15861da177e4SLinus Torvalds __u8 *buf; 15871da177e4SLinus Torvalds 15881da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 15891da177e4SLinus Torvalds return -EFAULT; 15901da177e4SLinus Torvalds 15915a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 15925a08ecceSAndrei Emeltchenko if (!hdev) 15931da177e4SLinus Torvalds return -ENODEV; 15941da177e4SLinus Torvalds 15950736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 15960736cfa8SMarcel Holtmann err = -EBUSY; 15970736cfa8SMarcel Holtmann goto done; 15980736cfa8SMarcel Holtmann } 15990736cfa8SMarcel Holtmann 16005b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 16015b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 16025b69bef5SMarcel Holtmann goto done; 16035b69bef5SMarcel Holtmann } 16045b69bef5SMarcel Holtmann 160556f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 160656f87901SJohan Hedberg err = -EOPNOTSUPP; 160756f87901SJohan Hedberg goto done; 160856f87901SJohan Hedberg } 160956f87901SJohan Hedberg 161009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 16111da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1612a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 16131f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 16141da177e4SLinus Torvalds do_inquiry = 1; 16151da177e4SLinus Torvalds } 161609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 16171da177e4SLinus Torvalds 161804837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 161970f23020SAndrei Emeltchenko 162070f23020SAndrei Emeltchenko if (do_inquiry) { 162101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 162201178cd4SJohan Hedberg timeo); 162370f23020SAndrei Emeltchenko if (err < 0) 16241da177e4SLinus Torvalds goto done; 16253e13fa1eSAndre Guedes 16263e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 16273e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 16283e13fa1eSAndre Guedes */ 16293e13fa1eSAndre Guedes if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, 16303e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 16313e13fa1eSAndre Guedes return -EINTR; 163270f23020SAndrei Emeltchenko } 16331da177e4SLinus Torvalds 16348fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 16358fc9ced3SGustavo Padovan * 255 entries 16368fc9ced3SGustavo Padovan */ 16371da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 16381da177e4SLinus Torvalds 16391da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 16401da177e4SLinus Torvalds * copy it to the user space. 16411da177e4SLinus Torvalds */ 164270f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 164370f23020SAndrei Emeltchenko if (!buf) { 16441da177e4SLinus Torvalds err = -ENOMEM; 16451da177e4SLinus Torvalds goto done; 16461da177e4SLinus Torvalds } 16471da177e4SLinus Torvalds 164809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 16491da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 165009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 16511da177e4SLinus Torvalds 16521da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 16531da177e4SLinus Torvalds 16541da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 16551da177e4SLinus Torvalds ptr += sizeof(ir); 16561da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 16571da177e4SLinus Torvalds ir.num_rsp)) 16581da177e4SLinus Torvalds err = -EFAULT; 16591da177e4SLinus Torvalds } else 16601da177e4SLinus Torvalds err = -EFAULT; 16611da177e4SLinus Torvalds 16621da177e4SLinus Torvalds kfree(buf); 16631da177e4SLinus Torvalds 16641da177e4SLinus Torvalds done: 16651da177e4SLinus Torvalds hci_dev_put(hdev); 16661da177e4SLinus Torvalds return err; 16671da177e4SLinus Torvalds } 16681da177e4SLinus Torvalds 1669cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 16701da177e4SLinus Torvalds { 16711da177e4SLinus Torvalds int ret = 0; 16721da177e4SLinus Torvalds 16731da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 16741da177e4SLinus Torvalds 16751da177e4SLinus Torvalds hci_req_lock(hdev); 16761da177e4SLinus Torvalds 167794324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 167894324962SJohan Hovold ret = -ENODEV; 167994324962SJohan Hovold goto done; 168094324962SJohan Hovold } 168194324962SJohan Hovold 1682a5c8f270SMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 1683a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1684a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1685bf543036SJohan Hedberg */ 1686a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 1687611b30f7SMarcel Holtmann ret = -ERFKILL; 1688611b30f7SMarcel Holtmann goto done; 1689611b30f7SMarcel Holtmann } 1690611b30f7SMarcel Holtmann 1691a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 1692a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 1693a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1694a5c8f270SMarcel Holtmann * or not. 1695a5c8f270SMarcel Holtmann * 1696a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1697a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1698a5c8f270SMarcel Holtmann */ 1699a5c8f270SMarcel Holtmann if (hdev->dev_type == HCI_BREDR && 1700a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1701a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1702a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1703a5c8f270SMarcel Holtmann goto done; 1704a5c8f270SMarcel Holtmann } 1705a5c8f270SMarcel Holtmann } 1706a5c8f270SMarcel Holtmann 17071da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 17081da177e4SLinus Torvalds ret = -EALREADY; 17091da177e4SLinus Torvalds goto done; 17101da177e4SLinus Torvalds } 17111da177e4SLinus Torvalds 17121da177e4SLinus Torvalds if (hdev->open(hdev)) { 17131da177e4SLinus Torvalds ret = -EIO; 17141da177e4SLinus Torvalds goto done; 17151da177e4SLinus Torvalds } 17161da177e4SLinus Torvalds 17171da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 17181da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1719f41c70c4SMarcel Holtmann 1720f41c70c4SMarcel Holtmann if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags)) 1721f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1722f41c70c4SMarcel Holtmann 1723f41c70c4SMarcel Holtmann if (!ret) { 1724f41c70c4SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 1725f41c70c4SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 1726f41c70c4SMarcel Holtmann 17270736cfa8SMarcel Holtmann if (!test_bit(HCI_RAW, &hdev->flags) && 17280736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 17292177bab5SJohan Hedberg ret = __hci_init(hdev); 17301da177e4SLinus Torvalds } 17311da177e4SLinus Torvalds 1732f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1733f41c70c4SMarcel Holtmann 17341da177e4SLinus Torvalds if (!ret) { 17351da177e4SLinus Torvalds hci_dev_hold(hdev); 17361da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 17371da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 1738bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 17390736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 17401514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 174109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1742744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 174309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 174456e5cb86SJohan Hedberg } 17451da177e4SLinus Torvalds } else { 17461da177e4SLinus Torvalds /* Init failed, cleanup */ 17473eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1748c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 1749b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 17501da177e4SLinus Torvalds 17511da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 17521da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 17531da177e4SLinus Torvalds 17541da177e4SLinus Torvalds if (hdev->flush) 17551da177e4SLinus Torvalds hdev->flush(hdev); 17561da177e4SLinus Torvalds 17571da177e4SLinus Torvalds if (hdev->sent_cmd) { 17581da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 17591da177e4SLinus Torvalds hdev->sent_cmd = NULL; 17601da177e4SLinus Torvalds } 17611da177e4SLinus Torvalds 17621da177e4SLinus Torvalds hdev->close(hdev); 17631da177e4SLinus Torvalds hdev->flags = 0; 17641da177e4SLinus Torvalds } 17651da177e4SLinus Torvalds 17661da177e4SLinus Torvalds done: 17671da177e4SLinus Torvalds hci_req_unlock(hdev); 17681da177e4SLinus Torvalds return ret; 17691da177e4SLinus Torvalds } 17701da177e4SLinus Torvalds 1771cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 1772cbed0ca1SJohan Hedberg 1773cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 1774cbed0ca1SJohan Hedberg { 1775cbed0ca1SJohan Hedberg struct hci_dev *hdev; 1776cbed0ca1SJohan Hedberg int err; 1777cbed0ca1SJohan Hedberg 1778cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 1779cbed0ca1SJohan Hedberg if (!hdev) 1780cbed0ca1SJohan Hedberg return -ENODEV; 1781cbed0ca1SJohan Hedberg 1782e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 1783e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 1784e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 1785e1d08f40SJohan Hedberg * completed. 1786e1d08f40SJohan Hedberg */ 1787e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1788e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 1789e1d08f40SJohan Hedberg 1790a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 1791a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 1792a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 1793a5c8f270SMarcel Holtmann */ 1794e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 1795e1d08f40SJohan Hedberg 1796cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 1797cbed0ca1SJohan Hedberg 1798cbed0ca1SJohan Hedberg hci_dev_put(hdev); 1799cbed0ca1SJohan Hedberg 1800cbed0ca1SJohan Hedberg return err; 1801cbed0ca1SJohan Hedberg } 1802cbed0ca1SJohan Hedberg 18031da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 18041da177e4SLinus Torvalds { 18051da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 18061da177e4SLinus Torvalds 180778c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 180878c04c0bSVinicius Costa Gomes 18091da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 18101da177e4SLinus Torvalds hci_req_lock(hdev); 18111da177e4SLinus Torvalds 18121da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 1813b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 18141da177e4SLinus Torvalds hci_req_unlock(hdev); 18151da177e4SLinus Torvalds return 0; 18161da177e4SLinus Torvalds } 18171da177e4SLinus Torvalds 18183eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 18193eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1820b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 18211da177e4SLinus Torvalds 182216ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 1823e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 182416ab91abSJohan Hedberg hdev->discov_timeout = 0; 18255e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 1826310a3d48SMarcel Holtmann clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 182716ab91abSJohan Hedberg } 182816ab91abSJohan Hedberg 1829a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 18307d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 18317d78525dSJohan Hedberg 18327ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 18337ba8b4beSAndre Guedes 183409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 18351f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 18361da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 183709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18381da177e4SLinus Torvalds 18391da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 18401da177e4SLinus Torvalds 18411da177e4SLinus Torvalds if (hdev->flush) 18421da177e4SLinus Torvalds hdev->flush(hdev); 18431da177e4SLinus Torvalds 18441da177e4SLinus Torvalds /* Reset device */ 18451da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 18461da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 18478af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 18483a6afbd2SMarcel Holtmann !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 1849a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 18501da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 185101178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 18521da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 18531da177e4SLinus Torvalds } 18541da177e4SLinus Torvalds 1855c347b765SGustavo F. Padovan /* flush cmd work */ 1856c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 18571da177e4SLinus Torvalds 18581da177e4SLinus Torvalds /* Drop queues */ 18591da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 18601da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 18611da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 18621da177e4SLinus Torvalds 18631da177e4SLinus Torvalds /* Drop last sent command */ 18641da177e4SLinus Torvalds if (hdev->sent_cmd) { 1865b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 18661da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 18671da177e4SLinus Torvalds hdev->sent_cmd = NULL; 18681da177e4SLinus Torvalds } 18691da177e4SLinus Torvalds 1870b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 1871b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 1872b6ddb638SJohan Hedberg 18731da177e4SLinus Torvalds /* After this point our queues are empty 18741da177e4SLinus Torvalds * and no tasks are scheduled. */ 18751da177e4SLinus Torvalds hdev->close(hdev); 18761da177e4SLinus Torvalds 187735b973c9SJohan Hedberg /* Clear flags */ 187835b973c9SJohan Hedberg hdev->flags = 0; 187935b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 188035b973c9SJohan Hedberg 188193c311a0SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 188293c311a0SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 188309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1884744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 188509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18868ee56540SMarcel Holtmann } 188793c311a0SMarcel Holtmann } 18885add6af8SJohan Hedberg 1889ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 1890536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 1891ced5c338SAndrei Emeltchenko 1892e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 189309b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 1894e59fda8dSJohan Hedberg 18951da177e4SLinus Torvalds hci_req_unlock(hdev); 18961da177e4SLinus Torvalds 18971da177e4SLinus Torvalds hci_dev_put(hdev); 18981da177e4SLinus Torvalds return 0; 18991da177e4SLinus Torvalds } 19001da177e4SLinus Torvalds 19011da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 19021da177e4SLinus Torvalds { 19031da177e4SLinus Torvalds struct hci_dev *hdev; 19041da177e4SLinus Torvalds int err; 19051da177e4SLinus Torvalds 190670f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 190770f23020SAndrei Emeltchenko if (!hdev) 19081da177e4SLinus Torvalds return -ENODEV; 19098ee56540SMarcel Holtmann 19100736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 19110736cfa8SMarcel Holtmann err = -EBUSY; 19120736cfa8SMarcel Holtmann goto done; 19130736cfa8SMarcel Holtmann } 19140736cfa8SMarcel Holtmann 19158ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 19168ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 19178ee56540SMarcel Holtmann 19181da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 19198ee56540SMarcel Holtmann 19200736cfa8SMarcel Holtmann done: 19211da177e4SLinus Torvalds hci_dev_put(hdev); 19221da177e4SLinus Torvalds return err; 19231da177e4SLinus Torvalds } 19241da177e4SLinus Torvalds 19251da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 19261da177e4SLinus Torvalds { 19271da177e4SLinus Torvalds struct hci_dev *hdev; 19281da177e4SLinus Torvalds int ret = 0; 19291da177e4SLinus Torvalds 193070f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 193170f23020SAndrei Emeltchenko if (!hdev) 19321da177e4SLinus Torvalds return -ENODEV; 19331da177e4SLinus Torvalds 19341da177e4SLinus Torvalds hci_req_lock(hdev); 19351da177e4SLinus Torvalds 1936808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 1937808a049eSMarcel Holtmann ret = -ENETDOWN; 19381da177e4SLinus Torvalds goto done; 1939808a049eSMarcel Holtmann } 19401da177e4SLinus Torvalds 19410736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 19420736cfa8SMarcel Holtmann ret = -EBUSY; 19430736cfa8SMarcel Holtmann goto done; 19440736cfa8SMarcel Holtmann } 19450736cfa8SMarcel Holtmann 19461da177e4SLinus Torvalds /* Drop queues */ 19471da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 19481da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 19491da177e4SLinus Torvalds 195009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 19511f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 19521da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 195309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 19541da177e4SLinus Torvalds 19551da177e4SLinus Torvalds if (hdev->flush) 19561da177e4SLinus Torvalds hdev->flush(hdev); 19571da177e4SLinus Torvalds 19581da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 19596ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 19601da177e4SLinus Torvalds 19611da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 196201178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 19631da177e4SLinus Torvalds 19641da177e4SLinus Torvalds done: 19651da177e4SLinus Torvalds hci_req_unlock(hdev); 19661da177e4SLinus Torvalds hci_dev_put(hdev); 19671da177e4SLinus Torvalds return ret; 19681da177e4SLinus Torvalds } 19691da177e4SLinus Torvalds 19701da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 19711da177e4SLinus Torvalds { 19721da177e4SLinus Torvalds struct hci_dev *hdev; 19731da177e4SLinus Torvalds int ret = 0; 19741da177e4SLinus Torvalds 197570f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 197670f23020SAndrei Emeltchenko if (!hdev) 19771da177e4SLinus Torvalds return -ENODEV; 19781da177e4SLinus Torvalds 19790736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 19800736cfa8SMarcel Holtmann ret = -EBUSY; 19810736cfa8SMarcel Holtmann goto done; 19820736cfa8SMarcel Holtmann } 19830736cfa8SMarcel Holtmann 19841da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 19851da177e4SLinus Torvalds 19860736cfa8SMarcel Holtmann done: 19871da177e4SLinus Torvalds hci_dev_put(hdev); 19881da177e4SLinus Torvalds return ret; 19891da177e4SLinus Torvalds } 19901da177e4SLinus Torvalds 19911da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 19921da177e4SLinus Torvalds { 19931da177e4SLinus Torvalds struct hci_dev *hdev; 19941da177e4SLinus Torvalds struct hci_dev_req dr; 19951da177e4SLinus Torvalds int err = 0; 19961da177e4SLinus Torvalds 19971da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 19981da177e4SLinus Torvalds return -EFAULT; 19991da177e4SLinus Torvalds 200070f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 200170f23020SAndrei Emeltchenko if (!hdev) 20021da177e4SLinus Torvalds return -ENODEV; 20031da177e4SLinus Torvalds 20040736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 20050736cfa8SMarcel Holtmann err = -EBUSY; 20060736cfa8SMarcel Holtmann goto done; 20070736cfa8SMarcel Holtmann } 20080736cfa8SMarcel Holtmann 20095b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 20105b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 20115b69bef5SMarcel Holtmann goto done; 20125b69bef5SMarcel Holtmann } 20135b69bef5SMarcel Holtmann 201456f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 201556f87901SJohan Hedberg err = -EOPNOTSUPP; 201656f87901SJohan Hedberg goto done; 201756f87901SJohan Hedberg } 201856f87901SJohan Hedberg 20191da177e4SLinus Torvalds switch (cmd) { 20201da177e4SLinus Torvalds case HCISETAUTH: 202101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 20225f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 20231da177e4SLinus Torvalds break; 20241da177e4SLinus Torvalds 20251da177e4SLinus Torvalds case HCISETENCRYPT: 20261da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 20271da177e4SLinus Torvalds err = -EOPNOTSUPP; 20281da177e4SLinus Torvalds break; 20291da177e4SLinus Torvalds } 20301da177e4SLinus Torvalds 20311da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 20321da177e4SLinus Torvalds /* Auth must be enabled first */ 203301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 20345f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 20351da177e4SLinus Torvalds if (err) 20361da177e4SLinus Torvalds break; 20371da177e4SLinus Torvalds } 20381da177e4SLinus Torvalds 203901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 20405f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 20411da177e4SLinus Torvalds break; 20421da177e4SLinus Torvalds 20431da177e4SLinus Torvalds case HCISETSCAN: 204401178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 20455f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 20461da177e4SLinus Torvalds break; 20471da177e4SLinus Torvalds 20481da177e4SLinus Torvalds case HCISETLINKPOL: 204901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 20505f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 20511da177e4SLinus Torvalds break; 20521da177e4SLinus Torvalds 20531da177e4SLinus Torvalds case HCISETLINKMODE: 2054e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 2055e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 2056e4e8e37cSMarcel Holtmann break; 2057e4e8e37cSMarcel Holtmann 2058e4e8e37cSMarcel Holtmann case HCISETPTYPE: 2059e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 20601da177e4SLinus Torvalds break; 20611da177e4SLinus Torvalds 20621da177e4SLinus Torvalds case HCISETACLMTU: 20631da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 20641da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 20651da177e4SLinus Torvalds break; 20661da177e4SLinus Torvalds 20671da177e4SLinus Torvalds case HCISETSCOMTU: 20681da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 20691da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 20701da177e4SLinus Torvalds break; 20711da177e4SLinus Torvalds 20721da177e4SLinus Torvalds default: 20731da177e4SLinus Torvalds err = -EINVAL; 20741da177e4SLinus Torvalds break; 20751da177e4SLinus Torvalds } 2076e4e8e37cSMarcel Holtmann 20770736cfa8SMarcel Holtmann done: 20781da177e4SLinus Torvalds hci_dev_put(hdev); 20791da177e4SLinus Torvalds return err; 20801da177e4SLinus Torvalds } 20811da177e4SLinus Torvalds 20821da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 20831da177e4SLinus Torvalds { 20848035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 20851da177e4SLinus Torvalds struct hci_dev_list_req *dl; 20861da177e4SLinus Torvalds struct hci_dev_req *dr; 20871da177e4SLinus Torvalds int n = 0, size, err; 20881da177e4SLinus Torvalds __u16 dev_num; 20891da177e4SLinus Torvalds 20901da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 20911da177e4SLinus Torvalds return -EFAULT; 20921da177e4SLinus Torvalds 20931da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 20941da177e4SLinus Torvalds return -EINVAL; 20951da177e4SLinus Torvalds 20961da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 20971da177e4SLinus Torvalds 209870f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 209970f23020SAndrei Emeltchenko if (!dl) 21001da177e4SLinus Torvalds return -ENOMEM; 21011da177e4SLinus Torvalds 21021da177e4SLinus Torvalds dr = dl->dev_req; 21031da177e4SLinus Torvalds 2104f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 21058035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 2106a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2107e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 2108c542a06cSJohan Hedberg 2109a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2110a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2111c542a06cSJohan Hedberg 21121da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 21131da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 2114c542a06cSJohan Hedberg 21151da177e4SLinus Torvalds if (++n >= dev_num) 21161da177e4SLinus Torvalds break; 21171da177e4SLinus Torvalds } 2118f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 21191da177e4SLinus Torvalds 21201da177e4SLinus Torvalds dl->dev_num = n; 21211da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 21221da177e4SLinus Torvalds 21231da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 21241da177e4SLinus Torvalds kfree(dl); 21251da177e4SLinus Torvalds 21261da177e4SLinus Torvalds return err ? -EFAULT : 0; 21271da177e4SLinus Torvalds } 21281da177e4SLinus Torvalds 21291da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 21301da177e4SLinus Torvalds { 21311da177e4SLinus Torvalds struct hci_dev *hdev; 21321da177e4SLinus Torvalds struct hci_dev_info di; 21331da177e4SLinus Torvalds int err = 0; 21341da177e4SLinus Torvalds 21351da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 21361da177e4SLinus Torvalds return -EFAULT; 21371da177e4SLinus Torvalds 213870f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 213970f23020SAndrei Emeltchenko if (!hdev) 21401da177e4SLinus Torvalds return -ENODEV; 21411da177e4SLinus Torvalds 2142a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 21433243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 2144ab81cbf9SJohan Hedberg 2145a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2146a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2147c542a06cSJohan Hedberg 21481da177e4SLinus Torvalds strcpy(di.name, hdev->name); 21491da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 215060f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 21511da177e4SLinus Torvalds di.flags = hdev->flags; 21521da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2153572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 21541da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 21551da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 21561da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 21571da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2158572c7f84SJohan Hedberg } else { 2159572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2160572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2161572c7f84SJohan Hedberg di.sco_mtu = 0; 2162572c7f84SJohan Hedberg di.sco_pkts = 0; 2163572c7f84SJohan Hedberg } 21641da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 21651da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 21661da177e4SLinus Torvalds 21671da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 21681da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 21691da177e4SLinus Torvalds 21701da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 21711da177e4SLinus Torvalds err = -EFAULT; 21721da177e4SLinus Torvalds 21731da177e4SLinus Torvalds hci_dev_put(hdev); 21741da177e4SLinus Torvalds 21751da177e4SLinus Torvalds return err; 21761da177e4SLinus Torvalds } 21771da177e4SLinus Torvalds 21781da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 21791da177e4SLinus Torvalds 2180611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2181611b30f7SMarcel Holtmann { 2182611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2183611b30f7SMarcel Holtmann 2184611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2185611b30f7SMarcel Holtmann 21860736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 21870736cfa8SMarcel Holtmann return -EBUSY; 21880736cfa8SMarcel Holtmann 21895e130367SJohan Hedberg if (blocked) { 21905e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 2191bf543036SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 2192611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 21935e130367SJohan Hedberg } else { 21945e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 21955e130367SJohan Hedberg } 2196611b30f7SMarcel Holtmann 2197611b30f7SMarcel Holtmann return 0; 2198611b30f7SMarcel Holtmann } 2199611b30f7SMarcel Holtmann 2200611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2201611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2202611b30f7SMarcel Holtmann }; 2203611b30f7SMarcel Holtmann 2204ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2205ab81cbf9SJohan Hedberg { 2206ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 220796570ffcSJohan Hedberg int err; 2208ab81cbf9SJohan Hedberg 2209ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2210ab81cbf9SJohan Hedberg 2211cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 221296570ffcSJohan Hedberg if (err < 0) { 221396570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 2214ab81cbf9SJohan Hedberg return; 221596570ffcSJohan Hedberg } 2216ab81cbf9SJohan Hedberg 2217a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2218a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2219a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2220a5c8f270SMarcel Holtmann */ 2221a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 2222a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 2223a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2224a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2225bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2226bf543036SJohan Hedberg hci_dev_do_close(hdev); 2227bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 222819202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 222919202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2230bf543036SJohan Hedberg } 2231ab81cbf9SJohan Hedberg 2232a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 2233744cf19eSJohan Hedberg mgmt_index_added(hdev); 2234ab81cbf9SJohan Hedberg } 2235ab81cbf9SJohan Hedberg 2236ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2237ab81cbf9SJohan Hedberg { 22383243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 22393243553fSJohan Hedberg power_off.work); 2240ab81cbf9SJohan Hedberg 2241ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2242ab81cbf9SJohan Hedberg 22438ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2244ab81cbf9SJohan Hedberg } 2245ab81cbf9SJohan Hedberg 224616ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 224716ab91abSJohan Hedberg { 224816ab91abSJohan Hedberg struct hci_dev *hdev; 224916ab91abSJohan Hedberg 225016ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 225116ab91abSJohan Hedberg 225216ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 225316ab91abSJohan Hedberg 2254d1967ff8SMarcel Holtmann mgmt_discoverable_timeout(hdev); 225516ab91abSJohan Hedberg } 225616ab91abSJohan Hedberg 22572aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 22582aeb9a1aSJohan Hedberg { 22594821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 22602aeb9a1aSJohan Hedberg 22614821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 22624821002cSJohan Hedberg list_del(&uuid->list); 22632aeb9a1aSJohan Hedberg kfree(uuid); 22642aeb9a1aSJohan Hedberg } 22652aeb9a1aSJohan Hedberg 22662aeb9a1aSJohan Hedberg return 0; 22672aeb9a1aSJohan Hedberg } 22682aeb9a1aSJohan Hedberg 226955ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 227055ed8ca1SJohan Hedberg { 227155ed8ca1SJohan Hedberg struct list_head *p, *n; 227255ed8ca1SJohan Hedberg 227355ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 227455ed8ca1SJohan Hedberg struct link_key *key; 227555ed8ca1SJohan Hedberg 227655ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 227755ed8ca1SJohan Hedberg 227855ed8ca1SJohan Hedberg list_del(p); 227955ed8ca1SJohan Hedberg kfree(key); 228055ed8ca1SJohan Hedberg } 228155ed8ca1SJohan Hedberg 228255ed8ca1SJohan Hedberg return 0; 228355ed8ca1SJohan Hedberg } 228455ed8ca1SJohan Hedberg 2285b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 2286b899efafSVinicius Costa Gomes { 2287b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2288b899efafSVinicius Costa Gomes 2289b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2290b899efafSVinicius Costa Gomes list_del(&k->list); 2291b899efafSVinicius Costa Gomes kfree(k); 2292b899efafSVinicius Costa Gomes } 2293b899efafSVinicius Costa Gomes 2294b899efafSVinicius Costa Gomes return 0; 2295b899efafSVinicius Costa Gomes } 2296b899efafSVinicius Costa Gomes 229755ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 229855ed8ca1SJohan Hedberg { 229955ed8ca1SJohan Hedberg struct link_key *k; 230055ed8ca1SJohan Hedberg 23018035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 230255ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 230355ed8ca1SJohan Hedberg return k; 230455ed8ca1SJohan Hedberg 230555ed8ca1SJohan Hedberg return NULL; 230655ed8ca1SJohan Hedberg } 230755ed8ca1SJohan Hedberg 2308745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2309d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2310d25e28abSJohan Hedberg { 2311d25e28abSJohan Hedberg /* Legacy key */ 2312d25e28abSJohan Hedberg if (key_type < 0x03) 2313745c0ce3SVishal Agarwal return true; 2314d25e28abSJohan Hedberg 2315d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2316d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2317745c0ce3SVishal Agarwal return false; 2318d25e28abSJohan Hedberg 2319d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2320d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2321745c0ce3SVishal Agarwal return false; 2322d25e28abSJohan Hedberg 2323d25e28abSJohan Hedberg /* Security mode 3 case */ 2324d25e28abSJohan Hedberg if (!conn) 2325745c0ce3SVishal Agarwal return true; 2326d25e28abSJohan Hedberg 2327d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2328d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2329745c0ce3SVishal Agarwal return true; 2330d25e28abSJohan Hedberg 2331d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2332d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2333745c0ce3SVishal Agarwal return true; 2334d25e28abSJohan Hedberg 2335d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2336d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2337745c0ce3SVishal Agarwal return true; 2338d25e28abSJohan Hedberg 2339d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2340d25e28abSJohan Hedberg * persistently */ 2341745c0ce3SVishal Agarwal return false; 2342d25e28abSJohan Hedberg } 2343d25e28abSJohan Hedberg 2344c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 234575d262c2SVinicius Costa Gomes { 2346c9839a11SVinicius Costa Gomes struct smp_ltk *k; 234775d262c2SVinicius Costa Gomes 2348c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 2349c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 2350c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 235175d262c2SVinicius Costa Gomes continue; 235275d262c2SVinicius Costa Gomes 235375d262c2SVinicius Costa Gomes return k; 235475d262c2SVinicius Costa Gomes } 235575d262c2SVinicius Costa Gomes 235675d262c2SVinicius Costa Gomes return NULL; 235775d262c2SVinicius Costa Gomes } 235875d262c2SVinicius Costa Gomes 2359c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2360c9839a11SVinicius Costa Gomes u8 addr_type) 236175d262c2SVinicius Costa Gomes { 2362c9839a11SVinicius Costa Gomes struct smp_ltk *k; 236375d262c2SVinicius Costa Gomes 2364c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 2365c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 2366c9839a11SVinicius Costa Gomes bacmp(bdaddr, &k->bdaddr) == 0) 236775d262c2SVinicius Costa Gomes return k; 236875d262c2SVinicius Costa Gomes 236975d262c2SVinicius Costa Gomes return NULL; 237075d262c2SVinicius Costa Gomes } 237175d262c2SVinicius Costa Gomes 2372d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 2373d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 237455ed8ca1SJohan Hedberg { 237555ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2376745c0ce3SVishal Agarwal u8 old_key_type; 2377745c0ce3SVishal Agarwal bool persistent; 237855ed8ca1SJohan Hedberg 237955ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 238055ed8ca1SJohan Hedberg if (old_key) { 238155ed8ca1SJohan Hedberg old_key_type = old_key->type; 238255ed8ca1SJohan Hedberg key = old_key; 238355ed8ca1SJohan Hedberg } else { 238412adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 238555ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 238655ed8ca1SJohan Hedberg if (!key) 238755ed8ca1SJohan Hedberg return -ENOMEM; 238855ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 238955ed8ca1SJohan Hedberg } 239055ed8ca1SJohan Hedberg 23916ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 239255ed8ca1SJohan Hedberg 2393d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2394d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2395d25e28abSJohan Hedberg * previous key */ 2396d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2397a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2398d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2399655fe6ecSJohan Hedberg if (conn) 2400655fe6ecSJohan Hedberg conn->key_type = type; 2401655fe6ecSJohan Hedberg } 2402d25e28abSJohan Hedberg 240355ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 24049b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 240555ed8ca1SJohan Hedberg key->pin_len = pin_len; 240655ed8ca1SJohan Hedberg 2407b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 240855ed8ca1SJohan Hedberg key->type = old_key_type; 24094748fed2SJohan Hedberg else 24104748fed2SJohan Hedberg key->type = type; 24114748fed2SJohan Hedberg 24124df378a1SJohan Hedberg if (!new_key) 24134df378a1SJohan Hedberg return 0; 24144df378a1SJohan Hedberg 24154df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 24164df378a1SJohan Hedberg 2417744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 24184df378a1SJohan Hedberg 24196ec5bcadSVishal Agarwal if (conn) 24206ec5bcadSVishal Agarwal conn->flush_key = !persistent; 242155ed8ca1SJohan Hedberg 242255ed8ca1SJohan Hedberg return 0; 242355ed8ca1SJohan Hedberg } 242455ed8ca1SJohan Hedberg 2425c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 24269a006657SAndrei Emeltchenko int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 242704124681SGustavo F. Padovan ediv, u8 rand[8]) 242875d262c2SVinicius Costa Gomes { 2429c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 243075d262c2SVinicius Costa Gomes 2431c9839a11SVinicius Costa Gomes if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 2432c9839a11SVinicius Costa Gomes return 0; 243375d262c2SVinicius Costa Gomes 2434c9839a11SVinicius Costa Gomes old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 2435c9839a11SVinicius Costa Gomes if (old_key) 243675d262c2SVinicius Costa Gomes key = old_key; 2437c9839a11SVinicius Costa Gomes else { 2438c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 243975d262c2SVinicius Costa Gomes if (!key) 244075d262c2SVinicius Costa Gomes return -ENOMEM; 2441c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 244275d262c2SVinicius Costa Gomes } 244375d262c2SVinicius Costa Gomes 244475d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2445c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2446c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2447c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2448c9839a11SVinicius Costa Gomes key->ediv = ediv; 2449c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2450c9839a11SVinicius Costa Gomes key->type = type; 2451c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 245275d262c2SVinicius Costa Gomes 2453c9839a11SVinicius Costa Gomes if (!new_key) 2454c9839a11SVinicius Costa Gomes return 0; 245575d262c2SVinicius Costa Gomes 2456261cc5aaSVinicius Costa Gomes if (type & HCI_SMP_LTK) 2457261cc5aaSVinicius Costa Gomes mgmt_new_ltk(hdev, key, 1); 2458261cc5aaSVinicius Costa Gomes 245975d262c2SVinicius Costa Gomes return 0; 246075d262c2SVinicius Costa Gomes } 246175d262c2SVinicius Costa Gomes 246255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 246355ed8ca1SJohan Hedberg { 246455ed8ca1SJohan Hedberg struct link_key *key; 246555ed8ca1SJohan Hedberg 246655ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 246755ed8ca1SJohan Hedberg if (!key) 246855ed8ca1SJohan Hedberg return -ENOENT; 246955ed8ca1SJohan Hedberg 24706ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 247155ed8ca1SJohan Hedberg 247255ed8ca1SJohan Hedberg list_del(&key->list); 247355ed8ca1SJohan Hedberg kfree(key); 247455ed8ca1SJohan Hedberg 247555ed8ca1SJohan Hedberg return 0; 247655ed8ca1SJohan Hedberg } 247755ed8ca1SJohan Hedberg 2478b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 2479b899efafSVinicius Costa Gomes { 2480b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2481b899efafSVinicius Costa Gomes 2482b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2483b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 2484b899efafSVinicius Costa Gomes continue; 2485b899efafSVinicius Costa Gomes 24866ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2487b899efafSVinicius Costa Gomes 2488b899efafSVinicius Costa Gomes list_del(&k->list); 2489b899efafSVinicius Costa Gomes kfree(k); 2490b899efafSVinicius Costa Gomes } 2491b899efafSVinicius Costa Gomes 2492b899efafSVinicius Costa Gomes return 0; 2493b899efafSVinicius Costa Gomes } 2494b899efafSVinicius Costa Gomes 24956bd32326SVille Tervo /* HCI command timer function */ 2496bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg) 24976bd32326SVille Tervo { 24986bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 24996bd32326SVille Tervo 2500bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2501bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2502bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2503bda4f23aSAndrei Emeltchenko 2504bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 2505bda4f23aSAndrei Emeltchenko } else { 25066bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 2507bda4f23aSAndrei Emeltchenko } 2508bda4f23aSAndrei Emeltchenko 25096bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2510c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 25116bd32326SVille Tervo } 25126bd32326SVille Tervo 25132763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 25142763eda6SSzymon Janc bdaddr_t *bdaddr) 25152763eda6SSzymon Janc { 25162763eda6SSzymon Janc struct oob_data *data; 25172763eda6SSzymon Janc 25182763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 25192763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 25202763eda6SSzymon Janc return data; 25212763eda6SSzymon Janc 25222763eda6SSzymon Janc return NULL; 25232763eda6SSzymon Janc } 25242763eda6SSzymon Janc 25252763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 25262763eda6SSzymon Janc { 25272763eda6SSzymon Janc struct oob_data *data; 25282763eda6SSzymon Janc 25292763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 25302763eda6SSzymon Janc if (!data) 25312763eda6SSzymon Janc return -ENOENT; 25322763eda6SSzymon Janc 25336ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 25342763eda6SSzymon Janc 25352763eda6SSzymon Janc list_del(&data->list); 25362763eda6SSzymon Janc kfree(data); 25372763eda6SSzymon Janc 25382763eda6SSzymon Janc return 0; 25392763eda6SSzymon Janc } 25402763eda6SSzymon Janc 25412763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 25422763eda6SSzymon Janc { 25432763eda6SSzymon Janc struct oob_data *data, *n; 25442763eda6SSzymon Janc 25452763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 25462763eda6SSzymon Janc list_del(&data->list); 25472763eda6SSzymon Janc kfree(data); 25482763eda6SSzymon Janc } 25492763eda6SSzymon Janc 25502763eda6SSzymon Janc return 0; 25512763eda6SSzymon Janc } 25522763eda6SSzymon Janc 25532763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 25542763eda6SSzymon Janc u8 *randomizer) 25552763eda6SSzymon Janc { 25562763eda6SSzymon Janc struct oob_data *data; 25572763eda6SSzymon Janc 25582763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 25592763eda6SSzymon Janc 25602763eda6SSzymon Janc if (!data) { 25612763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 25622763eda6SSzymon Janc if (!data) 25632763eda6SSzymon Janc return -ENOMEM; 25642763eda6SSzymon Janc 25652763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 25662763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 25672763eda6SSzymon Janc } 25682763eda6SSzymon Janc 25692763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 25702763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 25712763eda6SSzymon Janc 25726ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 25732763eda6SSzymon Janc 25742763eda6SSzymon Janc return 0; 25752763eda6SSzymon Janc } 25762763eda6SSzymon Janc 2577b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 2578b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 2579b2a66aadSAntti Julku { 2580b2a66aadSAntti Julku struct bdaddr_list *b; 2581b2a66aadSAntti Julku 2582b9ee0a78SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) { 2583b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2584b2a66aadSAntti Julku return b; 2585b9ee0a78SMarcel Holtmann } 2586b2a66aadSAntti Julku 2587b2a66aadSAntti Julku return NULL; 2588b2a66aadSAntti Julku } 2589b2a66aadSAntti Julku 2590b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 2591b2a66aadSAntti Julku { 2592b2a66aadSAntti Julku struct list_head *p, *n; 2593b2a66aadSAntti Julku 2594b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 2595b9ee0a78SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 2596b2a66aadSAntti Julku 2597b2a66aadSAntti Julku list_del(p); 2598b2a66aadSAntti Julku kfree(b); 2599b2a66aadSAntti Julku } 2600b2a66aadSAntti Julku 2601b2a66aadSAntti Julku return 0; 2602b2a66aadSAntti Julku } 2603b2a66aadSAntti Julku 260488c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2605b2a66aadSAntti Julku { 2606b2a66aadSAntti Julku struct bdaddr_list *entry; 2607b2a66aadSAntti Julku 2608b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 2609b2a66aadSAntti Julku return -EBADF; 2610b2a66aadSAntti Julku 2611b9ee0a78SMarcel Holtmann if (hci_blacklist_lookup(hdev, bdaddr, type)) 26125e762444SAntti Julku return -EEXIST; 2613b2a66aadSAntti Julku 2614b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 26155e762444SAntti Julku if (!entry) 26165e762444SAntti Julku return -ENOMEM; 2617b2a66aadSAntti Julku 2618b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 2619b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 2620b2a66aadSAntti Julku 2621b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 2622b2a66aadSAntti Julku 262388c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 2624b2a66aadSAntti Julku } 2625b2a66aadSAntti Julku 262688c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2627b2a66aadSAntti Julku { 2628b2a66aadSAntti Julku struct bdaddr_list *entry; 2629b2a66aadSAntti Julku 2630b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 26315e762444SAntti Julku return hci_blacklist_clear(hdev); 2632b2a66aadSAntti Julku 2633b9ee0a78SMarcel Holtmann entry = hci_blacklist_lookup(hdev, bdaddr, type); 26341ec918ceSSzymon Janc if (!entry) 26355e762444SAntti Julku return -ENOENT; 2636b2a66aadSAntti Julku 2637b2a66aadSAntti Julku list_del(&entry->list); 2638b2a66aadSAntti Julku kfree(entry); 2639b2a66aadSAntti Julku 264088c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 2641b2a66aadSAntti Julku } 2642b2a66aadSAntti Julku 26434c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 26447ba8b4beSAndre Guedes { 26454c87eaabSAndre Guedes if (status) { 26464c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 26477ba8b4beSAndre Guedes 26484c87eaabSAndre Guedes hci_dev_lock(hdev); 26494c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 26504c87eaabSAndre Guedes hci_dev_unlock(hdev); 26514c87eaabSAndre Guedes return; 26524c87eaabSAndre Guedes } 26537ba8b4beSAndre Guedes } 26547ba8b4beSAndre Guedes 26554c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 26567ba8b4beSAndre Guedes { 26574c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 26584c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 26594c87eaabSAndre Guedes struct hci_request req; 26604c87eaabSAndre Guedes struct hci_cp_inquiry cp; 26617ba8b4beSAndre Guedes int err; 26627ba8b4beSAndre Guedes 26634c87eaabSAndre Guedes if (status) { 26644c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 26654c87eaabSAndre Guedes return; 26667ba8b4beSAndre Guedes } 26677ba8b4beSAndre Guedes 26684c87eaabSAndre Guedes switch (hdev->discovery.type) { 26694c87eaabSAndre Guedes case DISCOV_TYPE_LE: 26704c87eaabSAndre Guedes hci_dev_lock(hdev); 26714c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 26724c87eaabSAndre Guedes hci_dev_unlock(hdev); 26734c87eaabSAndre Guedes break; 26747dbfac1dSAndre Guedes 26754c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 26764c87eaabSAndre Guedes hci_req_init(&req, hdev); 26777dbfac1dSAndre Guedes 26787dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 26794c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 26804c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 26814c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 26824c87eaabSAndre Guedes 26834c87eaabSAndre Guedes hci_dev_lock(hdev); 26844c87eaabSAndre Guedes 26854c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 26864c87eaabSAndre Guedes 26874c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 26884c87eaabSAndre Guedes if (err) { 26894c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 26904c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 26917dbfac1dSAndre Guedes } 26927dbfac1dSAndre Guedes 26934c87eaabSAndre Guedes hci_dev_unlock(hdev); 26944c87eaabSAndre Guedes break; 26954c87eaabSAndre Guedes } 26967dbfac1dSAndre Guedes } 26977dbfac1dSAndre Guedes 26987ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 26997ba8b4beSAndre Guedes { 27007ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 27017ba8b4beSAndre Guedes le_scan_disable.work); 27027ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 27034c87eaabSAndre Guedes struct hci_request req; 27044c87eaabSAndre Guedes int err; 27057ba8b4beSAndre Guedes 27067ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 27077ba8b4beSAndre Guedes 27084c87eaabSAndre Guedes hci_req_init(&req, hdev); 27097ba8b4beSAndre Guedes 27107ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 27114c87eaabSAndre Guedes cp.enable = LE_SCAN_DISABLE; 27124c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 27137ba8b4beSAndre Guedes 27144c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 27154c87eaabSAndre Guedes if (err) 27164c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 271728b75a89SAndre Guedes } 271828b75a89SAndre Guedes 27199be0dab7SDavid Herrmann /* Alloc HCI device */ 27209be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 27219be0dab7SDavid Herrmann { 27229be0dab7SDavid Herrmann struct hci_dev *hdev; 27239be0dab7SDavid Herrmann 27249be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 27259be0dab7SDavid Herrmann if (!hdev) 27269be0dab7SDavid Herrmann return NULL; 27279be0dab7SDavid Herrmann 2728b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 2729b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 2730b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 2731b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 2732b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 2733bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 2734bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2735b1b813d4SDavid Herrmann 2736b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 2737b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 2738b1b813d4SDavid Herrmann 2739bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 2740bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 2741bef64738SMarcel Holtmann 2742b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 2743b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 2744b1b813d4SDavid Herrmann 2745b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 2746b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 2747b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 2748b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 2749b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 2750b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 27516b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 2752b1b813d4SDavid Herrmann 2753b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 2754b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 2755b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 2756b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 2757b1b813d4SDavid Herrmann 2758b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 2759b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 2760b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 2761b1b813d4SDavid Herrmann 2762b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 2763b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 2764b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 2765b1b813d4SDavid Herrmann 2766b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 2767b1b813d4SDavid Herrmann 2768bda4f23aSAndrei Emeltchenko setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); 2769b1b813d4SDavid Herrmann 2770b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 2771b1b813d4SDavid Herrmann discovery_init(hdev); 27729be0dab7SDavid Herrmann 27739be0dab7SDavid Herrmann return hdev; 27749be0dab7SDavid Herrmann } 27759be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 27769be0dab7SDavid Herrmann 27779be0dab7SDavid Herrmann /* Free HCI device */ 27789be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 27799be0dab7SDavid Herrmann { 27809be0dab7SDavid Herrmann /* will free via device release */ 27819be0dab7SDavid Herrmann put_device(&hdev->dev); 27829be0dab7SDavid Herrmann } 27839be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 27849be0dab7SDavid Herrmann 27851da177e4SLinus Torvalds /* Register HCI device */ 27861da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 27871da177e4SLinus Torvalds { 2788b1b813d4SDavid Herrmann int id, error; 27891da177e4SLinus Torvalds 2790010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 27911da177e4SLinus Torvalds return -EINVAL; 27921da177e4SLinus Torvalds 279308add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 279408add513SMat Martineau * so the index can be used as the AMP controller ID. 279508add513SMat Martineau */ 27963df92b31SSasha Levin switch (hdev->dev_type) { 27973df92b31SSasha Levin case HCI_BREDR: 27983df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 27991da177e4SLinus Torvalds break; 28003df92b31SSasha Levin case HCI_AMP: 28013df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 28023df92b31SSasha Levin break; 28033df92b31SSasha Levin default: 28043df92b31SSasha Levin return -EINVAL; 28051da177e4SLinus Torvalds } 28061da177e4SLinus Torvalds 28073df92b31SSasha Levin if (id < 0) 28083df92b31SSasha Levin return id; 28093df92b31SSasha Levin 28101da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 28111da177e4SLinus Torvalds hdev->id = id; 28122d8b3a11SAndrei Emeltchenko 28132d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 28142d8b3a11SAndrei Emeltchenko 2815d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 2816d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 281733ca954dSDavid Herrmann if (!hdev->workqueue) { 281833ca954dSDavid Herrmann error = -ENOMEM; 281933ca954dSDavid Herrmann goto err; 282033ca954dSDavid Herrmann } 2821f48fd9c8SMarcel Holtmann 2822d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 2823d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 28246ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 28256ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 28266ead1bbcSJohan Hedberg error = -ENOMEM; 28276ead1bbcSJohan Hedberg goto err; 28286ead1bbcSJohan Hedberg } 28296ead1bbcSJohan Hedberg 28300153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 28310153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 28320153e2ecSMarcel Holtmann 2833bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 2834bdc3e0f1SMarcel Holtmann 2835bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 283633ca954dSDavid Herrmann if (error < 0) 283733ca954dSDavid Herrmann goto err_wqueue; 28381da177e4SLinus Torvalds 2839611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 2840a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 2841a8c5fb1aSGustavo Padovan hdev); 2842611b30f7SMarcel Holtmann if (hdev->rfkill) { 2843611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 2844611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2845611b30f7SMarcel Holtmann hdev->rfkill = NULL; 2846611b30f7SMarcel Holtmann } 2847611b30f7SMarcel Holtmann } 2848611b30f7SMarcel Holtmann 28495e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 28505e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 28515e130367SJohan Hedberg 2852a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 2853004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2854ce2be9acSAndrei Emeltchenko 285501cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 285656f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 285756f87901SJohan Hedberg * through reading supported features during init. 285856f87901SJohan Hedberg */ 285956f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 286056f87901SJohan Hedberg } 2861ce2be9acSAndrei Emeltchenko 2862fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 2863fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 2864fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 2865fcee3377SGustavo Padovan 28661da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 2867dc946bd8SDavid Herrmann hci_dev_hold(hdev); 28681da177e4SLinus Torvalds 286919202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 2870fbe96d6fSMarcel Holtmann 28711da177e4SLinus Torvalds return id; 2872f48fd9c8SMarcel Holtmann 287333ca954dSDavid Herrmann err_wqueue: 287433ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 28756ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 287633ca954dSDavid Herrmann err: 28773df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 2878f48fd9c8SMarcel Holtmann 287933ca954dSDavid Herrmann return error; 28801da177e4SLinus Torvalds } 28811da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 28821da177e4SLinus Torvalds 28831da177e4SLinus Torvalds /* Unregister HCI device */ 288459735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 28851da177e4SLinus Torvalds { 28863df92b31SSasha Levin int i, id; 2887ef222013SMarcel Holtmann 2888c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 28891da177e4SLinus Torvalds 289094324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 289194324962SJohan Hovold 28923df92b31SSasha Levin id = hdev->id; 28933df92b31SSasha Levin 2894f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 28951da177e4SLinus Torvalds list_del(&hdev->list); 2896f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 28971da177e4SLinus Torvalds 28981da177e4SLinus Torvalds hci_dev_do_close(hdev); 28991da177e4SLinus Torvalds 2900cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 2901ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 2902ef222013SMarcel Holtmann 2903b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 2904b9b5ef18SGustavo Padovan 2905ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 2906a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 290709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2908744cf19eSJohan Hedberg mgmt_index_removed(hdev); 290909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 291056e5cb86SJohan Hedberg } 2911ab81cbf9SJohan Hedberg 29122e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 29132e58ef3eSJohan Hedberg * pending list */ 29142e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 29152e58ef3eSJohan Hedberg 29161da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 29171da177e4SLinus Torvalds 2918611b30f7SMarcel Holtmann if (hdev->rfkill) { 2919611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 2920611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2921611b30f7SMarcel Holtmann } 2922611b30f7SMarcel Holtmann 2923bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 2924147e2d59SDave Young 29250153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 29260153e2ecSMarcel Holtmann 2927f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 29286ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 2929f48fd9c8SMarcel Holtmann 293009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2931e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 29322aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 293355ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 2934b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 29352763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 293609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 2937e2e0cacbSJohan Hedberg 2938dc946bd8SDavid Herrmann hci_dev_put(hdev); 29393df92b31SSasha Levin 29403df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 29411da177e4SLinus Torvalds } 29421da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 29431da177e4SLinus Torvalds 29441da177e4SLinus Torvalds /* Suspend HCI device */ 29451da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 29461da177e4SLinus Torvalds { 29471da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 29481da177e4SLinus Torvalds return 0; 29491da177e4SLinus Torvalds } 29501da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 29511da177e4SLinus Torvalds 29521da177e4SLinus Torvalds /* Resume HCI device */ 29531da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 29541da177e4SLinus Torvalds { 29551da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 29561da177e4SLinus Torvalds return 0; 29571da177e4SLinus Torvalds } 29581da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 29591da177e4SLinus Torvalds 296076bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 2961e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 296276bca880SMarcel Holtmann { 296376bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 296476bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 296576bca880SMarcel Holtmann kfree_skb(skb); 296676bca880SMarcel Holtmann return -ENXIO; 296776bca880SMarcel Holtmann } 296876bca880SMarcel Holtmann 2969d82603c6SJorrit Schippers /* Incoming skb */ 297076bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 297176bca880SMarcel Holtmann 297276bca880SMarcel Holtmann /* Time stamp */ 297376bca880SMarcel Holtmann __net_timestamp(skb); 297476bca880SMarcel Holtmann 297576bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 2976b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 2977c78ae283SMarcel Holtmann 297876bca880SMarcel Holtmann return 0; 297976bca880SMarcel Holtmann } 298076bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 298176bca880SMarcel Holtmann 298233e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 29831e429f38SGustavo F. Padovan int count, __u8 index) 298433e882a5SSuraj Sumangala { 298533e882a5SSuraj Sumangala int len = 0; 298633e882a5SSuraj Sumangala int hlen = 0; 298733e882a5SSuraj Sumangala int remain = count; 298833e882a5SSuraj Sumangala struct sk_buff *skb; 298933e882a5SSuraj Sumangala struct bt_skb_cb *scb; 299033e882a5SSuraj Sumangala 299133e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 299233e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 299333e882a5SSuraj Sumangala return -EILSEQ; 299433e882a5SSuraj Sumangala 299533e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 299633e882a5SSuraj Sumangala 299733e882a5SSuraj Sumangala if (!skb) { 299833e882a5SSuraj Sumangala switch (type) { 299933e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 300033e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 300133e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 300233e882a5SSuraj Sumangala break; 300333e882a5SSuraj Sumangala case HCI_EVENT_PKT: 300433e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 300533e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 300633e882a5SSuraj Sumangala break; 300733e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 300833e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 300933e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 301033e882a5SSuraj Sumangala break; 301133e882a5SSuraj Sumangala } 301233e882a5SSuraj Sumangala 30131e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 301433e882a5SSuraj Sumangala if (!skb) 301533e882a5SSuraj Sumangala return -ENOMEM; 301633e882a5SSuraj Sumangala 301733e882a5SSuraj Sumangala scb = (void *) skb->cb; 301833e882a5SSuraj Sumangala scb->expect = hlen; 301933e882a5SSuraj Sumangala scb->pkt_type = type; 302033e882a5SSuraj Sumangala 302133e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 302233e882a5SSuraj Sumangala } 302333e882a5SSuraj Sumangala 302433e882a5SSuraj Sumangala while (count) { 302533e882a5SSuraj Sumangala scb = (void *) skb->cb; 302689bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 302733e882a5SSuraj Sumangala 302833e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 302933e882a5SSuraj Sumangala 303033e882a5SSuraj Sumangala count -= len; 303133e882a5SSuraj Sumangala data += len; 303233e882a5SSuraj Sumangala scb->expect -= len; 303333e882a5SSuraj Sumangala remain = count; 303433e882a5SSuraj Sumangala 303533e882a5SSuraj Sumangala switch (type) { 303633e882a5SSuraj Sumangala case HCI_EVENT_PKT: 303733e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 303833e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 303933e882a5SSuraj Sumangala scb->expect = h->plen; 304033e882a5SSuraj Sumangala 304133e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 304233e882a5SSuraj Sumangala kfree_skb(skb); 304333e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 304433e882a5SSuraj Sumangala return -ENOMEM; 304533e882a5SSuraj Sumangala } 304633e882a5SSuraj Sumangala } 304733e882a5SSuraj Sumangala break; 304833e882a5SSuraj Sumangala 304933e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 305033e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 305133e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 305233e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 305333e882a5SSuraj Sumangala 305433e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 305533e882a5SSuraj Sumangala kfree_skb(skb); 305633e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 305733e882a5SSuraj Sumangala return -ENOMEM; 305833e882a5SSuraj Sumangala } 305933e882a5SSuraj Sumangala } 306033e882a5SSuraj Sumangala break; 306133e882a5SSuraj Sumangala 306233e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 306333e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 306433e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 306533e882a5SSuraj Sumangala scb->expect = h->dlen; 306633e882a5SSuraj Sumangala 306733e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 306833e882a5SSuraj Sumangala kfree_skb(skb); 306933e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 307033e882a5SSuraj Sumangala return -ENOMEM; 307133e882a5SSuraj Sumangala } 307233e882a5SSuraj Sumangala } 307333e882a5SSuraj Sumangala break; 307433e882a5SSuraj Sumangala } 307533e882a5SSuraj Sumangala 307633e882a5SSuraj Sumangala if (scb->expect == 0) { 307733e882a5SSuraj Sumangala /* Complete frame */ 307833e882a5SSuraj Sumangala 307933e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 3080e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 308133e882a5SSuraj Sumangala 308233e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 308333e882a5SSuraj Sumangala return remain; 308433e882a5SSuraj Sumangala } 308533e882a5SSuraj Sumangala } 308633e882a5SSuraj Sumangala 308733e882a5SSuraj Sumangala return remain; 308833e882a5SSuraj Sumangala } 308933e882a5SSuraj Sumangala 3090ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 3091ef222013SMarcel Holtmann { 3092f39a3c06SSuraj Sumangala int rem = 0; 3093f39a3c06SSuraj Sumangala 3094ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 3095ef222013SMarcel Holtmann return -EILSEQ; 3096ef222013SMarcel Holtmann 3097da5f6c37SGustavo F. Padovan while (count) { 30981e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 3099f39a3c06SSuraj Sumangala if (rem < 0) 3100f39a3c06SSuraj Sumangala return rem; 3101ef222013SMarcel Holtmann 3102f39a3c06SSuraj Sumangala data += (count - rem); 3103f39a3c06SSuraj Sumangala count = rem; 3104f81c6224SJoe Perches } 3105ef222013SMarcel Holtmann 3106f39a3c06SSuraj Sumangala return rem; 3107ef222013SMarcel Holtmann } 3108ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 3109ef222013SMarcel Holtmann 311099811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 311199811510SSuraj Sumangala 311299811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 311399811510SSuraj Sumangala { 311499811510SSuraj Sumangala int type; 311599811510SSuraj Sumangala int rem = 0; 311699811510SSuraj Sumangala 3117da5f6c37SGustavo F. Padovan while (count) { 311899811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 311999811510SSuraj Sumangala 312099811510SSuraj Sumangala if (!skb) { 312199811510SSuraj Sumangala struct { char type; } *pkt; 312299811510SSuraj Sumangala 312399811510SSuraj Sumangala /* Start of the frame */ 312499811510SSuraj Sumangala pkt = data; 312599811510SSuraj Sumangala type = pkt->type; 312699811510SSuraj Sumangala 312799811510SSuraj Sumangala data++; 312899811510SSuraj Sumangala count--; 312999811510SSuraj Sumangala } else 313099811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 313199811510SSuraj Sumangala 31321e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 31331e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 313499811510SSuraj Sumangala if (rem < 0) 313599811510SSuraj Sumangala return rem; 313699811510SSuraj Sumangala 313799811510SSuraj Sumangala data += (count - rem); 313899811510SSuraj Sumangala count = rem; 3139f81c6224SJoe Perches } 314099811510SSuraj Sumangala 314199811510SSuraj Sumangala return rem; 314299811510SSuraj Sumangala } 314399811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 314499811510SSuraj Sumangala 31451da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 31461da177e4SLinus Torvalds 31471da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 31481da177e4SLinus Torvalds { 31491da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 31501da177e4SLinus Torvalds 3151f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 31521da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 3153f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 31541da177e4SLinus Torvalds 31551da177e4SLinus Torvalds return 0; 31561da177e4SLinus Torvalds } 31571da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 31581da177e4SLinus Torvalds 31591da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 31601da177e4SLinus Torvalds { 31611da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 31621da177e4SLinus Torvalds 3163f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 31641da177e4SLinus Torvalds list_del(&cb->list); 3165f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 31661da177e4SLinus Torvalds 31671da177e4SLinus Torvalds return 0; 31681da177e4SLinus Torvalds } 31691da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 31701da177e4SLinus Torvalds 317151086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 31721da177e4SLinus Torvalds { 31730d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 31741da177e4SLinus Torvalds 31751da177e4SLinus Torvalds /* Time stamp */ 3176a61bbcf2SPatrick McHardy __net_timestamp(skb); 31771da177e4SLinus Torvalds 3178cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3179cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3180cd82e61cSMarcel Holtmann 3181cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3182cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3183470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 31841da177e4SLinus Torvalds } 31851da177e4SLinus Torvalds 31861da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 31871da177e4SLinus Torvalds skb_orphan(skb); 31881da177e4SLinus Torvalds 31897bd8f09fSMarcel Holtmann if (hdev->send(hdev, skb) < 0) 319051086991SMarcel Holtmann BT_ERR("%s sending frame failed", hdev->name); 31911da177e4SLinus Torvalds } 31921da177e4SLinus Torvalds 31933119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 31943119ae95SJohan Hedberg { 31953119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 31963119ae95SJohan Hedberg req->hdev = hdev; 31975d73e034SAndre Guedes req->err = 0; 31983119ae95SJohan Hedberg } 31993119ae95SJohan Hedberg 32003119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 32013119ae95SJohan Hedberg { 32023119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 32033119ae95SJohan Hedberg struct sk_buff *skb; 32043119ae95SJohan Hedberg unsigned long flags; 32053119ae95SJohan Hedberg 32063119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 32073119ae95SJohan Hedberg 32085d73e034SAndre Guedes /* If an error occured during request building, remove all HCI 32095d73e034SAndre Guedes * commands queued on the HCI request queue. 32105d73e034SAndre Guedes */ 32115d73e034SAndre Guedes if (req->err) { 32125d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 32135d73e034SAndre Guedes return req->err; 32145d73e034SAndre Guedes } 32155d73e034SAndre Guedes 32163119ae95SJohan Hedberg /* Do not allow empty requests */ 32173119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 3218382b0c39SAndre Guedes return -ENODATA; 32193119ae95SJohan Hedberg 32203119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 32213119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 32223119ae95SJohan Hedberg 32233119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 32243119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 32253119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 32263119ae95SJohan Hedberg 32273119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 32283119ae95SJohan Hedberg 32293119ae95SJohan Hedberg return 0; 32303119ae95SJohan Hedberg } 32313119ae95SJohan Hedberg 32321ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 323307dc93ddSJohan Hedberg u32 plen, const void *param) 32341da177e4SLinus Torvalds { 32351da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 32361da177e4SLinus Torvalds struct hci_command_hdr *hdr; 32371da177e4SLinus Torvalds struct sk_buff *skb; 32381da177e4SLinus Torvalds 32391da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 32401ca3a9d0SJohan Hedberg if (!skb) 32411ca3a9d0SJohan Hedberg return NULL; 32421da177e4SLinus Torvalds 32431da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 3244a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 32451da177e4SLinus Torvalds hdr->plen = plen; 32461da177e4SLinus Torvalds 32471da177e4SLinus Torvalds if (plen) 32481da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 32491da177e4SLinus Torvalds 32501da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 32511da177e4SLinus Torvalds 32520d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 3253c78ae283SMarcel Holtmann 32541ca3a9d0SJohan Hedberg return skb; 32551ca3a9d0SJohan Hedberg } 32561ca3a9d0SJohan Hedberg 32571ca3a9d0SJohan Hedberg /* Send HCI command */ 325807dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 325907dc93ddSJohan Hedberg const void *param) 32601ca3a9d0SJohan Hedberg { 32611ca3a9d0SJohan Hedberg struct sk_buff *skb; 32621ca3a9d0SJohan Hedberg 32631ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 32641ca3a9d0SJohan Hedberg 32651ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 32661ca3a9d0SJohan Hedberg if (!skb) { 32671ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 32681ca3a9d0SJohan Hedberg return -ENOMEM; 32691ca3a9d0SJohan Hedberg } 32701ca3a9d0SJohan Hedberg 327111714b3dSJohan Hedberg /* Stand-alone HCI commands must be flaged as 327211714b3dSJohan Hedberg * single-command requests. 327311714b3dSJohan Hedberg */ 327411714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 327511714b3dSJohan Hedberg 32761da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3277c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 32781da177e4SLinus Torvalds 32791da177e4SLinus Torvalds return 0; 32801da177e4SLinus Torvalds } 32811da177e4SLinus Torvalds 328271c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 328307dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 328407dc93ddSJohan Hedberg const void *param, u8 event) 328571c76a17SJohan Hedberg { 328671c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 328771c76a17SJohan Hedberg struct sk_buff *skb; 328871c76a17SJohan Hedberg 328971c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 329071c76a17SJohan Hedberg 329134739c1eSAndre Guedes /* If an error occured during request building, there is no point in 329234739c1eSAndre Guedes * queueing the HCI command. We can simply return. 329334739c1eSAndre Guedes */ 329434739c1eSAndre Guedes if (req->err) 329534739c1eSAndre Guedes return; 329634739c1eSAndre Guedes 329771c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 329871c76a17SJohan Hedberg if (!skb) { 32995d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 33005d73e034SAndre Guedes hdev->name, opcode); 33015d73e034SAndre Guedes req->err = -ENOMEM; 3302e348fe6bSAndre Guedes return; 330371c76a17SJohan Hedberg } 330471c76a17SJohan Hedberg 330571c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 330671c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 330771c76a17SJohan Hedberg 330802350a72SJohan Hedberg bt_cb(skb)->req.event = event; 330902350a72SJohan Hedberg 331071c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 331171c76a17SJohan Hedberg } 331271c76a17SJohan Hedberg 331307dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 331407dc93ddSJohan Hedberg const void *param) 331502350a72SJohan Hedberg { 331602350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 331702350a72SJohan Hedberg } 331802350a72SJohan Hedberg 33191da177e4SLinus Torvalds /* Get data from the previously sent command */ 3320a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 33211da177e4SLinus Torvalds { 33221da177e4SLinus Torvalds struct hci_command_hdr *hdr; 33231da177e4SLinus Torvalds 33241da177e4SLinus Torvalds if (!hdev->sent_cmd) 33251da177e4SLinus Torvalds return NULL; 33261da177e4SLinus Torvalds 33271da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 33281da177e4SLinus Torvalds 3329a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 33301da177e4SLinus Torvalds return NULL; 33311da177e4SLinus Torvalds 3332f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 33331da177e4SLinus Torvalds 33341da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 33351da177e4SLinus Torvalds } 33361da177e4SLinus Torvalds 33371da177e4SLinus Torvalds /* Send ACL data */ 33381da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 33391da177e4SLinus Torvalds { 33401da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 33411da177e4SLinus Torvalds int len = skb->len; 33421da177e4SLinus Torvalds 3343badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3344badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 33459c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3346aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3347aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 33481da177e4SLinus Torvalds } 33491da177e4SLinus Torvalds 3350ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 335173d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 33521da177e4SLinus Torvalds { 3353ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 33541da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 33551da177e4SLinus Torvalds struct sk_buff *list; 33561da177e4SLinus Torvalds 3357087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3358087bfd99SGustavo Padovan skb->data_len = 0; 3359087bfd99SGustavo Padovan 3360087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3361204a6e54SAndrei Emeltchenko 3362204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3363204a6e54SAndrei Emeltchenko case HCI_BREDR: 3364087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3365204a6e54SAndrei Emeltchenko break; 3366204a6e54SAndrei Emeltchenko case HCI_AMP: 3367204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3368204a6e54SAndrei Emeltchenko break; 3369204a6e54SAndrei Emeltchenko default: 3370204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 3371204a6e54SAndrei Emeltchenko return; 3372204a6e54SAndrei Emeltchenko } 3373087bfd99SGustavo Padovan 337470f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 337570f23020SAndrei Emeltchenko if (!list) { 33761da177e4SLinus Torvalds /* Non fragmented */ 33771da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 33781da177e4SLinus Torvalds 337973d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 33801da177e4SLinus Torvalds } else { 33811da177e4SLinus Torvalds /* Fragmented */ 33821da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 33831da177e4SLinus Torvalds 33841da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 33851da177e4SLinus Torvalds 33861da177e4SLinus Torvalds /* Queue all fragments atomically */ 3387af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 33881da177e4SLinus Torvalds 338973d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3390e702112fSAndrei Emeltchenko 3391e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3392e702112fSAndrei Emeltchenko flags |= ACL_CONT; 33931da177e4SLinus Torvalds do { 33941da177e4SLinus Torvalds skb = list; list = list->next; 33951da177e4SLinus Torvalds 33960d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3397e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 33981da177e4SLinus Torvalds 33991da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 34001da177e4SLinus Torvalds 340173d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 34021da177e4SLinus Torvalds } while (list); 34031da177e4SLinus Torvalds 3404af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 34051da177e4SLinus Torvalds } 340673d80debSLuiz Augusto von Dentz } 340773d80debSLuiz Augusto von Dentz 340873d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 340973d80debSLuiz Augusto von Dentz { 3410ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 341173d80debSLuiz Augusto von Dentz 3412f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 341373d80debSLuiz Augusto von Dentz 3414ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 34151da177e4SLinus Torvalds 34163eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 34171da177e4SLinus Torvalds } 34181da177e4SLinus Torvalds 34191da177e4SLinus Torvalds /* Send SCO data */ 34200d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 34211da177e4SLinus Torvalds { 34221da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 34231da177e4SLinus Torvalds struct hci_sco_hdr hdr; 34241da177e4SLinus Torvalds 34251da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 34261da177e4SLinus Torvalds 3427aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 34281da177e4SLinus Torvalds hdr.dlen = skb->len; 34291da177e4SLinus Torvalds 3430badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 3431badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 34329c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 34331da177e4SLinus Torvalds 34340d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 3435c78ae283SMarcel Holtmann 34361da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 34373eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 34381da177e4SLinus Torvalds } 34391da177e4SLinus Torvalds 34401da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 34411da177e4SLinus Torvalds 34421da177e4SLinus Torvalds /* HCI Connection scheduler */ 34436039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 3444a8c5fb1aSGustavo Padovan int *quote) 34451da177e4SLinus Torvalds { 34461da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 34478035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 3448abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 34491da177e4SLinus Torvalds 34501da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 34511da177e4SLinus Torvalds * added and removed with TX task disabled. */ 3452bf4c6325SGustavo F. Padovan 3453bf4c6325SGustavo F. Padovan rcu_read_lock(); 3454bf4c6325SGustavo F. Padovan 3455bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3456769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 34571da177e4SLinus Torvalds continue; 3458769be974SMarcel Holtmann 3459769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 3460769be974SMarcel Holtmann continue; 3461769be974SMarcel Holtmann 34621da177e4SLinus Torvalds num++; 34631da177e4SLinus Torvalds 34641da177e4SLinus Torvalds if (c->sent < min) { 34651da177e4SLinus Torvalds min = c->sent; 34661da177e4SLinus Torvalds conn = c; 34671da177e4SLinus Torvalds } 346852087a79SLuiz Augusto von Dentz 346952087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 347052087a79SLuiz Augusto von Dentz break; 34711da177e4SLinus Torvalds } 34721da177e4SLinus Torvalds 3473bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3474bf4c6325SGustavo F. Padovan 34751da177e4SLinus Torvalds if (conn) { 34766ed58ec5SVille Tervo int cnt, q; 34776ed58ec5SVille Tervo 34786ed58ec5SVille Tervo switch (conn->type) { 34796ed58ec5SVille Tervo case ACL_LINK: 34806ed58ec5SVille Tervo cnt = hdev->acl_cnt; 34816ed58ec5SVille Tervo break; 34826ed58ec5SVille Tervo case SCO_LINK: 34836ed58ec5SVille Tervo case ESCO_LINK: 34846ed58ec5SVille Tervo cnt = hdev->sco_cnt; 34856ed58ec5SVille Tervo break; 34866ed58ec5SVille Tervo case LE_LINK: 34876ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 34886ed58ec5SVille Tervo break; 34896ed58ec5SVille Tervo default: 34906ed58ec5SVille Tervo cnt = 0; 34916ed58ec5SVille Tervo BT_ERR("Unknown link type"); 34926ed58ec5SVille Tervo } 34936ed58ec5SVille Tervo 34946ed58ec5SVille Tervo q = cnt / num; 34951da177e4SLinus Torvalds *quote = q ? q : 1; 34961da177e4SLinus Torvalds } else 34971da177e4SLinus Torvalds *quote = 0; 34981da177e4SLinus Torvalds 34991da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 35001da177e4SLinus Torvalds return conn; 35011da177e4SLinus Torvalds } 35021da177e4SLinus Torvalds 35036039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 35041da177e4SLinus Torvalds { 35051da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 35061da177e4SLinus Torvalds struct hci_conn *c; 35071da177e4SLinus Torvalds 3508bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 35091da177e4SLinus Torvalds 3510bf4c6325SGustavo F. Padovan rcu_read_lock(); 3511bf4c6325SGustavo F. Padovan 35121da177e4SLinus Torvalds /* Kill stalled connections */ 3513bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3514bae1f5d9SVille Tervo if (c->type == type && c->sent) { 35156ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 35166ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 3517bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 35181da177e4SLinus Torvalds } 35191da177e4SLinus Torvalds } 3520bf4c6325SGustavo F. Padovan 3521bf4c6325SGustavo F. Padovan rcu_read_unlock(); 35221da177e4SLinus Torvalds } 35231da177e4SLinus Torvalds 35246039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 352573d80debSLuiz Augusto von Dentz int *quote) 352673d80debSLuiz Augusto von Dentz { 352773d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 352873d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 3529abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 353073d80debSLuiz Augusto von Dentz struct hci_conn *conn; 353173d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 353273d80debSLuiz Augusto von Dentz 353373d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 353473d80debSLuiz Augusto von Dentz 3535bf4c6325SGustavo F. Padovan rcu_read_lock(); 3536bf4c6325SGustavo F. Padovan 3537bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 353873d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 353973d80debSLuiz Augusto von Dentz 354073d80debSLuiz Augusto von Dentz if (conn->type != type) 354173d80debSLuiz Augusto von Dentz continue; 354273d80debSLuiz Augusto von Dentz 354373d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 354473d80debSLuiz Augusto von Dentz continue; 354573d80debSLuiz Augusto von Dentz 354673d80debSLuiz Augusto von Dentz conn_num++; 354773d80debSLuiz Augusto von Dentz 35488192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 354973d80debSLuiz Augusto von Dentz struct sk_buff *skb; 355073d80debSLuiz Augusto von Dentz 355173d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 355273d80debSLuiz Augusto von Dentz continue; 355373d80debSLuiz Augusto von Dentz 355473d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 355573d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 355673d80debSLuiz Augusto von Dentz continue; 355773d80debSLuiz Augusto von Dentz 355873d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 355973d80debSLuiz Augusto von Dentz num = 0; 356073d80debSLuiz Augusto von Dentz min = ~0; 356173d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 356273d80debSLuiz Augusto von Dentz } 356373d80debSLuiz Augusto von Dentz 356473d80debSLuiz Augusto von Dentz num++; 356573d80debSLuiz Augusto von Dentz 356673d80debSLuiz Augusto von Dentz if (conn->sent < min) { 356773d80debSLuiz Augusto von Dentz min = conn->sent; 356873d80debSLuiz Augusto von Dentz chan = tmp; 356973d80debSLuiz Augusto von Dentz } 357073d80debSLuiz Augusto von Dentz } 357173d80debSLuiz Augusto von Dentz 357273d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 357373d80debSLuiz Augusto von Dentz break; 357473d80debSLuiz Augusto von Dentz } 357573d80debSLuiz Augusto von Dentz 3576bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3577bf4c6325SGustavo F. Padovan 357873d80debSLuiz Augusto von Dentz if (!chan) 357973d80debSLuiz Augusto von Dentz return NULL; 358073d80debSLuiz Augusto von Dentz 358173d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 358273d80debSLuiz Augusto von Dentz case ACL_LINK: 358373d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 358473d80debSLuiz Augusto von Dentz break; 3585bd1eb66bSAndrei Emeltchenko case AMP_LINK: 3586bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 3587bd1eb66bSAndrei Emeltchenko break; 358873d80debSLuiz Augusto von Dentz case SCO_LINK: 358973d80debSLuiz Augusto von Dentz case ESCO_LINK: 359073d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 359173d80debSLuiz Augusto von Dentz break; 359273d80debSLuiz Augusto von Dentz case LE_LINK: 359373d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 359473d80debSLuiz Augusto von Dentz break; 359573d80debSLuiz Augusto von Dentz default: 359673d80debSLuiz Augusto von Dentz cnt = 0; 359773d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 359873d80debSLuiz Augusto von Dentz } 359973d80debSLuiz Augusto von Dentz 360073d80debSLuiz Augusto von Dentz q = cnt / num; 360173d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 360273d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 360373d80debSLuiz Augusto von Dentz return chan; 360473d80debSLuiz Augusto von Dentz } 360573d80debSLuiz Augusto von Dentz 360602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 360702b20f0bSLuiz Augusto von Dentz { 360802b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 360902b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 361002b20f0bSLuiz Augusto von Dentz int num = 0; 361102b20f0bSLuiz Augusto von Dentz 361202b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 361302b20f0bSLuiz Augusto von Dentz 3614bf4c6325SGustavo F. Padovan rcu_read_lock(); 3615bf4c6325SGustavo F. Padovan 3616bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 361702b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 361802b20f0bSLuiz Augusto von Dentz 361902b20f0bSLuiz Augusto von Dentz if (conn->type != type) 362002b20f0bSLuiz Augusto von Dentz continue; 362102b20f0bSLuiz Augusto von Dentz 362202b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 362302b20f0bSLuiz Augusto von Dentz continue; 362402b20f0bSLuiz Augusto von Dentz 362502b20f0bSLuiz Augusto von Dentz num++; 362602b20f0bSLuiz Augusto von Dentz 36278192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 362802b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 362902b20f0bSLuiz Augusto von Dentz 363002b20f0bSLuiz Augusto von Dentz if (chan->sent) { 363102b20f0bSLuiz Augusto von Dentz chan->sent = 0; 363202b20f0bSLuiz Augusto von Dentz continue; 363302b20f0bSLuiz Augusto von Dentz } 363402b20f0bSLuiz Augusto von Dentz 363502b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 363602b20f0bSLuiz Augusto von Dentz continue; 363702b20f0bSLuiz Augusto von Dentz 363802b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 363902b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 364002b20f0bSLuiz Augusto von Dentz continue; 364102b20f0bSLuiz Augusto von Dentz 364202b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 364302b20f0bSLuiz Augusto von Dentz 364402b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 364502b20f0bSLuiz Augusto von Dentz skb->priority); 364602b20f0bSLuiz Augusto von Dentz } 364702b20f0bSLuiz Augusto von Dentz 364802b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 364902b20f0bSLuiz Augusto von Dentz break; 365002b20f0bSLuiz Augusto von Dentz } 3651bf4c6325SGustavo F. Padovan 3652bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3653bf4c6325SGustavo F. Padovan 365402b20f0bSLuiz Augusto von Dentz } 365502b20f0bSLuiz Augusto von Dentz 3656b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 3657b71d385aSAndrei Emeltchenko { 3658b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 3659b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 3660b71d385aSAndrei Emeltchenko } 3661b71d385aSAndrei Emeltchenko 36626039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 36631da177e4SLinus Torvalds { 36641da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 36651da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 36661da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 366763d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 36685f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 3669bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 36701da177e4SLinus Torvalds } 367163d2bc1bSAndrei Emeltchenko } 36721da177e4SLinus Torvalds 36736039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 367463d2bc1bSAndrei Emeltchenko { 367563d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 367663d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 367763d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 367863d2bc1bSAndrei Emeltchenko int quote; 367963d2bc1bSAndrei Emeltchenko 368063d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 368104837f64SMarcel Holtmann 368273d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 368373d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 3684ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3685ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 368673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 368773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 368873d80debSLuiz Augusto von Dentz 3689ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3690ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3691ec1cce24SLuiz Augusto von Dentz break; 3692ec1cce24SLuiz Augusto von Dentz 3693ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3694ec1cce24SLuiz Augusto von Dentz 369573d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 369673d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 369704837f64SMarcel Holtmann 369857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 36991da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 37001da177e4SLinus Torvalds 37011da177e4SLinus Torvalds hdev->acl_cnt--; 370273d80debSLuiz Augusto von Dentz chan->sent++; 370373d80debSLuiz Augusto von Dentz chan->conn->sent++; 37041da177e4SLinus Torvalds } 37051da177e4SLinus Torvalds } 370602b20f0bSLuiz Augusto von Dentz 370702b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 370802b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 37091da177e4SLinus Torvalds } 37101da177e4SLinus Torvalds 37116039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 3712b71d385aSAndrei Emeltchenko { 371363d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 3714b71d385aSAndrei Emeltchenko struct hci_chan *chan; 3715b71d385aSAndrei Emeltchenko struct sk_buff *skb; 3716b71d385aSAndrei Emeltchenko int quote; 3717bd1eb66bSAndrei Emeltchenko u8 type; 3718b71d385aSAndrei Emeltchenko 371963d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 3720b71d385aSAndrei Emeltchenko 3721bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3722bd1eb66bSAndrei Emeltchenko 3723bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 3724bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 3725bd1eb66bSAndrei Emeltchenko else 3726bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 3727bd1eb66bSAndrei Emeltchenko 3728b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 3729bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 3730b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 3731b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 3732b71d385aSAndrei Emeltchenko int blocks; 3733b71d385aSAndrei Emeltchenko 3734b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 3735b71d385aSAndrei Emeltchenko skb->len, skb->priority); 3736b71d385aSAndrei Emeltchenko 3737b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 3738b71d385aSAndrei Emeltchenko if (skb->priority < priority) 3739b71d385aSAndrei Emeltchenko break; 3740b71d385aSAndrei Emeltchenko 3741b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 3742b71d385aSAndrei Emeltchenko 3743b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 3744b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 3745b71d385aSAndrei Emeltchenko return; 3746b71d385aSAndrei Emeltchenko 3747b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 3748b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 3749b71d385aSAndrei Emeltchenko 375057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 3751b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 3752b71d385aSAndrei Emeltchenko 3753b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 3754b71d385aSAndrei Emeltchenko quote -= blocks; 3755b71d385aSAndrei Emeltchenko 3756b71d385aSAndrei Emeltchenko chan->sent += blocks; 3757b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 3758b71d385aSAndrei Emeltchenko } 3759b71d385aSAndrei Emeltchenko } 3760b71d385aSAndrei Emeltchenko 3761b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 3762bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 3763b71d385aSAndrei Emeltchenko } 3764b71d385aSAndrei Emeltchenko 37656039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 3766b71d385aSAndrei Emeltchenko { 3767b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3768b71d385aSAndrei Emeltchenko 3769bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 3770bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 3771bd1eb66bSAndrei Emeltchenko return; 3772bd1eb66bSAndrei Emeltchenko 3773bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 3774bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 3775b71d385aSAndrei Emeltchenko return; 3776b71d385aSAndrei Emeltchenko 3777b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 3778b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 3779b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 3780b71d385aSAndrei Emeltchenko break; 3781b71d385aSAndrei Emeltchenko 3782b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 3783b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 3784b71d385aSAndrei Emeltchenko break; 3785b71d385aSAndrei Emeltchenko } 3786b71d385aSAndrei Emeltchenko } 3787b71d385aSAndrei Emeltchenko 37881da177e4SLinus Torvalds /* Schedule SCO */ 37896039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 37901da177e4SLinus Torvalds { 37911da177e4SLinus Torvalds struct hci_conn *conn; 37921da177e4SLinus Torvalds struct sk_buff *skb; 37931da177e4SLinus Torvalds int quote; 37941da177e4SLinus Torvalds 37951da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 37961da177e4SLinus Torvalds 379752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 379852087a79SLuiz Augusto von Dentz return; 379952087a79SLuiz Augusto von Dentz 38001da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 38011da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 38021da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 380357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 38041da177e4SLinus Torvalds 38051da177e4SLinus Torvalds conn->sent++; 38061da177e4SLinus Torvalds if (conn->sent == ~0) 38071da177e4SLinus Torvalds conn->sent = 0; 38081da177e4SLinus Torvalds } 38091da177e4SLinus Torvalds } 38101da177e4SLinus Torvalds } 38111da177e4SLinus Torvalds 38126039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 3813b6a0dc82SMarcel Holtmann { 3814b6a0dc82SMarcel Holtmann struct hci_conn *conn; 3815b6a0dc82SMarcel Holtmann struct sk_buff *skb; 3816b6a0dc82SMarcel Holtmann int quote; 3817b6a0dc82SMarcel Holtmann 3818b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 3819b6a0dc82SMarcel Holtmann 382052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 382152087a79SLuiz Augusto von Dentz return; 382252087a79SLuiz Augusto von Dentz 38238fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 38248fc9ced3SGustavo Padovan "e))) { 3825b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 3826b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 382757d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 3828b6a0dc82SMarcel Holtmann 3829b6a0dc82SMarcel Holtmann conn->sent++; 3830b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 3831b6a0dc82SMarcel Holtmann conn->sent = 0; 3832b6a0dc82SMarcel Holtmann } 3833b6a0dc82SMarcel Holtmann } 3834b6a0dc82SMarcel Holtmann } 3835b6a0dc82SMarcel Holtmann 38366039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 38376ed58ec5SVille Tervo { 383873d80debSLuiz Augusto von Dentz struct hci_chan *chan; 38396ed58ec5SVille Tervo struct sk_buff *skb; 384002b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 38416ed58ec5SVille Tervo 38426ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 38436ed58ec5SVille Tervo 384452087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 384552087a79SLuiz Augusto von Dentz return; 384652087a79SLuiz Augusto von Dentz 38476ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 38486ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 38496ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 3850bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 38516ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 3852bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 38536ed58ec5SVille Tervo } 38546ed58ec5SVille Tervo 38556ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 385602b20f0bSLuiz Augusto von Dentz tmp = cnt; 385773d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 3858ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3859ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 386073d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 386173d80debSLuiz Augusto von Dentz skb->len, skb->priority); 38626ed58ec5SVille Tervo 3863ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3864ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3865ec1cce24SLuiz Augusto von Dentz break; 3866ec1cce24SLuiz Augusto von Dentz 3867ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3868ec1cce24SLuiz Augusto von Dentz 386957d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 38706ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 38716ed58ec5SVille Tervo 38726ed58ec5SVille Tervo cnt--; 387373d80debSLuiz Augusto von Dentz chan->sent++; 387473d80debSLuiz Augusto von Dentz chan->conn->sent++; 38756ed58ec5SVille Tervo } 38766ed58ec5SVille Tervo } 387773d80debSLuiz Augusto von Dentz 38786ed58ec5SVille Tervo if (hdev->le_pkts) 38796ed58ec5SVille Tervo hdev->le_cnt = cnt; 38806ed58ec5SVille Tervo else 38816ed58ec5SVille Tervo hdev->acl_cnt = cnt; 388202b20f0bSLuiz Augusto von Dentz 388302b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 388402b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 38856ed58ec5SVille Tervo } 38866ed58ec5SVille Tervo 38873eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 38881da177e4SLinus Torvalds { 38893eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 38901da177e4SLinus Torvalds struct sk_buff *skb; 38911da177e4SLinus Torvalds 38926ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 38936ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 38941da177e4SLinus Torvalds 389552de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 38961da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 38971da177e4SLinus Torvalds hci_sched_acl(hdev); 38981da177e4SLinus Torvalds hci_sched_sco(hdev); 3899b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 39006ed58ec5SVille Tervo hci_sched_le(hdev); 390152de599eSMarcel Holtmann } 39026ed58ec5SVille Tervo 39031da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 39041da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 390557d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 39061da177e4SLinus Torvalds } 39071da177e4SLinus Torvalds 390825985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 39091da177e4SLinus Torvalds 39101da177e4SLinus Torvalds /* ACL data packet */ 39116039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 39121da177e4SLinus Torvalds { 39131da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 39141da177e4SLinus Torvalds struct hci_conn *conn; 39151da177e4SLinus Torvalds __u16 handle, flags; 39161da177e4SLinus Torvalds 39171da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 39181da177e4SLinus Torvalds 39191da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 39201da177e4SLinus Torvalds flags = hci_flags(handle); 39211da177e4SLinus Torvalds handle = hci_handle(handle); 39221da177e4SLinus Torvalds 3923f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 3924a8c5fb1aSGustavo Padovan handle, flags); 39251da177e4SLinus Torvalds 39261da177e4SLinus Torvalds hdev->stat.acl_rx++; 39271da177e4SLinus Torvalds 39281da177e4SLinus Torvalds hci_dev_lock(hdev); 39291da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 39301da177e4SLinus Torvalds hci_dev_unlock(hdev); 39311da177e4SLinus Torvalds 39321da177e4SLinus Torvalds if (conn) { 393365983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 393404837f64SMarcel Holtmann 39351da177e4SLinus Torvalds /* Send to upper protocol */ 3936686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 39371da177e4SLinus Torvalds return; 39381da177e4SLinus Torvalds } else { 39391da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 39401da177e4SLinus Torvalds hdev->name, handle); 39411da177e4SLinus Torvalds } 39421da177e4SLinus Torvalds 39431da177e4SLinus Torvalds kfree_skb(skb); 39441da177e4SLinus Torvalds } 39451da177e4SLinus Torvalds 39461da177e4SLinus Torvalds /* SCO data packet */ 39476039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 39481da177e4SLinus Torvalds { 39491da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 39501da177e4SLinus Torvalds struct hci_conn *conn; 39511da177e4SLinus Torvalds __u16 handle; 39521da177e4SLinus Torvalds 39531da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 39541da177e4SLinus Torvalds 39551da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 39561da177e4SLinus Torvalds 3957f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 39581da177e4SLinus Torvalds 39591da177e4SLinus Torvalds hdev->stat.sco_rx++; 39601da177e4SLinus Torvalds 39611da177e4SLinus Torvalds hci_dev_lock(hdev); 39621da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 39631da177e4SLinus Torvalds hci_dev_unlock(hdev); 39641da177e4SLinus Torvalds 39651da177e4SLinus Torvalds if (conn) { 39661da177e4SLinus Torvalds /* Send to upper protocol */ 3967686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 39681da177e4SLinus Torvalds return; 39691da177e4SLinus Torvalds } else { 39701da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 39711da177e4SLinus Torvalds hdev->name, handle); 39721da177e4SLinus Torvalds } 39731da177e4SLinus Torvalds 39741da177e4SLinus Torvalds kfree_skb(skb); 39751da177e4SLinus Torvalds } 39761da177e4SLinus Torvalds 39779238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 39789238f36aSJohan Hedberg { 39799238f36aSJohan Hedberg struct sk_buff *skb; 39809238f36aSJohan Hedberg 39819238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 39829238f36aSJohan Hedberg if (!skb) 39839238f36aSJohan Hedberg return true; 39849238f36aSJohan Hedberg 39859238f36aSJohan Hedberg return bt_cb(skb)->req.start; 39869238f36aSJohan Hedberg } 39879238f36aSJohan Hedberg 398842c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 398942c6b129SJohan Hedberg { 399042c6b129SJohan Hedberg struct hci_command_hdr *sent; 399142c6b129SJohan Hedberg struct sk_buff *skb; 399242c6b129SJohan Hedberg u16 opcode; 399342c6b129SJohan Hedberg 399442c6b129SJohan Hedberg if (!hdev->sent_cmd) 399542c6b129SJohan Hedberg return; 399642c6b129SJohan Hedberg 399742c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 399842c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 399942c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 400042c6b129SJohan Hedberg return; 400142c6b129SJohan Hedberg 400242c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 400342c6b129SJohan Hedberg if (!skb) 400442c6b129SJohan Hedberg return; 400542c6b129SJohan Hedberg 400642c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 400742c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 400842c6b129SJohan Hedberg } 400942c6b129SJohan Hedberg 40109238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 40119238f36aSJohan Hedberg { 40129238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 40139238f36aSJohan Hedberg struct sk_buff *skb; 40149238f36aSJohan Hedberg unsigned long flags; 40159238f36aSJohan Hedberg 40169238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 40179238f36aSJohan Hedberg 401842c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 401942c6b129SJohan Hedberg * sent we need to do special handling of it. 40209238f36aSJohan Hedberg */ 402142c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 402242c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 402342c6b129SJohan Hedberg * reset complete event during init and any pending 402442c6b129SJohan Hedberg * command will never be completed. In such a case we 402542c6b129SJohan Hedberg * need to resend whatever was the last sent 402642c6b129SJohan Hedberg * command. 402742c6b129SJohan Hedberg */ 402842c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 402942c6b129SJohan Hedberg hci_resend_last(hdev); 403042c6b129SJohan Hedberg 40319238f36aSJohan Hedberg return; 403242c6b129SJohan Hedberg } 40339238f36aSJohan Hedberg 40349238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 40359238f36aSJohan Hedberg * this request the request is not yet complete. 40369238f36aSJohan Hedberg */ 40379238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 40389238f36aSJohan Hedberg return; 40399238f36aSJohan Hedberg 40409238f36aSJohan Hedberg /* If this was the last command in a request the complete 40419238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 40429238f36aSJohan Hedberg * command queue (hdev->cmd_q). 40439238f36aSJohan Hedberg */ 40449238f36aSJohan Hedberg if (hdev->sent_cmd) { 40459238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 404653e21fbcSJohan Hedberg 404753e21fbcSJohan Hedberg if (req_complete) { 404853e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 404953e21fbcSJohan Hedberg * avoid calling the callback more than once if 405053e21fbcSJohan Hedberg * this function gets called again. 405153e21fbcSJohan Hedberg */ 405253e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 405353e21fbcSJohan Hedberg 40549238f36aSJohan Hedberg goto call_complete; 40559238f36aSJohan Hedberg } 405653e21fbcSJohan Hedberg } 40579238f36aSJohan Hedberg 40589238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 40599238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 40609238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 40619238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 40629238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 40639238f36aSJohan Hedberg break; 40649238f36aSJohan Hedberg } 40659238f36aSJohan Hedberg 40669238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 40679238f36aSJohan Hedberg kfree_skb(skb); 40689238f36aSJohan Hedberg } 40699238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 40709238f36aSJohan Hedberg 40719238f36aSJohan Hedberg call_complete: 40729238f36aSJohan Hedberg if (req_complete) 40739238f36aSJohan Hedberg req_complete(hdev, status); 40749238f36aSJohan Hedberg } 40759238f36aSJohan Hedberg 4076b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 40771da177e4SLinus Torvalds { 4078b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 40791da177e4SLinus Torvalds struct sk_buff *skb; 40801da177e4SLinus Torvalds 40811da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 40821da177e4SLinus Torvalds 40831da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 4084cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4085cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4086cd82e61cSMarcel Holtmann 40871da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 40881da177e4SLinus Torvalds /* Send copy to the sockets */ 4089470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 40901da177e4SLinus Torvalds } 40911da177e4SLinus Torvalds 40920736cfa8SMarcel Holtmann if (test_bit(HCI_RAW, &hdev->flags) || 40930736cfa8SMarcel Holtmann test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 40941da177e4SLinus Torvalds kfree_skb(skb); 40951da177e4SLinus Torvalds continue; 40961da177e4SLinus Torvalds } 40971da177e4SLinus Torvalds 40981da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 40991da177e4SLinus Torvalds /* Don't process data packets in this states. */ 41000d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 41011da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 41021da177e4SLinus Torvalds case HCI_SCODATA_PKT: 41031da177e4SLinus Torvalds kfree_skb(skb); 41041da177e4SLinus Torvalds continue; 41053ff50b79SStephen Hemminger } 41061da177e4SLinus Torvalds } 41071da177e4SLinus Torvalds 41081da177e4SLinus Torvalds /* Process frame */ 41090d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 41101da177e4SLinus Torvalds case HCI_EVENT_PKT: 4111b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 41121da177e4SLinus Torvalds hci_event_packet(hdev, skb); 41131da177e4SLinus Torvalds break; 41141da177e4SLinus Torvalds 41151da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 41161da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 41171da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 41181da177e4SLinus Torvalds break; 41191da177e4SLinus Torvalds 41201da177e4SLinus Torvalds case HCI_SCODATA_PKT: 41211da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 41221da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 41231da177e4SLinus Torvalds break; 41241da177e4SLinus Torvalds 41251da177e4SLinus Torvalds default: 41261da177e4SLinus Torvalds kfree_skb(skb); 41271da177e4SLinus Torvalds break; 41281da177e4SLinus Torvalds } 41291da177e4SLinus Torvalds } 41301da177e4SLinus Torvalds } 41311da177e4SLinus Torvalds 4132c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 41331da177e4SLinus Torvalds { 4134c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 41351da177e4SLinus Torvalds struct sk_buff *skb; 41361da177e4SLinus Torvalds 41372104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 41382104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 41391da177e4SLinus Torvalds 41401da177e4SLinus Torvalds /* Send queued commands */ 41415a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 41425a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 41435a08ecceSAndrei Emeltchenko if (!skb) 41445a08ecceSAndrei Emeltchenko return; 41455a08ecceSAndrei Emeltchenko 41461da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 41471da177e4SLinus Torvalds 4148a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 414970f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 41501da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 415157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 41527bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 41537bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 41547bdb8a5cSSzymon Janc else 41556bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 41565f246e89SAndrei Emeltchenko jiffies + HCI_CMD_TIMEOUT); 41571da177e4SLinus Torvalds } else { 41581da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4159c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 41601da177e4SLinus Torvalds } 41611da177e4SLinus Torvalds } 41621da177e4SLinus Torvalds } 4163