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++) { 68dfb826a8SMarcel Holtmann seq_printf(f, "Page %u: 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 } 75dfb826a8SMarcel Holtmann hci_dev_unlock(hdev); 76dfb826a8SMarcel Holtmann 77dfb826a8SMarcel Holtmann return 0; 78dfb826a8SMarcel Holtmann } 79dfb826a8SMarcel Holtmann 80dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file) 81dfb826a8SMarcel Holtmann { 82dfb826a8SMarcel Holtmann return single_open(file, features_show, inode->i_private); 83dfb826a8SMarcel Holtmann } 84dfb826a8SMarcel Holtmann 85dfb826a8SMarcel Holtmann static const struct file_operations features_fops = { 86dfb826a8SMarcel Holtmann .open = features_open, 87dfb826a8SMarcel Holtmann .read = seq_read, 88dfb826a8SMarcel Holtmann .llseek = seq_lseek, 89dfb826a8SMarcel Holtmann .release = single_release, 90dfb826a8SMarcel Holtmann }; 91dfb826a8SMarcel Holtmann 9270afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p) 9370afe0b8SMarcel Holtmann { 9470afe0b8SMarcel Holtmann struct hci_dev *hdev = f->private; 9570afe0b8SMarcel Holtmann struct bdaddr_list *b; 9670afe0b8SMarcel Holtmann 9770afe0b8SMarcel Holtmann hci_dev_lock(hdev); 9870afe0b8SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) 99b25f0785SMarcel Holtmann seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); 10070afe0b8SMarcel Holtmann hci_dev_unlock(hdev); 10170afe0b8SMarcel Holtmann 10270afe0b8SMarcel Holtmann return 0; 10370afe0b8SMarcel Holtmann } 10470afe0b8SMarcel Holtmann 10570afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file) 10670afe0b8SMarcel Holtmann { 10770afe0b8SMarcel Holtmann return single_open(file, blacklist_show, inode->i_private); 10870afe0b8SMarcel Holtmann } 10970afe0b8SMarcel Holtmann 11070afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = { 11170afe0b8SMarcel Holtmann .open = blacklist_open, 11270afe0b8SMarcel Holtmann .read = seq_read, 11370afe0b8SMarcel Holtmann .llseek = seq_lseek, 11470afe0b8SMarcel Holtmann .release = single_release, 11570afe0b8SMarcel Holtmann }; 11670afe0b8SMarcel Holtmann 11747219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p) 11847219839SMarcel Holtmann { 11947219839SMarcel Holtmann struct hci_dev *hdev = f->private; 12047219839SMarcel Holtmann struct bt_uuid *uuid; 12147219839SMarcel Holtmann 12247219839SMarcel Holtmann hci_dev_lock(hdev); 12347219839SMarcel Holtmann list_for_each_entry(uuid, &hdev->uuids, list) { 12447219839SMarcel Holtmann u32 data0, data5; 12547219839SMarcel Holtmann u16 data1, data2, data3, data4; 12647219839SMarcel Holtmann 12747219839SMarcel Holtmann data5 = get_unaligned_le32(uuid); 12847219839SMarcel Holtmann data4 = get_unaligned_le16(uuid + 4); 12947219839SMarcel Holtmann data3 = get_unaligned_le16(uuid + 6); 13047219839SMarcel Holtmann data2 = get_unaligned_le16(uuid + 8); 13147219839SMarcel Holtmann data1 = get_unaligned_le16(uuid + 10); 13247219839SMarcel Holtmann data0 = get_unaligned_le32(uuid + 12); 13347219839SMarcel Holtmann 13447219839SMarcel Holtmann seq_printf(f, "%.8x-%.4x-%.4x-%.4x-%.4x%.8x\n", 13547219839SMarcel Holtmann data0, data1, data2, data3, data4, data5); 13647219839SMarcel Holtmann } 13747219839SMarcel Holtmann hci_dev_unlock(hdev); 13847219839SMarcel Holtmann 13947219839SMarcel Holtmann return 0; 14047219839SMarcel Holtmann } 14147219839SMarcel Holtmann 14247219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file) 14347219839SMarcel Holtmann { 14447219839SMarcel Holtmann return single_open(file, uuids_show, inode->i_private); 14547219839SMarcel Holtmann } 14647219839SMarcel Holtmann 14747219839SMarcel Holtmann static const struct file_operations uuids_fops = { 14847219839SMarcel Holtmann .open = uuids_open, 14947219839SMarcel Holtmann .read = seq_read, 15047219839SMarcel Holtmann .llseek = seq_lseek, 15147219839SMarcel Holtmann .release = single_release, 15247219839SMarcel Holtmann }; 15347219839SMarcel Holtmann 154baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p) 155baf27f6eSMarcel Holtmann { 156baf27f6eSMarcel Holtmann struct hci_dev *hdev = f->private; 157baf27f6eSMarcel Holtmann struct discovery_state *cache = &hdev->discovery; 158baf27f6eSMarcel Holtmann struct inquiry_entry *e; 159baf27f6eSMarcel Holtmann 160baf27f6eSMarcel Holtmann hci_dev_lock(hdev); 161baf27f6eSMarcel Holtmann 162baf27f6eSMarcel Holtmann list_for_each_entry(e, &cache->all, all) { 163baf27f6eSMarcel Holtmann struct inquiry_data *data = &e->data; 164baf27f6eSMarcel Holtmann seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", 165baf27f6eSMarcel Holtmann &data->bdaddr, 166baf27f6eSMarcel Holtmann data->pscan_rep_mode, data->pscan_period_mode, 167baf27f6eSMarcel Holtmann data->pscan_mode, data->dev_class[2], 168baf27f6eSMarcel Holtmann data->dev_class[1], data->dev_class[0], 169baf27f6eSMarcel Holtmann __le16_to_cpu(data->clock_offset), 170baf27f6eSMarcel Holtmann data->rssi, data->ssp_mode, e->timestamp); 171baf27f6eSMarcel Holtmann } 172baf27f6eSMarcel Holtmann 173baf27f6eSMarcel Holtmann hci_dev_unlock(hdev); 174baf27f6eSMarcel Holtmann 175baf27f6eSMarcel Holtmann return 0; 176baf27f6eSMarcel Holtmann } 177baf27f6eSMarcel Holtmann 178baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file) 179baf27f6eSMarcel Holtmann { 180baf27f6eSMarcel Holtmann return single_open(file, inquiry_cache_show, inode->i_private); 181baf27f6eSMarcel Holtmann } 182baf27f6eSMarcel Holtmann 183baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = { 184baf27f6eSMarcel Holtmann .open = inquiry_cache_open, 185baf27f6eSMarcel Holtmann .read = seq_read, 186baf27f6eSMarcel Holtmann .llseek = seq_lseek, 187baf27f6eSMarcel Holtmann .release = single_release, 188baf27f6eSMarcel Holtmann }; 189baf27f6eSMarcel Holtmann 19002d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr) 19102d08d15SMarcel Holtmann { 19202d08d15SMarcel Holtmann struct hci_dev *hdev = f->private; 19302d08d15SMarcel Holtmann struct list_head *p, *n; 19402d08d15SMarcel Holtmann 19502d08d15SMarcel Holtmann hci_dev_lock(hdev); 19602d08d15SMarcel Holtmann list_for_each_safe(p, n, &hdev->link_keys) { 19702d08d15SMarcel Holtmann struct link_key *key = list_entry(p, struct link_key, list); 19802d08d15SMarcel Holtmann seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type, 19902d08d15SMarcel Holtmann HCI_LINK_KEY_SIZE, key->val, key->pin_len); 20002d08d15SMarcel Holtmann } 20102d08d15SMarcel Holtmann hci_dev_unlock(hdev); 20202d08d15SMarcel Holtmann 20302d08d15SMarcel Holtmann return 0; 20402d08d15SMarcel Holtmann } 20502d08d15SMarcel Holtmann 20602d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file) 20702d08d15SMarcel Holtmann { 20802d08d15SMarcel Holtmann return single_open(file, link_keys_show, inode->i_private); 20902d08d15SMarcel Holtmann } 21002d08d15SMarcel Holtmann 21102d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = { 21202d08d15SMarcel Holtmann .open = link_keys_open, 21302d08d15SMarcel Holtmann .read = seq_read, 21402d08d15SMarcel Holtmann .llseek = seq_lseek, 21502d08d15SMarcel Holtmann .release = single_release, 21602d08d15SMarcel Holtmann }; 21702d08d15SMarcel Holtmann 218babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr) 219babdbb3cSMarcel Holtmann { 220babdbb3cSMarcel Holtmann struct hci_dev *hdev = f->private; 221babdbb3cSMarcel Holtmann 222babdbb3cSMarcel Holtmann hci_dev_lock(hdev); 223babdbb3cSMarcel Holtmann seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], 224babdbb3cSMarcel Holtmann hdev->dev_class[1], hdev->dev_class[0]); 225babdbb3cSMarcel Holtmann hci_dev_unlock(hdev); 226babdbb3cSMarcel Holtmann 227babdbb3cSMarcel Holtmann return 0; 228babdbb3cSMarcel Holtmann } 229babdbb3cSMarcel Holtmann 230babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file) 231babdbb3cSMarcel Holtmann { 232babdbb3cSMarcel Holtmann return single_open(file, dev_class_show, inode->i_private); 233babdbb3cSMarcel Holtmann } 234babdbb3cSMarcel Holtmann 235babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = { 236babdbb3cSMarcel Holtmann .open = dev_class_open, 237babdbb3cSMarcel Holtmann .read = seq_read, 238babdbb3cSMarcel Holtmann .llseek = seq_lseek, 239babdbb3cSMarcel Holtmann .release = single_release, 240babdbb3cSMarcel Holtmann }; 241babdbb3cSMarcel Holtmann 242041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val) 243041000b9SMarcel Holtmann { 244041000b9SMarcel Holtmann struct hci_dev *hdev = data; 245041000b9SMarcel Holtmann 246041000b9SMarcel Holtmann hci_dev_lock(hdev); 247041000b9SMarcel Holtmann *val = hdev->voice_setting; 248041000b9SMarcel Holtmann hci_dev_unlock(hdev); 249041000b9SMarcel Holtmann 250041000b9SMarcel Holtmann return 0; 251041000b9SMarcel Holtmann } 252041000b9SMarcel Holtmann 253041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get, 254041000b9SMarcel Holtmann NULL, "0x%4.4llx\n"); 255041000b9SMarcel Holtmann 256ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val) 257ebd1e33bSMarcel Holtmann { 258ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 259ebd1e33bSMarcel Holtmann 260ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 261ebd1e33bSMarcel Holtmann hdev->auto_accept_delay = val; 262ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 263ebd1e33bSMarcel Holtmann 264ebd1e33bSMarcel Holtmann return 0; 265ebd1e33bSMarcel Holtmann } 266ebd1e33bSMarcel Holtmann 267ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val) 268ebd1e33bSMarcel Holtmann { 269ebd1e33bSMarcel Holtmann struct hci_dev *hdev = data; 270ebd1e33bSMarcel Holtmann 271ebd1e33bSMarcel Holtmann hci_dev_lock(hdev); 272ebd1e33bSMarcel Holtmann *val = hdev->auto_accept_delay; 273ebd1e33bSMarcel Holtmann hci_dev_unlock(hdev); 274ebd1e33bSMarcel Holtmann 275ebd1e33bSMarcel Holtmann return 0; 276ebd1e33bSMarcel Holtmann } 277ebd1e33bSMarcel Holtmann 278ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, 279ebd1e33bSMarcel Holtmann auto_accept_delay_set, "%llu\n"); 280ebd1e33bSMarcel Holtmann 2812bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val) 2822bfa3531SMarcel Holtmann { 2832bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 2842bfa3531SMarcel Holtmann 2852bfa3531SMarcel Holtmann if (val != 0 && (val < 500 || val > 3600000)) 2862bfa3531SMarcel Holtmann return -EINVAL; 2872bfa3531SMarcel Holtmann 2882bfa3531SMarcel Holtmann hci_dev_lock(hdev); 2892bfa3531SMarcel Holtmann hdev->idle_timeout= val; 2902bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 2912bfa3531SMarcel Holtmann 2922bfa3531SMarcel Holtmann return 0; 2932bfa3531SMarcel Holtmann } 2942bfa3531SMarcel Holtmann 2952bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val) 2962bfa3531SMarcel Holtmann { 2972bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 2982bfa3531SMarcel Holtmann 2992bfa3531SMarcel Holtmann hci_dev_lock(hdev); 3002bfa3531SMarcel Holtmann *val = hdev->idle_timeout; 3012bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 3022bfa3531SMarcel Holtmann 3032bfa3531SMarcel Holtmann return 0; 3042bfa3531SMarcel Holtmann } 3052bfa3531SMarcel Holtmann 3062bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get, 3072bfa3531SMarcel Holtmann idle_timeout_set, "%llu\n"); 3082bfa3531SMarcel Holtmann 3092bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val) 3102bfa3531SMarcel Holtmann { 3112bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 3122bfa3531SMarcel Holtmann 3132bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val > hdev->sniff_max_interval) 3142bfa3531SMarcel Holtmann return -EINVAL; 3152bfa3531SMarcel Holtmann 3162bfa3531SMarcel Holtmann hci_dev_lock(hdev); 3172bfa3531SMarcel Holtmann hdev->sniff_min_interval= val; 3182bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 3192bfa3531SMarcel Holtmann 3202bfa3531SMarcel Holtmann return 0; 3212bfa3531SMarcel Holtmann } 3222bfa3531SMarcel Holtmann 3232bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val) 3242bfa3531SMarcel Holtmann { 3252bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 3262bfa3531SMarcel Holtmann 3272bfa3531SMarcel Holtmann hci_dev_lock(hdev); 3282bfa3531SMarcel Holtmann *val = hdev->sniff_min_interval; 3292bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 3302bfa3531SMarcel Holtmann 3312bfa3531SMarcel Holtmann return 0; 3322bfa3531SMarcel Holtmann } 3332bfa3531SMarcel Holtmann 3342bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get, 3352bfa3531SMarcel Holtmann sniff_min_interval_set, "%llu\n"); 3362bfa3531SMarcel Holtmann 3372bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val) 3382bfa3531SMarcel Holtmann { 3392bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 3402bfa3531SMarcel Holtmann 3412bfa3531SMarcel Holtmann if (val == 0 || val % 2 || val < hdev->sniff_min_interval) 3422bfa3531SMarcel Holtmann return -EINVAL; 3432bfa3531SMarcel Holtmann 3442bfa3531SMarcel Holtmann hci_dev_lock(hdev); 3452bfa3531SMarcel Holtmann hdev->sniff_max_interval= val; 3462bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 3472bfa3531SMarcel Holtmann 3482bfa3531SMarcel Holtmann return 0; 3492bfa3531SMarcel Holtmann } 3502bfa3531SMarcel Holtmann 3512bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val) 3522bfa3531SMarcel Holtmann { 3532bfa3531SMarcel Holtmann struct hci_dev *hdev = data; 3542bfa3531SMarcel Holtmann 3552bfa3531SMarcel Holtmann hci_dev_lock(hdev); 3562bfa3531SMarcel Holtmann *val = hdev->sniff_max_interval; 3572bfa3531SMarcel Holtmann hci_dev_unlock(hdev); 3582bfa3531SMarcel Holtmann 3592bfa3531SMarcel Holtmann return 0; 3602bfa3531SMarcel Holtmann } 3612bfa3531SMarcel Holtmann 3622bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, 3632bfa3531SMarcel Holtmann sniff_max_interval_set, "%llu\n"); 3642bfa3531SMarcel Holtmann 365e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p) 366e7b8fc92SMarcel Holtmann { 367e7b8fc92SMarcel Holtmann struct hci_dev *hdev = f->private; 368e7b8fc92SMarcel Holtmann 369e7b8fc92SMarcel Holtmann hci_dev_lock(hdev); 370e7b8fc92SMarcel Holtmann seq_printf(f, "%pMR\n", &hdev->static_addr); 371e7b8fc92SMarcel Holtmann hci_dev_unlock(hdev); 372e7b8fc92SMarcel Holtmann 373e7b8fc92SMarcel Holtmann return 0; 374e7b8fc92SMarcel Holtmann } 375e7b8fc92SMarcel Holtmann 376e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file) 377e7b8fc92SMarcel Holtmann { 378e7b8fc92SMarcel Holtmann return single_open(file, static_address_show, inode->i_private); 379e7b8fc92SMarcel Holtmann } 380e7b8fc92SMarcel Holtmann 381e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = { 382e7b8fc92SMarcel Holtmann .open = static_address_open, 383e7b8fc92SMarcel Holtmann .read = seq_read, 384e7b8fc92SMarcel Holtmann .llseek = seq_lseek, 385e7b8fc92SMarcel Holtmann .release = single_release, 386e7b8fc92SMarcel Holtmann }; 387e7b8fc92SMarcel Holtmann 38892202185SMarcel Holtmann static int own_address_type_set(void *data, u64 val) 38992202185SMarcel Holtmann { 39092202185SMarcel Holtmann struct hci_dev *hdev = data; 39192202185SMarcel Holtmann 39292202185SMarcel Holtmann if (val != 0 && val != 1) 39392202185SMarcel Holtmann return -EINVAL; 39492202185SMarcel Holtmann 39592202185SMarcel Holtmann hci_dev_lock(hdev); 39692202185SMarcel Holtmann hdev->own_addr_type = val; 39792202185SMarcel Holtmann hci_dev_unlock(hdev); 39892202185SMarcel Holtmann 39992202185SMarcel Holtmann return 0; 40092202185SMarcel Holtmann } 40192202185SMarcel Holtmann 40292202185SMarcel Holtmann static int own_address_type_get(void *data, u64 *val) 40392202185SMarcel Holtmann { 40492202185SMarcel Holtmann struct hci_dev *hdev = data; 40592202185SMarcel Holtmann 40692202185SMarcel Holtmann hci_dev_lock(hdev); 40792202185SMarcel Holtmann *val = hdev->own_addr_type; 40892202185SMarcel Holtmann hci_dev_unlock(hdev); 40992202185SMarcel Holtmann 41092202185SMarcel Holtmann return 0; 41192202185SMarcel Holtmann } 41292202185SMarcel Holtmann 41392202185SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get, 41492202185SMarcel Holtmann own_address_type_set, "%llu\n"); 41592202185SMarcel Holtmann 4168f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr) 4178f8625cdSMarcel Holtmann { 4188f8625cdSMarcel Holtmann struct hci_dev *hdev = f->private; 4198f8625cdSMarcel Holtmann struct list_head *p, *n; 4208f8625cdSMarcel Holtmann 4218f8625cdSMarcel Holtmann hci_dev_lock(hdev); 4228f8625cdSMarcel Holtmann list_for_each_safe(p, n, &hdev->link_keys) { 4238f8625cdSMarcel Holtmann struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list); 4248f8625cdSMarcel Holtmann seq_printf(f, "%pMR (type %u) %u %u %u %.4x %*phN %*phN\\n", 4258f8625cdSMarcel Holtmann <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, 4268f8625cdSMarcel Holtmann ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), 4278f8625cdSMarcel Holtmann 8, ltk->rand, 16, ltk->val); 4288f8625cdSMarcel Holtmann } 4298f8625cdSMarcel Holtmann hci_dev_unlock(hdev); 4308f8625cdSMarcel Holtmann 4318f8625cdSMarcel Holtmann return 0; 4328f8625cdSMarcel Holtmann } 4338f8625cdSMarcel Holtmann 4348f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file) 4358f8625cdSMarcel Holtmann { 4368f8625cdSMarcel Holtmann return single_open(file, long_term_keys_show, inode->i_private); 4378f8625cdSMarcel Holtmann } 4388f8625cdSMarcel Holtmann 4398f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = { 4408f8625cdSMarcel Holtmann .open = long_term_keys_open, 4418f8625cdSMarcel Holtmann .read = seq_read, 4428f8625cdSMarcel Holtmann .llseek = seq_lseek, 4438f8625cdSMarcel Holtmann .release = single_release, 4448f8625cdSMarcel Holtmann }; 4458f8625cdSMarcel Holtmann 4461da177e4SLinus Torvalds /* ---- HCI requests ---- */ 4471da177e4SLinus Torvalds 44842c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 4491da177e4SLinus Torvalds { 45042c6b129SJohan Hedberg BT_DBG("%s result 0x%2.2x", hdev->name, result); 45175fb0e32SJohan Hedberg 4521da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 4531da177e4SLinus Torvalds hdev->req_result = result; 4541da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 4551da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 4561da177e4SLinus Torvalds } 4571da177e4SLinus Torvalds } 4581da177e4SLinus Torvalds 4591da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 4601da177e4SLinus Torvalds { 4611da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 4621da177e4SLinus Torvalds 4631da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 4641da177e4SLinus Torvalds hdev->req_result = err; 4651da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 4661da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 4671da177e4SLinus Torvalds } 4681da177e4SLinus Torvalds } 4691da177e4SLinus Torvalds 47077a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 47177a63e0aSFengguang Wu u8 event) 47275e84b7cSJohan Hedberg { 47375e84b7cSJohan Hedberg struct hci_ev_cmd_complete *ev; 47475e84b7cSJohan Hedberg struct hci_event_hdr *hdr; 47575e84b7cSJohan Hedberg struct sk_buff *skb; 47675e84b7cSJohan Hedberg 47775e84b7cSJohan Hedberg hci_dev_lock(hdev); 47875e84b7cSJohan Hedberg 47975e84b7cSJohan Hedberg skb = hdev->recv_evt; 48075e84b7cSJohan Hedberg hdev->recv_evt = NULL; 48175e84b7cSJohan Hedberg 48275e84b7cSJohan Hedberg hci_dev_unlock(hdev); 48375e84b7cSJohan Hedberg 48475e84b7cSJohan Hedberg if (!skb) 48575e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 48675e84b7cSJohan Hedberg 48775e84b7cSJohan Hedberg if (skb->len < sizeof(*hdr)) { 48875e84b7cSJohan Hedberg BT_ERR("Too short HCI event"); 48975e84b7cSJohan Hedberg goto failed; 49075e84b7cSJohan Hedberg } 49175e84b7cSJohan Hedberg 49275e84b7cSJohan Hedberg hdr = (void *) skb->data; 49375e84b7cSJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 49475e84b7cSJohan Hedberg 4957b1abbbeSJohan Hedberg if (event) { 4967b1abbbeSJohan Hedberg if (hdr->evt != event) 4977b1abbbeSJohan Hedberg goto failed; 4987b1abbbeSJohan Hedberg return skb; 4997b1abbbeSJohan Hedberg } 5007b1abbbeSJohan Hedberg 50175e84b7cSJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 50275e84b7cSJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 50375e84b7cSJohan Hedberg goto failed; 50475e84b7cSJohan Hedberg } 50575e84b7cSJohan Hedberg 50675e84b7cSJohan Hedberg if (skb->len < sizeof(*ev)) { 50775e84b7cSJohan Hedberg BT_ERR("Too short cmd_complete event"); 50875e84b7cSJohan Hedberg goto failed; 50975e84b7cSJohan Hedberg } 51075e84b7cSJohan Hedberg 51175e84b7cSJohan Hedberg ev = (void *) skb->data; 51275e84b7cSJohan Hedberg skb_pull(skb, sizeof(*ev)); 51375e84b7cSJohan Hedberg 51475e84b7cSJohan Hedberg if (opcode == __le16_to_cpu(ev->opcode)) 51575e84b7cSJohan Hedberg return skb; 51675e84b7cSJohan Hedberg 51775e84b7cSJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 51875e84b7cSJohan Hedberg __le16_to_cpu(ev->opcode)); 51975e84b7cSJohan Hedberg 52075e84b7cSJohan Hedberg failed: 52175e84b7cSJohan Hedberg kfree_skb(skb); 52275e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 52375e84b7cSJohan Hedberg } 52475e84b7cSJohan Hedberg 5257b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 52607dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout) 52775e84b7cSJohan Hedberg { 52875e84b7cSJohan Hedberg DECLARE_WAITQUEUE(wait, current); 52975e84b7cSJohan Hedberg struct hci_request req; 53075e84b7cSJohan Hedberg int err = 0; 53175e84b7cSJohan Hedberg 53275e84b7cSJohan Hedberg BT_DBG("%s", hdev->name); 53375e84b7cSJohan Hedberg 53475e84b7cSJohan Hedberg hci_req_init(&req, hdev); 53575e84b7cSJohan Hedberg 5367b1abbbeSJohan Hedberg hci_req_add_ev(&req, opcode, plen, param, event); 53775e84b7cSJohan Hedberg 53875e84b7cSJohan Hedberg hdev->req_status = HCI_REQ_PEND; 53975e84b7cSJohan Hedberg 54075e84b7cSJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 54175e84b7cSJohan Hedberg if (err < 0) 54275e84b7cSJohan Hedberg return ERR_PTR(err); 54375e84b7cSJohan Hedberg 54475e84b7cSJohan Hedberg add_wait_queue(&hdev->req_wait_q, &wait); 54575e84b7cSJohan Hedberg set_current_state(TASK_INTERRUPTIBLE); 54675e84b7cSJohan Hedberg 54775e84b7cSJohan Hedberg schedule_timeout(timeout); 54875e84b7cSJohan Hedberg 54975e84b7cSJohan Hedberg remove_wait_queue(&hdev->req_wait_q, &wait); 55075e84b7cSJohan Hedberg 55175e84b7cSJohan Hedberg if (signal_pending(current)) 55275e84b7cSJohan Hedberg return ERR_PTR(-EINTR); 55375e84b7cSJohan Hedberg 55475e84b7cSJohan Hedberg switch (hdev->req_status) { 55575e84b7cSJohan Hedberg case HCI_REQ_DONE: 55675e84b7cSJohan Hedberg err = -bt_to_errno(hdev->req_result); 55775e84b7cSJohan Hedberg break; 55875e84b7cSJohan Hedberg 55975e84b7cSJohan Hedberg case HCI_REQ_CANCELED: 56075e84b7cSJohan Hedberg err = -hdev->req_result; 56175e84b7cSJohan Hedberg break; 56275e84b7cSJohan Hedberg 56375e84b7cSJohan Hedberg default: 56475e84b7cSJohan Hedberg err = -ETIMEDOUT; 56575e84b7cSJohan Hedberg break; 56675e84b7cSJohan Hedberg } 56775e84b7cSJohan Hedberg 56875e84b7cSJohan Hedberg hdev->req_status = hdev->req_result = 0; 56975e84b7cSJohan Hedberg 57075e84b7cSJohan Hedberg BT_DBG("%s end: err %d", hdev->name, err); 57175e84b7cSJohan Hedberg 57275e84b7cSJohan Hedberg if (err < 0) 57375e84b7cSJohan Hedberg return ERR_PTR(err); 57475e84b7cSJohan Hedberg 5757b1abbbeSJohan Hedberg return hci_get_cmd_complete(hdev, opcode, event); 5767b1abbbeSJohan Hedberg } 5777b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev); 5787b1abbbeSJohan Hedberg 5797b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 58007dc93ddSJohan Hedberg const void *param, u32 timeout) 5817b1abbbeSJohan Hedberg { 5827b1abbbeSJohan Hedberg return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); 58375e84b7cSJohan Hedberg } 58475e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync); 58575e84b7cSJohan Hedberg 5861da177e4SLinus Torvalds /* Execute request and wait for completion. */ 58701178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev, 58842c6b129SJohan Hedberg void (*func)(struct hci_request *req, 58942c6b129SJohan Hedberg unsigned long opt), 5901da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 5911da177e4SLinus Torvalds { 59242c6b129SJohan Hedberg struct hci_request req; 5931da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 5941da177e4SLinus Torvalds int err = 0; 5951da177e4SLinus Torvalds 5961da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 5971da177e4SLinus Torvalds 59842c6b129SJohan Hedberg hci_req_init(&req, hdev); 59942c6b129SJohan Hedberg 6001da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 6011da177e4SLinus Torvalds 60242c6b129SJohan Hedberg func(&req, opt); 60353cce22dSJohan Hedberg 60442c6b129SJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 60542c6b129SJohan Hedberg if (err < 0) { 60653cce22dSJohan Hedberg hdev->req_status = 0; 607920c8300SAndre Guedes 608920c8300SAndre Guedes /* ENODATA means the HCI request command queue is empty. 609920c8300SAndre Guedes * This can happen when a request with conditionals doesn't 610920c8300SAndre Guedes * trigger any commands to be sent. This is normal behavior 611920c8300SAndre Guedes * and should not trigger an error return. 61242c6b129SJohan Hedberg */ 613920c8300SAndre Guedes if (err == -ENODATA) 61442c6b129SJohan Hedberg return 0; 615920c8300SAndre Guedes 616920c8300SAndre Guedes return err; 61753cce22dSJohan Hedberg } 61853cce22dSJohan Hedberg 619bc4445c7SAndre Guedes add_wait_queue(&hdev->req_wait_q, &wait); 620bc4445c7SAndre Guedes set_current_state(TASK_INTERRUPTIBLE); 621bc4445c7SAndre Guedes 6221da177e4SLinus Torvalds schedule_timeout(timeout); 6231da177e4SLinus Torvalds 6241da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 6251da177e4SLinus Torvalds 6261da177e4SLinus Torvalds if (signal_pending(current)) 6271da177e4SLinus Torvalds return -EINTR; 6281da177e4SLinus Torvalds 6291da177e4SLinus Torvalds switch (hdev->req_status) { 6301da177e4SLinus Torvalds case HCI_REQ_DONE: 631e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 6321da177e4SLinus Torvalds break; 6331da177e4SLinus Torvalds 6341da177e4SLinus Torvalds case HCI_REQ_CANCELED: 6351da177e4SLinus Torvalds err = -hdev->req_result; 6361da177e4SLinus Torvalds break; 6371da177e4SLinus Torvalds 6381da177e4SLinus Torvalds default: 6391da177e4SLinus Torvalds err = -ETIMEDOUT; 6401da177e4SLinus Torvalds break; 6413ff50b79SStephen Hemminger } 6421da177e4SLinus Torvalds 643a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 6441da177e4SLinus Torvalds 6451da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 6461da177e4SLinus Torvalds 6471da177e4SLinus Torvalds return err; 6481da177e4SLinus Torvalds } 6491da177e4SLinus Torvalds 65001178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev, 65142c6b129SJohan Hedberg void (*req)(struct hci_request *req, 65242c6b129SJohan Hedberg unsigned long opt), 6531da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 6541da177e4SLinus Torvalds { 6551da177e4SLinus Torvalds int ret; 6561da177e4SLinus Torvalds 6577c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 6587c6a329eSMarcel Holtmann return -ENETDOWN; 6597c6a329eSMarcel Holtmann 6601da177e4SLinus Torvalds /* Serialize all requests */ 6611da177e4SLinus Torvalds hci_req_lock(hdev); 66201178cd4SJohan Hedberg ret = __hci_req_sync(hdev, req, opt, timeout); 6631da177e4SLinus Torvalds hci_req_unlock(hdev); 6641da177e4SLinus Torvalds 6651da177e4SLinus Torvalds return ret; 6661da177e4SLinus Torvalds } 6671da177e4SLinus Torvalds 66842c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt) 6691da177e4SLinus Torvalds { 67042c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 6711da177e4SLinus Torvalds 6721da177e4SLinus Torvalds /* Reset device */ 67342c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 67442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 6751da177e4SLinus Torvalds } 6761da177e4SLinus Torvalds 67742c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 6781da177e4SLinus Torvalds { 67942c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 6802455a3eaSAndrei Emeltchenko 6811da177e4SLinus Torvalds /* Read Local Supported Features */ 68242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 6831da177e4SLinus Torvalds 6841143e5a6SMarcel Holtmann /* Read Local Version */ 68542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 6862177bab5SJohan Hedberg 6872177bab5SJohan Hedberg /* Read BD Address */ 68842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 6891da177e4SLinus Torvalds } 6901da177e4SLinus Torvalds 69142c6b129SJohan Hedberg static void amp_init(struct hci_request *req) 692e61ef499SAndrei Emeltchenko { 69342c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 6942455a3eaSAndrei Emeltchenko 695e61ef499SAndrei Emeltchenko /* Read Local Version */ 69642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 6976bcbc489SAndrei Emeltchenko 698f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 699f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 700f6996cfeSMarcel Holtmann 701f6996cfeSMarcel Holtmann /* Read Local Supported Features */ 702f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 703f6996cfeSMarcel Holtmann 7046bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 70542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 706e71dfabaSAndrei Emeltchenko 707e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 70842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 7097528ca1cSMarcel Holtmann 710f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 711f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 712f38ba941SMarcel Holtmann 7137528ca1cSMarcel Holtmann /* Read Location Data */ 7147528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 715e61ef499SAndrei Emeltchenko } 716e61ef499SAndrei Emeltchenko 71742c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 718e61ef499SAndrei Emeltchenko { 71942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 720e61ef499SAndrei Emeltchenko 721e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 722e61ef499SAndrei Emeltchenko 72311778716SAndrei Emeltchenko /* Reset */ 72411778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 72542c6b129SJohan Hedberg hci_reset_req(req, 0); 72611778716SAndrei Emeltchenko 727e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 728e61ef499SAndrei Emeltchenko case HCI_BREDR: 72942c6b129SJohan Hedberg bredr_init(req); 730e61ef499SAndrei Emeltchenko break; 731e61ef499SAndrei Emeltchenko 732e61ef499SAndrei Emeltchenko case HCI_AMP: 73342c6b129SJohan Hedberg amp_init(req); 734e61ef499SAndrei Emeltchenko break; 735e61ef499SAndrei Emeltchenko 736e61ef499SAndrei Emeltchenko default: 737e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 738e61ef499SAndrei Emeltchenko break; 739e61ef499SAndrei Emeltchenko } 740e61ef499SAndrei Emeltchenko } 741e61ef499SAndrei Emeltchenko 74242c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 7432177bab5SJohan Hedberg { 7444ca048e3SMarcel Holtmann struct hci_dev *hdev = req->hdev; 7454ca048e3SMarcel Holtmann 7462177bab5SJohan Hedberg __le16 param; 7472177bab5SJohan Hedberg __u8 flt_type; 7482177bab5SJohan Hedberg 7492177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 75042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 7512177bab5SJohan Hedberg 7522177bab5SJohan Hedberg /* Read Class of Device */ 75342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 7542177bab5SJohan Hedberg 7552177bab5SJohan Hedberg /* Read Local Name */ 75642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 7572177bab5SJohan Hedberg 7582177bab5SJohan Hedberg /* Read Voice Setting */ 75942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 7602177bab5SJohan Hedberg 761b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 762b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 763b4cb9fb2SMarcel Holtmann 7644b836f39SMarcel Holtmann /* Read Current IAC LAP */ 7654b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 7664b836f39SMarcel Holtmann 7672177bab5SJohan Hedberg /* Clear Event Filters */ 7682177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 76942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 7702177bab5SJohan Hedberg 7712177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 7722177bab5SJohan Hedberg param = __constant_cpu_to_le16(0x7d00); 77342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 7742177bab5SJohan Hedberg 7754ca048e3SMarcel Holtmann /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, 7764ca048e3SMarcel Holtmann * but it does not support page scan related HCI commands. 7774ca048e3SMarcel Holtmann */ 7784ca048e3SMarcel Holtmann if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) { 779f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 780f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 781f332ec66SJohan Hedberg } 7822177bab5SJohan Hedberg } 7832177bab5SJohan Hedberg 78442c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 7852177bab5SJohan Hedberg { 786c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 787c73eee91SJohan Hedberg 7882177bab5SJohan Hedberg /* Read LE Buffer Size */ 78942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 7902177bab5SJohan Hedberg 7912177bab5SJohan Hedberg /* Read LE Local Supported Features */ 79242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 7932177bab5SJohan Hedberg 7942177bab5SJohan Hedberg /* Read LE Advertising Channel TX Power */ 79542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 7962177bab5SJohan Hedberg 7972177bab5SJohan Hedberg /* Read LE White List Size */ 79842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 7992177bab5SJohan Hedberg 8002177bab5SJohan Hedberg /* Read LE Supported States */ 80142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 802c73eee91SJohan Hedberg 803c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 804c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 805c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 8062177bab5SJohan Hedberg } 8072177bab5SJohan Hedberg 8082177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 8092177bab5SJohan Hedberg { 8102177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 8112177bab5SJohan Hedberg return 0x02; 8122177bab5SJohan Hedberg 8132177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 8142177bab5SJohan Hedberg return 0x01; 8152177bab5SJohan Hedberg 8162177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 8172177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 8182177bab5SJohan Hedberg return 0x01; 8192177bab5SJohan Hedberg 8202177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 8212177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 8222177bab5SJohan Hedberg return 0x01; 8232177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 8242177bab5SJohan Hedberg return 0x01; 8252177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 8262177bab5SJohan Hedberg return 0x01; 8272177bab5SJohan Hedberg } 8282177bab5SJohan Hedberg 8292177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 8302177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 8312177bab5SJohan Hedberg return 0x01; 8322177bab5SJohan Hedberg 8332177bab5SJohan Hedberg return 0x00; 8342177bab5SJohan Hedberg } 8352177bab5SJohan Hedberg 83642c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 8372177bab5SJohan Hedberg { 8382177bab5SJohan Hedberg u8 mode; 8392177bab5SJohan Hedberg 84042c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 8412177bab5SJohan Hedberg 84242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 8432177bab5SJohan Hedberg } 8442177bab5SJohan Hedberg 84542c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 8462177bab5SJohan Hedberg { 84742c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 84842c6b129SJohan Hedberg 8492177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 8502177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 8512177bab5SJohan Hedberg * command otherwise. 8522177bab5SJohan Hedberg */ 8532177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 8542177bab5SJohan Hedberg 8552177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 8562177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 8572177bab5SJohan Hedberg */ 8582177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 8592177bab5SJohan Hedberg return; 8602177bab5SJohan Hedberg 8612177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 8622177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 8632177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 8642177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 8652177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 8662177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 867c7882cbdSMarcel Holtmann } else { 868c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 869c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 870c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 871c7882cbdSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 872c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 873c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 874c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 875c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 876c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 877c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 878c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 8792177bab5SJohan Hedberg } 8802177bab5SJohan Hedberg 8812177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 8822177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 8832177bab5SJohan Hedberg 8842177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 8852177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 8862177bab5SJohan Hedberg 8872177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 8882177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 8892177bab5SJohan Hedberg 8902177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 8912177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 8922177bab5SJohan Hedberg 8932177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 8942177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 8952177bab5SJohan Hedberg 8962177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 8972177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 8982177bab5SJohan Hedberg 8992177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 9002177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 9012177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 9022177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 9032177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 9042177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 9052177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 9062177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 9072177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 9082177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 9092177bab5SJohan Hedberg * Features Notification 9102177bab5SJohan Hedberg */ 9112177bab5SJohan Hedberg } 9122177bab5SJohan Hedberg 9132177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 9142177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 9152177bab5SJohan Hedberg 91642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 9172177bab5SJohan Hedberg 9182177bab5SJohan Hedberg if (lmp_le_capable(hdev)) { 9192177bab5SJohan Hedberg memset(events, 0, sizeof(events)); 9202177bab5SJohan Hedberg events[0] = 0x1f; 92142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, 9222177bab5SJohan Hedberg sizeof(events), events); 9232177bab5SJohan Hedberg } 9242177bab5SJohan Hedberg } 9252177bab5SJohan Hedberg 92642c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 9272177bab5SJohan Hedberg { 92842c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 92942c6b129SJohan Hedberg 9302177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 93142c6b129SJohan Hedberg bredr_setup(req); 93256f87901SJohan Hedberg else 93356f87901SJohan Hedberg clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 9342177bab5SJohan Hedberg 9352177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 93642c6b129SJohan Hedberg le_setup(req); 9372177bab5SJohan Hedberg 93842c6b129SJohan Hedberg hci_setup_event_mask(req); 9392177bab5SJohan Hedberg 9403f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 9413f8e2d75SJohan Hedberg * local supported commands HCI command. 9423f8e2d75SJohan Hedberg */ 9433f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 94442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 9452177bab5SJohan Hedberg 9462177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 94757af75a8SMarcel Holtmann /* When SSP is available, then the host features page 94857af75a8SMarcel Holtmann * should also be available as well. However some 94957af75a8SMarcel Holtmann * controllers list the max_page as 0 as long as SSP 95057af75a8SMarcel Holtmann * has not been enabled. To achieve proper debugging 95157af75a8SMarcel Holtmann * output, force the minimum max_page to 1 at least. 95257af75a8SMarcel Holtmann */ 95357af75a8SMarcel Holtmann hdev->max_page = 0x01; 95457af75a8SMarcel Holtmann 9552177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 9562177bab5SJohan Hedberg u8 mode = 0x01; 95742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 9582177bab5SJohan Hedberg sizeof(mode), &mode); 9592177bab5SJohan Hedberg } else { 9602177bab5SJohan Hedberg struct hci_cp_write_eir cp; 9612177bab5SJohan Hedberg 9622177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 9632177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 9642177bab5SJohan Hedberg 96542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 9662177bab5SJohan Hedberg } 9672177bab5SJohan Hedberg } 9682177bab5SJohan Hedberg 9692177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 97042c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 9712177bab5SJohan Hedberg 9722177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 97342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 9742177bab5SJohan Hedberg 9752177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 9762177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 9772177bab5SJohan Hedberg 9782177bab5SJohan Hedberg cp.page = 0x01; 97942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 98042c6b129SJohan Hedberg sizeof(cp), &cp); 9812177bab5SJohan Hedberg } 9822177bab5SJohan Hedberg 9832177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 9842177bab5SJohan Hedberg u8 enable = 1; 98542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 9862177bab5SJohan Hedberg &enable); 9872177bab5SJohan Hedberg } 9882177bab5SJohan Hedberg } 9892177bab5SJohan Hedberg 99042c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 9912177bab5SJohan Hedberg { 99242c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 9932177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 9942177bab5SJohan Hedberg u16 link_policy = 0; 9952177bab5SJohan Hedberg 9962177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 9972177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 9982177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 9992177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 10002177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 10012177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 10022177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 10032177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 10042177bab5SJohan Hedberg 10052177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 100642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 10072177bab5SJohan Hedberg } 10082177bab5SJohan Hedberg 100942c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 10102177bab5SJohan Hedberg { 101142c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 10122177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 10132177bab5SJohan Hedberg 1014c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 1015c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 1016c73eee91SJohan Hedberg return; 1017c73eee91SJohan Hedberg 10182177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 10192177bab5SJohan Hedberg 10202177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 10212177bab5SJohan Hedberg cp.le = 0x01; 10222177bab5SJohan Hedberg cp.simul = lmp_le_br_capable(hdev); 10232177bab5SJohan Hedberg } 10242177bab5SJohan Hedberg 10252177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 102642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 10272177bab5SJohan Hedberg &cp); 10282177bab5SJohan Hedberg } 10292177bab5SJohan Hedberg 1030d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 1031d62e6d67SJohan Hedberg { 1032d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 1033d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1034d62e6d67SJohan Hedberg 1035d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 1036d62e6d67SJohan Hedberg * enable all necessary events for it. 1037d62e6d67SJohan Hedberg */ 1038d62e6d67SJohan Hedberg if (hdev->features[2][0] & 0x01) { 1039d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 1040d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 1041d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 1042d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 1043d62e6d67SJohan Hedberg } 1044d62e6d67SJohan Hedberg 1045d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 1046d62e6d67SJohan Hedberg * enable all necessary events for it. 1047d62e6d67SJohan Hedberg */ 1048d62e6d67SJohan Hedberg if (hdev->features[2][0] & 0x02) { 1049d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 1050d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 1051d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 1052d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 1053d62e6d67SJohan Hedberg } 1054d62e6d67SJohan Hedberg 1055d62e6d67SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 1056d62e6d67SJohan Hedberg } 1057d62e6d67SJohan Hedberg 105842c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 10592177bab5SJohan Hedberg { 106042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 1061d2c5d77fSJohan Hedberg u8 p; 106242c6b129SJohan Hedberg 1063b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 1064b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 1065b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 1066b8f4e068SGustavo Padovan * 1067b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 1068b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 1069b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 1070b8f4e068SGustavo Padovan * command redundant anyway. 1071b8f4e068SGustavo Padovan */ 107259f45d57SJohan Hedberg if (hdev->commands[6] & 0x80) { 107359f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 107459f45d57SJohan Hedberg 107559f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 107659f45d57SJohan Hedberg cp.delete_all = 0x01; 107759f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 107859f45d57SJohan Hedberg sizeof(cp), &cp); 107959f45d57SJohan Hedberg } 108059f45d57SJohan Hedberg 10812177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 108242c6b129SJohan Hedberg hci_setup_link_policy(req); 10832177bab5SJohan Hedberg 108479830f66SMarcel Holtmann if (lmp_le_capable(hdev)) { 108579830f66SMarcel Holtmann /* If the controller has a public BD_ADDR, then by 108679830f66SMarcel Holtmann * default use that one. If this is a LE only 108779830f66SMarcel Holtmann * controller without one, default to the random 108879830f66SMarcel Holtmann * address. 108979830f66SMarcel Holtmann */ 109079830f66SMarcel Holtmann if (bacmp(&hdev->bdaddr, BDADDR_ANY)) 109179830f66SMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_PUBLIC; 109279830f66SMarcel Holtmann else 109379830f66SMarcel Holtmann hdev->own_addr_type = ADDR_LE_DEV_RANDOM; 109479830f66SMarcel Holtmann 109542c6b129SJohan Hedberg hci_set_le_support(req); 109679830f66SMarcel Holtmann } 1097d2c5d77fSJohan Hedberg 1098d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 1099d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 1100d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 1101d2c5d77fSJohan Hedberg 1102d2c5d77fSJohan Hedberg cp.page = p; 1103d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 1104d2c5d77fSJohan Hedberg sizeof(cp), &cp); 1105d2c5d77fSJohan Hedberg } 11062177bab5SJohan Hedberg } 11072177bab5SJohan Hedberg 11085d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt) 11095d4e7e8dSJohan Hedberg { 11105d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 11115d4e7e8dSJohan Hedberg 1112d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 1113d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 1114d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 1115d62e6d67SJohan Hedberg 11165d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 11175d4e7e8dSJohan Hedberg if (hdev->features[2][0] & 0x04) 11185d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 11195d4e7e8dSJohan Hedberg } 11205d4e7e8dSJohan Hedberg 11212177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 11222177bab5SJohan Hedberg { 11232177bab5SJohan Hedberg int err; 11242177bab5SJohan Hedberg 11252177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 11262177bab5SJohan Hedberg if (err < 0) 11272177bab5SJohan Hedberg return err; 11282177bab5SJohan Hedberg 11292177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 11302177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 11312177bab5SJohan Hedberg * first stage init. 11322177bab5SJohan Hedberg */ 11332177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 11342177bab5SJohan Hedberg return 0; 11352177bab5SJohan Hedberg 11362177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 11372177bab5SJohan Hedberg if (err < 0) 11382177bab5SJohan Hedberg return err; 11392177bab5SJohan Hedberg 11405d4e7e8dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 11415d4e7e8dSJohan Hedberg if (err < 0) 11425d4e7e8dSJohan Hedberg return err; 11435d4e7e8dSJohan Hedberg 1144baf27f6eSMarcel Holtmann err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 1145baf27f6eSMarcel Holtmann if (err < 0) 1146baf27f6eSMarcel Holtmann return err; 1147baf27f6eSMarcel Holtmann 1148baf27f6eSMarcel Holtmann /* Only create debugfs entries during the initial setup 1149baf27f6eSMarcel Holtmann * phase and not every time the controller gets powered on. 1150baf27f6eSMarcel Holtmann */ 1151baf27f6eSMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 1152baf27f6eSMarcel Holtmann return 0; 1153baf27f6eSMarcel Holtmann 1154dfb826a8SMarcel Holtmann debugfs_create_file("features", 0444, hdev->debugfs, hdev, 1155dfb826a8SMarcel Holtmann &features_fops); 1156ceeb3bc0SMarcel Holtmann debugfs_create_u16("manufacturer", 0444, hdev->debugfs, 1157ceeb3bc0SMarcel Holtmann &hdev->manufacturer); 1158ceeb3bc0SMarcel Holtmann debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); 1159ceeb3bc0SMarcel Holtmann debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); 116070afe0b8SMarcel Holtmann debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, 116170afe0b8SMarcel Holtmann &blacklist_fops); 116247219839SMarcel Holtmann debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); 116347219839SMarcel Holtmann 1164baf27f6eSMarcel Holtmann if (lmp_bredr_capable(hdev)) { 1165baf27f6eSMarcel Holtmann debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, 1166baf27f6eSMarcel Holtmann hdev, &inquiry_cache_fops); 116702d08d15SMarcel Holtmann debugfs_create_file("link_keys", 0400, hdev->debugfs, 116802d08d15SMarcel Holtmann hdev, &link_keys_fops); 1169babdbb3cSMarcel Holtmann debugfs_create_file("dev_class", 0444, hdev->debugfs, 1170babdbb3cSMarcel Holtmann hdev, &dev_class_fops); 1171041000b9SMarcel Holtmann debugfs_create_file("voice_setting", 0444, hdev->debugfs, 1172041000b9SMarcel Holtmann hdev, &voice_setting_fops); 1173baf27f6eSMarcel Holtmann } 1174baf27f6eSMarcel Holtmann 1175ebd1e33bSMarcel Holtmann if (lmp_ssp_capable(hdev)) 1176ebd1e33bSMarcel Holtmann debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, 1177ebd1e33bSMarcel Holtmann hdev, &auto_accept_delay_fops); 1178ebd1e33bSMarcel Holtmann 11792bfa3531SMarcel Holtmann if (lmp_sniff_capable(hdev)) { 11802bfa3531SMarcel Holtmann debugfs_create_file("idle_timeout", 0644, hdev->debugfs, 11812bfa3531SMarcel Holtmann hdev, &idle_timeout_fops); 11822bfa3531SMarcel Holtmann debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs, 11832bfa3531SMarcel Holtmann hdev, &sniff_min_interval_fops); 11842bfa3531SMarcel Holtmann debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs, 11852bfa3531SMarcel Holtmann hdev, &sniff_max_interval_fops); 11862bfa3531SMarcel Holtmann } 11872bfa3531SMarcel Holtmann 1188d0f729b8SMarcel Holtmann if (lmp_le_capable(hdev)) { 1189d0f729b8SMarcel Holtmann debugfs_create_u8("white_list_size", 0444, hdev->debugfs, 1190d0f729b8SMarcel Holtmann &hdev->le_white_list_size); 1191e7b8fc92SMarcel Holtmann debugfs_create_file("static_address", 0444, hdev->debugfs, 1192e7b8fc92SMarcel Holtmann hdev, &static_address_fops); 119392202185SMarcel Holtmann debugfs_create_file("own_address_type", 0644, hdev->debugfs, 119492202185SMarcel Holtmann hdev, &own_address_type_fops); 11958f8625cdSMarcel Holtmann debugfs_create_file("long_term_keys", 0400, hdev->debugfs, 11968f8625cdSMarcel Holtmann hdev, &long_term_keys_fops); 1197d0f729b8SMarcel Holtmann } 1198e7b8fc92SMarcel Holtmann 1199baf27f6eSMarcel Holtmann return 0; 12002177bab5SJohan Hedberg } 12012177bab5SJohan Hedberg 120242c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 12031da177e4SLinus Torvalds { 12041da177e4SLinus Torvalds __u8 scan = opt; 12051da177e4SLinus Torvalds 120642c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 12071da177e4SLinus Torvalds 12081da177e4SLinus Torvalds /* Inquiry and Page scans */ 120942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 12101da177e4SLinus Torvalds } 12111da177e4SLinus Torvalds 121242c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 12131da177e4SLinus Torvalds { 12141da177e4SLinus Torvalds __u8 auth = opt; 12151da177e4SLinus Torvalds 121642c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 12171da177e4SLinus Torvalds 12181da177e4SLinus Torvalds /* Authentication */ 121942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 12201da177e4SLinus Torvalds } 12211da177e4SLinus Torvalds 122242c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 12231da177e4SLinus Torvalds { 12241da177e4SLinus Torvalds __u8 encrypt = opt; 12251da177e4SLinus Torvalds 122642c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 12271da177e4SLinus Torvalds 1228e4e8e37cSMarcel Holtmann /* Encryption */ 122942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 12301da177e4SLinus Torvalds } 12311da177e4SLinus Torvalds 123242c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 1233e4e8e37cSMarcel Holtmann { 1234e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 1235e4e8e37cSMarcel Holtmann 123642c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 1237e4e8e37cSMarcel Holtmann 1238e4e8e37cSMarcel Holtmann /* Default link policy */ 123942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 1240e4e8e37cSMarcel Holtmann } 1241e4e8e37cSMarcel Holtmann 12421da177e4SLinus Torvalds /* Get HCI device by index. 12431da177e4SLinus Torvalds * Device is held on return. */ 12441da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 12451da177e4SLinus Torvalds { 12468035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 12471da177e4SLinus Torvalds 12481da177e4SLinus Torvalds BT_DBG("%d", index); 12491da177e4SLinus Torvalds 12501da177e4SLinus Torvalds if (index < 0) 12511da177e4SLinus Torvalds return NULL; 12521da177e4SLinus Torvalds 12531da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 12548035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 12551da177e4SLinus Torvalds if (d->id == index) { 12561da177e4SLinus Torvalds hdev = hci_dev_hold(d); 12571da177e4SLinus Torvalds break; 12581da177e4SLinus Torvalds } 12591da177e4SLinus Torvalds } 12601da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 12611da177e4SLinus Torvalds return hdev; 12621da177e4SLinus Torvalds } 12631da177e4SLinus Torvalds 12641da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 1265ff9ef578SJohan Hedberg 126630dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 126730dc78e1SJohan Hedberg { 126830dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 126930dc78e1SJohan Hedberg 12706fbe195dSAndre Guedes switch (discov->state) { 1271343f935bSAndre Guedes case DISCOVERY_FINDING: 12726fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 127330dc78e1SJohan Hedberg return true; 127430dc78e1SJohan Hedberg 12756fbe195dSAndre Guedes default: 127630dc78e1SJohan Hedberg return false; 127730dc78e1SJohan Hedberg } 12786fbe195dSAndre Guedes } 127930dc78e1SJohan Hedberg 1280ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 1281ff9ef578SJohan Hedberg { 1282ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 1283ff9ef578SJohan Hedberg 1284ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 1285ff9ef578SJohan Hedberg return; 1286ff9ef578SJohan Hedberg 1287ff9ef578SJohan Hedberg switch (state) { 1288ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 12897b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 1290ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 1291ff9ef578SJohan Hedberg break; 1292ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 1293ff9ef578SJohan Hedberg break; 1294343f935bSAndre Guedes case DISCOVERY_FINDING: 1295ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 1296ff9ef578SJohan Hedberg break; 129730dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 129830dc78e1SJohan Hedberg break; 1299ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 1300ff9ef578SJohan Hedberg break; 1301ff9ef578SJohan Hedberg } 1302ff9ef578SJohan Hedberg 1303ff9ef578SJohan Hedberg hdev->discovery.state = state; 1304ff9ef578SJohan Hedberg } 1305ff9ef578SJohan Hedberg 13061f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 13071da177e4SLinus Torvalds { 130830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1309b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 13101da177e4SLinus Torvalds 1311561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 1312561aafbcSJohan Hedberg list_del(&p->all); 1313b57c1a56SJohan Hedberg kfree(p); 13141da177e4SLinus Torvalds } 1315561aafbcSJohan Hedberg 1316561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 1317561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 13181da177e4SLinus Torvalds } 13191da177e4SLinus Torvalds 1320a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 1321a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 13221da177e4SLinus Torvalds { 132330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 13241da177e4SLinus Torvalds struct inquiry_entry *e; 13251da177e4SLinus Torvalds 13266ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 13271da177e4SLinus Torvalds 1328561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 13291da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 13301da177e4SLinus Torvalds return e; 13311da177e4SLinus Torvalds } 13321da177e4SLinus Torvalds 1333b57c1a56SJohan Hedberg return NULL; 1334b57c1a56SJohan Hedberg } 1335b57c1a56SJohan Hedberg 1336561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 1337561aafbcSJohan Hedberg bdaddr_t *bdaddr) 1338561aafbcSJohan Hedberg { 133930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1340561aafbcSJohan Hedberg struct inquiry_entry *e; 1341561aafbcSJohan Hedberg 13426ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1343561aafbcSJohan Hedberg 1344561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 1345561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 1346561aafbcSJohan Hedberg return e; 1347561aafbcSJohan Hedberg } 1348561aafbcSJohan Hedberg 1349561aafbcSJohan Hedberg return NULL; 1350561aafbcSJohan Hedberg } 1351561aafbcSJohan Hedberg 135230dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 135330dc78e1SJohan Hedberg bdaddr_t *bdaddr, 135430dc78e1SJohan Hedberg int state) 135530dc78e1SJohan Hedberg { 135630dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 135730dc78e1SJohan Hedberg struct inquiry_entry *e; 135830dc78e1SJohan Hedberg 13596ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 136030dc78e1SJohan Hedberg 136130dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 136230dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 136330dc78e1SJohan Hedberg return e; 136430dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 136530dc78e1SJohan Hedberg return e; 136630dc78e1SJohan Hedberg } 136730dc78e1SJohan Hedberg 136830dc78e1SJohan Hedberg return NULL; 136930dc78e1SJohan Hedberg } 137030dc78e1SJohan Hedberg 1371a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 1372a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 1373a3d4e20aSJohan Hedberg { 1374a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1375a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 1376a3d4e20aSJohan Hedberg struct inquiry_entry *p; 1377a3d4e20aSJohan Hedberg 1378a3d4e20aSJohan Hedberg list_del(&ie->list); 1379a3d4e20aSJohan Hedberg 1380a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 1381a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 1382a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 1383a3d4e20aSJohan Hedberg break; 1384a3d4e20aSJohan Hedberg pos = &p->list; 1385a3d4e20aSJohan Hedberg } 1386a3d4e20aSJohan Hedberg 1387a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 1388a3d4e20aSJohan Hedberg } 1389a3d4e20aSJohan Hedberg 13903175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 1391388fc8faSJohan Hedberg bool name_known, bool *ssp) 13921da177e4SLinus Torvalds { 139330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 139470f23020SAndrei Emeltchenko struct inquiry_entry *ie; 13951da177e4SLinus Torvalds 13966ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 13971da177e4SLinus Torvalds 13982b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 13992b2fec4dSSzymon Janc 1400388fc8faSJohan Hedberg if (ssp) 1401388fc8faSJohan Hedberg *ssp = data->ssp_mode; 1402388fc8faSJohan Hedberg 140370f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 1404a3d4e20aSJohan Hedberg if (ie) { 1405388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 1406388fc8faSJohan Hedberg *ssp = true; 1407388fc8faSJohan Hedberg 1408a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 1409a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 1410a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 1411a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 1412a3d4e20aSJohan Hedberg } 1413a3d4e20aSJohan Hedberg 1414561aafbcSJohan Hedberg goto update; 1415a3d4e20aSJohan Hedberg } 1416561aafbcSJohan Hedberg 14171da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 141870f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 141970f23020SAndrei Emeltchenko if (!ie) 14203175405bSJohan Hedberg return false; 142170f23020SAndrei Emeltchenko 1422561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 1423561aafbcSJohan Hedberg 1424561aafbcSJohan Hedberg if (name_known) { 1425561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1426561aafbcSJohan Hedberg } else { 1427561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 1428561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 1429561aafbcSJohan Hedberg } 1430561aafbcSJohan Hedberg 1431561aafbcSJohan Hedberg update: 1432561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 1433561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 1434561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 1435561aafbcSJohan Hedberg list_del(&ie->list); 14361da177e4SLinus Torvalds } 14371da177e4SLinus Torvalds 143870f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 143970f23020SAndrei Emeltchenko ie->timestamp = jiffies; 14401da177e4SLinus Torvalds cache->timestamp = jiffies; 14413175405bSJohan Hedberg 14423175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 14433175405bSJohan Hedberg return false; 14443175405bSJohan Hedberg 14453175405bSJohan Hedberg return true; 14461da177e4SLinus Torvalds } 14471da177e4SLinus Torvalds 14481da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 14491da177e4SLinus Torvalds { 145030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 14511da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 14521da177e4SLinus Torvalds struct inquiry_entry *e; 14531da177e4SLinus Torvalds int copied = 0; 14541da177e4SLinus Torvalds 1455561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 14561da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 1457b57c1a56SJohan Hedberg 1458b57c1a56SJohan Hedberg if (copied >= num) 1459b57c1a56SJohan Hedberg break; 1460b57c1a56SJohan Hedberg 14611da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 14621da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 14631da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 14641da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 14651da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 14661da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1467b57c1a56SJohan Hedberg 14681da177e4SLinus Torvalds info++; 1469b57c1a56SJohan Hedberg copied++; 14701da177e4SLinus Torvalds } 14711da177e4SLinus Torvalds 14721da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 14731da177e4SLinus Torvalds return copied; 14741da177e4SLinus Torvalds } 14751da177e4SLinus Torvalds 147642c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 14771da177e4SLinus Torvalds { 14781da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 147942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 14801da177e4SLinus Torvalds struct hci_cp_inquiry cp; 14811da177e4SLinus Torvalds 14821da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 14831da177e4SLinus Torvalds 14841da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 14851da177e4SLinus Torvalds return; 14861da177e4SLinus Torvalds 14871da177e4SLinus Torvalds /* Start Inquiry */ 14881da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 14891da177e4SLinus Torvalds cp.length = ir->length; 14901da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 149142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 14921da177e4SLinus Torvalds } 14931da177e4SLinus Torvalds 14943e13fa1eSAndre Guedes static int wait_inquiry(void *word) 14953e13fa1eSAndre Guedes { 14963e13fa1eSAndre Guedes schedule(); 14973e13fa1eSAndre Guedes return signal_pending(current); 14983e13fa1eSAndre Guedes } 14993e13fa1eSAndre Guedes 15001da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 15011da177e4SLinus Torvalds { 15021da177e4SLinus Torvalds __u8 __user *ptr = arg; 15031da177e4SLinus Torvalds struct hci_inquiry_req ir; 15041da177e4SLinus Torvalds struct hci_dev *hdev; 15051da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 15061da177e4SLinus Torvalds long timeo; 15071da177e4SLinus Torvalds __u8 *buf; 15081da177e4SLinus Torvalds 15091da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 15101da177e4SLinus Torvalds return -EFAULT; 15111da177e4SLinus Torvalds 15125a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 15135a08ecceSAndrei Emeltchenko if (!hdev) 15141da177e4SLinus Torvalds return -ENODEV; 15151da177e4SLinus Torvalds 15160736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 15170736cfa8SMarcel Holtmann err = -EBUSY; 15180736cfa8SMarcel Holtmann goto done; 15190736cfa8SMarcel Holtmann } 15200736cfa8SMarcel Holtmann 15215b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 15225b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 15235b69bef5SMarcel Holtmann goto done; 15245b69bef5SMarcel Holtmann } 15255b69bef5SMarcel Holtmann 152656f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 152756f87901SJohan Hedberg err = -EOPNOTSUPP; 152856f87901SJohan Hedberg goto done; 152956f87901SJohan Hedberg } 153056f87901SJohan Hedberg 153109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 15321da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1533a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 15341f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 15351da177e4SLinus Torvalds do_inquiry = 1; 15361da177e4SLinus Torvalds } 153709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 15381da177e4SLinus Torvalds 153904837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 154070f23020SAndrei Emeltchenko 154170f23020SAndrei Emeltchenko if (do_inquiry) { 154201178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 154301178cd4SJohan Hedberg timeo); 154470f23020SAndrei Emeltchenko if (err < 0) 15451da177e4SLinus Torvalds goto done; 15463e13fa1eSAndre Guedes 15473e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 15483e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 15493e13fa1eSAndre Guedes */ 15503e13fa1eSAndre Guedes if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, 15513e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 15523e13fa1eSAndre Guedes return -EINTR; 155370f23020SAndrei Emeltchenko } 15541da177e4SLinus Torvalds 15558fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 15568fc9ced3SGustavo Padovan * 255 entries 15578fc9ced3SGustavo Padovan */ 15581da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 15591da177e4SLinus Torvalds 15601da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 15611da177e4SLinus Torvalds * copy it to the user space. 15621da177e4SLinus Torvalds */ 156370f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 156470f23020SAndrei Emeltchenko if (!buf) { 15651da177e4SLinus Torvalds err = -ENOMEM; 15661da177e4SLinus Torvalds goto done; 15671da177e4SLinus Torvalds } 15681da177e4SLinus Torvalds 156909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 15701da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 157109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 15721da177e4SLinus Torvalds 15731da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 15741da177e4SLinus Torvalds 15751da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 15761da177e4SLinus Torvalds ptr += sizeof(ir); 15771da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 15781da177e4SLinus Torvalds ir.num_rsp)) 15791da177e4SLinus Torvalds err = -EFAULT; 15801da177e4SLinus Torvalds } else 15811da177e4SLinus Torvalds err = -EFAULT; 15821da177e4SLinus Torvalds 15831da177e4SLinus Torvalds kfree(buf); 15841da177e4SLinus Torvalds 15851da177e4SLinus Torvalds done: 15861da177e4SLinus Torvalds hci_dev_put(hdev); 15871da177e4SLinus Torvalds return err; 15881da177e4SLinus Torvalds } 15891da177e4SLinus Torvalds 1590cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 15911da177e4SLinus Torvalds { 15921da177e4SLinus Torvalds int ret = 0; 15931da177e4SLinus Torvalds 15941da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 15951da177e4SLinus Torvalds 15961da177e4SLinus Torvalds hci_req_lock(hdev); 15971da177e4SLinus Torvalds 159894324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 159994324962SJohan Hovold ret = -ENODEV; 160094324962SJohan Hovold goto done; 160194324962SJohan Hovold } 160294324962SJohan Hovold 1603a5c8f270SMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 1604a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1605a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1606bf543036SJohan Hedberg */ 1607a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 1608611b30f7SMarcel Holtmann ret = -ERFKILL; 1609611b30f7SMarcel Holtmann goto done; 1610611b30f7SMarcel Holtmann } 1611611b30f7SMarcel Holtmann 1612a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 1613a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 1614a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1615a5c8f270SMarcel Holtmann * or not. 1616a5c8f270SMarcel Holtmann * 1617a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1618a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1619a5c8f270SMarcel Holtmann */ 1620a5c8f270SMarcel Holtmann if (hdev->dev_type == HCI_BREDR && 1621a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1622a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1623a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1624a5c8f270SMarcel Holtmann goto done; 1625a5c8f270SMarcel Holtmann } 1626a5c8f270SMarcel Holtmann } 1627a5c8f270SMarcel Holtmann 16281da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 16291da177e4SLinus Torvalds ret = -EALREADY; 16301da177e4SLinus Torvalds goto done; 16311da177e4SLinus Torvalds } 16321da177e4SLinus Torvalds 16331da177e4SLinus Torvalds if (hdev->open(hdev)) { 16341da177e4SLinus Torvalds ret = -EIO; 16351da177e4SLinus Torvalds goto done; 16361da177e4SLinus Torvalds } 16371da177e4SLinus Torvalds 16381da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 16391da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1640f41c70c4SMarcel Holtmann 1641f41c70c4SMarcel Holtmann if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags)) 1642f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1643f41c70c4SMarcel Holtmann 1644f41c70c4SMarcel Holtmann if (!ret) { 1645f41c70c4SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 1646f41c70c4SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 1647f41c70c4SMarcel Holtmann 16480736cfa8SMarcel Holtmann if (!test_bit(HCI_RAW, &hdev->flags) && 16490736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 16502177bab5SJohan Hedberg ret = __hci_init(hdev); 16511da177e4SLinus Torvalds } 16521da177e4SLinus Torvalds 1653f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1654f41c70c4SMarcel Holtmann 16551da177e4SLinus Torvalds if (!ret) { 16561da177e4SLinus Torvalds hci_dev_hold(hdev); 16571da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 16581da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 1659bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 16600736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 16611514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 166209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1663744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 166409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 166556e5cb86SJohan Hedberg } 16661da177e4SLinus Torvalds } else { 16671da177e4SLinus Torvalds /* Init failed, cleanup */ 16683eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1669c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 1670b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 16711da177e4SLinus Torvalds 16721da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 16731da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 16741da177e4SLinus Torvalds 16751da177e4SLinus Torvalds if (hdev->flush) 16761da177e4SLinus Torvalds hdev->flush(hdev); 16771da177e4SLinus Torvalds 16781da177e4SLinus Torvalds if (hdev->sent_cmd) { 16791da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 16801da177e4SLinus Torvalds hdev->sent_cmd = NULL; 16811da177e4SLinus Torvalds } 16821da177e4SLinus Torvalds 16831da177e4SLinus Torvalds hdev->close(hdev); 16841da177e4SLinus Torvalds hdev->flags = 0; 16851da177e4SLinus Torvalds } 16861da177e4SLinus Torvalds 16871da177e4SLinus Torvalds done: 16881da177e4SLinus Torvalds hci_req_unlock(hdev); 16891da177e4SLinus Torvalds return ret; 16901da177e4SLinus Torvalds } 16911da177e4SLinus Torvalds 1692cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 1693cbed0ca1SJohan Hedberg 1694cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 1695cbed0ca1SJohan Hedberg { 1696cbed0ca1SJohan Hedberg struct hci_dev *hdev; 1697cbed0ca1SJohan Hedberg int err; 1698cbed0ca1SJohan Hedberg 1699cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 1700cbed0ca1SJohan Hedberg if (!hdev) 1701cbed0ca1SJohan Hedberg return -ENODEV; 1702cbed0ca1SJohan Hedberg 1703e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 1704e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 1705e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 1706e1d08f40SJohan Hedberg * completed. 1707e1d08f40SJohan Hedberg */ 1708e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1709e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 1710e1d08f40SJohan Hedberg 1711a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 1712a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 1713a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 1714a5c8f270SMarcel Holtmann */ 1715e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 1716e1d08f40SJohan Hedberg 1717cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 1718cbed0ca1SJohan Hedberg 1719cbed0ca1SJohan Hedberg hci_dev_put(hdev); 1720cbed0ca1SJohan Hedberg 1721cbed0ca1SJohan Hedberg return err; 1722cbed0ca1SJohan Hedberg } 1723cbed0ca1SJohan Hedberg 17241da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 17251da177e4SLinus Torvalds { 17261da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 17271da177e4SLinus Torvalds 172878c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 172978c04c0bSVinicius Costa Gomes 17301da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 17311da177e4SLinus Torvalds hci_req_lock(hdev); 17321da177e4SLinus Torvalds 17331da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 1734b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 17351da177e4SLinus Torvalds hci_req_unlock(hdev); 17361da177e4SLinus Torvalds return 0; 17371da177e4SLinus Torvalds } 17381da177e4SLinus Torvalds 17393eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 17403eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1741b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 17421da177e4SLinus Torvalds 174316ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 1744e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 174516ab91abSJohan Hedberg hdev->discov_timeout = 0; 17465e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 1747310a3d48SMarcel Holtmann clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); 174816ab91abSJohan Hedberg } 174916ab91abSJohan Hedberg 1750a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 17517d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 17527d78525dSJohan Hedberg 17537ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 17547ba8b4beSAndre Guedes 175509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 17561f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 17571da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 175809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 17591da177e4SLinus Torvalds 17601da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 17611da177e4SLinus Torvalds 17621da177e4SLinus Torvalds if (hdev->flush) 17631da177e4SLinus Torvalds hdev->flush(hdev); 17641da177e4SLinus Torvalds 17651da177e4SLinus Torvalds /* Reset device */ 17661da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 17671da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 17688af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 17693a6afbd2SMarcel Holtmann !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 1770a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 17711da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 177201178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 17731da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 17741da177e4SLinus Torvalds } 17751da177e4SLinus Torvalds 1776c347b765SGustavo F. Padovan /* flush cmd work */ 1777c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 17781da177e4SLinus Torvalds 17791da177e4SLinus Torvalds /* Drop queues */ 17801da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 17811da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 17821da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 17831da177e4SLinus Torvalds 17841da177e4SLinus Torvalds /* Drop last sent command */ 17851da177e4SLinus Torvalds if (hdev->sent_cmd) { 1786b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 17871da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 17881da177e4SLinus Torvalds hdev->sent_cmd = NULL; 17891da177e4SLinus Torvalds } 17901da177e4SLinus Torvalds 1791b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 1792b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 1793b6ddb638SJohan Hedberg 17941da177e4SLinus Torvalds /* After this point our queues are empty 17951da177e4SLinus Torvalds * and no tasks are scheduled. */ 17961da177e4SLinus Torvalds hdev->close(hdev); 17971da177e4SLinus Torvalds 179835b973c9SJohan Hedberg /* Clear flags */ 179935b973c9SJohan Hedberg hdev->flags = 0; 180035b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 180135b973c9SJohan Hedberg 180293c311a0SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 180393c311a0SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 180409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1805744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 180609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18078ee56540SMarcel Holtmann } 180893c311a0SMarcel Holtmann } 18095add6af8SJohan Hedberg 1810ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 1811536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 1812ced5c338SAndrei Emeltchenko 1813e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 181409b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 1815e59fda8dSJohan Hedberg 18161da177e4SLinus Torvalds hci_req_unlock(hdev); 18171da177e4SLinus Torvalds 18181da177e4SLinus Torvalds hci_dev_put(hdev); 18191da177e4SLinus Torvalds return 0; 18201da177e4SLinus Torvalds } 18211da177e4SLinus Torvalds 18221da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 18231da177e4SLinus Torvalds { 18241da177e4SLinus Torvalds struct hci_dev *hdev; 18251da177e4SLinus Torvalds int err; 18261da177e4SLinus Torvalds 182770f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 182870f23020SAndrei Emeltchenko if (!hdev) 18291da177e4SLinus Torvalds return -ENODEV; 18308ee56540SMarcel Holtmann 18310736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 18320736cfa8SMarcel Holtmann err = -EBUSY; 18330736cfa8SMarcel Holtmann goto done; 18340736cfa8SMarcel Holtmann } 18350736cfa8SMarcel Holtmann 18368ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 18378ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 18388ee56540SMarcel Holtmann 18391da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 18408ee56540SMarcel Holtmann 18410736cfa8SMarcel Holtmann done: 18421da177e4SLinus Torvalds hci_dev_put(hdev); 18431da177e4SLinus Torvalds return err; 18441da177e4SLinus Torvalds } 18451da177e4SLinus Torvalds 18461da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 18471da177e4SLinus Torvalds { 18481da177e4SLinus Torvalds struct hci_dev *hdev; 18491da177e4SLinus Torvalds int ret = 0; 18501da177e4SLinus Torvalds 185170f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 185270f23020SAndrei Emeltchenko if (!hdev) 18531da177e4SLinus Torvalds return -ENODEV; 18541da177e4SLinus Torvalds 18551da177e4SLinus Torvalds hci_req_lock(hdev); 18561da177e4SLinus Torvalds 1857808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 1858808a049eSMarcel Holtmann ret = -ENETDOWN; 18591da177e4SLinus Torvalds goto done; 1860808a049eSMarcel Holtmann } 18611da177e4SLinus Torvalds 18620736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 18630736cfa8SMarcel Holtmann ret = -EBUSY; 18640736cfa8SMarcel Holtmann goto done; 18650736cfa8SMarcel Holtmann } 18660736cfa8SMarcel Holtmann 18671da177e4SLinus Torvalds /* Drop queues */ 18681da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 18691da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 18701da177e4SLinus Torvalds 187109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 18721f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 18731da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 187409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 18751da177e4SLinus Torvalds 18761da177e4SLinus Torvalds if (hdev->flush) 18771da177e4SLinus Torvalds hdev->flush(hdev); 18781da177e4SLinus Torvalds 18791da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 18806ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 18811da177e4SLinus Torvalds 18821da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 188301178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 18841da177e4SLinus Torvalds 18851da177e4SLinus Torvalds done: 18861da177e4SLinus Torvalds hci_req_unlock(hdev); 18871da177e4SLinus Torvalds hci_dev_put(hdev); 18881da177e4SLinus Torvalds return ret; 18891da177e4SLinus Torvalds } 18901da177e4SLinus Torvalds 18911da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 18921da177e4SLinus Torvalds { 18931da177e4SLinus Torvalds struct hci_dev *hdev; 18941da177e4SLinus Torvalds int ret = 0; 18951da177e4SLinus Torvalds 189670f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 189770f23020SAndrei Emeltchenko if (!hdev) 18981da177e4SLinus Torvalds return -ENODEV; 18991da177e4SLinus Torvalds 19000736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 19010736cfa8SMarcel Holtmann ret = -EBUSY; 19020736cfa8SMarcel Holtmann goto done; 19030736cfa8SMarcel Holtmann } 19040736cfa8SMarcel Holtmann 19051da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 19061da177e4SLinus Torvalds 19070736cfa8SMarcel Holtmann done: 19081da177e4SLinus Torvalds hci_dev_put(hdev); 19091da177e4SLinus Torvalds return ret; 19101da177e4SLinus Torvalds } 19111da177e4SLinus Torvalds 19121da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 19131da177e4SLinus Torvalds { 19141da177e4SLinus Torvalds struct hci_dev *hdev; 19151da177e4SLinus Torvalds struct hci_dev_req dr; 19161da177e4SLinus Torvalds int err = 0; 19171da177e4SLinus Torvalds 19181da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 19191da177e4SLinus Torvalds return -EFAULT; 19201da177e4SLinus Torvalds 192170f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 192270f23020SAndrei Emeltchenko if (!hdev) 19231da177e4SLinus Torvalds return -ENODEV; 19241da177e4SLinus Torvalds 19250736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 19260736cfa8SMarcel Holtmann err = -EBUSY; 19270736cfa8SMarcel Holtmann goto done; 19280736cfa8SMarcel Holtmann } 19290736cfa8SMarcel Holtmann 19305b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 19315b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 19325b69bef5SMarcel Holtmann goto done; 19335b69bef5SMarcel Holtmann } 19345b69bef5SMarcel Holtmann 193556f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 193656f87901SJohan Hedberg err = -EOPNOTSUPP; 193756f87901SJohan Hedberg goto done; 193856f87901SJohan Hedberg } 193956f87901SJohan Hedberg 19401da177e4SLinus Torvalds switch (cmd) { 19411da177e4SLinus Torvalds case HCISETAUTH: 194201178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 19435f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 19441da177e4SLinus Torvalds break; 19451da177e4SLinus Torvalds 19461da177e4SLinus Torvalds case HCISETENCRYPT: 19471da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 19481da177e4SLinus Torvalds err = -EOPNOTSUPP; 19491da177e4SLinus Torvalds break; 19501da177e4SLinus Torvalds } 19511da177e4SLinus Torvalds 19521da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 19531da177e4SLinus Torvalds /* Auth must be enabled first */ 195401178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 19555f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 19561da177e4SLinus Torvalds if (err) 19571da177e4SLinus Torvalds break; 19581da177e4SLinus Torvalds } 19591da177e4SLinus Torvalds 196001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 19615f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 19621da177e4SLinus Torvalds break; 19631da177e4SLinus Torvalds 19641da177e4SLinus Torvalds case HCISETSCAN: 196501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 19665f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 19671da177e4SLinus Torvalds break; 19681da177e4SLinus Torvalds 19691da177e4SLinus Torvalds case HCISETLINKPOL: 197001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 19715f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 19721da177e4SLinus Torvalds break; 19731da177e4SLinus Torvalds 19741da177e4SLinus Torvalds case HCISETLINKMODE: 1975e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 1976e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 1977e4e8e37cSMarcel Holtmann break; 1978e4e8e37cSMarcel Holtmann 1979e4e8e37cSMarcel Holtmann case HCISETPTYPE: 1980e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 19811da177e4SLinus Torvalds break; 19821da177e4SLinus Torvalds 19831da177e4SLinus Torvalds case HCISETACLMTU: 19841da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 19851da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 19861da177e4SLinus Torvalds break; 19871da177e4SLinus Torvalds 19881da177e4SLinus Torvalds case HCISETSCOMTU: 19891da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 19901da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 19911da177e4SLinus Torvalds break; 19921da177e4SLinus Torvalds 19931da177e4SLinus Torvalds default: 19941da177e4SLinus Torvalds err = -EINVAL; 19951da177e4SLinus Torvalds break; 19961da177e4SLinus Torvalds } 1997e4e8e37cSMarcel Holtmann 19980736cfa8SMarcel Holtmann done: 19991da177e4SLinus Torvalds hci_dev_put(hdev); 20001da177e4SLinus Torvalds return err; 20011da177e4SLinus Torvalds } 20021da177e4SLinus Torvalds 20031da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 20041da177e4SLinus Torvalds { 20058035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 20061da177e4SLinus Torvalds struct hci_dev_list_req *dl; 20071da177e4SLinus Torvalds struct hci_dev_req *dr; 20081da177e4SLinus Torvalds int n = 0, size, err; 20091da177e4SLinus Torvalds __u16 dev_num; 20101da177e4SLinus Torvalds 20111da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 20121da177e4SLinus Torvalds return -EFAULT; 20131da177e4SLinus Torvalds 20141da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 20151da177e4SLinus Torvalds return -EINVAL; 20161da177e4SLinus Torvalds 20171da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 20181da177e4SLinus Torvalds 201970f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 202070f23020SAndrei Emeltchenko if (!dl) 20211da177e4SLinus Torvalds return -ENOMEM; 20221da177e4SLinus Torvalds 20231da177e4SLinus Torvalds dr = dl->dev_req; 20241da177e4SLinus Torvalds 2025f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 20268035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 2027a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 2028e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 2029c542a06cSJohan Hedberg 2030a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2031a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2032c542a06cSJohan Hedberg 20331da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 20341da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 2035c542a06cSJohan Hedberg 20361da177e4SLinus Torvalds if (++n >= dev_num) 20371da177e4SLinus Torvalds break; 20381da177e4SLinus Torvalds } 2039f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 20401da177e4SLinus Torvalds 20411da177e4SLinus Torvalds dl->dev_num = n; 20421da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 20431da177e4SLinus Torvalds 20441da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 20451da177e4SLinus Torvalds kfree(dl); 20461da177e4SLinus Torvalds 20471da177e4SLinus Torvalds return err ? -EFAULT : 0; 20481da177e4SLinus Torvalds } 20491da177e4SLinus Torvalds 20501da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 20511da177e4SLinus Torvalds { 20521da177e4SLinus Torvalds struct hci_dev *hdev; 20531da177e4SLinus Torvalds struct hci_dev_info di; 20541da177e4SLinus Torvalds int err = 0; 20551da177e4SLinus Torvalds 20561da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 20571da177e4SLinus Torvalds return -EFAULT; 20581da177e4SLinus Torvalds 205970f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 206070f23020SAndrei Emeltchenko if (!hdev) 20611da177e4SLinus Torvalds return -ENODEV; 20621da177e4SLinus Torvalds 2063a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 20643243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 2065ab81cbf9SJohan Hedberg 2066a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2067a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 2068c542a06cSJohan Hedberg 20691da177e4SLinus Torvalds strcpy(di.name, hdev->name); 20701da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 207160f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 20721da177e4SLinus Torvalds di.flags = hdev->flags; 20731da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 2074572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 20751da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 20761da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 20771da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 20781da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 2079572c7f84SJohan Hedberg } else { 2080572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 2081572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 2082572c7f84SJohan Hedberg di.sco_mtu = 0; 2083572c7f84SJohan Hedberg di.sco_pkts = 0; 2084572c7f84SJohan Hedberg } 20851da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 20861da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 20871da177e4SLinus Torvalds 20881da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 20891da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 20901da177e4SLinus Torvalds 20911da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 20921da177e4SLinus Torvalds err = -EFAULT; 20931da177e4SLinus Torvalds 20941da177e4SLinus Torvalds hci_dev_put(hdev); 20951da177e4SLinus Torvalds 20961da177e4SLinus Torvalds return err; 20971da177e4SLinus Torvalds } 20981da177e4SLinus Torvalds 20991da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 21001da177e4SLinus Torvalds 2101611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 2102611b30f7SMarcel Holtmann { 2103611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 2104611b30f7SMarcel Holtmann 2105611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 2106611b30f7SMarcel Holtmann 21070736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 21080736cfa8SMarcel Holtmann return -EBUSY; 21090736cfa8SMarcel Holtmann 21105e130367SJohan Hedberg if (blocked) { 21115e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 2112bf543036SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 2113611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 21145e130367SJohan Hedberg } else { 21155e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 21165e130367SJohan Hedberg } 2117611b30f7SMarcel Holtmann 2118611b30f7SMarcel Holtmann return 0; 2119611b30f7SMarcel Holtmann } 2120611b30f7SMarcel Holtmann 2121611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 2122611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 2123611b30f7SMarcel Holtmann }; 2124611b30f7SMarcel Holtmann 2125ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 2126ab81cbf9SJohan Hedberg { 2127ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 212896570ffcSJohan Hedberg int err; 2129ab81cbf9SJohan Hedberg 2130ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2131ab81cbf9SJohan Hedberg 2132cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 213396570ffcSJohan Hedberg if (err < 0) { 213496570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 2135ab81cbf9SJohan Hedberg return; 213696570ffcSJohan Hedberg } 2137ab81cbf9SJohan Hedberg 2138a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 2139a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 2140a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 2141a5c8f270SMarcel Holtmann */ 2142a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 2143a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 2144a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 2145a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 2146bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2147bf543036SJohan Hedberg hci_dev_do_close(hdev); 2148bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 214919202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 215019202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 2151bf543036SJohan Hedberg } 2152ab81cbf9SJohan Hedberg 2153a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 2154744cf19eSJohan Hedberg mgmt_index_added(hdev); 2155ab81cbf9SJohan Hedberg } 2156ab81cbf9SJohan Hedberg 2157ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 2158ab81cbf9SJohan Hedberg { 21593243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 21603243553fSJohan Hedberg power_off.work); 2161ab81cbf9SJohan Hedberg 2162ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 2163ab81cbf9SJohan Hedberg 21648ee56540SMarcel Holtmann hci_dev_do_close(hdev); 2165ab81cbf9SJohan Hedberg } 2166ab81cbf9SJohan Hedberg 216716ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 216816ab91abSJohan Hedberg { 216916ab91abSJohan Hedberg struct hci_dev *hdev; 217016ab91abSJohan Hedberg 217116ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 217216ab91abSJohan Hedberg 217316ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 217416ab91abSJohan Hedberg 2175d1967ff8SMarcel Holtmann mgmt_discoverable_timeout(hdev); 217616ab91abSJohan Hedberg } 217716ab91abSJohan Hedberg 21782aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 21792aeb9a1aSJohan Hedberg { 21804821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 21812aeb9a1aSJohan Hedberg 21824821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 21834821002cSJohan Hedberg list_del(&uuid->list); 21842aeb9a1aSJohan Hedberg kfree(uuid); 21852aeb9a1aSJohan Hedberg } 21862aeb9a1aSJohan Hedberg 21872aeb9a1aSJohan Hedberg return 0; 21882aeb9a1aSJohan Hedberg } 21892aeb9a1aSJohan Hedberg 219055ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 219155ed8ca1SJohan Hedberg { 219255ed8ca1SJohan Hedberg struct list_head *p, *n; 219355ed8ca1SJohan Hedberg 219455ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 219555ed8ca1SJohan Hedberg struct link_key *key; 219655ed8ca1SJohan Hedberg 219755ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 219855ed8ca1SJohan Hedberg 219955ed8ca1SJohan Hedberg list_del(p); 220055ed8ca1SJohan Hedberg kfree(key); 220155ed8ca1SJohan Hedberg } 220255ed8ca1SJohan Hedberg 220355ed8ca1SJohan Hedberg return 0; 220455ed8ca1SJohan Hedberg } 220555ed8ca1SJohan Hedberg 2206b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 2207b899efafSVinicius Costa Gomes { 2208b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2209b899efafSVinicius Costa Gomes 2210b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2211b899efafSVinicius Costa Gomes list_del(&k->list); 2212b899efafSVinicius Costa Gomes kfree(k); 2213b899efafSVinicius Costa Gomes } 2214b899efafSVinicius Costa Gomes 2215b899efafSVinicius Costa Gomes return 0; 2216b899efafSVinicius Costa Gomes } 2217b899efafSVinicius Costa Gomes 221855ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 221955ed8ca1SJohan Hedberg { 222055ed8ca1SJohan Hedberg struct link_key *k; 222155ed8ca1SJohan Hedberg 22228035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 222355ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 222455ed8ca1SJohan Hedberg return k; 222555ed8ca1SJohan Hedberg 222655ed8ca1SJohan Hedberg return NULL; 222755ed8ca1SJohan Hedberg } 222855ed8ca1SJohan Hedberg 2229745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 2230d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 2231d25e28abSJohan Hedberg { 2232d25e28abSJohan Hedberg /* Legacy key */ 2233d25e28abSJohan Hedberg if (key_type < 0x03) 2234745c0ce3SVishal Agarwal return true; 2235d25e28abSJohan Hedberg 2236d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 2237d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 2238745c0ce3SVishal Agarwal return false; 2239d25e28abSJohan Hedberg 2240d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 2241d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 2242745c0ce3SVishal Agarwal return false; 2243d25e28abSJohan Hedberg 2244d25e28abSJohan Hedberg /* Security mode 3 case */ 2245d25e28abSJohan Hedberg if (!conn) 2246745c0ce3SVishal Agarwal return true; 2247d25e28abSJohan Hedberg 2248d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 2249d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 2250745c0ce3SVishal Agarwal return true; 2251d25e28abSJohan Hedberg 2252d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 2253d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 2254745c0ce3SVishal Agarwal return true; 2255d25e28abSJohan Hedberg 2256d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 2257d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 2258745c0ce3SVishal Agarwal return true; 2259d25e28abSJohan Hedberg 2260d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 2261d25e28abSJohan Hedberg * persistently */ 2262745c0ce3SVishal Agarwal return false; 2263d25e28abSJohan Hedberg } 2264d25e28abSJohan Hedberg 2265c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 226675d262c2SVinicius Costa Gomes { 2267c9839a11SVinicius Costa Gomes struct smp_ltk *k; 226875d262c2SVinicius Costa Gomes 2269c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 2270c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 2271c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 227275d262c2SVinicius Costa Gomes continue; 227375d262c2SVinicius Costa Gomes 227475d262c2SVinicius Costa Gomes return k; 227575d262c2SVinicius Costa Gomes } 227675d262c2SVinicius Costa Gomes 227775d262c2SVinicius Costa Gomes return NULL; 227875d262c2SVinicius Costa Gomes } 227975d262c2SVinicius Costa Gomes 2280c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2281c9839a11SVinicius Costa Gomes u8 addr_type) 228275d262c2SVinicius Costa Gomes { 2283c9839a11SVinicius Costa Gomes struct smp_ltk *k; 228475d262c2SVinicius Costa Gomes 2285c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 2286c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 2287c9839a11SVinicius Costa Gomes bacmp(bdaddr, &k->bdaddr) == 0) 228875d262c2SVinicius Costa Gomes return k; 228975d262c2SVinicius Costa Gomes 229075d262c2SVinicius Costa Gomes return NULL; 229175d262c2SVinicius Costa Gomes } 229275d262c2SVinicius Costa Gomes 2293d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 2294d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 229555ed8ca1SJohan Hedberg { 229655ed8ca1SJohan Hedberg struct link_key *key, *old_key; 2297745c0ce3SVishal Agarwal u8 old_key_type; 2298745c0ce3SVishal Agarwal bool persistent; 229955ed8ca1SJohan Hedberg 230055ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 230155ed8ca1SJohan Hedberg if (old_key) { 230255ed8ca1SJohan Hedberg old_key_type = old_key->type; 230355ed8ca1SJohan Hedberg key = old_key; 230455ed8ca1SJohan Hedberg } else { 230512adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 230655ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 230755ed8ca1SJohan Hedberg if (!key) 230855ed8ca1SJohan Hedberg return -ENOMEM; 230955ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 231055ed8ca1SJohan Hedberg } 231155ed8ca1SJohan Hedberg 23126ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 231355ed8ca1SJohan Hedberg 2314d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 2315d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 2316d25e28abSJohan Hedberg * previous key */ 2317d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 2318a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 2319d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 2320655fe6ecSJohan Hedberg if (conn) 2321655fe6ecSJohan Hedberg conn->key_type = type; 2322655fe6ecSJohan Hedberg } 2323d25e28abSJohan Hedberg 232455ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 23259b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 232655ed8ca1SJohan Hedberg key->pin_len = pin_len; 232755ed8ca1SJohan Hedberg 2328b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 232955ed8ca1SJohan Hedberg key->type = old_key_type; 23304748fed2SJohan Hedberg else 23314748fed2SJohan Hedberg key->type = type; 23324748fed2SJohan Hedberg 23334df378a1SJohan Hedberg if (!new_key) 23344df378a1SJohan Hedberg return 0; 23354df378a1SJohan Hedberg 23364df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 23374df378a1SJohan Hedberg 2338744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 23394df378a1SJohan Hedberg 23406ec5bcadSVishal Agarwal if (conn) 23416ec5bcadSVishal Agarwal conn->flush_key = !persistent; 234255ed8ca1SJohan Hedberg 234355ed8ca1SJohan Hedberg return 0; 234455ed8ca1SJohan Hedberg } 234555ed8ca1SJohan Hedberg 2346c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 23479a006657SAndrei Emeltchenko int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 234804124681SGustavo F. Padovan ediv, u8 rand[8]) 234975d262c2SVinicius Costa Gomes { 2350c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 235175d262c2SVinicius Costa Gomes 2352c9839a11SVinicius Costa Gomes if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 2353c9839a11SVinicius Costa Gomes return 0; 235475d262c2SVinicius Costa Gomes 2355c9839a11SVinicius Costa Gomes old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 2356c9839a11SVinicius Costa Gomes if (old_key) 235775d262c2SVinicius Costa Gomes key = old_key; 2358c9839a11SVinicius Costa Gomes else { 2359c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 236075d262c2SVinicius Costa Gomes if (!key) 236175d262c2SVinicius Costa Gomes return -ENOMEM; 2362c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 236375d262c2SVinicius Costa Gomes } 236475d262c2SVinicius Costa Gomes 236575d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 2366c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 2367c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 2368c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 2369c9839a11SVinicius Costa Gomes key->ediv = ediv; 2370c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2371c9839a11SVinicius Costa Gomes key->type = type; 2372c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 237375d262c2SVinicius Costa Gomes 2374c9839a11SVinicius Costa Gomes if (!new_key) 2375c9839a11SVinicius Costa Gomes return 0; 237675d262c2SVinicius Costa Gomes 2377261cc5aaSVinicius Costa Gomes if (type & HCI_SMP_LTK) 2378261cc5aaSVinicius Costa Gomes mgmt_new_ltk(hdev, key, 1); 2379261cc5aaSVinicius Costa Gomes 238075d262c2SVinicius Costa Gomes return 0; 238175d262c2SVinicius Costa Gomes } 238275d262c2SVinicius Costa Gomes 238355ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 238455ed8ca1SJohan Hedberg { 238555ed8ca1SJohan Hedberg struct link_key *key; 238655ed8ca1SJohan Hedberg 238755ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 238855ed8ca1SJohan Hedberg if (!key) 238955ed8ca1SJohan Hedberg return -ENOENT; 239055ed8ca1SJohan Hedberg 23916ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 239255ed8ca1SJohan Hedberg 239355ed8ca1SJohan Hedberg list_del(&key->list); 239455ed8ca1SJohan Hedberg kfree(key); 239555ed8ca1SJohan Hedberg 239655ed8ca1SJohan Hedberg return 0; 239755ed8ca1SJohan Hedberg } 239855ed8ca1SJohan Hedberg 2399b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 2400b899efafSVinicius Costa Gomes { 2401b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2402b899efafSVinicius Costa Gomes 2403b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2404b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 2405b899efafSVinicius Costa Gomes continue; 2406b899efafSVinicius Costa Gomes 24076ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2408b899efafSVinicius Costa Gomes 2409b899efafSVinicius Costa Gomes list_del(&k->list); 2410b899efafSVinicius Costa Gomes kfree(k); 2411b899efafSVinicius Costa Gomes } 2412b899efafSVinicius Costa Gomes 2413b899efafSVinicius Costa Gomes return 0; 2414b899efafSVinicius Costa Gomes } 2415b899efafSVinicius Costa Gomes 24166bd32326SVille Tervo /* HCI command timer function */ 2417bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg) 24186bd32326SVille Tervo { 24196bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 24206bd32326SVille Tervo 2421bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2422bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2423bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2424bda4f23aSAndrei Emeltchenko 2425bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 2426bda4f23aSAndrei Emeltchenko } else { 24276bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 2428bda4f23aSAndrei Emeltchenko } 2429bda4f23aSAndrei Emeltchenko 24306bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2431c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 24326bd32326SVille Tervo } 24336bd32326SVille Tervo 24342763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 24352763eda6SSzymon Janc bdaddr_t *bdaddr) 24362763eda6SSzymon Janc { 24372763eda6SSzymon Janc struct oob_data *data; 24382763eda6SSzymon Janc 24392763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 24402763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 24412763eda6SSzymon Janc return data; 24422763eda6SSzymon Janc 24432763eda6SSzymon Janc return NULL; 24442763eda6SSzymon Janc } 24452763eda6SSzymon Janc 24462763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 24472763eda6SSzymon Janc { 24482763eda6SSzymon Janc struct oob_data *data; 24492763eda6SSzymon Janc 24502763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 24512763eda6SSzymon Janc if (!data) 24522763eda6SSzymon Janc return -ENOENT; 24532763eda6SSzymon Janc 24546ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 24552763eda6SSzymon Janc 24562763eda6SSzymon Janc list_del(&data->list); 24572763eda6SSzymon Janc kfree(data); 24582763eda6SSzymon Janc 24592763eda6SSzymon Janc return 0; 24602763eda6SSzymon Janc } 24612763eda6SSzymon Janc 24622763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 24632763eda6SSzymon Janc { 24642763eda6SSzymon Janc struct oob_data *data, *n; 24652763eda6SSzymon Janc 24662763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 24672763eda6SSzymon Janc list_del(&data->list); 24682763eda6SSzymon Janc kfree(data); 24692763eda6SSzymon Janc } 24702763eda6SSzymon Janc 24712763eda6SSzymon Janc return 0; 24722763eda6SSzymon Janc } 24732763eda6SSzymon Janc 24742763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 24752763eda6SSzymon Janc u8 *randomizer) 24762763eda6SSzymon Janc { 24772763eda6SSzymon Janc struct oob_data *data; 24782763eda6SSzymon Janc 24792763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 24802763eda6SSzymon Janc 24812763eda6SSzymon Janc if (!data) { 24822763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 24832763eda6SSzymon Janc if (!data) 24842763eda6SSzymon Janc return -ENOMEM; 24852763eda6SSzymon Janc 24862763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 24872763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 24882763eda6SSzymon Janc } 24892763eda6SSzymon Janc 24902763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 24912763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 24922763eda6SSzymon Janc 24936ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 24942763eda6SSzymon Janc 24952763eda6SSzymon Janc return 0; 24962763eda6SSzymon Janc } 24972763eda6SSzymon Janc 2498b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 2499b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 2500b2a66aadSAntti Julku { 2501b2a66aadSAntti Julku struct bdaddr_list *b; 2502b2a66aadSAntti Julku 2503b9ee0a78SMarcel Holtmann list_for_each_entry(b, &hdev->blacklist, list) { 2504b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2505b2a66aadSAntti Julku return b; 2506b9ee0a78SMarcel Holtmann } 2507b2a66aadSAntti Julku 2508b2a66aadSAntti Julku return NULL; 2509b2a66aadSAntti Julku } 2510b2a66aadSAntti Julku 2511b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 2512b2a66aadSAntti Julku { 2513b2a66aadSAntti Julku struct list_head *p, *n; 2514b2a66aadSAntti Julku 2515b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 2516b9ee0a78SMarcel Holtmann struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); 2517b2a66aadSAntti Julku 2518b2a66aadSAntti Julku list_del(p); 2519b2a66aadSAntti Julku kfree(b); 2520b2a66aadSAntti Julku } 2521b2a66aadSAntti Julku 2522b2a66aadSAntti Julku return 0; 2523b2a66aadSAntti Julku } 2524b2a66aadSAntti Julku 252588c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2526b2a66aadSAntti Julku { 2527b2a66aadSAntti Julku struct bdaddr_list *entry; 2528b2a66aadSAntti Julku 2529b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 2530b2a66aadSAntti Julku return -EBADF; 2531b2a66aadSAntti Julku 2532b9ee0a78SMarcel Holtmann if (hci_blacklist_lookup(hdev, bdaddr, type)) 25335e762444SAntti Julku return -EEXIST; 2534b2a66aadSAntti Julku 2535b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 25365e762444SAntti Julku if (!entry) 25375e762444SAntti Julku return -ENOMEM; 2538b2a66aadSAntti Julku 2539b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 2540b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 2541b2a66aadSAntti Julku 2542b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 2543b2a66aadSAntti Julku 254488c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 2545b2a66aadSAntti Julku } 2546b2a66aadSAntti Julku 254788c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2548b2a66aadSAntti Julku { 2549b2a66aadSAntti Julku struct bdaddr_list *entry; 2550b2a66aadSAntti Julku 2551b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 25525e762444SAntti Julku return hci_blacklist_clear(hdev); 2553b2a66aadSAntti Julku 2554b9ee0a78SMarcel Holtmann entry = hci_blacklist_lookup(hdev, bdaddr, type); 25551ec918ceSSzymon Janc if (!entry) 25565e762444SAntti Julku return -ENOENT; 2557b2a66aadSAntti Julku 2558b2a66aadSAntti Julku list_del(&entry->list); 2559b2a66aadSAntti Julku kfree(entry); 2560b2a66aadSAntti Julku 256188c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 2562b2a66aadSAntti Julku } 2563b2a66aadSAntti Julku 25644c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 25657ba8b4beSAndre Guedes { 25664c87eaabSAndre Guedes if (status) { 25674c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 25687ba8b4beSAndre Guedes 25694c87eaabSAndre Guedes hci_dev_lock(hdev); 25704c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 25714c87eaabSAndre Guedes hci_dev_unlock(hdev); 25724c87eaabSAndre Guedes return; 25734c87eaabSAndre Guedes } 25747ba8b4beSAndre Guedes } 25757ba8b4beSAndre Guedes 25764c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 25777ba8b4beSAndre Guedes { 25784c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 25794c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 25804c87eaabSAndre Guedes struct hci_request req; 25814c87eaabSAndre Guedes struct hci_cp_inquiry cp; 25827ba8b4beSAndre Guedes int err; 25837ba8b4beSAndre Guedes 25844c87eaabSAndre Guedes if (status) { 25854c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 25864c87eaabSAndre Guedes return; 25877ba8b4beSAndre Guedes } 25887ba8b4beSAndre Guedes 25894c87eaabSAndre Guedes switch (hdev->discovery.type) { 25904c87eaabSAndre Guedes case DISCOV_TYPE_LE: 25914c87eaabSAndre Guedes hci_dev_lock(hdev); 25924c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 25934c87eaabSAndre Guedes hci_dev_unlock(hdev); 25944c87eaabSAndre Guedes break; 25957dbfac1dSAndre Guedes 25964c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 25974c87eaabSAndre Guedes hci_req_init(&req, hdev); 25987dbfac1dSAndre Guedes 25997dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 26004c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 26014c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 26024c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 26034c87eaabSAndre Guedes 26044c87eaabSAndre Guedes hci_dev_lock(hdev); 26054c87eaabSAndre Guedes 26064c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 26074c87eaabSAndre Guedes 26084c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 26094c87eaabSAndre Guedes if (err) { 26104c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 26114c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 26127dbfac1dSAndre Guedes } 26137dbfac1dSAndre Guedes 26144c87eaabSAndre Guedes hci_dev_unlock(hdev); 26154c87eaabSAndre Guedes break; 26164c87eaabSAndre Guedes } 26177dbfac1dSAndre Guedes } 26187dbfac1dSAndre Guedes 26197ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 26207ba8b4beSAndre Guedes { 26217ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 26227ba8b4beSAndre Guedes le_scan_disable.work); 26237ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 26244c87eaabSAndre Guedes struct hci_request req; 26254c87eaabSAndre Guedes int err; 26267ba8b4beSAndre Guedes 26277ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 26287ba8b4beSAndre Guedes 26294c87eaabSAndre Guedes hci_req_init(&req, hdev); 26307ba8b4beSAndre Guedes 26317ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 26324c87eaabSAndre Guedes cp.enable = LE_SCAN_DISABLE; 26334c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 26347ba8b4beSAndre Guedes 26354c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 26364c87eaabSAndre Guedes if (err) 26374c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 263828b75a89SAndre Guedes } 263928b75a89SAndre Guedes 26409be0dab7SDavid Herrmann /* Alloc HCI device */ 26419be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 26429be0dab7SDavid Herrmann { 26439be0dab7SDavid Herrmann struct hci_dev *hdev; 26449be0dab7SDavid Herrmann 26459be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 26469be0dab7SDavid Herrmann if (!hdev) 26479be0dab7SDavid Herrmann return NULL; 26489be0dab7SDavid Herrmann 2649b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 2650b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 2651b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 2652b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 2653b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 2654bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 2655bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2656b1b813d4SDavid Herrmann 2657b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 2658b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 2659b1b813d4SDavid Herrmann 2660bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 2661bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 2662bef64738SMarcel Holtmann 2663b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 2664b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 2665b1b813d4SDavid Herrmann 2666b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 2667b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 2668b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 2669b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 2670b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 2671b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 26726b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 2673b1b813d4SDavid Herrmann 2674b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 2675b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 2676b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 2677b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 2678b1b813d4SDavid Herrmann 2679b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 2680b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 2681b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 2682b1b813d4SDavid Herrmann 2683b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 2684b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 2685b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 2686b1b813d4SDavid Herrmann 2687b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 2688b1b813d4SDavid Herrmann 2689bda4f23aSAndrei Emeltchenko setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); 2690b1b813d4SDavid Herrmann 2691b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 2692b1b813d4SDavid Herrmann discovery_init(hdev); 26939be0dab7SDavid Herrmann 26949be0dab7SDavid Herrmann return hdev; 26959be0dab7SDavid Herrmann } 26969be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 26979be0dab7SDavid Herrmann 26989be0dab7SDavid Herrmann /* Free HCI device */ 26999be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 27009be0dab7SDavid Herrmann { 27019be0dab7SDavid Herrmann /* will free via device release */ 27029be0dab7SDavid Herrmann put_device(&hdev->dev); 27039be0dab7SDavid Herrmann } 27049be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 27059be0dab7SDavid Herrmann 27061da177e4SLinus Torvalds /* Register HCI device */ 27071da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 27081da177e4SLinus Torvalds { 2709b1b813d4SDavid Herrmann int id, error; 27101da177e4SLinus Torvalds 2711010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 27121da177e4SLinus Torvalds return -EINVAL; 27131da177e4SLinus Torvalds 271408add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 271508add513SMat Martineau * so the index can be used as the AMP controller ID. 271608add513SMat Martineau */ 27173df92b31SSasha Levin switch (hdev->dev_type) { 27183df92b31SSasha Levin case HCI_BREDR: 27193df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 27201da177e4SLinus Torvalds break; 27213df92b31SSasha Levin case HCI_AMP: 27223df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 27233df92b31SSasha Levin break; 27243df92b31SSasha Levin default: 27253df92b31SSasha Levin return -EINVAL; 27261da177e4SLinus Torvalds } 27271da177e4SLinus Torvalds 27283df92b31SSasha Levin if (id < 0) 27293df92b31SSasha Levin return id; 27303df92b31SSasha Levin 27311da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 27321da177e4SLinus Torvalds hdev->id = id; 27332d8b3a11SAndrei Emeltchenko 27342d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 27352d8b3a11SAndrei Emeltchenko 2736d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 2737d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 273833ca954dSDavid Herrmann if (!hdev->workqueue) { 273933ca954dSDavid Herrmann error = -ENOMEM; 274033ca954dSDavid Herrmann goto err; 274133ca954dSDavid Herrmann } 2742f48fd9c8SMarcel Holtmann 2743d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 2744d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 27456ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 27466ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 27476ead1bbcSJohan Hedberg error = -ENOMEM; 27486ead1bbcSJohan Hedberg goto err; 27496ead1bbcSJohan Hedberg } 27506ead1bbcSJohan Hedberg 27510153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 27520153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 27530153e2ecSMarcel Holtmann 2754bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 2755bdc3e0f1SMarcel Holtmann 2756bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 275733ca954dSDavid Herrmann if (error < 0) 275833ca954dSDavid Herrmann goto err_wqueue; 27591da177e4SLinus Torvalds 2760611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 2761a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 2762a8c5fb1aSGustavo Padovan hdev); 2763611b30f7SMarcel Holtmann if (hdev->rfkill) { 2764611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 2765611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2766611b30f7SMarcel Holtmann hdev->rfkill = NULL; 2767611b30f7SMarcel Holtmann } 2768611b30f7SMarcel Holtmann } 2769611b30f7SMarcel Holtmann 27705e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 27715e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 27725e130367SJohan Hedberg 2773a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 2774004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2775ce2be9acSAndrei Emeltchenko 277601cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 277756f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 277856f87901SJohan Hedberg * through reading supported features during init. 277956f87901SJohan Hedberg */ 278056f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 278156f87901SJohan Hedberg } 2782ce2be9acSAndrei Emeltchenko 2783fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 2784fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 2785fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 2786fcee3377SGustavo Padovan 27871da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 2788dc946bd8SDavid Herrmann hci_dev_hold(hdev); 27891da177e4SLinus Torvalds 279019202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 2791fbe96d6fSMarcel Holtmann 27921da177e4SLinus Torvalds return id; 2793f48fd9c8SMarcel Holtmann 279433ca954dSDavid Herrmann err_wqueue: 279533ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 27966ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 279733ca954dSDavid Herrmann err: 27983df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 2799f48fd9c8SMarcel Holtmann 280033ca954dSDavid Herrmann return error; 28011da177e4SLinus Torvalds } 28021da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 28031da177e4SLinus Torvalds 28041da177e4SLinus Torvalds /* Unregister HCI device */ 280559735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 28061da177e4SLinus Torvalds { 28073df92b31SSasha Levin int i, id; 2808ef222013SMarcel Holtmann 2809c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 28101da177e4SLinus Torvalds 281194324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 281294324962SJohan Hovold 28133df92b31SSasha Levin id = hdev->id; 28143df92b31SSasha Levin 2815f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 28161da177e4SLinus Torvalds list_del(&hdev->list); 2817f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 28181da177e4SLinus Torvalds 28191da177e4SLinus Torvalds hci_dev_do_close(hdev); 28201da177e4SLinus Torvalds 2821cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 2822ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 2823ef222013SMarcel Holtmann 2824b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 2825b9b5ef18SGustavo Padovan 2826ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 2827a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 282809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2829744cf19eSJohan Hedberg mgmt_index_removed(hdev); 283009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 283156e5cb86SJohan Hedberg } 2832ab81cbf9SJohan Hedberg 28332e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 28342e58ef3eSJohan Hedberg * pending list */ 28352e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 28362e58ef3eSJohan Hedberg 28371da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 28381da177e4SLinus Torvalds 2839611b30f7SMarcel Holtmann if (hdev->rfkill) { 2840611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 2841611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2842611b30f7SMarcel Holtmann } 2843611b30f7SMarcel Holtmann 2844bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 2845147e2d59SDave Young 28460153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 28470153e2ecSMarcel Holtmann 2848f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 28496ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 2850f48fd9c8SMarcel Holtmann 285109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2852e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 28532aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 285455ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 2855b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 28562763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 285709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 2858e2e0cacbSJohan Hedberg 2859dc946bd8SDavid Herrmann hci_dev_put(hdev); 28603df92b31SSasha Levin 28613df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 28621da177e4SLinus Torvalds } 28631da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 28641da177e4SLinus Torvalds 28651da177e4SLinus Torvalds /* Suspend HCI device */ 28661da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 28671da177e4SLinus Torvalds { 28681da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 28691da177e4SLinus Torvalds return 0; 28701da177e4SLinus Torvalds } 28711da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 28721da177e4SLinus Torvalds 28731da177e4SLinus Torvalds /* Resume HCI device */ 28741da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 28751da177e4SLinus Torvalds { 28761da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 28771da177e4SLinus Torvalds return 0; 28781da177e4SLinus Torvalds } 28791da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 28801da177e4SLinus Torvalds 288176bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 2882e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 288376bca880SMarcel Holtmann { 288476bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 288576bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 288676bca880SMarcel Holtmann kfree_skb(skb); 288776bca880SMarcel Holtmann return -ENXIO; 288876bca880SMarcel Holtmann } 288976bca880SMarcel Holtmann 2890d82603c6SJorrit Schippers /* Incoming skb */ 289176bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 289276bca880SMarcel Holtmann 289376bca880SMarcel Holtmann /* Time stamp */ 289476bca880SMarcel Holtmann __net_timestamp(skb); 289576bca880SMarcel Holtmann 289676bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 2897b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 2898c78ae283SMarcel Holtmann 289976bca880SMarcel Holtmann return 0; 290076bca880SMarcel Holtmann } 290176bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 290276bca880SMarcel Holtmann 290333e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 29041e429f38SGustavo F. Padovan int count, __u8 index) 290533e882a5SSuraj Sumangala { 290633e882a5SSuraj Sumangala int len = 0; 290733e882a5SSuraj Sumangala int hlen = 0; 290833e882a5SSuraj Sumangala int remain = count; 290933e882a5SSuraj Sumangala struct sk_buff *skb; 291033e882a5SSuraj Sumangala struct bt_skb_cb *scb; 291133e882a5SSuraj Sumangala 291233e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 291333e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 291433e882a5SSuraj Sumangala return -EILSEQ; 291533e882a5SSuraj Sumangala 291633e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 291733e882a5SSuraj Sumangala 291833e882a5SSuraj Sumangala if (!skb) { 291933e882a5SSuraj Sumangala switch (type) { 292033e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 292133e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 292233e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 292333e882a5SSuraj Sumangala break; 292433e882a5SSuraj Sumangala case HCI_EVENT_PKT: 292533e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 292633e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 292733e882a5SSuraj Sumangala break; 292833e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 292933e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 293033e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 293133e882a5SSuraj Sumangala break; 293233e882a5SSuraj Sumangala } 293333e882a5SSuraj Sumangala 29341e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 293533e882a5SSuraj Sumangala if (!skb) 293633e882a5SSuraj Sumangala return -ENOMEM; 293733e882a5SSuraj Sumangala 293833e882a5SSuraj Sumangala scb = (void *) skb->cb; 293933e882a5SSuraj Sumangala scb->expect = hlen; 294033e882a5SSuraj Sumangala scb->pkt_type = type; 294133e882a5SSuraj Sumangala 294233e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 294333e882a5SSuraj Sumangala } 294433e882a5SSuraj Sumangala 294533e882a5SSuraj Sumangala while (count) { 294633e882a5SSuraj Sumangala scb = (void *) skb->cb; 294789bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 294833e882a5SSuraj Sumangala 294933e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 295033e882a5SSuraj Sumangala 295133e882a5SSuraj Sumangala count -= len; 295233e882a5SSuraj Sumangala data += len; 295333e882a5SSuraj Sumangala scb->expect -= len; 295433e882a5SSuraj Sumangala remain = count; 295533e882a5SSuraj Sumangala 295633e882a5SSuraj Sumangala switch (type) { 295733e882a5SSuraj Sumangala case HCI_EVENT_PKT: 295833e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 295933e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 296033e882a5SSuraj Sumangala scb->expect = h->plen; 296133e882a5SSuraj Sumangala 296233e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 296333e882a5SSuraj Sumangala kfree_skb(skb); 296433e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 296533e882a5SSuraj Sumangala return -ENOMEM; 296633e882a5SSuraj Sumangala } 296733e882a5SSuraj Sumangala } 296833e882a5SSuraj Sumangala break; 296933e882a5SSuraj Sumangala 297033e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 297133e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 297233e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 297333e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 297433e882a5SSuraj Sumangala 297533e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 297633e882a5SSuraj Sumangala kfree_skb(skb); 297733e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 297833e882a5SSuraj Sumangala return -ENOMEM; 297933e882a5SSuraj Sumangala } 298033e882a5SSuraj Sumangala } 298133e882a5SSuraj Sumangala break; 298233e882a5SSuraj Sumangala 298333e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 298433e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 298533e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 298633e882a5SSuraj Sumangala scb->expect = h->dlen; 298733e882a5SSuraj Sumangala 298833e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 298933e882a5SSuraj Sumangala kfree_skb(skb); 299033e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 299133e882a5SSuraj Sumangala return -ENOMEM; 299233e882a5SSuraj Sumangala } 299333e882a5SSuraj Sumangala } 299433e882a5SSuraj Sumangala break; 299533e882a5SSuraj Sumangala } 299633e882a5SSuraj Sumangala 299733e882a5SSuraj Sumangala if (scb->expect == 0) { 299833e882a5SSuraj Sumangala /* Complete frame */ 299933e882a5SSuraj Sumangala 300033e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 3001e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 300233e882a5SSuraj Sumangala 300333e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 300433e882a5SSuraj Sumangala return remain; 300533e882a5SSuraj Sumangala } 300633e882a5SSuraj Sumangala } 300733e882a5SSuraj Sumangala 300833e882a5SSuraj Sumangala return remain; 300933e882a5SSuraj Sumangala } 301033e882a5SSuraj Sumangala 3011ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 3012ef222013SMarcel Holtmann { 3013f39a3c06SSuraj Sumangala int rem = 0; 3014f39a3c06SSuraj Sumangala 3015ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 3016ef222013SMarcel Holtmann return -EILSEQ; 3017ef222013SMarcel Holtmann 3018da5f6c37SGustavo F. Padovan while (count) { 30191e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 3020f39a3c06SSuraj Sumangala if (rem < 0) 3021f39a3c06SSuraj Sumangala return rem; 3022ef222013SMarcel Holtmann 3023f39a3c06SSuraj Sumangala data += (count - rem); 3024f39a3c06SSuraj Sumangala count = rem; 3025f81c6224SJoe Perches } 3026ef222013SMarcel Holtmann 3027f39a3c06SSuraj Sumangala return rem; 3028ef222013SMarcel Holtmann } 3029ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 3030ef222013SMarcel Holtmann 303199811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 303299811510SSuraj Sumangala 303399811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 303499811510SSuraj Sumangala { 303599811510SSuraj Sumangala int type; 303699811510SSuraj Sumangala int rem = 0; 303799811510SSuraj Sumangala 3038da5f6c37SGustavo F. Padovan while (count) { 303999811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 304099811510SSuraj Sumangala 304199811510SSuraj Sumangala if (!skb) { 304299811510SSuraj Sumangala struct { char type; } *pkt; 304399811510SSuraj Sumangala 304499811510SSuraj Sumangala /* Start of the frame */ 304599811510SSuraj Sumangala pkt = data; 304699811510SSuraj Sumangala type = pkt->type; 304799811510SSuraj Sumangala 304899811510SSuraj Sumangala data++; 304999811510SSuraj Sumangala count--; 305099811510SSuraj Sumangala } else 305199811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 305299811510SSuraj Sumangala 30531e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 30541e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 305599811510SSuraj Sumangala if (rem < 0) 305699811510SSuraj Sumangala return rem; 305799811510SSuraj Sumangala 305899811510SSuraj Sumangala data += (count - rem); 305999811510SSuraj Sumangala count = rem; 3060f81c6224SJoe Perches } 306199811510SSuraj Sumangala 306299811510SSuraj Sumangala return rem; 306399811510SSuraj Sumangala } 306499811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 306599811510SSuraj Sumangala 30661da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 30671da177e4SLinus Torvalds 30681da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 30691da177e4SLinus Torvalds { 30701da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 30711da177e4SLinus Torvalds 3072f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 30731da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 3074f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 30751da177e4SLinus Torvalds 30761da177e4SLinus Torvalds return 0; 30771da177e4SLinus Torvalds } 30781da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 30791da177e4SLinus Torvalds 30801da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 30811da177e4SLinus Torvalds { 30821da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 30831da177e4SLinus Torvalds 3084f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 30851da177e4SLinus Torvalds list_del(&cb->list); 3086f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 30871da177e4SLinus Torvalds 30881da177e4SLinus Torvalds return 0; 30891da177e4SLinus Torvalds } 30901da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 30911da177e4SLinus Torvalds 309251086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 30931da177e4SLinus Torvalds { 30940d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 30951da177e4SLinus Torvalds 30961da177e4SLinus Torvalds /* Time stamp */ 3097a61bbcf2SPatrick McHardy __net_timestamp(skb); 30981da177e4SLinus Torvalds 3099cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3100cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3101cd82e61cSMarcel Holtmann 3102cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3103cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3104470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 31051da177e4SLinus Torvalds } 31061da177e4SLinus Torvalds 31071da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 31081da177e4SLinus Torvalds skb_orphan(skb); 31091da177e4SLinus Torvalds 31107bd8f09fSMarcel Holtmann if (hdev->send(hdev, skb) < 0) 311151086991SMarcel Holtmann BT_ERR("%s sending frame failed", hdev->name); 31121da177e4SLinus Torvalds } 31131da177e4SLinus Torvalds 31143119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 31153119ae95SJohan Hedberg { 31163119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 31173119ae95SJohan Hedberg req->hdev = hdev; 31185d73e034SAndre Guedes req->err = 0; 31193119ae95SJohan Hedberg } 31203119ae95SJohan Hedberg 31213119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 31223119ae95SJohan Hedberg { 31233119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 31243119ae95SJohan Hedberg struct sk_buff *skb; 31253119ae95SJohan Hedberg unsigned long flags; 31263119ae95SJohan Hedberg 31273119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 31283119ae95SJohan Hedberg 31295d73e034SAndre Guedes /* If an error occured during request building, remove all HCI 31305d73e034SAndre Guedes * commands queued on the HCI request queue. 31315d73e034SAndre Guedes */ 31325d73e034SAndre Guedes if (req->err) { 31335d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 31345d73e034SAndre Guedes return req->err; 31355d73e034SAndre Guedes } 31365d73e034SAndre Guedes 31373119ae95SJohan Hedberg /* Do not allow empty requests */ 31383119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 3139382b0c39SAndre Guedes return -ENODATA; 31403119ae95SJohan Hedberg 31413119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 31423119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 31433119ae95SJohan Hedberg 31443119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 31453119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 31463119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 31473119ae95SJohan Hedberg 31483119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 31493119ae95SJohan Hedberg 31503119ae95SJohan Hedberg return 0; 31513119ae95SJohan Hedberg } 31523119ae95SJohan Hedberg 31531ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 315407dc93ddSJohan Hedberg u32 plen, const void *param) 31551da177e4SLinus Torvalds { 31561da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 31571da177e4SLinus Torvalds struct hci_command_hdr *hdr; 31581da177e4SLinus Torvalds struct sk_buff *skb; 31591da177e4SLinus Torvalds 31601da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 31611ca3a9d0SJohan Hedberg if (!skb) 31621ca3a9d0SJohan Hedberg return NULL; 31631da177e4SLinus Torvalds 31641da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 3165a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 31661da177e4SLinus Torvalds hdr->plen = plen; 31671da177e4SLinus Torvalds 31681da177e4SLinus Torvalds if (plen) 31691da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 31701da177e4SLinus Torvalds 31711da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 31721da177e4SLinus Torvalds 31730d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 3174c78ae283SMarcel Holtmann 31751ca3a9d0SJohan Hedberg return skb; 31761ca3a9d0SJohan Hedberg } 31771ca3a9d0SJohan Hedberg 31781ca3a9d0SJohan Hedberg /* Send HCI command */ 317907dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 318007dc93ddSJohan Hedberg const void *param) 31811ca3a9d0SJohan Hedberg { 31821ca3a9d0SJohan Hedberg struct sk_buff *skb; 31831ca3a9d0SJohan Hedberg 31841ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 31851ca3a9d0SJohan Hedberg 31861ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 31871ca3a9d0SJohan Hedberg if (!skb) { 31881ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 31891ca3a9d0SJohan Hedberg return -ENOMEM; 31901ca3a9d0SJohan Hedberg } 31911ca3a9d0SJohan Hedberg 319211714b3dSJohan Hedberg /* Stand-alone HCI commands must be flaged as 319311714b3dSJohan Hedberg * single-command requests. 319411714b3dSJohan Hedberg */ 319511714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 319611714b3dSJohan Hedberg 31971da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3198c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 31991da177e4SLinus Torvalds 32001da177e4SLinus Torvalds return 0; 32011da177e4SLinus Torvalds } 32021da177e4SLinus Torvalds 320371c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 320407dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 320507dc93ddSJohan Hedberg const void *param, u8 event) 320671c76a17SJohan Hedberg { 320771c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 320871c76a17SJohan Hedberg struct sk_buff *skb; 320971c76a17SJohan Hedberg 321071c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 321171c76a17SJohan Hedberg 321234739c1eSAndre Guedes /* If an error occured during request building, there is no point in 321334739c1eSAndre Guedes * queueing the HCI command. We can simply return. 321434739c1eSAndre Guedes */ 321534739c1eSAndre Guedes if (req->err) 321634739c1eSAndre Guedes return; 321734739c1eSAndre Guedes 321871c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 321971c76a17SJohan Hedberg if (!skb) { 32205d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 32215d73e034SAndre Guedes hdev->name, opcode); 32225d73e034SAndre Guedes req->err = -ENOMEM; 3223e348fe6bSAndre Guedes return; 322471c76a17SJohan Hedberg } 322571c76a17SJohan Hedberg 322671c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 322771c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 322871c76a17SJohan Hedberg 322902350a72SJohan Hedberg bt_cb(skb)->req.event = event; 323002350a72SJohan Hedberg 323171c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 323271c76a17SJohan Hedberg } 323371c76a17SJohan Hedberg 323407dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 323507dc93ddSJohan Hedberg const void *param) 323602350a72SJohan Hedberg { 323702350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 323802350a72SJohan Hedberg } 323902350a72SJohan Hedberg 32401da177e4SLinus Torvalds /* Get data from the previously sent command */ 3241a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 32421da177e4SLinus Torvalds { 32431da177e4SLinus Torvalds struct hci_command_hdr *hdr; 32441da177e4SLinus Torvalds 32451da177e4SLinus Torvalds if (!hdev->sent_cmd) 32461da177e4SLinus Torvalds return NULL; 32471da177e4SLinus Torvalds 32481da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 32491da177e4SLinus Torvalds 3250a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 32511da177e4SLinus Torvalds return NULL; 32521da177e4SLinus Torvalds 3253f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 32541da177e4SLinus Torvalds 32551da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 32561da177e4SLinus Torvalds } 32571da177e4SLinus Torvalds 32581da177e4SLinus Torvalds /* Send ACL data */ 32591da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 32601da177e4SLinus Torvalds { 32611da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 32621da177e4SLinus Torvalds int len = skb->len; 32631da177e4SLinus Torvalds 3264badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3265badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 32669c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3267aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3268aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 32691da177e4SLinus Torvalds } 32701da177e4SLinus Torvalds 3271ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 327273d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 32731da177e4SLinus Torvalds { 3274ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 32751da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 32761da177e4SLinus Torvalds struct sk_buff *list; 32771da177e4SLinus Torvalds 3278087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3279087bfd99SGustavo Padovan skb->data_len = 0; 3280087bfd99SGustavo Padovan 3281087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3282204a6e54SAndrei Emeltchenko 3283204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3284204a6e54SAndrei Emeltchenko case HCI_BREDR: 3285087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3286204a6e54SAndrei Emeltchenko break; 3287204a6e54SAndrei Emeltchenko case HCI_AMP: 3288204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3289204a6e54SAndrei Emeltchenko break; 3290204a6e54SAndrei Emeltchenko default: 3291204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 3292204a6e54SAndrei Emeltchenko return; 3293204a6e54SAndrei Emeltchenko } 3294087bfd99SGustavo Padovan 329570f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 329670f23020SAndrei Emeltchenko if (!list) { 32971da177e4SLinus Torvalds /* Non fragmented */ 32981da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 32991da177e4SLinus Torvalds 330073d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 33011da177e4SLinus Torvalds } else { 33021da177e4SLinus Torvalds /* Fragmented */ 33031da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 33041da177e4SLinus Torvalds 33051da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 33061da177e4SLinus Torvalds 33071da177e4SLinus Torvalds /* Queue all fragments atomically */ 3308af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 33091da177e4SLinus Torvalds 331073d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3311e702112fSAndrei Emeltchenko 3312e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3313e702112fSAndrei Emeltchenko flags |= ACL_CONT; 33141da177e4SLinus Torvalds do { 33151da177e4SLinus Torvalds skb = list; list = list->next; 33161da177e4SLinus Torvalds 33170d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 3318e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 33191da177e4SLinus Torvalds 33201da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 33211da177e4SLinus Torvalds 332273d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 33231da177e4SLinus Torvalds } while (list); 33241da177e4SLinus Torvalds 3325af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 33261da177e4SLinus Torvalds } 332773d80debSLuiz Augusto von Dentz } 332873d80debSLuiz Augusto von Dentz 332973d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 333073d80debSLuiz Augusto von Dentz { 3331ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 333273d80debSLuiz Augusto von Dentz 3333f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 333473d80debSLuiz Augusto von Dentz 3335ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 33361da177e4SLinus Torvalds 33373eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 33381da177e4SLinus Torvalds } 33391da177e4SLinus Torvalds 33401da177e4SLinus Torvalds /* Send SCO data */ 33410d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 33421da177e4SLinus Torvalds { 33431da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 33441da177e4SLinus Torvalds struct hci_sco_hdr hdr; 33451da177e4SLinus Torvalds 33461da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 33471da177e4SLinus Torvalds 3348aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 33491da177e4SLinus Torvalds hdr.dlen = skb->len; 33501da177e4SLinus Torvalds 3351badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 3352badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 33539c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 33541da177e4SLinus Torvalds 33550d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 3356c78ae283SMarcel Holtmann 33571da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 33583eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 33591da177e4SLinus Torvalds } 33601da177e4SLinus Torvalds 33611da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 33621da177e4SLinus Torvalds 33631da177e4SLinus Torvalds /* HCI Connection scheduler */ 33646039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 3365a8c5fb1aSGustavo Padovan int *quote) 33661da177e4SLinus Torvalds { 33671da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 33688035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 3369abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 33701da177e4SLinus Torvalds 33711da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 33721da177e4SLinus Torvalds * added and removed with TX task disabled. */ 3373bf4c6325SGustavo F. Padovan 3374bf4c6325SGustavo F. Padovan rcu_read_lock(); 3375bf4c6325SGustavo F. Padovan 3376bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3377769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 33781da177e4SLinus Torvalds continue; 3379769be974SMarcel Holtmann 3380769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 3381769be974SMarcel Holtmann continue; 3382769be974SMarcel Holtmann 33831da177e4SLinus Torvalds num++; 33841da177e4SLinus Torvalds 33851da177e4SLinus Torvalds if (c->sent < min) { 33861da177e4SLinus Torvalds min = c->sent; 33871da177e4SLinus Torvalds conn = c; 33881da177e4SLinus Torvalds } 338952087a79SLuiz Augusto von Dentz 339052087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 339152087a79SLuiz Augusto von Dentz break; 33921da177e4SLinus Torvalds } 33931da177e4SLinus Torvalds 3394bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3395bf4c6325SGustavo F. Padovan 33961da177e4SLinus Torvalds if (conn) { 33976ed58ec5SVille Tervo int cnt, q; 33986ed58ec5SVille Tervo 33996ed58ec5SVille Tervo switch (conn->type) { 34006ed58ec5SVille Tervo case ACL_LINK: 34016ed58ec5SVille Tervo cnt = hdev->acl_cnt; 34026ed58ec5SVille Tervo break; 34036ed58ec5SVille Tervo case SCO_LINK: 34046ed58ec5SVille Tervo case ESCO_LINK: 34056ed58ec5SVille Tervo cnt = hdev->sco_cnt; 34066ed58ec5SVille Tervo break; 34076ed58ec5SVille Tervo case LE_LINK: 34086ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 34096ed58ec5SVille Tervo break; 34106ed58ec5SVille Tervo default: 34116ed58ec5SVille Tervo cnt = 0; 34126ed58ec5SVille Tervo BT_ERR("Unknown link type"); 34136ed58ec5SVille Tervo } 34146ed58ec5SVille Tervo 34156ed58ec5SVille Tervo q = cnt / num; 34161da177e4SLinus Torvalds *quote = q ? q : 1; 34171da177e4SLinus Torvalds } else 34181da177e4SLinus Torvalds *quote = 0; 34191da177e4SLinus Torvalds 34201da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 34211da177e4SLinus Torvalds return conn; 34221da177e4SLinus Torvalds } 34231da177e4SLinus Torvalds 34246039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 34251da177e4SLinus Torvalds { 34261da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 34271da177e4SLinus Torvalds struct hci_conn *c; 34281da177e4SLinus Torvalds 3429bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 34301da177e4SLinus Torvalds 3431bf4c6325SGustavo F. Padovan rcu_read_lock(); 3432bf4c6325SGustavo F. Padovan 34331da177e4SLinus Torvalds /* Kill stalled connections */ 3434bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3435bae1f5d9SVille Tervo if (c->type == type && c->sent) { 34366ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 34376ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 3438bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 34391da177e4SLinus Torvalds } 34401da177e4SLinus Torvalds } 3441bf4c6325SGustavo F. Padovan 3442bf4c6325SGustavo F. Padovan rcu_read_unlock(); 34431da177e4SLinus Torvalds } 34441da177e4SLinus Torvalds 34456039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 344673d80debSLuiz Augusto von Dentz int *quote) 344773d80debSLuiz Augusto von Dentz { 344873d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 344973d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 3450abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 345173d80debSLuiz Augusto von Dentz struct hci_conn *conn; 345273d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 345373d80debSLuiz Augusto von Dentz 345473d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 345573d80debSLuiz Augusto von Dentz 3456bf4c6325SGustavo F. Padovan rcu_read_lock(); 3457bf4c6325SGustavo F. Padovan 3458bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 345973d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 346073d80debSLuiz Augusto von Dentz 346173d80debSLuiz Augusto von Dentz if (conn->type != type) 346273d80debSLuiz Augusto von Dentz continue; 346373d80debSLuiz Augusto von Dentz 346473d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 346573d80debSLuiz Augusto von Dentz continue; 346673d80debSLuiz Augusto von Dentz 346773d80debSLuiz Augusto von Dentz conn_num++; 346873d80debSLuiz Augusto von Dentz 34698192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 347073d80debSLuiz Augusto von Dentz struct sk_buff *skb; 347173d80debSLuiz Augusto von Dentz 347273d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 347373d80debSLuiz Augusto von Dentz continue; 347473d80debSLuiz Augusto von Dentz 347573d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 347673d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 347773d80debSLuiz Augusto von Dentz continue; 347873d80debSLuiz Augusto von Dentz 347973d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 348073d80debSLuiz Augusto von Dentz num = 0; 348173d80debSLuiz Augusto von Dentz min = ~0; 348273d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 348373d80debSLuiz Augusto von Dentz } 348473d80debSLuiz Augusto von Dentz 348573d80debSLuiz Augusto von Dentz num++; 348673d80debSLuiz Augusto von Dentz 348773d80debSLuiz Augusto von Dentz if (conn->sent < min) { 348873d80debSLuiz Augusto von Dentz min = conn->sent; 348973d80debSLuiz Augusto von Dentz chan = tmp; 349073d80debSLuiz Augusto von Dentz } 349173d80debSLuiz Augusto von Dentz } 349273d80debSLuiz Augusto von Dentz 349373d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 349473d80debSLuiz Augusto von Dentz break; 349573d80debSLuiz Augusto von Dentz } 349673d80debSLuiz Augusto von Dentz 3497bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3498bf4c6325SGustavo F. Padovan 349973d80debSLuiz Augusto von Dentz if (!chan) 350073d80debSLuiz Augusto von Dentz return NULL; 350173d80debSLuiz Augusto von Dentz 350273d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 350373d80debSLuiz Augusto von Dentz case ACL_LINK: 350473d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 350573d80debSLuiz Augusto von Dentz break; 3506bd1eb66bSAndrei Emeltchenko case AMP_LINK: 3507bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 3508bd1eb66bSAndrei Emeltchenko break; 350973d80debSLuiz Augusto von Dentz case SCO_LINK: 351073d80debSLuiz Augusto von Dentz case ESCO_LINK: 351173d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 351273d80debSLuiz Augusto von Dentz break; 351373d80debSLuiz Augusto von Dentz case LE_LINK: 351473d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 351573d80debSLuiz Augusto von Dentz break; 351673d80debSLuiz Augusto von Dentz default: 351773d80debSLuiz Augusto von Dentz cnt = 0; 351873d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 351973d80debSLuiz Augusto von Dentz } 352073d80debSLuiz Augusto von Dentz 352173d80debSLuiz Augusto von Dentz q = cnt / num; 352273d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 352373d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 352473d80debSLuiz Augusto von Dentz return chan; 352573d80debSLuiz Augusto von Dentz } 352673d80debSLuiz Augusto von Dentz 352702b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 352802b20f0bSLuiz Augusto von Dentz { 352902b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 353002b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 353102b20f0bSLuiz Augusto von Dentz int num = 0; 353202b20f0bSLuiz Augusto von Dentz 353302b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 353402b20f0bSLuiz Augusto von Dentz 3535bf4c6325SGustavo F. Padovan rcu_read_lock(); 3536bf4c6325SGustavo F. Padovan 3537bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 353802b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 353902b20f0bSLuiz Augusto von Dentz 354002b20f0bSLuiz Augusto von Dentz if (conn->type != type) 354102b20f0bSLuiz Augusto von Dentz continue; 354202b20f0bSLuiz Augusto von Dentz 354302b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 354402b20f0bSLuiz Augusto von Dentz continue; 354502b20f0bSLuiz Augusto von Dentz 354602b20f0bSLuiz Augusto von Dentz num++; 354702b20f0bSLuiz Augusto von Dentz 35488192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 354902b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 355002b20f0bSLuiz Augusto von Dentz 355102b20f0bSLuiz Augusto von Dentz if (chan->sent) { 355202b20f0bSLuiz Augusto von Dentz chan->sent = 0; 355302b20f0bSLuiz Augusto von Dentz continue; 355402b20f0bSLuiz Augusto von Dentz } 355502b20f0bSLuiz Augusto von Dentz 355602b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 355702b20f0bSLuiz Augusto von Dentz continue; 355802b20f0bSLuiz Augusto von Dentz 355902b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 356002b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 356102b20f0bSLuiz Augusto von Dentz continue; 356202b20f0bSLuiz Augusto von Dentz 356302b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 356402b20f0bSLuiz Augusto von Dentz 356502b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 356602b20f0bSLuiz Augusto von Dentz skb->priority); 356702b20f0bSLuiz Augusto von Dentz } 356802b20f0bSLuiz Augusto von Dentz 356902b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 357002b20f0bSLuiz Augusto von Dentz break; 357102b20f0bSLuiz Augusto von Dentz } 3572bf4c6325SGustavo F. Padovan 3573bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3574bf4c6325SGustavo F. Padovan 357502b20f0bSLuiz Augusto von Dentz } 357602b20f0bSLuiz Augusto von Dentz 3577b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 3578b71d385aSAndrei Emeltchenko { 3579b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 3580b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 3581b71d385aSAndrei Emeltchenko } 3582b71d385aSAndrei Emeltchenko 35836039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 35841da177e4SLinus Torvalds { 35851da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 35861da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 35871da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 358863d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 35895f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 3590bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 35911da177e4SLinus Torvalds } 359263d2bc1bSAndrei Emeltchenko } 35931da177e4SLinus Torvalds 35946039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 359563d2bc1bSAndrei Emeltchenko { 359663d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 359763d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 359863d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 359963d2bc1bSAndrei Emeltchenko int quote; 360063d2bc1bSAndrei Emeltchenko 360163d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 360204837f64SMarcel Holtmann 360373d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 360473d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 3605ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3606ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 360773d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 360873d80debSLuiz Augusto von Dentz skb->len, skb->priority); 360973d80debSLuiz Augusto von Dentz 3610ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3611ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3612ec1cce24SLuiz Augusto von Dentz break; 3613ec1cce24SLuiz Augusto von Dentz 3614ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3615ec1cce24SLuiz Augusto von Dentz 361673d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 361773d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 361804837f64SMarcel Holtmann 361957d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 36201da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 36211da177e4SLinus Torvalds 36221da177e4SLinus Torvalds hdev->acl_cnt--; 362373d80debSLuiz Augusto von Dentz chan->sent++; 362473d80debSLuiz Augusto von Dentz chan->conn->sent++; 36251da177e4SLinus Torvalds } 36261da177e4SLinus Torvalds } 362702b20f0bSLuiz Augusto von Dentz 362802b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 362902b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 36301da177e4SLinus Torvalds } 36311da177e4SLinus Torvalds 36326039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 3633b71d385aSAndrei Emeltchenko { 363463d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 3635b71d385aSAndrei Emeltchenko struct hci_chan *chan; 3636b71d385aSAndrei Emeltchenko struct sk_buff *skb; 3637b71d385aSAndrei Emeltchenko int quote; 3638bd1eb66bSAndrei Emeltchenko u8 type; 3639b71d385aSAndrei Emeltchenko 364063d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 3641b71d385aSAndrei Emeltchenko 3642bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3643bd1eb66bSAndrei Emeltchenko 3644bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 3645bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 3646bd1eb66bSAndrei Emeltchenko else 3647bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 3648bd1eb66bSAndrei Emeltchenko 3649b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 3650bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 3651b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 3652b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 3653b71d385aSAndrei Emeltchenko int blocks; 3654b71d385aSAndrei Emeltchenko 3655b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 3656b71d385aSAndrei Emeltchenko skb->len, skb->priority); 3657b71d385aSAndrei Emeltchenko 3658b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 3659b71d385aSAndrei Emeltchenko if (skb->priority < priority) 3660b71d385aSAndrei Emeltchenko break; 3661b71d385aSAndrei Emeltchenko 3662b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 3663b71d385aSAndrei Emeltchenko 3664b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 3665b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 3666b71d385aSAndrei Emeltchenko return; 3667b71d385aSAndrei Emeltchenko 3668b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 3669b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 3670b71d385aSAndrei Emeltchenko 367157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 3672b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 3673b71d385aSAndrei Emeltchenko 3674b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 3675b71d385aSAndrei Emeltchenko quote -= blocks; 3676b71d385aSAndrei Emeltchenko 3677b71d385aSAndrei Emeltchenko chan->sent += blocks; 3678b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 3679b71d385aSAndrei Emeltchenko } 3680b71d385aSAndrei Emeltchenko } 3681b71d385aSAndrei Emeltchenko 3682b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 3683bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 3684b71d385aSAndrei Emeltchenko } 3685b71d385aSAndrei Emeltchenko 36866039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 3687b71d385aSAndrei Emeltchenko { 3688b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3689b71d385aSAndrei Emeltchenko 3690bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 3691bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 3692bd1eb66bSAndrei Emeltchenko return; 3693bd1eb66bSAndrei Emeltchenko 3694bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 3695bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 3696b71d385aSAndrei Emeltchenko return; 3697b71d385aSAndrei Emeltchenko 3698b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 3699b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 3700b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 3701b71d385aSAndrei Emeltchenko break; 3702b71d385aSAndrei Emeltchenko 3703b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 3704b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 3705b71d385aSAndrei Emeltchenko break; 3706b71d385aSAndrei Emeltchenko } 3707b71d385aSAndrei Emeltchenko } 3708b71d385aSAndrei Emeltchenko 37091da177e4SLinus Torvalds /* Schedule SCO */ 37106039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 37111da177e4SLinus Torvalds { 37121da177e4SLinus Torvalds struct hci_conn *conn; 37131da177e4SLinus Torvalds struct sk_buff *skb; 37141da177e4SLinus Torvalds int quote; 37151da177e4SLinus Torvalds 37161da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 37171da177e4SLinus Torvalds 371852087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 371952087a79SLuiz Augusto von Dentz return; 372052087a79SLuiz Augusto von Dentz 37211da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 37221da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 37231da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 372457d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 37251da177e4SLinus Torvalds 37261da177e4SLinus Torvalds conn->sent++; 37271da177e4SLinus Torvalds if (conn->sent == ~0) 37281da177e4SLinus Torvalds conn->sent = 0; 37291da177e4SLinus Torvalds } 37301da177e4SLinus Torvalds } 37311da177e4SLinus Torvalds } 37321da177e4SLinus Torvalds 37336039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 3734b6a0dc82SMarcel Holtmann { 3735b6a0dc82SMarcel Holtmann struct hci_conn *conn; 3736b6a0dc82SMarcel Holtmann struct sk_buff *skb; 3737b6a0dc82SMarcel Holtmann int quote; 3738b6a0dc82SMarcel Holtmann 3739b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 3740b6a0dc82SMarcel Holtmann 374152087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 374252087a79SLuiz Augusto von Dentz return; 374352087a79SLuiz Augusto von Dentz 37448fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 37458fc9ced3SGustavo Padovan "e))) { 3746b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 3747b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 374857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 3749b6a0dc82SMarcel Holtmann 3750b6a0dc82SMarcel Holtmann conn->sent++; 3751b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 3752b6a0dc82SMarcel Holtmann conn->sent = 0; 3753b6a0dc82SMarcel Holtmann } 3754b6a0dc82SMarcel Holtmann } 3755b6a0dc82SMarcel Holtmann } 3756b6a0dc82SMarcel Holtmann 37576039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 37586ed58ec5SVille Tervo { 375973d80debSLuiz Augusto von Dentz struct hci_chan *chan; 37606ed58ec5SVille Tervo struct sk_buff *skb; 376102b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 37626ed58ec5SVille Tervo 37636ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 37646ed58ec5SVille Tervo 376552087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 376652087a79SLuiz Augusto von Dentz return; 376752087a79SLuiz Augusto von Dentz 37686ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 37696ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 37706ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 3771bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 37726ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 3773bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 37746ed58ec5SVille Tervo } 37756ed58ec5SVille Tervo 37766ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 377702b20f0bSLuiz Augusto von Dentz tmp = cnt; 377873d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 3779ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3780ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 378173d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 378273d80debSLuiz Augusto von Dentz skb->len, skb->priority); 37836ed58ec5SVille Tervo 3784ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3785ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3786ec1cce24SLuiz Augusto von Dentz break; 3787ec1cce24SLuiz Augusto von Dentz 3788ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3789ec1cce24SLuiz Augusto von Dentz 379057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 37916ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 37926ed58ec5SVille Tervo 37936ed58ec5SVille Tervo cnt--; 379473d80debSLuiz Augusto von Dentz chan->sent++; 379573d80debSLuiz Augusto von Dentz chan->conn->sent++; 37966ed58ec5SVille Tervo } 37976ed58ec5SVille Tervo } 379873d80debSLuiz Augusto von Dentz 37996ed58ec5SVille Tervo if (hdev->le_pkts) 38006ed58ec5SVille Tervo hdev->le_cnt = cnt; 38016ed58ec5SVille Tervo else 38026ed58ec5SVille Tervo hdev->acl_cnt = cnt; 380302b20f0bSLuiz Augusto von Dentz 380402b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 380502b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 38066ed58ec5SVille Tervo } 38076ed58ec5SVille Tervo 38083eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 38091da177e4SLinus Torvalds { 38103eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 38111da177e4SLinus Torvalds struct sk_buff *skb; 38121da177e4SLinus Torvalds 38136ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 38146ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 38151da177e4SLinus Torvalds 381652de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 38171da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 38181da177e4SLinus Torvalds hci_sched_acl(hdev); 38191da177e4SLinus Torvalds hci_sched_sco(hdev); 3820b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 38216ed58ec5SVille Tervo hci_sched_le(hdev); 382252de599eSMarcel Holtmann } 38236ed58ec5SVille Tervo 38241da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 38251da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 382657d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 38271da177e4SLinus Torvalds } 38281da177e4SLinus Torvalds 382925985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 38301da177e4SLinus Torvalds 38311da177e4SLinus Torvalds /* ACL data packet */ 38326039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 38331da177e4SLinus Torvalds { 38341da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 38351da177e4SLinus Torvalds struct hci_conn *conn; 38361da177e4SLinus Torvalds __u16 handle, flags; 38371da177e4SLinus Torvalds 38381da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 38391da177e4SLinus Torvalds 38401da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 38411da177e4SLinus Torvalds flags = hci_flags(handle); 38421da177e4SLinus Torvalds handle = hci_handle(handle); 38431da177e4SLinus Torvalds 3844f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 3845a8c5fb1aSGustavo Padovan handle, flags); 38461da177e4SLinus Torvalds 38471da177e4SLinus Torvalds hdev->stat.acl_rx++; 38481da177e4SLinus Torvalds 38491da177e4SLinus Torvalds hci_dev_lock(hdev); 38501da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 38511da177e4SLinus Torvalds hci_dev_unlock(hdev); 38521da177e4SLinus Torvalds 38531da177e4SLinus Torvalds if (conn) { 385465983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 385504837f64SMarcel Holtmann 38561da177e4SLinus Torvalds /* Send to upper protocol */ 3857686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 38581da177e4SLinus Torvalds return; 38591da177e4SLinus Torvalds } else { 38601da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 38611da177e4SLinus Torvalds hdev->name, handle); 38621da177e4SLinus Torvalds } 38631da177e4SLinus Torvalds 38641da177e4SLinus Torvalds kfree_skb(skb); 38651da177e4SLinus Torvalds } 38661da177e4SLinus Torvalds 38671da177e4SLinus Torvalds /* SCO data packet */ 38686039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 38691da177e4SLinus Torvalds { 38701da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 38711da177e4SLinus Torvalds struct hci_conn *conn; 38721da177e4SLinus Torvalds __u16 handle; 38731da177e4SLinus Torvalds 38741da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 38751da177e4SLinus Torvalds 38761da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 38771da177e4SLinus Torvalds 3878f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 38791da177e4SLinus Torvalds 38801da177e4SLinus Torvalds hdev->stat.sco_rx++; 38811da177e4SLinus Torvalds 38821da177e4SLinus Torvalds hci_dev_lock(hdev); 38831da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 38841da177e4SLinus Torvalds hci_dev_unlock(hdev); 38851da177e4SLinus Torvalds 38861da177e4SLinus Torvalds if (conn) { 38871da177e4SLinus Torvalds /* Send to upper protocol */ 3888686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 38891da177e4SLinus Torvalds return; 38901da177e4SLinus Torvalds } else { 38911da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 38921da177e4SLinus Torvalds hdev->name, handle); 38931da177e4SLinus Torvalds } 38941da177e4SLinus Torvalds 38951da177e4SLinus Torvalds kfree_skb(skb); 38961da177e4SLinus Torvalds } 38971da177e4SLinus Torvalds 38989238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 38999238f36aSJohan Hedberg { 39009238f36aSJohan Hedberg struct sk_buff *skb; 39019238f36aSJohan Hedberg 39029238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 39039238f36aSJohan Hedberg if (!skb) 39049238f36aSJohan Hedberg return true; 39059238f36aSJohan Hedberg 39069238f36aSJohan Hedberg return bt_cb(skb)->req.start; 39079238f36aSJohan Hedberg } 39089238f36aSJohan Hedberg 390942c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 391042c6b129SJohan Hedberg { 391142c6b129SJohan Hedberg struct hci_command_hdr *sent; 391242c6b129SJohan Hedberg struct sk_buff *skb; 391342c6b129SJohan Hedberg u16 opcode; 391442c6b129SJohan Hedberg 391542c6b129SJohan Hedberg if (!hdev->sent_cmd) 391642c6b129SJohan Hedberg return; 391742c6b129SJohan Hedberg 391842c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 391942c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 392042c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 392142c6b129SJohan Hedberg return; 392242c6b129SJohan Hedberg 392342c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 392442c6b129SJohan Hedberg if (!skb) 392542c6b129SJohan Hedberg return; 392642c6b129SJohan Hedberg 392742c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 392842c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 392942c6b129SJohan Hedberg } 393042c6b129SJohan Hedberg 39319238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 39329238f36aSJohan Hedberg { 39339238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 39349238f36aSJohan Hedberg struct sk_buff *skb; 39359238f36aSJohan Hedberg unsigned long flags; 39369238f36aSJohan Hedberg 39379238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 39389238f36aSJohan Hedberg 393942c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 394042c6b129SJohan Hedberg * sent we need to do special handling of it. 39419238f36aSJohan Hedberg */ 394242c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 394342c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 394442c6b129SJohan Hedberg * reset complete event during init and any pending 394542c6b129SJohan Hedberg * command will never be completed. In such a case we 394642c6b129SJohan Hedberg * need to resend whatever was the last sent 394742c6b129SJohan Hedberg * command. 394842c6b129SJohan Hedberg */ 394942c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 395042c6b129SJohan Hedberg hci_resend_last(hdev); 395142c6b129SJohan Hedberg 39529238f36aSJohan Hedberg return; 395342c6b129SJohan Hedberg } 39549238f36aSJohan Hedberg 39559238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 39569238f36aSJohan Hedberg * this request the request is not yet complete. 39579238f36aSJohan Hedberg */ 39589238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 39599238f36aSJohan Hedberg return; 39609238f36aSJohan Hedberg 39619238f36aSJohan Hedberg /* If this was the last command in a request the complete 39629238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 39639238f36aSJohan Hedberg * command queue (hdev->cmd_q). 39649238f36aSJohan Hedberg */ 39659238f36aSJohan Hedberg if (hdev->sent_cmd) { 39669238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 396753e21fbcSJohan Hedberg 396853e21fbcSJohan Hedberg if (req_complete) { 396953e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 397053e21fbcSJohan Hedberg * avoid calling the callback more than once if 397153e21fbcSJohan Hedberg * this function gets called again. 397253e21fbcSJohan Hedberg */ 397353e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 397453e21fbcSJohan Hedberg 39759238f36aSJohan Hedberg goto call_complete; 39769238f36aSJohan Hedberg } 397753e21fbcSJohan Hedberg } 39789238f36aSJohan Hedberg 39799238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 39809238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 39819238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 39829238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 39839238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 39849238f36aSJohan Hedberg break; 39859238f36aSJohan Hedberg } 39869238f36aSJohan Hedberg 39879238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 39889238f36aSJohan Hedberg kfree_skb(skb); 39899238f36aSJohan Hedberg } 39909238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 39919238f36aSJohan Hedberg 39929238f36aSJohan Hedberg call_complete: 39939238f36aSJohan Hedberg if (req_complete) 39949238f36aSJohan Hedberg req_complete(hdev, status); 39959238f36aSJohan Hedberg } 39969238f36aSJohan Hedberg 3997b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 39981da177e4SLinus Torvalds { 3999b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 40001da177e4SLinus Torvalds struct sk_buff *skb; 40011da177e4SLinus Torvalds 40021da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 40031da177e4SLinus Torvalds 40041da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 4005cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4006cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4007cd82e61cSMarcel Holtmann 40081da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 40091da177e4SLinus Torvalds /* Send copy to the sockets */ 4010470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 40111da177e4SLinus Torvalds } 40121da177e4SLinus Torvalds 40130736cfa8SMarcel Holtmann if (test_bit(HCI_RAW, &hdev->flags) || 40140736cfa8SMarcel Holtmann test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 40151da177e4SLinus Torvalds kfree_skb(skb); 40161da177e4SLinus Torvalds continue; 40171da177e4SLinus Torvalds } 40181da177e4SLinus Torvalds 40191da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 40201da177e4SLinus Torvalds /* Don't process data packets in this states. */ 40210d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 40221da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 40231da177e4SLinus Torvalds case HCI_SCODATA_PKT: 40241da177e4SLinus Torvalds kfree_skb(skb); 40251da177e4SLinus Torvalds continue; 40263ff50b79SStephen Hemminger } 40271da177e4SLinus Torvalds } 40281da177e4SLinus Torvalds 40291da177e4SLinus Torvalds /* Process frame */ 40300d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 40311da177e4SLinus Torvalds case HCI_EVENT_PKT: 4032b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 40331da177e4SLinus Torvalds hci_event_packet(hdev, skb); 40341da177e4SLinus Torvalds break; 40351da177e4SLinus Torvalds 40361da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 40371da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 40381da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 40391da177e4SLinus Torvalds break; 40401da177e4SLinus Torvalds 40411da177e4SLinus Torvalds case HCI_SCODATA_PKT: 40421da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 40431da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 40441da177e4SLinus Torvalds break; 40451da177e4SLinus Torvalds 40461da177e4SLinus Torvalds default: 40471da177e4SLinus Torvalds kfree_skb(skb); 40481da177e4SLinus Torvalds break; 40491da177e4SLinus Torvalds } 40501da177e4SLinus Torvalds } 40511da177e4SLinus Torvalds } 40521da177e4SLinus Torvalds 4053c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 40541da177e4SLinus Torvalds { 4055c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 40561da177e4SLinus Torvalds struct sk_buff *skb; 40571da177e4SLinus Torvalds 40582104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 40592104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 40601da177e4SLinus Torvalds 40611da177e4SLinus Torvalds /* Send queued commands */ 40625a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 40635a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 40645a08ecceSAndrei Emeltchenko if (!skb) 40655a08ecceSAndrei Emeltchenko return; 40665a08ecceSAndrei Emeltchenko 40671da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 40681da177e4SLinus Torvalds 4069a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 407070f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 40711da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 407257d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 40737bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 40747bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 40757bdb8a5cSSzymon Janc else 40766bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 40775f246e89SAndrei Emeltchenko jiffies + HCI_CMD_TIMEOUT); 40781da177e4SLinus Torvalds } else { 40791da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4080c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 40811da177e4SLinus Torvalds } 40821da177e4SLinus Torvalds } 40831da177e4SLinus Torvalds } 4084