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> 29611b30f7SMarcel Holtmann #include <linux/rfkill.h> 30baf27f6eSMarcel Holtmann #include <linux/debugfs.h> 3199780a7bSJohan Hedberg #include <linux/crypto.h> 327a0e5b15SMatthias Kaehlcke #include <linux/property.h> 339952d90eSAbhishek Pandit-Subedi #include <linux/suspend.h> 349952d90eSAbhishek Pandit-Subedi #include <linux/wait.h> 3547219839SMarcel Holtmann #include <asm/unaligned.h> 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 381da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 394bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h> 40af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h> 411da177e4SLinus Torvalds 420857dd3bSJohan Hedberg #include "hci_request.h" 4360c5f5fbSMarcel Holtmann #include "hci_debugfs.h" 44970c4e46SJohan Hedberg #include "smp.h" 456d5d2ee6SHeiner Kallweit #include "leds.h" 46145373cbSMiao-chen Chou #include "msft.h" 47f67743f9SMarcel Holtmann #include "aosp.h" 488961987fSKiran K #include "hci_codec.h" 49970c4e46SJohan Hedberg 50b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 51c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 523eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds /* HCI device list */ 551da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 561da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds /* HCI callback list */ 591da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 60fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock); 611da177e4SLinus Torvalds 623df92b31SSasha Levin /* HCI ID Numbering */ 633df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 643df92b31SSasha Levin 65a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt) 661da177e4SLinus Torvalds { 671da177e4SLinus Torvalds __u8 scan = opt; 681da177e4SLinus Torvalds 6942c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 701da177e4SLinus Torvalds 711da177e4SLinus Torvalds /* Inquiry and Page scans */ 7242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 73a1d01db1SJohan Hedberg return 0; 741da177e4SLinus Torvalds } 751da177e4SLinus Torvalds 76a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt) 771da177e4SLinus Torvalds { 781da177e4SLinus Torvalds __u8 auth = opt; 791da177e4SLinus Torvalds 8042c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds /* Authentication */ 8342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 84a1d01db1SJohan Hedberg return 0; 851da177e4SLinus Torvalds } 861da177e4SLinus Torvalds 87a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt) 881da177e4SLinus Torvalds { 891da177e4SLinus Torvalds __u8 encrypt = opt; 901da177e4SLinus Torvalds 9142c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 921da177e4SLinus Torvalds 93e4e8e37cSMarcel Holtmann /* Encryption */ 9442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 95a1d01db1SJohan Hedberg return 0; 961da177e4SLinus Torvalds } 971da177e4SLinus Torvalds 98a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt) 99e4e8e37cSMarcel Holtmann { 100e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 101e4e8e37cSMarcel Holtmann 10242c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 103e4e8e37cSMarcel Holtmann 104e4e8e37cSMarcel Holtmann /* Default link policy */ 10542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 106a1d01db1SJohan Hedberg return 0; 107e4e8e37cSMarcel Holtmann } 108e4e8e37cSMarcel Holtmann 1091da177e4SLinus Torvalds /* Get HCI device by index. 1101da177e4SLinus Torvalds * Device is held on return. */ 1111da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 1121da177e4SLinus Torvalds { 1138035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds BT_DBG("%d", index); 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds if (index < 0) 1181da177e4SLinus Torvalds return NULL; 1191da177e4SLinus Torvalds 1201da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 1218035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 1221da177e4SLinus Torvalds if (d->id == index) { 1231da177e4SLinus Torvalds hdev = hci_dev_hold(d); 1241da177e4SLinus Torvalds break; 1251da177e4SLinus Torvalds } 1261da177e4SLinus Torvalds } 1271da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 1281da177e4SLinus Torvalds return hdev; 1291da177e4SLinus Torvalds } 1301da177e4SLinus Torvalds 1311da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 132ff9ef578SJohan Hedberg 13330dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 13430dc78e1SJohan Hedberg { 13530dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 13630dc78e1SJohan Hedberg 1376fbe195dSAndre Guedes switch (discov->state) { 138343f935bSAndre Guedes case DISCOVERY_FINDING: 1396fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 14030dc78e1SJohan Hedberg return true; 14130dc78e1SJohan Hedberg 1426fbe195dSAndre Guedes default: 14330dc78e1SJohan Hedberg return false; 14430dc78e1SJohan Hedberg } 1456fbe195dSAndre Guedes } 14630dc78e1SJohan Hedberg 147ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 148ff9ef578SJohan Hedberg { 149bb3e0a33SJohan Hedberg int old_state = hdev->discovery.state; 150bb3e0a33SJohan Hedberg 151ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 152ff9ef578SJohan Hedberg 153bb3e0a33SJohan Hedberg if (old_state == state) 154ff9ef578SJohan Hedberg return; 155ff9ef578SJohan Hedberg 156bb3e0a33SJohan Hedberg hdev->discovery.state = state; 157bb3e0a33SJohan Hedberg 158ff9ef578SJohan Hedberg switch (state) { 159ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 1605bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev); 161c54c3860SAndre Guedes 162bb3e0a33SJohan Hedberg if (old_state != DISCOVERY_STARTING) 163ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 164ff9ef578SJohan Hedberg break; 165ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 166ff9ef578SJohan Hedberg break; 167343f935bSAndre Guedes case DISCOVERY_FINDING: 168ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 169ff9ef578SJohan Hedberg break; 17030dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 17130dc78e1SJohan Hedberg break; 172ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 173ff9ef578SJohan Hedberg break; 174ff9ef578SJohan Hedberg } 175ff9ef578SJohan Hedberg } 176ff9ef578SJohan Hedberg 1771f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 1781da177e4SLinus Torvalds { 17930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 180b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 1811da177e4SLinus Torvalds 182561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 183561aafbcSJohan Hedberg list_del(&p->all); 184b57c1a56SJohan Hedberg kfree(p); 1851da177e4SLinus Torvalds } 186561aafbcSJohan Hedberg 187561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 188561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 1891da177e4SLinus Torvalds } 1901da177e4SLinus Torvalds 191a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 192a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 1931da177e4SLinus Torvalds { 19430883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1951da177e4SLinus Torvalds struct inquiry_entry *e; 1961da177e4SLinus Torvalds 1976ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1981da177e4SLinus Torvalds 199561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 2001da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 2011da177e4SLinus Torvalds return e; 2021da177e4SLinus Torvalds } 2031da177e4SLinus Torvalds 204b57c1a56SJohan Hedberg return NULL; 205b57c1a56SJohan Hedberg } 206b57c1a56SJohan Hedberg 207561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 208561aafbcSJohan Hedberg bdaddr_t *bdaddr) 209561aafbcSJohan Hedberg { 21030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 211561aafbcSJohan Hedberg struct inquiry_entry *e; 212561aafbcSJohan Hedberg 2136ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 214561aafbcSJohan Hedberg 215561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 216561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 217561aafbcSJohan Hedberg return e; 218561aafbcSJohan Hedberg } 219561aafbcSJohan Hedberg 220561aafbcSJohan Hedberg return NULL; 221561aafbcSJohan Hedberg } 222561aafbcSJohan Hedberg 22330dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 22430dc78e1SJohan Hedberg bdaddr_t *bdaddr, 22530dc78e1SJohan Hedberg int state) 22630dc78e1SJohan Hedberg { 22730dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 22830dc78e1SJohan Hedberg struct inquiry_entry *e; 22930dc78e1SJohan Hedberg 2306ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 23130dc78e1SJohan Hedberg 23230dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 23330dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 23430dc78e1SJohan Hedberg return e; 23530dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 23630dc78e1SJohan Hedberg return e; 23730dc78e1SJohan Hedberg } 23830dc78e1SJohan Hedberg 23930dc78e1SJohan Hedberg return NULL; 24030dc78e1SJohan Hedberg } 24130dc78e1SJohan Hedberg 242a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 243a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 244a3d4e20aSJohan Hedberg { 245a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 246a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 247a3d4e20aSJohan Hedberg struct inquiry_entry *p; 248a3d4e20aSJohan Hedberg 249a3d4e20aSJohan Hedberg list_del(&ie->list); 250a3d4e20aSJohan Hedberg 251a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 252a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 253a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 254a3d4e20aSJohan Hedberg break; 255a3d4e20aSJohan Hedberg pos = &p->list; 256a3d4e20aSJohan Hedberg } 257a3d4e20aSJohan Hedberg 258a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 259a3d4e20aSJohan Hedberg } 260a3d4e20aSJohan Hedberg 261af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 262af58925cSMarcel Holtmann bool name_known) 2631da177e4SLinus Torvalds { 26430883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 26570f23020SAndrei Emeltchenko struct inquiry_entry *ie; 266af58925cSMarcel Holtmann u32 flags = 0; 2671da177e4SLinus Torvalds 2686ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 2691da177e4SLinus Torvalds 2706928a924SJohan Hedberg hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR); 2712b2fec4dSSzymon Janc 272af58925cSMarcel Holtmann if (!data->ssp_mode) 273af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 274388fc8faSJohan Hedberg 27570f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 276a3d4e20aSJohan Hedberg if (ie) { 277af58925cSMarcel Holtmann if (!ie->data.ssp_mode) 278af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 279388fc8faSJohan Hedberg 280a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 281a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 282a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 283a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 284a3d4e20aSJohan Hedberg } 285a3d4e20aSJohan Hedberg 286561aafbcSJohan Hedberg goto update; 287a3d4e20aSJohan Hedberg } 288561aafbcSJohan Hedberg 2891da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 29027f70f3eSJohan Hedberg ie = kzalloc(sizeof(*ie), GFP_KERNEL); 291af58925cSMarcel Holtmann if (!ie) { 292af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 293af58925cSMarcel Holtmann goto done; 294af58925cSMarcel Holtmann } 29570f23020SAndrei Emeltchenko 296561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 297561aafbcSJohan Hedberg 298561aafbcSJohan Hedberg if (name_known) { 299561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 300561aafbcSJohan Hedberg } else { 301561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 302561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 303561aafbcSJohan Hedberg } 304561aafbcSJohan Hedberg 305561aafbcSJohan Hedberg update: 306561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 307561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 308561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 309561aafbcSJohan Hedberg list_del(&ie->list); 3101da177e4SLinus Torvalds } 3111da177e4SLinus Torvalds 31270f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 31370f23020SAndrei Emeltchenko ie->timestamp = jiffies; 3141da177e4SLinus Torvalds cache->timestamp = jiffies; 3153175405bSJohan Hedberg 3163175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 317af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 3183175405bSJohan Hedberg 319af58925cSMarcel Holtmann done: 320af58925cSMarcel Holtmann return flags; 3211da177e4SLinus Torvalds } 3221da177e4SLinus Torvalds 3231da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 3241da177e4SLinus Torvalds { 32530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 3261da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 3271da177e4SLinus Torvalds struct inquiry_entry *e; 3281da177e4SLinus Torvalds int copied = 0; 3291da177e4SLinus Torvalds 330561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 3311da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 332b57c1a56SJohan Hedberg 333b57c1a56SJohan Hedberg if (copied >= num) 334b57c1a56SJohan Hedberg break; 335b57c1a56SJohan Hedberg 3361da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 3371da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 3381da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 3391da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 3401da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 3411da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 342b57c1a56SJohan Hedberg 3431da177e4SLinus Torvalds info++; 344b57c1a56SJohan Hedberg copied++; 3451da177e4SLinus Torvalds } 3461da177e4SLinus Torvalds 3471da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 3481da177e4SLinus Torvalds return copied; 3491da177e4SLinus Torvalds } 3501da177e4SLinus Torvalds 351a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt) 3521da177e4SLinus Torvalds { 3531da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 35442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 3551da177e4SLinus Torvalds struct hci_cp_inquiry cp; 3561da177e4SLinus Torvalds 3571da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 3581da177e4SLinus Torvalds 3591da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 360a1d01db1SJohan Hedberg return 0; 3611da177e4SLinus Torvalds 3621da177e4SLinus Torvalds /* Start Inquiry */ 3631da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 3641da177e4SLinus Torvalds cp.length = ir->length; 3651da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 36642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 367a1d01db1SJohan Hedberg 368a1d01db1SJohan Hedberg return 0; 3691da177e4SLinus Torvalds } 3701da177e4SLinus Torvalds 3711da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 3721da177e4SLinus Torvalds { 3731da177e4SLinus Torvalds __u8 __user *ptr = arg; 3741da177e4SLinus Torvalds struct hci_inquiry_req ir; 3751da177e4SLinus Torvalds struct hci_dev *hdev; 3761da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 3771da177e4SLinus Torvalds long timeo; 3781da177e4SLinus Torvalds __u8 *buf; 3791da177e4SLinus Torvalds 3801da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 3811da177e4SLinus Torvalds return -EFAULT; 3821da177e4SLinus Torvalds 3835a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 3845a08ecceSAndrei Emeltchenko if (!hdev) 3851da177e4SLinus Torvalds return -ENODEV; 3861da177e4SLinus Torvalds 387d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 3880736cfa8SMarcel Holtmann err = -EBUSY; 3890736cfa8SMarcel Holtmann goto done; 3900736cfa8SMarcel Holtmann } 3910736cfa8SMarcel Holtmann 392d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 393fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 394fee746b0SMarcel Holtmann goto done; 395fee746b0SMarcel Holtmann } 396fee746b0SMarcel Holtmann 397ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 3985b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 3995b69bef5SMarcel Holtmann goto done; 4005b69bef5SMarcel Holtmann } 4015b69bef5SMarcel Holtmann 402d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 40356f87901SJohan Hedberg err = -EOPNOTSUPP; 40456f87901SJohan Hedberg goto done; 40556f87901SJohan Hedberg } 40656f87901SJohan Hedberg 407f41a4b2bSPavel Skripkin /* Restrict maximum inquiry length to 60 seconds */ 408f41a4b2bSPavel Skripkin if (ir.length > 60) { 409f41a4b2bSPavel Skripkin err = -EINVAL; 410f41a4b2bSPavel Skripkin goto done; 411f41a4b2bSPavel Skripkin } 412f41a4b2bSPavel Skripkin 41309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4141da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 415a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 4161f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 4171da177e4SLinus Torvalds do_inquiry = 1; 4181da177e4SLinus Torvalds } 41909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 4201da177e4SLinus Torvalds 42104837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 42270f23020SAndrei Emeltchenko 42370f23020SAndrei Emeltchenko if (do_inquiry) { 42401178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 4254ebeee2dSJohan Hedberg timeo, NULL); 42670f23020SAndrei Emeltchenko if (err < 0) 4271da177e4SLinus Torvalds goto done; 4283e13fa1eSAndre Guedes 4293e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 4303e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 4313e13fa1eSAndre Guedes */ 43274316201SNeilBrown if (wait_on_bit(&hdev->flags, HCI_INQUIRY, 43328a758c8SPan Bian TASK_INTERRUPTIBLE)) { 43428a758c8SPan Bian err = -EINTR; 43528a758c8SPan Bian goto done; 43628a758c8SPan Bian } 43770f23020SAndrei Emeltchenko } 4381da177e4SLinus Torvalds 4398fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 4408fc9ced3SGustavo Padovan * 255 entries 4418fc9ced3SGustavo Padovan */ 4421da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 4431da177e4SLinus Torvalds 4441da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 4451da177e4SLinus Torvalds * copy it to the user space. 4461da177e4SLinus Torvalds */ 4476da2ec56SKees Cook buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL); 44870f23020SAndrei Emeltchenko if (!buf) { 4491da177e4SLinus Torvalds err = -ENOMEM; 4501da177e4SLinus Torvalds goto done; 4511da177e4SLinus Torvalds } 4521da177e4SLinus Torvalds 45309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4541da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 45509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 4561da177e4SLinus Torvalds 4571da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 4581da177e4SLinus Torvalds 4591da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 4601da177e4SLinus Torvalds ptr += sizeof(ir); 4611da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 4621da177e4SLinus Torvalds ir.num_rsp)) 4631da177e4SLinus Torvalds err = -EFAULT; 4641da177e4SLinus Torvalds } else 4651da177e4SLinus Torvalds err = -EFAULT; 4661da177e4SLinus Torvalds 4671da177e4SLinus Torvalds kfree(buf); 4681da177e4SLinus Torvalds 4691da177e4SLinus Torvalds done: 4701da177e4SLinus Torvalds hci_dev_put(hdev); 4711da177e4SLinus Torvalds return err; 4721da177e4SLinus Torvalds } 4731da177e4SLinus Torvalds 474cf75ad8bSLuiz Augusto von Dentz static int hci_dev_do_open(struct hci_dev *hdev) 475cf75ad8bSLuiz Augusto von Dentz { 476cf75ad8bSLuiz Augusto von Dentz int ret = 0; 477cf75ad8bSLuiz Augusto von Dentz 478cf75ad8bSLuiz Augusto von Dentz BT_DBG("%s %p", hdev->name, hdev); 479cf75ad8bSLuiz Augusto von Dentz 480cf75ad8bSLuiz Augusto von Dentz hci_req_sync_lock(hdev); 481cf75ad8bSLuiz Augusto von Dentz 482cf75ad8bSLuiz Augusto von Dentz ret = hci_dev_open_sync(hdev); 483cf75ad8bSLuiz Augusto von Dentz 484b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 4851da177e4SLinus Torvalds return ret; 4861da177e4SLinus Torvalds } 4871da177e4SLinus Torvalds 488cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 489cbed0ca1SJohan Hedberg 490cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 491cbed0ca1SJohan Hedberg { 492cbed0ca1SJohan Hedberg struct hci_dev *hdev; 493cbed0ca1SJohan Hedberg int err; 494cbed0ca1SJohan Hedberg 495cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 496cbed0ca1SJohan Hedberg if (!hdev) 497cbed0ca1SJohan Hedberg return -ENODEV; 498cbed0ca1SJohan Hedberg 4994a964404SMarcel Holtmann /* Devices that are marked as unconfigured can only be powered 500fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices 501fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is 502fee746b0SMarcel Holtmann * possible. 503fee746b0SMarcel Holtmann * 504fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag 505fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to 506fee746b0SMarcel Holtmann * open the device. 507fee746b0SMarcel Holtmann */ 508d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 509d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 510fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 511fee746b0SMarcel Holtmann goto done; 512fee746b0SMarcel Holtmann } 513fee746b0SMarcel Holtmann 514e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 515e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 516e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 517e1d08f40SJohan Hedberg * completed. 518e1d08f40SJohan Hedberg */ 519a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 520e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 521e1d08f40SJohan Hedberg 522a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 523a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 524a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 525a5c8f270SMarcel Holtmann */ 526e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 527e1d08f40SJohan Hedberg 52812aa4f0aSMarcel Holtmann /* For controllers not using the management interface and that 529b6ae8457SJohan Hedberg * are brought up using legacy ioctl, set the HCI_BONDABLE bit 53012aa4f0aSMarcel Holtmann * so that pairing works for them. Once the management interface 53112aa4f0aSMarcel Holtmann * is in use this bit will be cleared again and userspace has 53212aa4f0aSMarcel Holtmann * to explicitly enable it. 53312aa4f0aSMarcel Holtmann */ 534d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 535d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_MGMT)) 536a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BONDABLE); 53712aa4f0aSMarcel Holtmann 538cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 539cbed0ca1SJohan Hedberg 540fee746b0SMarcel Holtmann done: 541cbed0ca1SJohan Hedberg hci_dev_put(hdev); 542cbed0ca1SJohan Hedberg return err; 543cbed0ca1SJohan Hedberg } 544cbed0ca1SJohan Hedberg 545cf75ad8bSLuiz Augusto von Dentz int hci_dev_do_close(struct hci_dev *hdev) 546cf75ad8bSLuiz Augusto von Dentz { 547cf75ad8bSLuiz Augusto von Dentz int err; 548cf75ad8bSLuiz Augusto von Dentz 549cf75ad8bSLuiz Augusto von Dentz BT_DBG("%s %p", hdev->name, hdev); 550cf75ad8bSLuiz Augusto von Dentz 551cf75ad8bSLuiz Augusto von Dentz hci_req_sync_lock(hdev); 552cf75ad8bSLuiz Augusto von Dentz 553cf75ad8bSLuiz Augusto von Dentz err = hci_dev_close_sync(hdev); 554cf75ad8bSLuiz Augusto von Dentz 555b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 5561da177e4SLinus Torvalds 55761969ef8SKangmin Park return err; 5581da177e4SLinus Torvalds } 5591da177e4SLinus Torvalds 5601da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 5611da177e4SLinus Torvalds { 5621da177e4SLinus Torvalds struct hci_dev *hdev; 5631da177e4SLinus Torvalds int err; 5641da177e4SLinus Torvalds 56570f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 56670f23020SAndrei Emeltchenko if (!hdev) 5671da177e4SLinus Torvalds return -ENODEV; 5688ee56540SMarcel Holtmann 569d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 5700736cfa8SMarcel Holtmann err = -EBUSY; 5710736cfa8SMarcel Holtmann goto done; 5720736cfa8SMarcel Holtmann } 5730736cfa8SMarcel Holtmann 574a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 5758ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 5768ee56540SMarcel Holtmann 5771da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 5788ee56540SMarcel Holtmann 5790736cfa8SMarcel Holtmann done: 5801da177e4SLinus Torvalds hci_dev_put(hdev); 5811da177e4SLinus Torvalds return err; 5821da177e4SLinus Torvalds } 5831da177e4SLinus Torvalds 5845c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev) 5851da177e4SLinus Torvalds { 5865c912495SMarcel Holtmann int ret; 5871da177e4SLinus Torvalds 5885c912495SMarcel Holtmann BT_DBG("%s %p", hdev->name, hdev); 5891da177e4SLinus Torvalds 590b504430cSJohan Hedberg hci_req_sync_lock(hdev); 5911da177e4SLinus Torvalds 5921da177e4SLinus Torvalds /* Drop queues */ 5931da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 5941da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 5951da177e4SLinus Torvalds 59676727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 59776727c02SJohan Hedberg * ensuring the workqueue is empty up front. 59876727c02SJohan Hedberg */ 59976727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 60076727c02SJohan Hedberg 60109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 6021f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 6031da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 60409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 6051da177e4SLinus Torvalds 6061da177e4SLinus Torvalds if (hdev->flush) 6071da177e4SLinus Torvalds hdev->flush(hdev); 6081da177e4SLinus Torvalds 6091da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 6106ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 6111da177e4SLinus Torvalds 612*d0b13706SLuiz Augusto von Dentz ret = hci_reset_sync(hdev); 6131da177e4SLinus Torvalds 614b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 6151da177e4SLinus Torvalds return ret; 6161da177e4SLinus Torvalds } 6171da177e4SLinus Torvalds 6185c912495SMarcel Holtmann int hci_dev_reset(__u16 dev) 6195c912495SMarcel Holtmann { 6205c912495SMarcel Holtmann struct hci_dev *hdev; 6215c912495SMarcel Holtmann int err; 6225c912495SMarcel Holtmann 6235c912495SMarcel Holtmann hdev = hci_dev_get(dev); 6245c912495SMarcel Holtmann if (!hdev) 6255c912495SMarcel Holtmann return -ENODEV; 6265c912495SMarcel Holtmann 6275c912495SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 6285c912495SMarcel Holtmann err = -ENETDOWN; 6295c912495SMarcel Holtmann goto done; 6305c912495SMarcel Holtmann } 6315c912495SMarcel Holtmann 632d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 6335c912495SMarcel Holtmann err = -EBUSY; 6345c912495SMarcel Holtmann goto done; 6355c912495SMarcel Holtmann } 6365c912495SMarcel Holtmann 637d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 6385c912495SMarcel Holtmann err = -EOPNOTSUPP; 6395c912495SMarcel Holtmann goto done; 6405c912495SMarcel Holtmann } 6415c912495SMarcel Holtmann 6425c912495SMarcel Holtmann err = hci_dev_do_reset(hdev); 6435c912495SMarcel Holtmann 6445c912495SMarcel Holtmann done: 6455c912495SMarcel Holtmann hci_dev_put(hdev); 6465c912495SMarcel Holtmann return err; 6475c912495SMarcel Holtmann } 6485c912495SMarcel Holtmann 6491da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 6501da177e4SLinus Torvalds { 6511da177e4SLinus Torvalds struct hci_dev *hdev; 6521da177e4SLinus Torvalds int ret = 0; 6531da177e4SLinus Torvalds 65470f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 65570f23020SAndrei Emeltchenko if (!hdev) 6561da177e4SLinus Torvalds return -ENODEV; 6571da177e4SLinus Torvalds 658d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 6590736cfa8SMarcel Holtmann ret = -EBUSY; 6600736cfa8SMarcel Holtmann goto done; 6610736cfa8SMarcel Holtmann } 6620736cfa8SMarcel Holtmann 663d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 664fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 665fee746b0SMarcel Holtmann goto done; 666fee746b0SMarcel Holtmann } 667fee746b0SMarcel Holtmann 6681da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 6691da177e4SLinus Torvalds 6700736cfa8SMarcel Holtmann done: 6711da177e4SLinus Torvalds hci_dev_put(hdev); 6721da177e4SLinus Torvalds return ret; 6731da177e4SLinus Torvalds } 6741da177e4SLinus Torvalds 6755bee2fd6SLuiz Augusto von Dentz static void hci_update_passive_scan_state(struct hci_dev *hdev, u8 scan) 676123abc08SJohan Hedberg { 677bc6d2d04SJohan Hedberg bool conn_changed, discov_changed; 678123abc08SJohan Hedberg 679123abc08SJohan Hedberg BT_DBG("%s scan 0x%02x", hdev->name, scan); 680123abc08SJohan Hedberg 681123abc08SJohan Hedberg if ((scan & SCAN_PAGE)) 682238be788SMarcel Holtmann conn_changed = !hci_dev_test_and_set_flag(hdev, 683238be788SMarcel Holtmann HCI_CONNECTABLE); 684123abc08SJohan Hedberg else 685a69d8927SMarcel Holtmann conn_changed = hci_dev_test_and_clear_flag(hdev, 686a69d8927SMarcel Holtmann HCI_CONNECTABLE); 687123abc08SJohan Hedberg 688bc6d2d04SJohan Hedberg if ((scan & SCAN_INQUIRY)) { 689238be788SMarcel Holtmann discov_changed = !hci_dev_test_and_set_flag(hdev, 690238be788SMarcel Holtmann HCI_DISCOVERABLE); 691bc6d2d04SJohan Hedberg } else { 692a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 693a69d8927SMarcel Holtmann discov_changed = hci_dev_test_and_clear_flag(hdev, 694a69d8927SMarcel Holtmann HCI_DISCOVERABLE); 695bc6d2d04SJohan Hedberg } 696bc6d2d04SJohan Hedberg 697d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 698123abc08SJohan Hedberg return; 699123abc08SJohan Hedberg 700bc6d2d04SJohan Hedberg if (conn_changed || discov_changed) { 701bc6d2d04SJohan Hedberg /* In case this was disabled through mgmt */ 702a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 703bc6d2d04SJohan Hedberg 704d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 705cab054abSJohan Hedberg hci_req_update_adv_data(hdev, hdev->cur_adv_instance); 706bc6d2d04SJohan Hedberg 707123abc08SJohan Hedberg mgmt_new_settings(hdev); 708123abc08SJohan Hedberg } 709bc6d2d04SJohan Hedberg } 710123abc08SJohan Hedberg 7111da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 7121da177e4SLinus Torvalds { 7131da177e4SLinus Torvalds struct hci_dev *hdev; 7141da177e4SLinus Torvalds struct hci_dev_req dr; 7151da177e4SLinus Torvalds int err = 0; 7161da177e4SLinus Torvalds 7171da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 7181da177e4SLinus Torvalds return -EFAULT; 7191da177e4SLinus Torvalds 72070f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 72170f23020SAndrei Emeltchenko if (!hdev) 7221da177e4SLinus Torvalds return -ENODEV; 7231da177e4SLinus Torvalds 724d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 7250736cfa8SMarcel Holtmann err = -EBUSY; 7260736cfa8SMarcel Holtmann goto done; 7270736cfa8SMarcel Holtmann } 7280736cfa8SMarcel Holtmann 729d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 730fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 731fee746b0SMarcel Holtmann goto done; 732fee746b0SMarcel Holtmann } 733fee746b0SMarcel Holtmann 734ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 7355b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 7365b69bef5SMarcel Holtmann goto done; 7375b69bef5SMarcel Holtmann } 7385b69bef5SMarcel Holtmann 739d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 74056f87901SJohan Hedberg err = -EOPNOTSUPP; 74156f87901SJohan Hedberg goto done; 74256f87901SJohan Hedberg } 74356f87901SJohan Hedberg 7441da177e4SLinus Torvalds switch (cmd) { 7451da177e4SLinus Torvalds case HCISETAUTH: 74601178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 7474ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 7481da177e4SLinus Torvalds break; 7491da177e4SLinus Torvalds 7501da177e4SLinus Torvalds case HCISETENCRYPT: 7511da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 7521da177e4SLinus Torvalds err = -EOPNOTSUPP; 7531da177e4SLinus Torvalds break; 7541da177e4SLinus Torvalds } 7551da177e4SLinus Torvalds 7561da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 7571da177e4SLinus Torvalds /* Auth must be enabled first */ 75801178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 7594ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 7601da177e4SLinus Torvalds if (err) 7611da177e4SLinus Torvalds break; 7621da177e4SLinus Torvalds } 7631da177e4SLinus Torvalds 76401178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 7654ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 7661da177e4SLinus Torvalds break; 7671da177e4SLinus Torvalds 7681da177e4SLinus Torvalds case HCISETSCAN: 76901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 7704ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 77191a668b0SJohan Hedberg 772bc6d2d04SJohan Hedberg /* Ensure that the connectable and discoverable states 773bc6d2d04SJohan Hedberg * get correctly modified as this was a non-mgmt change. 77491a668b0SJohan Hedberg */ 775123abc08SJohan Hedberg if (!err) 7765bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan_state(hdev, dr.dev_opt); 7771da177e4SLinus Torvalds break; 7781da177e4SLinus Torvalds 7791da177e4SLinus Torvalds case HCISETLINKPOL: 78001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 7814ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 7821da177e4SLinus Torvalds break; 7831da177e4SLinus Torvalds 7841da177e4SLinus Torvalds case HCISETLINKMODE: 785e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 786e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 787e4e8e37cSMarcel Holtmann break; 788e4e8e37cSMarcel Holtmann 789e4e8e37cSMarcel Holtmann case HCISETPTYPE: 790b7c23df8SJaganath Kanakkassery if (hdev->pkt_type == (__u16) dr.dev_opt) 791b7c23df8SJaganath Kanakkassery break; 792b7c23df8SJaganath Kanakkassery 793e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 794b7c23df8SJaganath Kanakkassery mgmt_phy_configuration_changed(hdev, NULL); 7951da177e4SLinus Torvalds break; 7961da177e4SLinus Torvalds 7971da177e4SLinus Torvalds case HCISETACLMTU: 7981da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 7991da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 8001da177e4SLinus Torvalds break; 8011da177e4SLinus Torvalds 8021da177e4SLinus Torvalds case HCISETSCOMTU: 8031da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 8041da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 8051da177e4SLinus Torvalds break; 8061da177e4SLinus Torvalds 8071da177e4SLinus Torvalds default: 8081da177e4SLinus Torvalds err = -EINVAL; 8091da177e4SLinus Torvalds break; 8101da177e4SLinus Torvalds } 811e4e8e37cSMarcel Holtmann 8120736cfa8SMarcel Holtmann done: 8131da177e4SLinus Torvalds hci_dev_put(hdev); 8141da177e4SLinus Torvalds return err; 8151da177e4SLinus Torvalds } 8161da177e4SLinus Torvalds 8171da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 8181da177e4SLinus Torvalds { 8198035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 8201da177e4SLinus Torvalds struct hci_dev_list_req *dl; 8211da177e4SLinus Torvalds struct hci_dev_req *dr; 8221da177e4SLinus Torvalds int n = 0, size, err; 8231da177e4SLinus Torvalds __u16 dev_num; 8241da177e4SLinus Torvalds 8251da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 8261da177e4SLinus Torvalds return -EFAULT; 8271da177e4SLinus Torvalds 8281da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 8291da177e4SLinus Torvalds return -EINVAL; 8301da177e4SLinus Torvalds 8311da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 8321da177e4SLinus Torvalds 83370f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 83470f23020SAndrei Emeltchenko if (!dl) 8351da177e4SLinus Torvalds return -ENOMEM; 8361da177e4SLinus Torvalds 8371da177e4SLinus Torvalds dr = dl->dev_req; 8381da177e4SLinus Torvalds 839f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 8408035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 8412e84d8dbSMarcel Holtmann unsigned long flags = hdev->flags; 842c542a06cSJohan Hedberg 8432e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 8442e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 8452e84d8dbSMarcel Holtmann * device is actually down. 8462e84d8dbSMarcel Holtmann */ 847d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 8482e84d8dbSMarcel Holtmann flags &= ~BIT(HCI_UP); 849c542a06cSJohan Hedberg 8501da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 8512e84d8dbSMarcel Holtmann (dr + n)->dev_opt = flags; 852c542a06cSJohan Hedberg 8531da177e4SLinus Torvalds if (++n >= dev_num) 8541da177e4SLinus Torvalds break; 8551da177e4SLinus Torvalds } 856f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 8571da177e4SLinus Torvalds 8581da177e4SLinus Torvalds dl->dev_num = n; 8591da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 8601da177e4SLinus Torvalds 8611da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 8621da177e4SLinus Torvalds kfree(dl); 8631da177e4SLinus Torvalds 8641da177e4SLinus Torvalds return err ? -EFAULT : 0; 8651da177e4SLinus Torvalds } 8661da177e4SLinus Torvalds 8671da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 8681da177e4SLinus Torvalds { 8691da177e4SLinus Torvalds struct hci_dev *hdev; 8701da177e4SLinus Torvalds struct hci_dev_info di; 8712e84d8dbSMarcel Holtmann unsigned long flags; 8721da177e4SLinus Torvalds int err = 0; 8731da177e4SLinus Torvalds 8741da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 8751da177e4SLinus Torvalds return -EFAULT; 8761da177e4SLinus Torvalds 87770f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 87870f23020SAndrei Emeltchenko if (!hdev) 8791da177e4SLinus Torvalds return -ENODEV; 8801da177e4SLinus Torvalds 8812e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 8822e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 8832e84d8dbSMarcel Holtmann * device is actually down. 8842e84d8dbSMarcel Holtmann */ 885d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 8862e84d8dbSMarcel Holtmann flags = hdev->flags & ~BIT(HCI_UP); 8872e84d8dbSMarcel Holtmann else 8882e84d8dbSMarcel Holtmann flags = hdev->flags; 889c542a06cSJohan Hedberg 8901da177e4SLinus Torvalds strcpy(di.name, hdev->name); 8911da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 89260f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 8932e84d8dbSMarcel Holtmann di.flags = flags; 8941da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 895572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 8961da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 8971da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 8981da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 8991da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 900572c7f84SJohan Hedberg } else { 901572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 902572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 903572c7f84SJohan Hedberg di.sco_mtu = 0; 904572c7f84SJohan Hedberg di.sco_pkts = 0; 905572c7f84SJohan Hedberg } 9061da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 9071da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 9081da177e4SLinus Torvalds 9091da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 9101da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 9111da177e4SLinus Torvalds 9121da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 9131da177e4SLinus Torvalds err = -EFAULT; 9141da177e4SLinus Torvalds 9151da177e4SLinus Torvalds hci_dev_put(hdev); 9161da177e4SLinus Torvalds 9171da177e4SLinus Torvalds return err; 9181da177e4SLinus Torvalds } 9191da177e4SLinus Torvalds 9201da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 9211da177e4SLinus Torvalds 922611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 923611b30f7SMarcel Holtmann { 924611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 925611b30f7SMarcel Holtmann 926611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 927611b30f7SMarcel Holtmann 928d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) 9290736cfa8SMarcel Holtmann return -EBUSY; 9300736cfa8SMarcel Holtmann 9315e130367SJohan Hedberg if (blocked) { 932a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 933d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 934d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 935611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 9365e130367SJohan Hedberg } else { 937a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_RFKILLED); 9385e130367SJohan Hedberg } 939611b30f7SMarcel Holtmann 940611b30f7SMarcel Holtmann return 0; 941611b30f7SMarcel Holtmann } 942611b30f7SMarcel Holtmann 943611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 944611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 945611b30f7SMarcel Holtmann }; 946611b30f7SMarcel Holtmann 947ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 948ab81cbf9SJohan Hedberg { 949ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 95096570ffcSJohan Hedberg int err; 951ab81cbf9SJohan Hedberg 952ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 953ab81cbf9SJohan Hedberg 9542ff13894SJohan Hedberg if (test_bit(HCI_UP, &hdev->flags) && 9552ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 9562ff13894SJohan Hedberg hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) { 957d82142a8SWei-Ning Huang cancel_delayed_work(&hdev->power_off); 958cf75ad8bSLuiz Augusto von Dentz err = hci_powered_update_sync(hdev); 9592ff13894SJohan Hedberg mgmt_power_on(hdev, err); 9602ff13894SJohan Hedberg return; 9612ff13894SJohan Hedberg } 9622ff13894SJohan Hedberg 963cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 96496570ffcSJohan Hedberg if (err < 0) { 9653ad67582SJaganath Kanakkassery hci_dev_lock(hdev); 96696570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 9673ad67582SJaganath Kanakkassery hci_dev_unlock(hdev); 968ab81cbf9SJohan Hedberg return; 96996570ffcSJohan Hedberg } 970ab81cbf9SJohan Hedberg 971a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 972a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 973a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 974a5c8f270SMarcel Holtmann */ 975d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED) || 976d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_UNCONFIGURED) || 977ca8bee5dSMarcel Holtmann (hdev->dev_type == HCI_PRIMARY && 978a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 979a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 980a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_AUTO_OFF); 981bf543036SJohan Hedberg hci_dev_do_close(hdev); 982d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) { 98319202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 98419202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 985bf543036SJohan Hedberg } 986ab81cbf9SJohan Hedberg 987a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) { 9884a964404SMarcel Holtmann /* For unconfigured devices, set the HCI_RAW flag 9894a964404SMarcel Holtmann * so that userspace can easily identify them. 9904a964404SMarcel Holtmann */ 991d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 9924a964404SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 9930602a8adSMarcel Holtmann 9940602a8adSMarcel Holtmann /* For fully configured devices, this will send 9950602a8adSMarcel Holtmann * the Index Added event. For unconfigured devices, 9960602a8adSMarcel Holtmann * it will send Unconfigued Index Added event. 9970602a8adSMarcel Holtmann * 9980602a8adSMarcel Holtmann * Devices with HCI_QUIRK_RAW_DEVICE are ignored 9990602a8adSMarcel Holtmann * and no event will be send. 10000602a8adSMarcel Holtmann */ 1001744cf19eSJohan Hedberg mgmt_index_added(hdev); 1002a69d8927SMarcel Holtmann } else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) { 10035ea234d3SMarcel Holtmann /* When the controller is now configured, then it 10045ea234d3SMarcel Holtmann * is important to clear the HCI_RAW flag. 10055ea234d3SMarcel Holtmann */ 1006d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 10075ea234d3SMarcel Holtmann clear_bit(HCI_RAW, &hdev->flags); 10085ea234d3SMarcel Holtmann 1009d603b76bSMarcel Holtmann /* Powering on the controller with HCI_CONFIG set only 1010d603b76bSMarcel Holtmann * happens with the transition from unconfigured to 1011d603b76bSMarcel Holtmann * configured. This will send the Index Added event. 1012d603b76bSMarcel Holtmann */ 1013d603b76bSMarcel Holtmann mgmt_index_added(hdev); 1014ab81cbf9SJohan Hedberg } 1015ab81cbf9SJohan Hedberg } 1016ab81cbf9SJohan Hedberg 1017ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1018ab81cbf9SJohan Hedberg { 10193243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 10203243553fSJohan Hedberg power_off.work); 1021ab81cbf9SJohan Hedberg 1022ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1023ab81cbf9SJohan Hedberg 10248ee56540SMarcel Holtmann hci_dev_do_close(hdev); 1025ab81cbf9SJohan Hedberg } 1026ab81cbf9SJohan Hedberg 1027c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work) 1028c7741d16SMarcel Holtmann { 1029c7741d16SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset); 1030c7741d16SMarcel Holtmann 1031c7741d16SMarcel Holtmann BT_DBG("%s", hdev->name); 1032c7741d16SMarcel Holtmann 1033c7741d16SMarcel Holtmann if (hdev->hw_error) 1034c7741d16SMarcel Holtmann hdev->hw_error(hdev, hdev->hw_error_code); 1035c7741d16SMarcel Holtmann else 10362064ee33SMarcel Holtmann bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code); 1037c7741d16SMarcel Holtmann 1038c7741d16SMarcel Holtmann if (hci_dev_do_close(hdev)) 1039c7741d16SMarcel Holtmann return; 1040c7741d16SMarcel Holtmann 1041c7741d16SMarcel Holtmann hci_dev_do_open(hdev); 1042c7741d16SMarcel Holtmann } 1043c7741d16SMarcel Holtmann 104435f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 10452aeb9a1aSJohan Hedberg { 10464821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 10472aeb9a1aSJohan Hedberg 10484821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 10494821002cSJohan Hedberg list_del(&uuid->list); 10502aeb9a1aSJohan Hedberg kfree(uuid); 10512aeb9a1aSJohan Hedberg } 10522aeb9a1aSJohan Hedberg } 10532aeb9a1aSJohan Hedberg 105435f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 105555ed8ca1SJohan Hedberg { 105655ed8ca1SJohan Hedberg struct link_key *key; 105755ed8ca1SJohan Hedberg 1058d7d41682SMadhuparna Bhowmik list_for_each_entry(key, &hdev->link_keys, list) { 10590378b597SJohan Hedberg list_del_rcu(&key->list); 10600378b597SJohan Hedberg kfree_rcu(key, rcu); 106155ed8ca1SJohan Hedberg } 106255ed8ca1SJohan Hedberg } 106355ed8ca1SJohan Hedberg 106435f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 1065b899efafSVinicius Costa Gomes { 1066970d0f1bSJohan Hedberg struct smp_ltk *k; 1067b899efafSVinicius Costa Gomes 1068d7d41682SMadhuparna Bhowmik list_for_each_entry(k, &hdev->long_term_keys, list) { 1069970d0f1bSJohan Hedberg list_del_rcu(&k->list); 1070970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 1071b899efafSVinicius Costa Gomes } 1072b899efafSVinicius Costa Gomes } 1073b899efafSVinicius Costa Gomes 1074970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 1075970c4e46SJohan Hedberg { 1076adae20cbSJohan Hedberg struct smp_irk *k; 1077970c4e46SJohan Hedberg 1078d7d41682SMadhuparna Bhowmik list_for_each_entry(k, &hdev->identity_resolving_keys, list) { 1079adae20cbSJohan Hedberg list_del_rcu(&k->list); 1080adae20cbSJohan Hedberg kfree_rcu(k, rcu); 1081970c4e46SJohan Hedberg } 1082970c4e46SJohan Hedberg } 1083970c4e46SJohan Hedberg 1084600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev) 1085600a8749SAlain Michaud { 1086600a8749SAlain Michaud struct blocked_key *b; 1087600a8749SAlain Michaud 1088d7d41682SMadhuparna Bhowmik list_for_each_entry(b, &hdev->blocked_keys, list) { 1089600a8749SAlain Michaud list_del_rcu(&b->list); 1090600a8749SAlain Michaud kfree_rcu(b, rcu); 1091600a8749SAlain Michaud } 1092600a8749SAlain Michaud } 1093600a8749SAlain Michaud 1094600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16]) 1095600a8749SAlain Michaud { 1096600a8749SAlain Michaud bool blocked = false; 1097600a8749SAlain Michaud struct blocked_key *b; 1098600a8749SAlain Michaud 1099600a8749SAlain Michaud rcu_read_lock(); 11000c2ac7d4SMadhuparna Bhowmik list_for_each_entry_rcu(b, &hdev->blocked_keys, list) { 1101600a8749SAlain Michaud if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) { 1102600a8749SAlain Michaud blocked = true; 1103600a8749SAlain Michaud break; 1104600a8749SAlain Michaud } 1105600a8749SAlain Michaud } 1106600a8749SAlain Michaud 1107600a8749SAlain Michaud rcu_read_unlock(); 1108600a8749SAlain Michaud return blocked; 1109600a8749SAlain Michaud } 1110600a8749SAlain Michaud 111155ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 111255ed8ca1SJohan Hedberg { 111355ed8ca1SJohan Hedberg struct link_key *k; 111455ed8ca1SJohan Hedberg 11150378b597SJohan Hedberg rcu_read_lock(); 11160378b597SJohan Hedberg list_for_each_entry_rcu(k, &hdev->link_keys, list) { 11170378b597SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) { 11180378b597SJohan Hedberg rcu_read_unlock(); 1119600a8749SAlain Michaud 1120600a8749SAlain Michaud if (hci_is_blocked_key(hdev, 1121600a8749SAlain Michaud HCI_BLOCKED_KEY_TYPE_LINKKEY, 1122600a8749SAlain Michaud k->val)) { 1123600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, 1124600a8749SAlain Michaud "Link key blocked for %pMR", 1125600a8749SAlain Michaud &k->bdaddr); 1126600a8749SAlain Michaud return NULL; 1127600a8749SAlain Michaud } 1128600a8749SAlain Michaud 112955ed8ca1SJohan Hedberg return k; 11300378b597SJohan Hedberg } 11310378b597SJohan Hedberg } 11320378b597SJohan Hedberg rcu_read_unlock(); 113355ed8ca1SJohan Hedberg 113455ed8ca1SJohan Hedberg return NULL; 113555ed8ca1SJohan Hedberg } 113655ed8ca1SJohan Hedberg 1137745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 1138d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 1139d25e28abSJohan Hedberg { 1140d25e28abSJohan Hedberg /* Legacy key */ 1141d25e28abSJohan Hedberg if (key_type < 0x03) 1142745c0ce3SVishal Agarwal return true; 1143d25e28abSJohan Hedberg 1144d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 1145d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 1146745c0ce3SVishal Agarwal return false; 1147d25e28abSJohan Hedberg 1148d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 1149d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 1150745c0ce3SVishal Agarwal return false; 1151d25e28abSJohan Hedberg 1152d25e28abSJohan Hedberg /* Security mode 3 case */ 1153d25e28abSJohan Hedberg if (!conn) 1154745c0ce3SVishal Agarwal return true; 1155d25e28abSJohan Hedberg 1156e3befab9SJohan Hedberg /* BR/EDR key derived using SC from an LE link */ 1157e3befab9SJohan Hedberg if (conn->type == LE_LINK) 1158e3befab9SJohan Hedberg return true; 1159e3befab9SJohan Hedberg 1160d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 1161d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 1162745c0ce3SVishal Agarwal return true; 1163d25e28abSJohan Hedberg 1164d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 1165d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 1166745c0ce3SVishal Agarwal return true; 1167d25e28abSJohan Hedberg 1168d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 1169d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 1170745c0ce3SVishal Agarwal return true; 1171d25e28abSJohan Hedberg 1172d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 1173d25e28abSJohan Hedberg * persistently */ 1174745c0ce3SVishal Agarwal return false; 1175d25e28abSJohan Hedberg } 1176d25e28abSJohan Hedberg 1177e804d25dSJohan Hedberg static u8 ltk_role(u8 type) 117898a0b845SJohan Hedberg { 1179e804d25dSJohan Hedberg if (type == SMP_LTK) 1180e804d25dSJohan Hedberg return HCI_ROLE_MASTER; 118198a0b845SJohan Hedberg 1182e804d25dSJohan Hedberg return HCI_ROLE_SLAVE; 118398a0b845SJohan Hedberg } 118498a0b845SJohan Hedberg 1185f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 1186e804d25dSJohan Hedberg u8 addr_type, u8 role) 118775d262c2SVinicius Costa Gomes { 1188c9839a11SVinicius Costa Gomes struct smp_ltk *k; 118975d262c2SVinicius Costa Gomes 1190970d0f1bSJohan Hedberg rcu_read_lock(); 1191970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 11925378bc56SJohan Hedberg if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr)) 11935378bc56SJohan Hedberg continue; 11945378bc56SJohan Hedberg 1195923e2414SJohan Hedberg if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) { 1196970d0f1bSJohan Hedberg rcu_read_unlock(); 1197600a8749SAlain Michaud 1198600a8749SAlain Michaud if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK, 1199600a8749SAlain Michaud k->val)) { 1200600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, 1201600a8749SAlain Michaud "LTK blocked for %pMR", 1202600a8749SAlain Michaud &k->bdaddr); 1203600a8749SAlain Michaud return NULL; 1204600a8749SAlain Michaud } 1205600a8749SAlain Michaud 120675d262c2SVinicius Costa Gomes return k; 1207970d0f1bSJohan Hedberg } 1208970d0f1bSJohan Hedberg } 1209970d0f1bSJohan Hedberg rcu_read_unlock(); 121075d262c2SVinicius Costa Gomes 121175d262c2SVinicius Costa Gomes return NULL; 121275d262c2SVinicius Costa Gomes } 121375d262c2SVinicius Costa Gomes 1214970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 1215970c4e46SJohan Hedberg { 1216600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL; 1217970c4e46SJohan Hedberg struct smp_irk *irk; 1218970c4e46SJohan Hedberg 1219adae20cbSJohan Hedberg rcu_read_lock(); 1220adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 1221adae20cbSJohan Hedberg if (!bacmp(&irk->rpa, rpa)) { 1222600a8749SAlain Michaud irk_to_return = irk; 1223600a8749SAlain Michaud goto done; 1224970c4e46SJohan Hedberg } 1225adae20cbSJohan Hedberg } 1226970c4e46SJohan Hedberg 1227adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 1228defce9e8SJohan Hedberg if (smp_irk_matches(hdev, irk->val, rpa)) { 1229970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 1230600a8749SAlain Michaud irk_to_return = irk; 1231600a8749SAlain Michaud goto done; 1232970c4e46SJohan Hedberg } 1233970c4e46SJohan Hedberg } 1234600a8749SAlain Michaud 1235600a8749SAlain Michaud done: 1236600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK, 1237600a8749SAlain Michaud irk_to_return->val)) { 1238600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR", 1239600a8749SAlain Michaud &irk_to_return->bdaddr); 1240600a8749SAlain Michaud irk_to_return = NULL; 1241600a8749SAlain Michaud } 1242600a8749SAlain Michaud 1243adae20cbSJohan Hedberg rcu_read_unlock(); 1244970c4e46SJohan Hedberg 1245600a8749SAlain Michaud return irk_to_return; 1246970c4e46SJohan Hedberg } 1247970c4e46SJohan Hedberg 1248970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1249970c4e46SJohan Hedberg u8 addr_type) 1250970c4e46SJohan Hedberg { 1251600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL; 1252970c4e46SJohan Hedberg struct smp_irk *irk; 1253970c4e46SJohan Hedberg 12546cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 12556cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 12566cfc9988SJohan Hedberg return NULL; 12576cfc9988SJohan Hedberg 1258adae20cbSJohan Hedberg rcu_read_lock(); 1259adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 1260970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 1261adae20cbSJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) { 1262600a8749SAlain Michaud irk_to_return = irk; 1263600a8749SAlain Michaud goto done; 1264970c4e46SJohan Hedberg } 1265adae20cbSJohan Hedberg } 1266600a8749SAlain Michaud 1267600a8749SAlain Michaud done: 1268600a8749SAlain Michaud 1269600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK, 1270600a8749SAlain Michaud irk_to_return->val)) { 1271600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR", 1272600a8749SAlain Michaud &irk_to_return->bdaddr); 1273600a8749SAlain Michaud irk_to_return = NULL; 1274600a8749SAlain Michaud } 1275600a8749SAlain Michaud 1276adae20cbSJohan Hedberg rcu_read_unlock(); 1277970c4e46SJohan Hedberg 1278600a8749SAlain Michaud return irk_to_return; 1279970c4e46SJohan Hedberg } 1280970c4e46SJohan Hedberg 1281567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 12827652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 12837652ff6aSJohan Hedberg u8 pin_len, bool *persistent) 128455ed8ca1SJohan Hedberg { 128555ed8ca1SJohan Hedberg struct link_key *key, *old_key; 1286745c0ce3SVishal Agarwal u8 old_key_type; 128755ed8ca1SJohan Hedberg 128855ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 128955ed8ca1SJohan Hedberg if (old_key) { 129055ed8ca1SJohan Hedberg old_key_type = old_key->type; 129155ed8ca1SJohan Hedberg key = old_key; 129255ed8ca1SJohan Hedberg } else { 129312adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 12940a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 129555ed8ca1SJohan Hedberg if (!key) 1296567fa2aaSJohan Hedberg return NULL; 12970378b597SJohan Hedberg list_add_rcu(&key->list, &hdev->link_keys); 129855ed8ca1SJohan Hedberg } 129955ed8ca1SJohan Hedberg 13006ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 130155ed8ca1SJohan Hedberg 1302d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1303d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1304d25e28abSJohan Hedberg * previous key */ 1305d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1306a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 1307d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1308655fe6ecSJohan Hedberg if (conn) 1309655fe6ecSJohan Hedberg conn->key_type = type; 1310655fe6ecSJohan Hedberg } 1311d25e28abSJohan Hedberg 131255ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 13139b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 131455ed8ca1SJohan Hedberg key->pin_len = pin_len; 131555ed8ca1SJohan Hedberg 1316b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 131755ed8ca1SJohan Hedberg key->type = old_key_type; 13184748fed2SJohan Hedberg else 13194748fed2SJohan Hedberg key->type = type; 13204748fed2SJohan Hedberg 13217652ff6aSJohan Hedberg if (persistent) 13227652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type, 13237652ff6aSJohan Hedberg old_key_type); 13244df378a1SJohan Hedberg 1325567fa2aaSJohan Hedberg return key; 132655ed8ca1SJohan Hedberg } 132755ed8ca1SJohan Hedberg 1328ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 132935d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 1330fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand) 133175d262c2SVinicius Costa Gomes { 1332c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 1333e804d25dSJohan Hedberg u8 role = ltk_role(type); 133475d262c2SVinicius Costa Gomes 1335f3a73d97SJohan Hedberg old_key = hci_find_ltk(hdev, bdaddr, addr_type, role); 1336c9839a11SVinicius Costa Gomes if (old_key) 133775d262c2SVinicius Costa Gomes key = old_key; 1338c9839a11SVinicius Costa Gomes else { 13390a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 134075d262c2SVinicius Costa Gomes if (!key) 1341ca9142b8SJohan Hedberg return NULL; 1342970d0f1bSJohan Hedberg list_add_rcu(&key->list, &hdev->long_term_keys); 134375d262c2SVinicius Costa Gomes } 134475d262c2SVinicius Costa Gomes 134575d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 1346c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 1347c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 1348c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 1349c9839a11SVinicius Costa Gomes key->ediv = ediv; 1350fe39c7b2SMarcel Holtmann key->rand = rand; 1351c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 1352c9839a11SVinicius Costa Gomes key->type = type; 135375d262c2SVinicius Costa Gomes 1354ca9142b8SJohan Hedberg return key; 135575d262c2SVinicius Costa Gomes } 135675d262c2SVinicius Costa Gomes 1357ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 1358ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 1359970c4e46SJohan Hedberg { 1360970c4e46SJohan Hedberg struct smp_irk *irk; 1361970c4e46SJohan Hedberg 1362970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 1363970c4e46SJohan Hedberg if (!irk) { 1364970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 1365970c4e46SJohan Hedberg if (!irk) 1366ca9142b8SJohan Hedberg return NULL; 1367970c4e46SJohan Hedberg 1368970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 1369970c4e46SJohan Hedberg irk->addr_type = addr_type; 1370970c4e46SJohan Hedberg 1371adae20cbSJohan Hedberg list_add_rcu(&irk->list, &hdev->identity_resolving_keys); 1372970c4e46SJohan Hedberg } 1373970c4e46SJohan Hedberg 1374970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 1375970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 1376970c4e46SJohan Hedberg 1377ca9142b8SJohan Hedberg return irk; 1378970c4e46SJohan Hedberg } 1379970c4e46SJohan Hedberg 138055ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 138155ed8ca1SJohan Hedberg { 138255ed8ca1SJohan Hedberg struct link_key *key; 138355ed8ca1SJohan Hedberg 138455ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 138555ed8ca1SJohan Hedberg if (!key) 138655ed8ca1SJohan Hedberg return -ENOENT; 138755ed8ca1SJohan Hedberg 13886ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 138955ed8ca1SJohan Hedberg 13900378b597SJohan Hedberg list_del_rcu(&key->list); 13910378b597SJohan Hedberg kfree_rcu(key, rcu); 139255ed8ca1SJohan Hedberg 139355ed8ca1SJohan Hedberg return 0; 139455ed8ca1SJohan Hedberg } 139555ed8ca1SJohan Hedberg 1396e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 1397b899efafSVinicius Costa Gomes { 1398970d0f1bSJohan Hedberg struct smp_ltk *k; 1399c51ffa0bSJohan Hedberg int removed = 0; 1400b899efafSVinicius Costa Gomes 1401970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 1402e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 1403b899efafSVinicius Costa Gomes continue; 1404b899efafSVinicius Costa Gomes 14056ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 1406b899efafSVinicius Costa Gomes 1407970d0f1bSJohan Hedberg list_del_rcu(&k->list); 1408970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 1409c51ffa0bSJohan Hedberg removed++; 1410b899efafSVinicius Costa Gomes } 1411b899efafSVinicius Costa Gomes 1412c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 1413b899efafSVinicius Costa Gomes } 1414b899efafSVinicius Costa Gomes 1415a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 1416a7ec7338SJohan Hedberg { 1417adae20cbSJohan Hedberg struct smp_irk *k; 1418a7ec7338SJohan Hedberg 1419adae20cbSJohan Hedberg list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { 1420a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 1421a7ec7338SJohan Hedberg continue; 1422a7ec7338SJohan Hedberg 1423a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 1424a7ec7338SJohan Hedberg 1425adae20cbSJohan Hedberg list_del_rcu(&k->list); 1426adae20cbSJohan Hedberg kfree_rcu(k, rcu); 1427a7ec7338SJohan Hedberg } 1428a7ec7338SJohan Hedberg } 1429a7ec7338SJohan Hedberg 143055e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 143155e76b38SJohan Hedberg { 143255e76b38SJohan Hedberg struct smp_ltk *k; 14334ba9faf3SJohan Hedberg struct smp_irk *irk; 143455e76b38SJohan Hedberg u8 addr_type; 143555e76b38SJohan Hedberg 143655e76b38SJohan Hedberg if (type == BDADDR_BREDR) { 143755e76b38SJohan Hedberg if (hci_find_link_key(hdev, bdaddr)) 143855e76b38SJohan Hedberg return true; 143955e76b38SJohan Hedberg return false; 144055e76b38SJohan Hedberg } 144155e76b38SJohan Hedberg 144255e76b38SJohan Hedberg /* Convert to HCI addr type which struct smp_ltk uses */ 144355e76b38SJohan Hedberg if (type == BDADDR_LE_PUBLIC) 144455e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_PUBLIC; 144555e76b38SJohan Hedberg else 144655e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_RANDOM; 144755e76b38SJohan Hedberg 14484ba9faf3SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, addr_type); 14494ba9faf3SJohan Hedberg if (irk) { 14504ba9faf3SJohan Hedberg bdaddr = &irk->bdaddr; 14514ba9faf3SJohan Hedberg addr_type = irk->addr_type; 14524ba9faf3SJohan Hedberg } 14534ba9faf3SJohan Hedberg 145455e76b38SJohan Hedberg rcu_read_lock(); 145555e76b38SJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 145687c8b28dSJohan Hedberg if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) { 145787c8b28dSJohan Hedberg rcu_read_unlock(); 145855e76b38SJohan Hedberg return true; 145955e76b38SJohan Hedberg } 146087c8b28dSJohan Hedberg } 146155e76b38SJohan Hedberg rcu_read_unlock(); 146255e76b38SJohan Hedberg 146355e76b38SJohan Hedberg return false; 146455e76b38SJohan Hedberg } 146555e76b38SJohan Hedberg 14666bd32326SVille Tervo /* HCI command timer function */ 146765cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work) 14686bd32326SVille Tervo { 146965cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, 147065cc2b49SMarcel Holtmann cmd_timer.work); 14716bd32326SVille Tervo 1472bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 1473bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 1474bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 1475bda4f23aSAndrei Emeltchenko 14762064ee33SMarcel Holtmann bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); 1477bda4f23aSAndrei Emeltchenko } else { 14782064ee33SMarcel Holtmann bt_dev_err(hdev, "command tx timeout"); 1479bda4f23aSAndrei Emeltchenko } 1480bda4f23aSAndrei Emeltchenko 1481e2bef384SRajat Jain if (hdev->cmd_timeout) 1482e2bef384SRajat Jain hdev->cmd_timeout(hdev); 1483e2bef384SRajat Jain 14846bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 1485c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 14866bd32326SVille Tervo } 14876bd32326SVille Tervo 1488de75cd0dSManish Mandlik /* HCI ncmd timer function */ 1489de75cd0dSManish Mandlik static void hci_ncmd_timeout(struct work_struct *work) 1490de75cd0dSManish Mandlik { 1491de75cd0dSManish Mandlik struct hci_dev *hdev = container_of(work, struct hci_dev, 1492de75cd0dSManish Mandlik ncmd_timer.work); 1493de75cd0dSManish Mandlik 1494de75cd0dSManish Mandlik bt_dev_err(hdev, "Controller not accepting commands anymore: ncmd = 0"); 1495de75cd0dSManish Mandlik 1496de75cd0dSManish Mandlik /* During HCI_INIT phase no events can be injected if the ncmd timer 1497de75cd0dSManish Mandlik * triggers since the procedure has its own timeout handling. 1498de75cd0dSManish Mandlik */ 1499de75cd0dSManish Mandlik if (test_bit(HCI_INIT, &hdev->flags)) 1500de75cd0dSManish Mandlik return; 1501de75cd0dSManish Mandlik 1502de75cd0dSManish Mandlik /* This is an irrecoverable state, inject hardware error event */ 1503de75cd0dSManish Mandlik hci_reset_dev(hdev); 1504de75cd0dSManish Mandlik } 1505de75cd0dSManish Mandlik 15062763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 15076928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type) 15082763eda6SSzymon Janc { 15092763eda6SSzymon Janc struct oob_data *data; 15102763eda6SSzymon Janc 15116928a924SJohan Hedberg list_for_each_entry(data, &hdev->remote_oob_data, list) { 15126928a924SJohan Hedberg if (bacmp(bdaddr, &data->bdaddr) != 0) 15136928a924SJohan Hedberg continue; 15146928a924SJohan Hedberg if (data->bdaddr_type != bdaddr_type) 15156928a924SJohan Hedberg continue; 15162763eda6SSzymon Janc return data; 15176928a924SJohan Hedberg } 15182763eda6SSzymon Janc 15192763eda6SSzymon Janc return NULL; 15202763eda6SSzymon Janc } 15212763eda6SSzymon Janc 15226928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 15236928a924SJohan Hedberg u8 bdaddr_type) 15242763eda6SSzymon Janc { 15252763eda6SSzymon Janc struct oob_data *data; 15262763eda6SSzymon Janc 15276928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 15282763eda6SSzymon Janc if (!data) 15292763eda6SSzymon Janc return -ENOENT; 15302763eda6SSzymon Janc 15316928a924SJohan Hedberg BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type); 15322763eda6SSzymon Janc 15332763eda6SSzymon Janc list_del(&data->list); 15342763eda6SSzymon Janc kfree(data); 15352763eda6SSzymon Janc 15362763eda6SSzymon Janc return 0; 15372763eda6SSzymon Janc } 15382763eda6SSzymon Janc 153935f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 15402763eda6SSzymon Janc { 15412763eda6SSzymon Janc struct oob_data *data, *n; 15422763eda6SSzymon Janc 15432763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 15442763eda6SSzymon Janc list_del(&data->list); 15452763eda6SSzymon Janc kfree(data); 15462763eda6SSzymon Janc } 15472763eda6SSzymon Janc } 15482763eda6SSzymon Janc 15490798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 15506928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192, 155138da1703SJohan Hedberg u8 *hash256, u8 *rand256) 15520798872eSMarcel Holtmann { 15530798872eSMarcel Holtmann struct oob_data *data; 15540798872eSMarcel Holtmann 15556928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 15560798872eSMarcel Holtmann if (!data) { 15570a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 15580798872eSMarcel Holtmann if (!data) 15590798872eSMarcel Holtmann return -ENOMEM; 15600798872eSMarcel Holtmann 15610798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 15626928a924SJohan Hedberg data->bdaddr_type = bdaddr_type; 15630798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 15640798872eSMarcel Holtmann } 15650798872eSMarcel Holtmann 156681328d5cSJohan Hedberg if (hash192 && rand192) { 15670798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 156838da1703SJohan Hedberg memcpy(data->rand192, rand192, sizeof(data->rand192)); 1569f7697b16SMarcel Holtmann if (hash256 && rand256) 1570f7697b16SMarcel Holtmann data->present = 0x03; 157181328d5cSJohan Hedberg } else { 157281328d5cSJohan Hedberg memset(data->hash192, 0, sizeof(data->hash192)); 157381328d5cSJohan Hedberg memset(data->rand192, 0, sizeof(data->rand192)); 1574f7697b16SMarcel Holtmann if (hash256 && rand256) 1575f7697b16SMarcel Holtmann data->present = 0x02; 1576f7697b16SMarcel Holtmann else 1577f7697b16SMarcel Holtmann data->present = 0x00; 157881328d5cSJohan Hedberg } 15790798872eSMarcel Holtmann 158081328d5cSJohan Hedberg if (hash256 && rand256) { 15810798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 158238da1703SJohan Hedberg memcpy(data->rand256, rand256, sizeof(data->rand256)); 158381328d5cSJohan Hedberg } else { 158481328d5cSJohan Hedberg memset(data->hash256, 0, sizeof(data->hash256)); 158581328d5cSJohan Hedberg memset(data->rand256, 0, sizeof(data->rand256)); 1586f7697b16SMarcel Holtmann if (hash192 && rand192) 1587f7697b16SMarcel Holtmann data->present = 0x01; 158881328d5cSJohan Hedberg } 15890798872eSMarcel Holtmann 15906ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 15912763eda6SSzymon Janc 15922763eda6SSzymon Janc return 0; 15932763eda6SSzymon Janc } 15942763eda6SSzymon Janc 1595d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 1596d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance) 1597d2609b34SFlorian Grandel { 1598d2609b34SFlorian Grandel struct adv_info *adv_instance; 1599d2609b34SFlorian Grandel 1600d2609b34SFlorian Grandel list_for_each_entry(adv_instance, &hdev->adv_instances, list) { 1601d2609b34SFlorian Grandel if (adv_instance->instance == instance) 1602d2609b34SFlorian Grandel return adv_instance; 1603d2609b34SFlorian Grandel } 1604d2609b34SFlorian Grandel 1605d2609b34SFlorian Grandel return NULL; 1606d2609b34SFlorian Grandel } 1607d2609b34SFlorian Grandel 1608d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 160974b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance) 161074b93e9fSPrasanna Karthik { 1611d2609b34SFlorian Grandel struct adv_info *cur_instance; 1612d2609b34SFlorian Grandel 1613d2609b34SFlorian Grandel cur_instance = hci_find_adv_instance(hdev, instance); 1614d2609b34SFlorian Grandel if (!cur_instance) 1615d2609b34SFlorian Grandel return NULL; 1616d2609b34SFlorian Grandel 1617d2609b34SFlorian Grandel if (cur_instance == list_last_entry(&hdev->adv_instances, 1618d2609b34SFlorian Grandel struct adv_info, list)) 1619d2609b34SFlorian Grandel return list_first_entry(&hdev->adv_instances, 1620d2609b34SFlorian Grandel struct adv_info, list); 1621d2609b34SFlorian Grandel else 1622d2609b34SFlorian Grandel return list_next_entry(cur_instance, list); 1623d2609b34SFlorian Grandel } 1624d2609b34SFlorian Grandel 1625d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 1626d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance) 1627d2609b34SFlorian Grandel { 1628d2609b34SFlorian Grandel struct adv_info *adv_instance; 1629d2609b34SFlorian Grandel 1630d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 1631d2609b34SFlorian Grandel if (!adv_instance) 1632d2609b34SFlorian Grandel return -ENOENT; 1633d2609b34SFlorian Grandel 1634d2609b34SFlorian Grandel BT_DBG("%s removing %dMR", hdev->name, instance); 1635d2609b34SFlorian Grandel 1636cab054abSJohan Hedberg if (hdev->cur_adv_instance == instance) { 1637cab054abSJohan Hedberg if (hdev->adv_instance_timeout) { 16385d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 16395d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 16405d900e46SFlorian Grandel } 1641cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 1642cab054abSJohan Hedberg } 16435d900e46SFlorian Grandel 1644a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 1645a73c046aSJaganath Kanakkassery 1646d2609b34SFlorian Grandel list_del(&adv_instance->list); 1647d2609b34SFlorian Grandel kfree(adv_instance); 1648d2609b34SFlorian Grandel 1649d2609b34SFlorian Grandel hdev->adv_instance_cnt--; 1650d2609b34SFlorian Grandel 1651d2609b34SFlorian Grandel return 0; 1652d2609b34SFlorian Grandel } 1653d2609b34SFlorian Grandel 1654a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired) 1655a73c046aSJaganath Kanakkassery { 1656a73c046aSJaganath Kanakkassery struct adv_info *adv_instance, *n; 1657a73c046aSJaganath Kanakkassery 1658a73c046aSJaganath Kanakkassery list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) 1659a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = rpa_expired; 1660a73c046aSJaganath Kanakkassery } 1661a73c046aSJaganath Kanakkassery 1662d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 1663d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev) 1664d2609b34SFlorian Grandel { 1665d2609b34SFlorian Grandel struct adv_info *adv_instance, *n; 1666d2609b34SFlorian Grandel 16675d900e46SFlorian Grandel if (hdev->adv_instance_timeout) { 16685d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 16695d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 16705d900e46SFlorian Grandel } 16715d900e46SFlorian Grandel 1672d2609b34SFlorian Grandel list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) { 1673a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 1674d2609b34SFlorian Grandel list_del(&adv_instance->list); 1675d2609b34SFlorian Grandel kfree(adv_instance); 1676d2609b34SFlorian Grandel } 1677d2609b34SFlorian Grandel 1678d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 1679cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 1680d2609b34SFlorian Grandel } 1681d2609b34SFlorian Grandel 1682a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work) 1683a73c046aSJaganath Kanakkassery { 1684a73c046aSJaganath Kanakkassery struct adv_info *adv_instance = container_of(work, struct adv_info, 1685a73c046aSJaganath Kanakkassery rpa_expired_cb.work); 1686a73c046aSJaganath Kanakkassery 1687a73c046aSJaganath Kanakkassery BT_DBG(""); 1688a73c046aSJaganath Kanakkassery 1689a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = true; 1690a73c046aSJaganath Kanakkassery } 1691a73c046aSJaganath Kanakkassery 1692d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 1693d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags, 1694d2609b34SFlorian Grandel u16 adv_data_len, u8 *adv_data, 1695d2609b34SFlorian Grandel u16 scan_rsp_len, u8 *scan_rsp_data, 16969bf9f4b6SDaniel Winkler u16 timeout, u16 duration, s8 tx_power, 16979bf9f4b6SDaniel Winkler u32 min_interval, u32 max_interval) 1698d2609b34SFlorian Grandel { 1699d2609b34SFlorian Grandel struct adv_info *adv_instance; 1700d2609b34SFlorian Grandel 1701d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 1702d2609b34SFlorian Grandel if (adv_instance) { 1703d2609b34SFlorian Grandel memset(adv_instance->adv_data, 0, 1704d2609b34SFlorian Grandel sizeof(adv_instance->adv_data)); 1705d2609b34SFlorian Grandel memset(adv_instance->scan_rsp_data, 0, 1706d2609b34SFlorian Grandel sizeof(adv_instance->scan_rsp_data)); 1707d2609b34SFlorian Grandel } else { 17081d0fac2cSLuiz Augusto von Dentz if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets || 170987597482SDaniel Winkler instance < 1 || instance > hdev->le_num_of_adv_sets) 1710d2609b34SFlorian Grandel return -EOVERFLOW; 1711d2609b34SFlorian Grandel 171239ecfad6SJohan Hedberg adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL); 1713d2609b34SFlorian Grandel if (!adv_instance) 1714d2609b34SFlorian Grandel return -ENOMEM; 1715d2609b34SFlorian Grandel 1716fffd38bcSFlorian Grandel adv_instance->pending = true; 1717d2609b34SFlorian Grandel adv_instance->instance = instance; 1718d2609b34SFlorian Grandel list_add(&adv_instance->list, &hdev->adv_instances); 1719d2609b34SFlorian Grandel hdev->adv_instance_cnt++; 1720d2609b34SFlorian Grandel } 1721d2609b34SFlorian Grandel 1722d2609b34SFlorian Grandel adv_instance->flags = flags; 1723d2609b34SFlorian Grandel adv_instance->adv_data_len = adv_data_len; 1724d2609b34SFlorian Grandel adv_instance->scan_rsp_len = scan_rsp_len; 17259bf9f4b6SDaniel Winkler adv_instance->min_interval = min_interval; 17269bf9f4b6SDaniel Winkler adv_instance->max_interval = max_interval; 17279bf9f4b6SDaniel Winkler adv_instance->tx_power = tx_power; 1728d2609b34SFlorian Grandel 1729d2609b34SFlorian Grandel if (adv_data_len) 1730d2609b34SFlorian Grandel memcpy(adv_instance->adv_data, adv_data, adv_data_len); 1731d2609b34SFlorian Grandel 1732d2609b34SFlorian Grandel if (scan_rsp_len) 1733d2609b34SFlorian Grandel memcpy(adv_instance->scan_rsp_data, 1734d2609b34SFlorian Grandel scan_rsp_data, scan_rsp_len); 1735d2609b34SFlorian Grandel 1736d2609b34SFlorian Grandel adv_instance->timeout = timeout; 17375d900e46SFlorian Grandel adv_instance->remaining_time = timeout; 1738d2609b34SFlorian Grandel 1739d2609b34SFlorian Grandel if (duration == 0) 174010873f99SAlain Michaud adv_instance->duration = hdev->def_multi_adv_rotation_duration; 1741d2609b34SFlorian Grandel else 1742d2609b34SFlorian Grandel adv_instance->duration = duration; 1743d2609b34SFlorian Grandel 1744a73c046aSJaganath Kanakkassery INIT_DELAYED_WORK(&adv_instance->rpa_expired_cb, 1745a73c046aSJaganath Kanakkassery adv_instance_rpa_expired); 1746a73c046aSJaganath Kanakkassery 1747d2609b34SFlorian Grandel BT_DBG("%s for %dMR", hdev->name, instance); 1748d2609b34SFlorian Grandel 1749d2609b34SFlorian Grandel return 0; 1750d2609b34SFlorian Grandel } 1751d2609b34SFlorian Grandel 1752e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */ 175331aab5c2SDaniel Winkler int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance, 175431aab5c2SDaniel Winkler u16 adv_data_len, u8 *adv_data, 175531aab5c2SDaniel Winkler u16 scan_rsp_len, u8 *scan_rsp_data) 175631aab5c2SDaniel Winkler { 175731aab5c2SDaniel Winkler struct adv_info *adv_instance; 175831aab5c2SDaniel Winkler 175931aab5c2SDaniel Winkler adv_instance = hci_find_adv_instance(hdev, instance); 176031aab5c2SDaniel Winkler 176131aab5c2SDaniel Winkler /* If advertisement doesn't exist, we can't modify its data */ 176231aab5c2SDaniel Winkler if (!adv_instance) 176331aab5c2SDaniel Winkler return -ENOENT; 176431aab5c2SDaniel Winkler 176531aab5c2SDaniel Winkler if (adv_data_len) { 176631aab5c2SDaniel Winkler memset(adv_instance->adv_data, 0, 176731aab5c2SDaniel Winkler sizeof(adv_instance->adv_data)); 176831aab5c2SDaniel Winkler memcpy(adv_instance->adv_data, adv_data, adv_data_len); 176931aab5c2SDaniel Winkler adv_instance->adv_data_len = adv_data_len; 177031aab5c2SDaniel Winkler } 177131aab5c2SDaniel Winkler 177231aab5c2SDaniel Winkler if (scan_rsp_len) { 177331aab5c2SDaniel Winkler memset(adv_instance->scan_rsp_data, 0, 177431aab5c2SDaniel Winkler sizeof(adv_instance->scan_rsp_data)); 177531aab5c2SDaniel Winkler memcpy(adv_instance->scan_rsp_data, 177631aab5c2SDaniel Winkler scan_rsp_data, scan_rsp_len); 177731aab5c2SDaniel Winkler adv_instance->scan_rsp_len = scan_rsp_len; 177831aab5c2SDaniel Winkler } 177931aab5c2SDaniel Winkler 178031aab5c2SDaniel Winkler return 0; 178131aab5c2SDaniel Winkler } 178231aab5c2SDaniel Winkler 178331aab5c2SDaniel Winkler /* This function requires the caller holds hdev->lock */ 178401ce70b0SLuiz Augusto von Dentz u32 hci_adv_instance_flags(struct hci_dev *hdev, u8 instance) 178501ce70b0SLuiz Augusto von Dentz { 178601ce70b0SLuiz Augusto von Dentz u32 flags; 178701ce70b0SLuiz Augusto von Dentz struct adv_info *adv; 178801ce70b0SLuiz Augusto von Dentz 178901ce70b0SLuiz Augusto von Dentz if (instance == 0x00) { 179001ce70b0SLuiz Augusto von Dentz /* Instance 0 always manages the "Tx Power" and "Flags" 179101ce70b0SLuiz Augusto von Dentz * fields 179201ce70b0SLuiz Augusto von Dentz */ 179301ce70b0SLuiz Augusto von Dentz flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS; 179401ce70b0SLuiz Augusto von Dentz 179501ce70b0SLuiz Augusto von Dentz /* For instance 0, the HCI_ADVERTISING_CONNECTABLE setting 179601ce70b0SLuiz Augusto von Dentz * corresponds to the "connectable" instance flag. 179701ce70b0SLuiz Augusto von Dentz */ 179801ce70b0SLuiz Augusto von Dentz if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE)) 179901ce70b0SLuiz Augusto von Dentz flags |= MGMT_ADV_FLAG_CONNECTABLE; 180001ce70b0SLuiz Augusto von Dentz 180101ce70b0SLuiz Augusto von Dentz if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) 180201ce70b0SLuiz Augusto von Dentz flags |= MGMT_ADV_FLAG_LIMITED_DISCOV; 180301ce70b0SLuiz Augusto von Dentz else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE)) 180401ce70b0SLuiz Augusto von Dentz flags |= MGMT_ADV_FLAG_DISCOV; 180501ce70b0SLuiz Augusto von Dentz 180601ce70b0SLuiz Augusto von Dentz return flags; 180701ce70b0SLuiz Augusto von Dentz } 180801ce70b0SLuiz Augusto von Dentz 180901ce70b0SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, instance); 181001ce70b0SLuiz Augusto von Dentz 181101ce70b0SLuiz Augusto von Dentz /* Return 0 when we got an invalid instance identifier. */ 181201ce70b0SLuiz Augusto von Dentz if (!adv) 181301ce70b0SLuiz Augusto von Dentz return 0; 181401ce70b0SLuiz Augusto von Dentz 181501ce70b0SLuiz Augusto von Dentz return adv->flags; 181601ce70b0SLuiz Augusto von Dentz } 181701ce70b0SLuiz Augusto von Dentz 181801ce70b0SLuiz Augusto von Dentz bool hci_adv_instance_is_scannable(struct hci_dev *hdev, u8 instance) 181901ce70b0SLuiz Augusto von Dentz { 182001ce70b0SLuiz Augusto von Dentz struct adv_info *adv; 182101ce70b0SLuiz Augusto von Dentz 182201ce70b0SLuiz Augusto von Dentz /* Instance 0x00 always set local name */ 182301ce70b0SLuiz Augusto von Dentz if (instance == 0x00) 182401ce70b0SLuiz Augusto von Dentz return true; 182501ce70b0SLuiz Augusto von Dentz 182601ce70b0SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, instance); 182701ce70b0SLuiz Augusto von Dentz if (!adv) 182801ce70b0SLuiz Augusto von Dentz return false; 182901ce70b0SLuiz Augusto von Dentz 183001ce70b0SLuiz Augusto von Dentz if (adv->flags & MGMT_ADV_FLAG_APPEARANCE || 183101ce70b0SLuiz Augusto von Dentz adv->flags & MGMT_ADV_FLAG_LOCAL_NAME) 183201ce70b0SLuiz Augusto von Dentz return true; 183301ce70b0SLuiz Augusto von Dentz 183401ce70b0SLuiz Augusto von Dentz return adv->scan_rsp_len ? true : false; 183501ce70b0SLuiz Augusto von Dentz } 183601ce70b0SLuiz Augusto von Dentz 183701ce70b0SLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */ 1838e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev) 1839e5e1e7fdSMiao-chen Chou { 1840b139553dSMiao-chen Chou struct adv_monitor *monitor; 1841b139553dSMiao-chen Chou int handle; 1842b139553dSMiao-chen Chou 1843b139553dSMiao-chen Chou idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle) 184466bd095aSArchie Pusaka hci_free_adv_monitor(hdev, monitor); 1845b139553dSMiao-chen Chou 1846e5e1e7fdSMiao-chen Chou idr_destroy(&hdev->adv_monitors_idr); 1847e5e1e7fdSMiao-chen Chou } 1848e5e1e7fdSMiao-chen Chou 184966bd095aSArchie Pusaka /* Frees the monitor structure and do some bookkeepings. 185066bd095aSArchie Pusaka * This function requires the caller holds hdev->lock. 185166bd095aSArchie Pusaka */ 185266bd095aSArchie Pusaka void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor) 1853b139553dSMiao-chen Chou { 1854b139553dSMiao-chen Chou struct adv_pattern *pattern; 1855b139553dSMiao-chen Chou struct adv_pattern *tmp; 1856b139553dSMiao-chen Chou 1857b139553dSMiao-chen Chou if (!monitor) 1858b139553dSMiao-chen Chou return; 1859b139553dSMiao-chen Chou 186066bd095aSArchie Pusaka list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) { 186166bd095aSArchie Pusaka list_del(&pattern->list); 1862b139553dSMiao-chen Chou kfree(pattern); 186366bd095aSArchie Pusaka } 186466bd095aSArchie Pusaka 186566bd095aSArchie Pusaka if (monitor->handle) 186666bd095aSArchie Pusaka idr_remove(&hdev->adv_monitors_idr, monitor->handle); 186766bd095aSArchie Pusaka 186866bd095aSArchie Pusaka if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) { 186966bd095aSArchie Pusaka hdev->adv_monitors_cnt--; 187066bd095aSArchie Pusaka mgmt_adv_monitor_removed(hdev, monitor->handle); 187166bd095aSArchie Pusaka } 1872b139553dSMiao-chen Chou 1873b139553dSMiao-chen Chou kfree(monitor); 1874b139553dSMiao-chen Chou } 1875b139553dSMiao-chen Chou 1876a2a4dedfSArchie Pusaka int hci_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status) 1877a2a4dedfSArchie Pusaka { 1878a2a4dedfSArchie Pusaka return mgmt_add_adv_patterns_monitor_complete(hdev, status); 1879a2a4dedfSArchie Pusaka } 1880a2a4dedfSArchie Pusaka 188166bd095aSArchie Pusaka int hci_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status) 188266bd095aSArchie Pusaka { 188366bd095aSArchie Pusaka return mgmt_remove_adv_monitor_complete(hdev, status); 188466bd095aSArchie Pusaka } 188566bd095aSArchie Pusaka 1886a2a4dedfSArchie Pusaka /* Assigns handle to a monitor, and if offloading is supported and power is on, 1887a2a4dedfSArchie Pusaka * also attempts to forward the request to the controller. 1888a2a4dedfSArchie Pusaka * Returns true if request is forwarded (result is pending), false otherwise. 1889a2a4dedfSArchie Pusaka * This function requires the caller holds hdev->lock. 1890a2a4dedfSArchie Pusaka */ 1891a2a4dedfSArchie Pusaka bool hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor, 1892a2a4dedfSArchie Pusaka int *err) 1893b139553dSMiao-chen Chou { 1894b139553dSMiao-chen Chou int min, max, handle; 1895b139553dSMiao-chen Chou 1896a2a4dedfSArchie Pusaka *err = 0; 1897a2a4dedfSArchie Pusaka 1898a2a4dedfSArchie Pusaka if (!monitor) { 1899a2a4dedfSArchie Pusaka *err = -EINVAL; 1900a2a4dedfSArchie Pusaka return false; 1901a2a4dedfSArchie Pusaka } 1902b139553dSMiao-chen Chou 1903b139553dSMiao-chen Chou min = HCI_MIN_ADV_MONITOR_HANDLE; 1904b139553dSMiao-chen Chou max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES; 1905b139553dSMiao-chen Chou handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max, 1906b139553dSMiao-chen Chou GFP_KERNEL); 1907a2a4dedfSArchie Pusaka if (handle < 0) { 1908a2a4dedfSArchie Pusaka *err = handle; 1909a2a4dedfSArchie Pusaka return false; 1910a2a4dedfSArchie Pusaka } 1911b139553dSMiao-chen Chou 1912b139553dSMiao-chen Chou monitor->handle = handle; 19138208f5a9SMiao-chen Chou 1914a2a4dedfSArchie Pusaka if (!hdev_is_powered(hdev)) 1915a2a4dedfSArchie Pusaka return false; 19168208f5a9SMiao-chen Chou 1917a2a4dedfSArchie Pusaka switch (hci_get_adv_monitor_offload_ext(hdev)) { 1918a2a4dedfSArchie Pusaka case HCI_ADV_MONITOR_EXT_NONE: 19195bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev); 1920a2a4dedfSArchie Pusaka bt_dev_dbg(hdev, "%s add monitor status %d", hdev->name, *err); 1921a2a4dedfSArchie Pusaka /* Message was not forwarded to controller - not an error */ 1922a2a4dedfSArchie Pusaka return false; 1923a2a4dedfSArchie Pusaka case HCI_ADV_MONITOR_EXT_MSFT: 1924a2a4dedfSArchie Pusaka *err = msft_add_monitor_pattern(hdev, monitor); 1925a2a4dedfSArchie Pusaka bt_dev_dbg(hdev, "%s add monitor msft status %d", hdev->name, 1926a2a4dedfSArchie Pusaka *err); 1927a2a4dedfSArchie Pusaka break; 1928a2a4dedfSArchie Pusaka } 1929a2a4dedfSArchie Pusaka 1930a2a4dedfSArchie Pusaka return (*err == 0); 1931b139553dSMiao-chen Chou } 1932b139553dSMiao-chen Chou 193366bd095aSArchie Pusaka /* Attempts to tell the controller and free the monitor. If somehow the 193466bd095aSArchie Pusaka * controller doesn't have a corresponding handle, remove anyway. 193566bd095aSArchie Pusaka * Returns true if request is forwarded (result is pending), false otherwise. 193666bd095aSArchie Pusaka * This function requires the caller holds hdev->lock. 193766bd095aSArchie Pusaka */ 193866bd095aSArchie Pusaka static bool hci_remove_adv_monitor(struct hci_dev *hdev, 193966bd095aSArchie Pusaka struct adv_monitor *monitor, 194066bd095aSArchie Pusaka u16 handle, int *err) 1941bd2fbc6cSMiao-chen Chou { 194266bd095aSArchie Pusaka *err = 0; 1943bd2fbc6cSMiao-chen Chou 194466bd095aSArchie Pusaka switch (hci_get_adv_monitor_offload_ext(hdev)) { 194566bd095aSArchie Pusaka case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */ 194666bd095aSArchie Pusaka goto free_monitor; 194766bd095aSArchie Pusaka case HCI_ADV_MONITOR_EXT_MSFT: 194866bd095aSArchie Pusaka *err = msft_remove_monitor(hdev, monitor, handle); 194966bd095aSArchie Pusaka break; 1950bd2fbc6cSMiao-chen Chou } 1951bd2fbc6cSMiao-chen Chou 195266bd095aSArchie Pusaka /* In case no matching handle registered, just free the monitor */ 195366bd095aSArchie Pusaka if (*err == -ENOENT) 195466bd095aSArchie Pusaka goto free_monitor; 1955bd2fbc6cSMiao-chen Chou 195666bd095aSArchie Pusaka return (*err == 0); 1957bd2fbc6cSMiao-chen Chou 195866bd095aSArchie Pusaka free_monitor: 195966bd095aSArchie Pusaka if (*err == -ENOENT) 196066bd095aSArchie Pusaka bt_dev_warn(hdev, "Removing monitor with no matching handle %d", 196166bd095aSArchie Pusaka monitor->handle); 196266bd095aSArchie Pusaka hci_free_adv_monitor(hdev, monitor); 196366bd095aSArchie Pusaka 196466bd095aSArchie Pusaka *err = 0; 196566bd095aSArchie Pusaka return false; 1966bd2fbc6cSMiao-chen Chou } 1967bd2fbc6cSMiao-chen Chou 196866bd095aSArchie Pusaka /* Returns true if request is forwarded (result is pending), false otherwise. 196966bd095aSArchie Pusaka * This function requires the caller holds hdev->lock. 197066bd095aSArchie Pusaka */ 197166bd095aSArchie Pusaka bool hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle, int *err) 197266bd095aSArchie Pusaka { 197366bd095aSArchie Pusaka struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle); 197466bd095aSArchie Pusaka bool pending; 197566bd095aSArchie Pusaka 197666bd095aSArchie Pusaka if (!monitor) { 197766bd095aSArchie Pusaka *err = -EINVAL; 197866bd095aSArchie Pusaka return false; 197966bd095aSArchie Pusaka } 198066bd095aSArchie Pusaka 198166bd095aSArchie Pusaka pending = hci_remove_adv_monitor(hdev, monitor, handle, err); 198266bd095aSArchie Pusaka if (!*err && !pending) 19835bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev); 19848208f5a9SMiao-chen Chou 198566bd095aSArchie Pusaka bt_dev_dbg(hdev, "%s remove monitor handle %d, status %d, %spending", 198666bd095aSArchie Pusaka hdev->name, handle, *err, pending ? "" : "not "); 198766bd095aSArchie Pusaka 198866bd095aSArchie Pusaka return pending; 198966bd095aSArchie Pusaka } 199066bd095aSArchie Pusaka 199166bd095aSArchie Pusaka /* Returns true if request is forwarded (result is pending), false otherwise. 199266bd095aSArchie Pusaka * This function requires the caller holds hdev->lock. 199366bd095aSArchie Pusaka */ 199466bd095aSArchie Pusaka bool hci_remove_all_adv_monitor(struct hci_dev *hdev, int *err) 199566bd095aSArchie Pusaka { 199666bd095aSArchie Pusaka struct adv_monitor *monitor; 199766bd095aSArchie Pusaka int idr_next_id = 0; 199866bd095aSArchie Pusaka bool pending = false; 199966bd095aSArchie Pusaka bool update = false; 200066bd095aSArchie Pusaka 200166bd095aSArchie Pusaka *err = 0; 200266bd095aSArchie Pusaka 200366bd095aSArchie Pusaka while (!*err && !pending) { 200466bd095aSArchie Pusaka monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id); 200566bd095aSArchie Pusaka if (!monitor) 200666bd095aSArchie Pusaka break; 200766bd095aSArchie Pusaka 200866bd095aSArchie Pusaka pending = hci_remove_adv_monitor(hdev, monitor, 0, err); 200966bd095aSArchie Pusaka 201066bd095aSArchie Pusaka if (!*err && !pending) 201166bd095aSArchie Pusaka update = true; 201266bd095aSArchie Pusaka } 201366bd095aSArchie Pusaka 201466bd095aSArchie Pusaka if (update) 20155bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev); 201666bd095aSArchie Pusaka 201766bd095aSArchie Pusaka bt_dev_dbg(hdev, "%s remove all monitors status %d, %spending", 201866bd095aSArchie Pusaka hdev->name, *err, pending ? "" : "not "); 201966bd095aSArchie Pusaka 202066bd095aSArchie Pusaka return pending; 2021bd2fbc6cSMiao-chen Chou } 2022bd2fbc6cSMiao-chen Chou 20238208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */ 20248208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev) 20258208f5a9SMiao-chen Chou { 20268208f5a9SMiao-chen Chou return !idr_is_empty(&hdev->adv_monitors_idr); 20278208f5a9SMiao-chen Chou } 20288208f5a9SMiao-chen Chou 2029a2a4dedfSArchie Pusaka int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev) 2030a2a4dedfSArchie Pusaka { 2031a2a4dedfSArchie Pusaka if (msft_monitor_supported(hdev)) 2032a2a4dedfSArchie Pusaka return HCI_ADV_MONITOR_EXT_MSFT; 2033a2a4dedfSArchie Pusaka 2034a2a4dedfSArchie Pusaka return HCI_ADV_MONITOR_EXT_NONE; 2035a2a4dedfSArchie Pusaka } 2036a2a4dedfSArchie Pusaka 2037dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list, 2038b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 2039b2a66aadSAntti Julku { 2040b2a66aadSAntti Julku struct bdaddr_list *b; 2041b2a66aadSAntti Julku 2042dcc36c16SJohan Hedberg list_for_each_entry(b, bdaddr_list, list) { 2043b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2044b2a66aadSAntti Julku return b; 2045b9ee0a78SMarcel Holtmann } 2046b2a66aadSAntti Julku 2047b2a66aadSAntti Julku return NULL; 2048b2a66aadSAntti Julku } 2049b2a66aadSAntti Julku 2050b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk( 2051b950aa88SAnkit Navik struct list_head *bdaddr_list, bdaddr_t *bdaddr, 2052b950aa88SAnkit Navik u8 type) 2053b950aa88SAnkit Navik { 2054b950aa88SAnkit Navik struct bdaddr_list_with_irk *b; 2055b950aa88SAnkit Navik 2056b950aa88SAnkit Navik list_for_each_entry(b, bdaddr_list, list) { 2057b950aa88SAnkit Navik if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2058b950aa88SAnkit Navik return b; 2059b950aa88SAnkit Navik } 2060b950aa88SAnkit Navik 2061b950aa88SAnkit Navik return NULL; 2062b950aa88SAnkit Navik } 2063b950aa88SAnkit Navik 20648baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags * 20658baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list, 20668baaa403SAbhishek Pandit-Subedi bdaddr_t *bdaddr, u8 type) 20678baaa403SAbhishek Pandit-Subedi { 20688baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *b; 20698baaa403SAbhishek Pandit-Subedi 20708baaa403SAbhishek Pandit-Subedi list_for_each_entry(b, bdaddr_list, list) { 20718baaa403SAbhishek Pandit-Subedi if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 20728baaa403SAbhishek Pandit-Subedi return b; 20738baaa403SAbhishek Pandit-Subedi } 20748baaa403SAbhishek Pandit-Subedi 20758baaa403SAbhishek Pandit-Subedi return NULL; 20768baaa403SAbhishek Pandit-Subedi } 20778baaa403SAbhishek Pandit-Subedi 2078dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list) 2079b2a66aadSAntti Julku { 20807eb7404fSGeliang Tang struct bdaddr_list *b, *n; 2081b2a66aadSAntti Julku 20827eb7404fSGeliang Tang list_for_each_entry_safe(b, n, bdaddr_list, list) { 20837eb7404fSGeliang Tang list_del(&b->list); 2084b2a66aadSAntti Julku kfree(b); 2085b2a66aadSAntti Julku } 2086b2a66aadSAntti Julku } 2087b2a66aadSAntti Julku 2088dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type) 2089b2a66aadSAntti Julku { 2090b2a66aadSAntti Julku struct bdaddr_list *entry; 2091b2a66aadSAntti Julku 2092b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 2093b2a66aadSAntti Julku return -EBADF; 2094b2a66aadSAntti Julku 2095dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(list, bdaddr, type)) 20965e762444SAntti Julku return -EEXIST; 2097b2a66aadSAntti Julku 209827f70f3eSJohan Hedberg entry = kzalloc(sizeof(*entry), GFP_KERNEL); 20995e762444SAntti Julku if (!entry) 21005e762444SAntti Julku return -ENOMEM; 2101b2a66aadSAntti Julku 2102b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 2103b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 2104b2a66aadSAntti Julku 2105dcc36c16SJohan Hedberg list_add(&entry->list, list); 2106b2a66aadSAntti Julku 21072a8357f2SJohan Hedberg return 0; 2108b2a66aadSAntti Julku } 2109b2a66aadSAntti Julku 2110b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr, 2111b950aa88SAnkit Navik u8 type, u8 *peer_irk, u8 *local_irk) 2112b950aa88SAnkit Navik { 2113b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 2114b950aa88SAnkit Navik 2115b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) 2116b950aa88SAnkit Navik return -EBADF; 2117b950aa88SAnkit Navik 2118b950aa88SAnkit Navik if (hci_bdaddr_list_lookup(list, bdaddr, type)) 2119b950aa88SAnkit Navik return -EEXIST; 2120b950aa88SAnkit Navik 2121b950aa88SAnkit Navik entry = kzalloc(sizeof(*entry), GFP_KERNEL); 2122b950aa88SAnkit Navik if (!entry) 2123b950aa88SAnkit Navik return -ENOMEM; 2124b950aa88SAnkit Navik 2125b950aa88SAnkit Navik bacpy(&entry->bdaddr, bdaddr); 2126b950aa88SAnkit Navik entry->bdaddr_type = type; 2127b950aa88SAnkit Navik 2128b950aa88SAnkit Navik if (peer_irk) 2129b950aa88SAnkit Navik memcpy(entry->peer_irk, peer_irk, 16); 2130b950aa88SAnkit Navik 2131b950aa88SAnkit Navik if (local_irk) 2132b950aa88SAnkit Navik memcpy(entry->local_irk, local_irk, 16); 2133b950aa88SAnkit Navik 2134b950aa88SAnkit Navik list_add(&entry->list, list); 2135b950aa88SAnkit Navik 2136b950aa88SAnkit Navik return 0; 2137b950aa88SAnkit Navik } 2138b950aa88SAnkit Navik 21398baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr, 21408baaa403SAbhishek Pandit-Subedi u8 type, u32 flags) 21418baaa403SAbhishek Pandit-Subedi { 21428baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *entry; 21438baaa403SAbhishek Pandit-Subedi 21448baaa403SAbhishek Pandit-Subedi if (!bacmp(bdaddr, BDADDR_ANY)) 21458baaa403SAbhishek Pandit-Subedi return -EBADF; 21468baaa403SAbhishek Pandit-Subedi 21478baaa403SAbhishek Pandit-Subedi if (hci_bdaddr_list_lookup(list, bdaddr, type)) 21488baaa403SAbhishek Pandit-Subedi return -EEXIST; 21498baaa403SAbhishek Pandit-Subedi 21508baaa403SAbhishek Pandit-Subedi entry = kzalloc(sizeof(*entry), GFP_KERNEL); 21518baaa403SAbhishek Pandit-Subedi if (!entry) 21528baaa403SAbhishek Pandit-Subedi return -ENOMEM; 21538baaa403SAbhishek Pandit-Subedi 21548baaa403SAbhishek Pandit-Subedi bacpy(&entry->bdaddr, bdaddr); 21558baaa403SAbhishek Pandit-Subedi entry->bdaddr_type = type; 21568baaa403SAbhishek Pandit-Subedi entry->current_flags = flags; 21578baaa403SAbhishek Pandit-Subedi 21588baaa403SAbhishek Pandit-Subedi list_add(&entry->list, list); 21598baaa403SAbhishek Pandit-Subedi 21608baaa403SAbhishek Pandit-Subedi return 0; 21618baaa403SAbhishek Pandit-Subedi } 21628baaa403SAbhishek Pandit-Subedi 2163dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type) 2164b2a66aadSAntti Julku { 2165b2a66aadSAntti Julku struct bdaddr_list *entry; 2166b2a66aadSAntti Julku 216735f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 2168dcc36c16SJohan Hedberg hci_bdaddr_list_clear(list); 216935f7498aSJohan Hedberg return 0; 217035f7498aSJohan Hedberg } 2171b2a66aadSAntti Julku 2172dcc36c16SJohan Hedberg entry = hci_bdaddr_list_lookup(list, bdaddr, type); 2173d2ab0ac1SMarcel Holtmann if (!entry) 2174d2ab0ac1SMarcel Holtmann return -ENOENT; 2175d2ab0ac1SMarcel Holtmann 2176d2ab0ac1SMarcel Holtmann list_del(&entry->list); 2177d2ab0ac1SMarcel Holtmann kfree(entry); 2178d2ab0ac1SMarcel Holtmann 2179d2ab0ac1SMarcel Holtmann return 0; 2180d2ab0ac1SMarcel Holtmann } 2181d2ab0ac1SMarcel Holtmann 2182b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr, 2183b950aa88SAnkit Navik u8 type) 2184b950aa88SAnkit Navik { 2185b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 2186b950aa88SAnkit Navik 2187b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) { 2188b950aa88SAnkit Navik hci_bdaddr_list_clear(list); 2189b950aa88SAnkit Navik return 0; 2190b950aa88SAnkit Navik } 2191b950aa88SAnkit Navik 2192b950aa88SAnkit Navik entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type); 2193b950aa88SAnkit Navik if (!entry) 2194b950aa88SAnkit Navik return -ENOENT; 2195b950aa88SAnkit Navik 2196b950aa88SAnkit Navik list_del(&entry->list); 2197b950aa88SAnkit Navik kfree(entry); 2198b950aa88SAnkit Navik 2199b950aa88SAnkit Navik return 0; 2200b950aa88SAnkit Navik } 2201b950aa88SAnkit Navik 22028baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr, 22038baaa403SAbhishek Pandit-Subedi u8 type) 22048baaa403SAbhishek Pandit-Subedi { 22058baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *entry; 22068baaa403SAbhishek Pandit-Subedi 22078baaa403SAbhishek Pandit-Subedi if (!bacmp(bdaddr, BDADDR_ANY)) { 22088baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_clear(list); 22098baaa403SAbhishek Pandit-Subedi return 0; 22108baaa403SAbhishek Pandit-Subedi } 22118baaa403SAbhishek Pandit-Subedi 22128baaa403SAbhishek Pandit-Subedi entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type); 22138baaa403SAbhishek Pandit-Subedi if (!entry) 22148baaa403SAbhishek Pandit-Subedi return -ENOENT; 22158baaa403SAbhishek Pandit-Subedi 22168baaa403SAbhishek Pandit-Subedi list_del(&entry->list); 22178baaa403SAbhishek Pandit-Subedi kfree(entry); 22188baaa403SAbhishek Pandit-Subedi 22198baaa403SAbhishek Pandit-Subedi return 0; 22208baaa403SAbhishek Pandit-Subedi } 22218baaa403SAbhishek Pandit-Subedi 222215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 222315819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 222415819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 222515819a70SAndre Guedes { 222615819a70SAndre Guedes struct hci_conn_params *params; 222715819a70SAndre Guedes 222815819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 222915819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 223015819a70SAndre Guedes params->addr_type == addr_type) { 223115819a70SAndre Guedes return params; 223215819a70SAndre Guedes } 223315819a70SAndre Guedes } 223415819a70SAndre Guedes 223515819a70SAndre Guedes return NULL; 223615819a70SAndre Guedes } 223715819a70SAndre Guedes 223815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 2239501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 22404b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type) 224115819a70SAndre Guedes { 2242912b42efSJohan Hedberg struct hci_conn_params *param; 224315819a70SAndre Guedes 2244501f8827SJohan Hedberg list_for_each_entry(param, list, action) { 2245912b42efSJohan Hedberg if (bacmp(¶m->addr, addr) == 0 && 2246912b42efSJohan Hedberg param->addr_type == addr_type) 2247912b42efSJohan Hedberg return param; 22484b10966fSMarcel Holtmann } 22494b10966fSMarcel Holtmann 22504b10966fSMarcel Holtmann return NULL; 225115819a70SAndre Guedes } 225215819a70SAndre Guedes 225315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 225451d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 225551d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type) 225615819a70SAndre Guedes { 225715819a70SAndre Guedes struct hci_conn_params *params; 225815819a70SAndre Guedes 225915819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 2260cef952ceSAndre Guedes if (params) 226151d167c0SMarcel Holtmann return params; 226215819a70SAndre Guedes 226315819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 226415819a70SAndre Guedes if (!params) { 22652064ee33SMarcel Holtmann bt_dev_err(hdev, "out of memory"); 226651d167c0SMarcel Holtmann return NULL; 226715819a70SAndre Guedes } 226815819a70SAndre Guedes 226915819a70SAndre Guedes bacpy(¶ms->addr, addr); 227015819a70SAndre Guedes params->addr_type = addr_type; 2271cef952ceSAndre Guedes 2272cef952ceSAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 227393450c75SJohan Hedberg INIT_LIST_HEAD(¶ms->action); 2274cef952ceSAndre Guedes 2275bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval; 2276bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval; 2277bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency; 2278bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout; 2279bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED; 2280bf5b3c8bSMarcel Holtmann 2281bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 2282bf5b3c8bSMarcel Holtmann 228351d167c0SMarcel Holtmann return params; 2284bf5b3c8bSMarcel Holtmann } 2285bf5b3c8bSMarcel Holtmann 2286f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params) 2287f6c63249SJohan Hedberg { 2288f6c63249SJohan Hedberg if (params->conn) { 2289f6c63249SJohan Hedberg hci_conn_drop(params->conn); 2290f6c63249SJohan Hedberg hci_conn_put(params->conn); 2291f6c63249SJohan Hedberg } 2292f6c63249SJohan Hedberg 2293f6c63249SJohan Hedberg list_del(¶ms->action); 2294f6c63249SJohan Hedberg list_del(¶ms->list); 2295f6c63249SJohan Hedberg kfree(params); 2296f6c63249SJohan Hedberg } 2297f6c63249SJohan Hedberg 229815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 229915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 230015819a70SAndre Guedes { 230115819a70SAndre Guedes struct hci_conn_params *params; 230215819a70SAndre Guedes 230315819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 230415819a70SAndre Guedes if (!params) 230515819a70SAndre Guedes return; 230615819a70SAndre Guedes 2307f6c63249SJohan Hedberg hci_conn_params_free(params); 230815819a70SAndre Guedes 23095bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev); 231095305baaSJohan Hedberg 231115819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 231215819a70SAndre Guedes } 231315819a70SAndre Guedes 231415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 231555af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev) 231615819a70SAndre Guedes { 231715819a70SAndre Guedes struct hci_conn_params *params, *tmp; 231815819a70SAndre Guedes 231915819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 232055af49a8SJohan Hedberg if (params->auto_connect != HCI_AUTO_CONN_DISABLED) 232155af49a8SJohan Hedberg continue; 2322f75113a2SJakub Pawlowski 232391641b79SZheng Yongjun /* If trying to establish one time connection to disabled 2324f75113a2SJakub Pawlowski * device, leave the params, but mark them as just once. 2325f75113a2SJakub Pawlowski */ 2326f75113a2SJakub Pawlowski if (params->explicit_connect) { 2327f75113a2SJakub Pawlowski params->auto_connect = HCI_AUTO_CONN_EXPLICIT; 2328f75113a2SJakub Pawlowski continue; 2329f75113a2SJakub Pawlowski } 2330f75113a2SJakub Pawlowski 233115819a70SAndre Guedes list_del(¶ms->list); 233215819a70SAndre Guedes kfree(params); 233315819a70SAndre Guedes } 233415819a70SAndre Guedes 233555af49a8SJohan Hedberg BT_DBG("All LE disabled connection parameters were removed"); 233655af49a8SJohan Hedberg } 233755af49a8SJohan Hedberg 233855af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */ 2339030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev) 234015819a70SAndre Guedes { 234115819a70SAndre Guedes struct hci_conn_params *params, *tmp; 234215819a70SAndre Guedes 2343f6c63249SJohan Hedberg list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) 2344f6c63249SJohan Hedberg hci_conn_params_free(params); 234515819a70SAndre Guedes 234615819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 234715819a70SAndre Guedes } 234815819a70SAndre Guedes 2349a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 2350a1f4c318SJohan Hedberg * 2351a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 2352a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 2353a1f4c318SJohan Hedberg * the static random address. 2354a1f4c318SJohan Hedberg * 2355a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 2356a1f4c318SJohan Hedberg * public address to use the static random address instead. 235750b5b952SMarcel Holtmann * 235850b5b952SMarcel Holtmann * In case BR/EDR has been disabled on a dual-mode controller and 235950b5b952SMarcel Holtmann * userspace has configured a static address, then that address 236050b5b952SMarcel Holtmann * becomes the identity address instead of the public BR/EDR address. 2361a1f4c318SJohan Hedberg */ 2362a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 2363a1f4c318SJohan Hedberg u8 *bdaddr_type) 2364a1f4c318SJohan Hedberg { 2365b7cb93e5SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) || 236650b5b952SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) || 2367d7a5a11dSMarcel Holtmann (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) && 236850b5b952SMarcel Holtmann bacmp(&hdev->static_addr, BDADDR_ANY))) { 2369a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 2370a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 2371a1f4c318SJohan Hedberg } else { 2372a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 2373a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 2374a1f4c318SJohan Hedberg } 2375a1f4c318SJohan Hedberg } 2376a1f4c318SJohan Hedberg 23770e995280SAbhishek Pandit-Subedi static void hci_suspend_clear_tasks(struct hci_dev *hdev) 23780e995280SAbhishek Pandit-Subedi { 23790e995280SAbhishek Pandit-Subedi int i; 23800e995280SAbhishek Pandit-Subedi 23810e995280SAbhishek Pandit-Subedi for (i = 0; i < __SUSPEND_NUM_TASKS; i++) 23820e995280SAbhishek Pandit-Subedi clear_bit(i, hdev->suspend_tasks); 23830e995280SAbhishek Pandit-Subedi 23840e995280SAbhishek Pandit-Subedi wake_up(&hdev->suspend_wait_q); 23850e995280SAbhishek Pandit-Subedi } 23860e995280SAbhishek Pandit-Subedi 23879952d90eSAbhishek Pandit-Subedi static int hci_suspend_wait_event(struct hci_dev *hdev) 23889952d90eSAbhishek Pandit-Subedi { 23899952d90eSAbhishek Pandit-Subedi #define WAKE_COND \ 23909952d90eSAbhishek Pandit-Subedi (find_first_bit(hdev->suspend_tasks, __SUSPEND_NUM_TASKS) == \ 23919952d90eSAbhishek Pandit-Subedi __SUSPEND_NUM_TASKS) 23929952d90eSAbhishek Pandit-Subedi 23939952d90eSAbhishek Pandit-Subedi int i; 23949952d90eSAbhishek Pandit-Subedi int ret = wait_event_timeout(hdev->suspend_wait_q, 23959952d90eSAbhishek Pandit-Subedi WAKE_COND, SUSPEND_NOTIFIER_TIMEOUT); 23969952d90eSAbhishek Pandit-Subedi 23979952d90eSAbhishek Pandit-Subedi if (ret == 0) { 2398a9ec8423SAbhishek Pandit-Subedi bt_dev_err(hdev, "Timed out waiting for suspend events"); 23999952d90eSAbhishek Pandit-Subedi for (i = 0; i < __SUSPEND_NUM_TASKS; ++i) { 24009952d90eSAbhishek Pandit-Subedi if (test_bit(i, hdev->suspend_tasks)) 2401a9ec8423SAbhishek Pandit-Subedi bt_dev_err(hdev, "Suspend timeout bit: %d", i); 24029952d90eSAbhishek Pandit-Subedi clear_bit(i, hdev->suspend_tasks); 24039952d90eSAbhishek Pandit-Subedi } 24049952d90eSAbhishek Pandit-Subedi 24059952d90eSAbhishek Pandit-Subedi ret = -ETIMEDOUT; 24069952d90eSAbhishek Pandit-Subedi } else { 24079952d90eSAbhishek Pandit-Subedi ret = 0; 24089952d90eSAbhishek Pandit-Subedi } 24099952d90eSAbhishek Pandit-Subedi 24109952d90eSAbhishek Pandit-Subedi return ret; 24119952d90eSAbhishek Pandit-Subedi } 24129952d90eSAbhishek Pandit-Subedi 24139952d90eSAbhishek Pandit-Subedi static void hci_prepare_suspend(struct work_struct *work) 24149952d90eSAbhishek Pandit-Subedi { 24159952d90eSAbhishek Pandit-Subedi struct hci_dev *hdev = 24169952d90eSAbhishek Pandit-Subedi container_of(work, struct hci_dev, suspend_prepare); 24179952d90eSAbhishek Pandit-Subedi 24189952d90eSAbhishek Pandit-Subedi hci_dev_lock(hdev); 24199952d90eSAbhishek Pandit-Subedi hci_req_prepare_suspend(hdev, hdev->suspend_state_next); 24209952d90eSAbhishek Pandit-Subedi hci_dev_unlock(hdev); 24219952d90eSAbhishek Pandit-Subedi } 24229952d90eSAbhishek Pandit-Subedi 24238731840aSAbhishek Pandit-Subedi static int hci_change_suspend_state(struct hci_dev *hdev, 24248731840aSAbhishek Pandit-Subedi enum suspended_state next) 24258731840aSAbhishek Pandit-Subedi { 24268731840aSAbhishek Pandit-Subedi hdev->suspend_state_next = next; 24278731840aSAbhishek Pandit-Subedi set_bit(SUSPEND_PREPARE_NOTIFIER, hdev->suspend_tasks); 24288731840aSAbhishek Pandit-Subedi queue_work(hdev->req_workqueue, &hdev->suspend_prepare); 24298731840aSAbhishek Pandit-Subedi return hci_suspend_wait_event(hdev); 24308731840aSAbhishek Pandit-Subedi } 24318731840aSAbhishek Pandit-Subedi 24322f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev) 24332f20216cSAbhishek Pandit-Subedi { 24342f20216cSAbhishek Pandit-Subedi hci_dev_lock(hdev); 24352f20216cSAbhishek Pandit-Subedi 24362f20216cSAbhishek Pandit-Subedi hdev->wake_reason = 0; 24372f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, BDADDR_ANY); 24382f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = 0; 24392f20216cSAbhishek Pandit-Subedi 24402f20216cSAbhishek Pandit-Subedi hci_dev_unlock(hdev); 24412f20216cSAbhishek Pandit-Subedi } 24422f20216cSAbhishek Pandit-Subedi 24439952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, 24449952d90eSAbhishek Pandit-Subedi void *data) 24459952d90eSAbhishek Pandit-Subedi { 24469952d90eSAbhishek Pandit-Subedi struct hci_dev *hdev = 24479952d90eSAbhishek Pandit-Subedi container_of(nb, struct hci_dev, suspend_notifier); 24489952d90eSAbhishek Pandit-Subedi int ret = 0; 24499952d90eSAbhishek Pandit-Subedi 2450e1b77d68SLuiz Augusto von Dentz if (action == PM_SUSPEND_PREPARE) 2451e1b77d68SLuiz Augusto von Dentz ret = hci_suspend_dev(hdev); 2452e1b77d68SLuiz Augusto von Dentz else if (action == PM_POST_SUSPEND) 2453e1b77d68SLuiz Augusto von Dentz ret = hci_resume_dev(hdev); 24549952d90eSAbhishek Pandit-Subedi 2455a9ec8423SAbhishek Pandit-Subedi if (ret) 2456a9ec8423SAbhishek Pandit-Subedi bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d", 2457a9ec8423SAbhishek Pandit-Subedi action, ret); 2458a9ec8423SAbhishek Pandit-Subedi 245924b06572SMax Chou return NOTIFY_DONE; 24609952d90eSAbhishek Pandit-Subedi } 24618731840aSAbhishek Pandit-Subedi 24629be0dab7SDavid Herrmann /* Alloc HCI device */ 24636ec56613STedd Ho-Jeong An struct hci_dev *hci_alloc_dev_priv(int sizeof_priv) 24649be0dab7SDavid Herrmann { 24659be0dab7SDavid Herrmann struct hci_dev *hdev; 24666ec56613STedd Ho-Jeong An unsigned int alloc_size; 24679be0dab7SDavid Herrmann 24686ec56613STedd Ho-Jeong An alloc_size = sizeof(*hdev); 24696ec56613STedd Ho-Jeong An if (sizeof_priv) { 24706ec56613STedd Ho-Jeong An /* Fixme: May need ALIGN-ment? */ 24716ec56613STedd Ho-Jeong An alloc_size += sizeof_priv; 24726ec56613STedd Ho-Jeong An } 24736ec56613STedd Ho-Jeong An 24746ec56613STedd Ho-Jeong An hdev = kzalloc(alloc_size, GFP_KERNEL); 24759be0dab7SDavid Herrmann if (!hdev) 24769be0dab7SDavid Herrmann return NULL; 24779be0dab7SDavid Herrmann 2478b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 2479b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 2480b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 2481b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 2482b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 248396c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */ 2484bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 2485bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2486d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 2487d2609b34SFlorian Grandel hdev->cur_adv_instance = 0x00; 24885d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 2489b1b813d4SDavid Herrmann 2490c4f1f408SHoward Chung hdev->advmon_allowlist_duration = 300; 2491c4f1f408SHoward Chung hdev->advmon_no_filter_duration = 500; 249280af16a3SHoward Chung hdev->enable_advmon_interleave_scan = 0x00; /* Default to disable */ 2493c4f1f408SHoward Chung 2494b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 2495b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 2496b1b813d4SDavid Herrmann 24973f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 2498628531c9SGeorg Lukas hdev->le_adv_min_interval = 0x0800; 2499628531c9SGeorg Lukas hdev->le_adv_max_interval = 0x0800; 2500bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 2501bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 250210873f99SAlain Michaud hdev->le_scan_int_suspend = 0x0400; 250310873f99SAlain Michaud hdev->le_scan_window_suspend = 0x0012; 250410873f99SAlain Michaud hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT; 250510873f99SAlain Michaud hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN; 2506ba29d036SMarcel Holtmann hdev->le_scan_int_adv_monitor = 0x0060; 2507ba29d036SMarcel Holtmann hdev->le_scan_window_adv_monitor = 0x0030; 250810873f99SAlain Michaud hdev->le_scan_int_connect = 0x0060; 250910873f99SAlain Michaud hdev->le_scan_window_connect = 0x0060; 2510b48c3b59SJonas Holmberg hdev->le_conn_min_interval = 0x0018; 2511b48c3b59SJonas Holmberg hdev->le_conn_max_interval = 0x0028; 251204fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000; 251304fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a; 2514a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = 0x001b; 2515a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = 0x0148; 2516a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = 0x001b; 2517a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = 0x0148; 2518a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = 0x001b; 2519a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = 0x0148; 252030d65e08SMatias Karhumaa hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE; 252130d65e08SMatias Karhumaa hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE; 25226decb5b4SJaganath Kanakkassery hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M; 25236decb5b4SJaganath Kanakkassery hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M; 25241d0fac2cSLuiz Augusto von Dentz hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES; 252510873f99SAlain Michaud hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION; 252649b020c1SAlain Michaud hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT; 25277c395ea5SDaniel Winkler hdev->min_le_tx_power = HCI_TX_POWER_INVALID; 25287c395ea5SDaniel Winkler hdev->max_le_tx_power = HCI_TX_POWER_INVALID; 2529bef64738SMarcel Holtmann 2530d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 2531b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 253231ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 253331ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 2534302975cbSSpoorthi Ravishankar Koppad hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT; 253558a96fc3SMarcel Holtmann hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE; 2536d6bfd59cSJohan Hedberg 253710873f99SAlain Michaud /* default 1.28 sec page scan */ 253810873f99SAlain Michaud hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD; 253910873f99SAlain Michaud hdev->def_page_scan_int = 0x0800; 254010873f99SAlain Michaud hdev->def_page_scan_window = 0x0012; 254110873f99SAlain Michaud 2542b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 2543b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 2544b1b813d4SDavid Herrmann 2545b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 25463d4f9c00SArchie Pusaka INIT_LIST_HEAD(&hdev->reject_list); 25473d4f9c00SArchie Pusaka INIT_LIST_HEAD(&hdev->accept_list); 2548b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 2549b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 2550b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 2551970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 2552b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 25533d4f9c00SArchie Pusaka INIT_LIST_HEAD(&hdev->le_accept_list); 2554cfdb0c2dSAnkit Navik INIT_LIST_HEAD(&hdev->le_resolv_list); 255515819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 255677a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 255766f8455aSJohan Hedberg INIT_LIST_HEAD(&hdev->pend_le_reports); 25586b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 2559d2609b34SFlorian Grandel INIT_LIST_HEAD(&hdev->adv_instances); 2560600a8749SAlain Michaud INIT_LIST_HEAD(&hdev->blocked_keys); 2561b1b813d4SDavid Herrmann 25628961987fSKiran K INIT_LIST_HEAD(&hdev->local_codecs); 2563b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 2564b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 2565b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 2566b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 2567c7741d16SMarcel Holtmann INIT_WORK(&hdev->error_reset, hci_error_reset); 25689952d90eSAbhishek Pandit-Subedi INIT_WORK(&hdev->suspend_prepare, hci_prepare_suspend); 2569b1b813d4SDavid Herrmann 25706a98e383SMarcel Holtmann hci_cmd_sync_init(hdev); 25716a98e383SMarcel Holtmann 2572b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 2573b1b813d4SDavid Herrmann 2574b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 2575b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 2576b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 2577b1b813d4SDavid Herrmann 2578b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 25799952d90eSAbhishek Pandit-Subedi init_waitqueue_head(&hdev->suspend_wait_q); 2580b1b813d4SDavid Herrmann 258165cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout); 2582de75cd0dSManish Mandlik INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout); 2583b1b813d4SDavid Herrmann 25845fc16cc4SJohan Hedberg hci_request_setup(hdev); 25855fc16cc4SJohan Hedberg 2586b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 2587b1b813d4SDavid Herrmann discovery_init(hdev); 25889be0dab7SDavid Herrmann 25899be0dab7SDavid Herrmann return hdev; 25909be0dab7SDavid Herrmann } 25916ec56613STedd Ho-Jeong An EXPORT_SYMBOL(hci_alloc_dev_priv); 25929be0dab7SDavid Herrmann 25939be0dab7SDavid Herrmann /* Free HCI device */ 25949be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 25959be0dab7SDavid Herrmann { 25969be0dab7SDavid Herrmann /* will free via device release */ 25979be0dab7SDavid Herrmann put_device(&hdev->dev); 25989be0dab7SDavid Herrmann } 25999be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 26009be0dab7SDavid Herrmann 26011da177e4SLinus Torvalds /* Register HCI device */ 26021da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 26031da177e4SLinus Torvalds { 2604b1b813d4SDavid Herrmann int id, error; 26051da177e4SLinus Torvalds 260674292d5aSMarcel Holtmann if (!hdev->open || !hdev->close || !hdev->send) 26071da177e4SLinus Torvalds return -EINVAL; 26081da177e4SLinus Torvalds 260908add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 261008add513SMat Martineau * so the index can be used as the AMP controller ID. 261108add513SMat Martineau */ 26123df92b31SSasha Levin switch (hdev->dev_type) { 2613ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 26143df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 26151da177e4SLinus Torvalds break; 26163df92b31SSasha Levin case HCI_AMP: 26173df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 26183df92b31SSasha Levin break; 26193df92b31SSasha Levin default: 26203df92b31SSasha Levin return -EINVAL; 26211da177e4SLinus Torvalds } 26221da177e4SLinus Torvalds 26233df92b31SSasha Levin if (id < 0) 26243df92b31SSasha Levin return id; 26253df92b31SSasha Levin 26261da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 26271da177e4SLinus Torvalds hdev->id = id; 26282d8b3a11SAndrei Emeltchenko 26292d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 26302d8b3a11SAndrei Emeltchenko 263129e2dd0dSTejun Heo hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name); 263233ca954dSDavid Herrmann if (!hdev->workqueue) { 263333ca954dSDavid Herrmann error = -ENOMEM; 263433ca954dSDavid Herrmann goto err; 263533ca954dSDavid Herrmann } 2636f48fd9c8SMarcel Holtmann 263729e2dd0dSTejun Heo hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, 263829e2dd0dSTejun Heo hdev->name); 26396ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 26406ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 26416ead1bbcSJohan Hedberg error = -ENOMEM; 26426ead1bbcSJohan Hedberg goto err; 26436ead1bbcSJohan Hedberg } 26446ead1bbcSJohan Hedberg 26450153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 26460153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 26470153e2ecSMarcel Holtmann 2648bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 2649bdc3e0f1SMarcel Holtmann 2650bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 265133ca954dSDavid Herrmann if (error < 0) 265254506918SJohan Hedberg goto err_wqueue; 26531da177e4SLinus Torvalds 26546d5d2ee6SHeiner Kallweit hci_leds_init(hdev); 26556d5d2ee6SHeiner Kallweit 2656611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 2657a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 2658a8c5fb1aSGustavo Padovan hdev); 2659611b30f7SMarcel Holtmann if (hdev->rfkill) { 2660611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 2661611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2662611b30f7SMarcel Holtmann hdev->rfkill = NULL; 2663611b30f7SMarcel Holtmann } 2664611b30f7SMarcel Holtmann } 2665611b30f7SMarcel Holtmann 26665e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 2667a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 26685e130367SJohan Hedberg 2669a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SETUP); 2670a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_AUTO_OFF); 2671ce2be9acSAndrei Emeltchenko 2672ca8bee5dSMarcel Holtmann if (hdev->dev_type == HCI_PRIMARY) { 267356f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 267456f87901SJohan Hedberg * through reading supported features during init. 267556f87901SJohan Hedberg */ 2676a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 267756f87901SJohan Hedberg } 2678ce2be9acSAndrei Emeltchenko 2679fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 2680fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 2681fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 2682fcee3377SGustavo Padovan 26834a964404SMarcel Holtmann /* Devices that are marked for raw-only usage are unconfigured 26844a964404SMarcel Holtmann * and should not be included in normal operation. 2685fee746b0SMarcel Holtmann */ 2686fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 2687a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 2688fee746b0SMarcel Holtmann 268905fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_REG); 2690dc946bd8SDavid Herrmann hci_dev_hold(hdev); 26911da177e4SLinus Torvalds 2692219991e6SHans de Goede if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) { 26939952d90eSAbhishek Pandit-Subedi hdev->suspend_notifier.notifier_call = hci_suspend_notifier; 26949952d90eSAbhishek Pandit-Subedi error = register_pm_notifier(&hdev->suspend_notifier); 26959952d90eSAbhishek Pandit-Subedi if (error) 26969952d90eSAbhishek Pandit-Subedi goto err_wqueue; 2697219991e6SHans de Goede } 26989952d90eSAbhishek Pandit-Subedi 269919202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 2700fbe96d6fSMarcel Holtmann 2701e5e1e7fdSMiao-chen Chou idr_init(&hdev->adv_monitors_idr); 27025031ffccSMiao-chen Chou msft_register(hdev); 2703e5e1e7fdSMiao-chen Chou 27041da177e4SLinus Torvalds return id; 2705f48fd9c8SMarcel Holtmann 270633ca954dSDavid Herrmann err_wqueue: 27075a4bb6a8SWei Yongjun debugfs_remove_recursive(hdev->debugfs); 270833ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 27096ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 271033ca954dSDavid Herrmann err: 27113df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 2712f48fd9c8SMarcel Holtmann 271333ca954dSDavid Herrmann return error; 27141da177e4SLinus Torvalds } 27151da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 27161da177e4SLinus Torvalds 27171da177e4SLinus Torvalds /* Unregister HCI device */ 271859735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 27191da177e4SLinus Torvalds { 2720c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 27211da177e4SLinus Torvalds 2722a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNREGISTER); 272394324962SJohan Hovold 2724f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 27251da177e4SLinus Torvalds list_del(&hdev->list); 2726f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 27271da177e4SLinus Torvalds 2728b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 2729b9b5ef18SGustavo Padovan 27306a98e383SMarcel Holtmann hci_cmd_sync_clear(hdev); 27316a98e383SMarcel Holtmann 2732219991e6SHans de Goede if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) { 27330e995280SAbhishek Pandit-Subedi hci_suspend_clear_tasks(hdev); 27349952d90eSAbhishek Pandit-Subedi unregister_pm_notifier(&hdev->suspend_notifier); 27354e8c36c3SAbhishek Pandit-Subedi cancel_work_sync(&hdev->suspend_prepare); 2736219991e6SHans de Goede } 27374e8c36c3SAbhishek Pandit-Subedi 27385031ffccSMiao-chen Chou msft_unregister(hdev); 27395031ffccSMiao-chen Chou 27404e8c36c3SAbhishek Pandit-Subedi hci_dev_do_close(hdev); 27419952d90eSAbhishek Pandit-Subedi 2742ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 2743d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_SETUP) && 2744d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 274509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2746744cf19eSJohan Hedberg mgmt_index_removed(hdev); 274709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 274856e5cb86SJohan Hedberg } 2749ab81cbf9SJohan Hedberg 27502e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 27512e58ef3eSJohan Hedberg * pending list */ 27522e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 27532e58ef3eSJohan Hedberg 275405fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UNREG); 27551da177e4SLinus Torvalds 2756611b30f7SMarcel Holtmann if (hdev->rfkill) { 2757611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 2758611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2759611b30f7SMarcel Holtmann } 2760611b30f7SMarcel Holtmann 2761bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 2762e61fbee7SDavid S. Miller /* Actual cleanup is deferred until hci_release_dev(). */ 2763e0448092STetsuo Handa hci_dev_put(hdev); 2764e0448092STetsuo Handa } 2765e0448092STetsuo Handa EXPORT_SYMBOL(hci_unregister_dev); 2766147e2d59SDave Young 276758ce6d5bSTetsuo Handa /* Release HCI device */ 276858ce6d5bSTetsuo Handa void hci_release_dev(struct hci_dev *hdev) 2769e0448092STetsuo Handa { 27700153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 27715177a838SMarcel Holtmann kfree_const(hdev->hw_info); 27725177a838SMarcel Holtmann kfree_const(hdev->fw_info); 27730153e2ecSMarcel Holtmann 2774f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 27756ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 2776f48fd9c8SMarcel Holtmann 277709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 27783d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->reject_list); 27793d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->accept_list); 27802aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 278155ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 2782b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 2783970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 27842763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 2785d2609b34SFlorian Grandel hci_adv_instances_clear(hdev); 2786e5e1e7fdSMiao-chen Chou hci_adv_monitors_clear(hdev); 27873d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->le_accept_list); 2788cfdb0c2dSAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 2789373110c5SJohan Hedberg hci_conn_params_clear_all(hdev); 279022078800SMarcel Holtmann hci_discovery_filter_clear(hdev); 2791600a8749SAlain Michaud hci_blocked_keys_clear(hdev); 279209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 2793e2e0cacbSJohan Hedberg 2794e0448092STetsuo Handa ida_simple_remove(&hci_index_ida, hdev->id); 279558ce6d5bSTetsuo Handa kfree(hdev); 27961da177e4SLinus Torvalds } 279758ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_release_dev); 27981da177e4SLinus Torvalds 27991da177e4SLinus Torvalds /* Suspend HCI device */ 28001da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 28011da177e4SLinus Torvalds { 2802e1b77d68SLuiz Augusto von Dentz int ret; 2803e1b77d68SLuiz Augusto von Dentz u8 state = BT_RUNNING; 2804e1b77d68SLuiz Augusto von Dentz 2805e1b77d68SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 2806e1b77d68SLuiz Augusto von Dentz 2807e1b77d68SLuiz Augusto von Dentz /* Suspend should only act on when powered. */ 2808e1b77d68SLuiz Augusto von Dentz if (!hdev_is_powered(hdev) || 2809e1b77d68SLuiz Augusto von Dentz hci_dev_test_flag(hdev, HCI_UNREGISTER)) 28101da177e4SLinus Torvalds return 0; 2811e1b77d68SLuiz Augusto von Dentz 2812e1b77d68SLuiz Augusto von Dentz /* If powering down, wait for completion. */ 2813e1b77d68SLuiz Augusto von Dentz if (mgmt_powering_down(hdev)) { 2814e1b77d68SLuiz Augusto von Dentz set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks); 2815e1b77d68SLuiz Augusto von Dentz ret = hci_suspend_wait_event(hdev); 2816e1b77d68SLuiz Augusto von Dentz if (ret) 2817e1b77d68SLuiz Augusto von Dentz goto done; 2818e1b77d68SLuiz Augusto von Dentz } 2819e1b77d68SLuiz Augusto von Dentz 2820e1b77d68SLuiz Augusto von Dentz /* Suspend consists of two actions: 2821e1b77d68SLuiz Augusto von Dentz * - First, disconnect everything and make the controller not 2822e1b77d68SLuiz Augusto von Dentz * connectable (disabling scanning) 2823e1b77d68SLuiz Augusto von Dentz * - Second, program event filter/accept list and enable scan 2824e1b77d68SLuiz Augusto von Dentz */ 2825e1b77d68SLuiz Augusto von Dentz ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT); 28264539ca67SLuiz Augusto von Dentz if (ret) 28274539ca67SLuiz Augusto von Dentz goto clear; 28284539ca67SLuiz Augusto von Dentz 2829e1b77d68SLuiz Augusto von Dentz state = BT_SUSPEND_DISCONNECT; 2830e1b77d68SLuiz Augusto von Dentz 28314539ca67SLuiz Augusto von Dentz /* Only configure accept list if device may wakeup. */ 28324539ca67SLuiz Augusto von Dentz if (hdev->wakeup && hdev->wakeup(hdev)) { 2833e1b77d68SLuiz Augusto von Dentz ret = hci_change_suspend_state(hdev, BT_SUSPEND_CONFIGURE_WAKE); 2834e1b77d68SLuiz Augusto von Dentz if (!ret) 2835e1b77d68SLuiz Augusto von Dentz state = BT_SUSPEND_CONFIGURE_WAKE; 2836e1b77d68SLuiz Augusto von Dentz } 2837e1b77d68SLuiz Augusto von Dentz 28384539ca67SLuiz Augusto von Dentz clear: 2839e1b77d68SLuiz Augusto von Dentz hci_clear_wake_reason(hdev); 2840e1b77d68SLuiz Augusto von Dentz mgmt_suspending(hdev, state); 2841e1b77d68SLuiz Augusto von Dentz 2842e1b77d68SLuiz Augusto von Dentz done: 2843e1b77d68SLuiz Augusto von Dentz /* We always allow suspend even if suspend preparation failed and 2844e1b77d68SLuiz Augusto von Dentz * attempt to recover in resume. 2845e1b77d68SLuiz Augusto von Dentz */ 2846e1b77d68SLuiz Augusto von Dentz hci_sock_dev_event(hdev, HCI_DEV_SUSPEND); 2847e1b77d68SLuiz Augusto von Dentz return ret; 28481da177e4SLinus Torvalds } 28491da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 28501da177e4SLinus Torvalds 28511da177e4SLinus Torvalds /* Resume HCI device */ 28521da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 28531da177e4SLinus Torvalds { 2854e1b77d68SLuiz Augusto von Dentz int ret; 2855e1b77d68SLuiz Augusto von Dentz 2856e1b77d68SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 2857e1b77d68SLuiz Augusto von Dentz 2858e1b77d68SLuiz Augusto von Dentz /* Resume should only act on when powered. */ 2859e1b77d68SLuiz Augusto von Dentz if (!hdev_is_powered(hdev) || 2860e1b77d68SLuiz Augusto von Dentz hci_dev_test_flag(hdev, HCI_UNREGISTER)) 28611da177e4SLinus Torvalds return 0; 2862e1b77d68SLuiz Augusto von Dentz 2863e1b77d68SLuiz Augusto von Dentz /* If powering down don't attempt to resume */ 2864e1b77d68SLuiz Augusto von Dentz if (mgmt_powering_down(hdev)) 2865e1b77d68SLuiz Augusto von Dentz return 0; 2866e1b77d68SLuiz Augusto von Dentz 2867e1b77d68SLuiz Augusto von Dentz ret = hci_change_suspend_state(hdev, BT_RUNNING); 2868e1b77d68SLuiz Augusto von Dentz 2869e1b77d68SLuiz Augusto von Dentz mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr, 2870e1b77d68SLuiz Augusto von Dentz hdev->wake_addr_type); 2871e1b77d68SLuiz Augusto von Dentz 2872e1b77d68SLuiz Augusto von Dentz hci_sock_dev_event(hdev, HCI_DEV_RESUME); 2873e1b77d68SLuiz Augusto von Dentz return ret; 28741da177e4SLinus Torvalds } 28751da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 28761da177e4SLinus Torvalds 287775e0569fSMarcel Holtmann /* Reset HCI device */ 287875e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev) 287975e0569fSMarcel Holtmann { 28801e4b6e91SColin Ian King static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; 288175e0569fSMarcel Holtmann struct sk_buff *skb; 288275e0569fSMarcel Holtmann 288375e0569fSMarcel Holtmann skb = bt_skb_alloc(3, GFP_ATOMIC); 288475e0569fSMarcel Holtmann if (!skb) 288575e0569fSMarcel Holtmann return -ENOMEM; 288675e0569fSMarcel Holtmann 2887d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_EVENT_PKT; 288859ae1d12SJohannes Berg skb_put_data(skb, hw_err, 3); 288975e0569fSMarcel Holtmann 2890de75cd0dSManish Mandlik bt_dev_err(hdev, "Injecting HCI hardware error event"); 2891de75cd0dSManish Mandlik 289275e0569fSMarcel Holtmann /* Send Hardware Error to upper stack */ 289375e0569fSMarcel Holtmann return hci_recv_frame(hdev, skb); 289475e0569fSMarcel Holtmann } 289575e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev); 289675e0569fSMarcel Holtmann 289776bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 2898e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 289976bca880SMarcel Holtmann { 290076bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 290176bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 290276bca880SMarcel Holtmann kfree_skb(skb); 290376bca880SMarcel Holtmann return -ENXIO; 290476bca880SMarcel Holtmann } 290576bca880SMarcel Holtmann 2906d79f34e3SMarcel Holtmann if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT && 2907d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && 2908cc974003SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_SCODATA_PKT && 2909cc974003SMarcel Holtmann hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) { 2910fe806dceSMarcel Holtmann kfree_skb(skb); 2911fe806dceSMarcel Holtmann return -EINVAL; 2912fe806dceSMarcel Holtmann } 2913fe806dceSMarcel Holtmann 2914d82603c6SJorrit Schippers /* Incoming skb */ 291576bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 291676bca880SMarcel Holtmann 291776bca880SMarcel Holtmann /* Time stamp */ 291876bca880SMarcel Holtmann __net_timestamp(skb); 291976bca880SMarcel Holtmann 292076bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 2921b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 2922c78ae283SMarcel Holtmann 292376bca880SMarcel Holtmann return 0; 292476bca880SMarcel Holtmann } 292576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 292676bca880SMarcel Holtmann 2927e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */ 2928e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb) 2929e875ff84SMarcel Holtmann { 2930581d6fd6SMarcel Holtmann /* Mark as diagnostic packet */ 2931d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_DIAG_PKT; 2932581d6fd6SMarcel Holtmann 2933e875ff84SMarcel Holtmann /* Time stamp */ 2934e875ff84SMarcel Holtmann __net_timestamp(skb); 2935e875ff84SMarcel Holtmann 2936581d6fd6SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 2937581d6fd6SMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 2938e875ff84SMarcel Holtmann 2939e875ff84SMarcel Holtmann return 0; 2940e875ff84SMarcel Holtmann } 2941e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag); 2942e875ff84SMarcel Holtmann 29435177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...) 29445177a838SMarcel Holtmann { 29455177a838SMarcel Holtmann va_list vargs; 29465177a838SMarcel Holtmann 29475177a838SMarcel Holtmann va_start(vargs, fmt); 29485177a838SMarcel Holtmann kfree_const(hdev->hw_info); 29495177a838SMarcel Holtmann hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 29505177a838SMarcel Holtmann va_end(vargs); 29515177a838SMarcel Holtmann } 29525177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info); 29535177a838SMarcel Holtmann 29545177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...) 29555177a838SMarcel Holtmann { 29565177a838SMarcel Holtmann va_list vargs; 29575177a838SMarcel Holtmann 29585177a838SMarcel Holtmann va_start(vargs, fmt); 29595177a838SMarcel Holtmann kfree_const(hdev->fw_info); 29605177a838SMarcel Holtmann hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 29615177a838SMarcel Holtmann va_end(vargs); 29625177a838SMarcel Holtmann } 29635177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info); 29645177a838SMarcel Holtmann 29651da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 29661da177e4SLinus Torvalds 29671da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 29681da177e4SLinus Torvalds { 29691da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 29701da177e4SLinus Torvalds 2971fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 297200629e0fSJohan Hedberg list_add_tail(&cb->list, &hci_cb_list); 2973fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 29741da177e4SLinus Torvalds 29751da177e4SLinus Torvalds return 0; 29761da177e4SLinus Torvalds } 29771da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 29781da177e4SLinus Torvalds 29791da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 29801da177e4SLinus Torvalds { 29811da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 29821da177e4SLinus Torvalds 2983fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 29841da177e4SLinus Torvalds list_del(&cb->list); 2985fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 29861da177e4SLinus Torvalds 29871da177e4SLinus Torvalds return 0; 29881da177e4SLinus Torvalds } 29891da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 29901da177e4SLinus Torvalds 299151086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 29921da177e4SLinus Torvalds { 2993cdc52faaSMarcel Holtmann int err; 2994cdc52faaSMarcel Holtmann 2995d79f34e3SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb), 2996d79f34e3SMarcel Holtmann skb->len); 29971da177e4SLinus Torvalds 29981da177e4SLinus Torvalds /* Time stamp */ 2999a61bbcf2SPatrick McHardy __net_timestamp(skb); 30001da177e4SLinus Torvalds 3001cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3002cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3003cd82e61cSMarcel Holtmann 3004cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3005cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3006470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 30071da177e4SLinus Torvalds } 30081da177e4SLinus Torvalds 30091da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 30101da177e4SLinus Torvalds skb_orphan(skb); 30111da177e4SLinus Torvalds 301273d0d3c8SMarcel Holtmann if (!test_bit(HCI_RUNNING, &hdev->flags)) { 301373d0d3c8SMarcel Holtmann kfree_skb(skb); 301473d0d3c8SMarcel Holtmann return; 301573d0d3c8SMarcel Holtmann } 301673d0d3c8SMarcel Holtmann 3017cdc52faaSMarcel Holtmann err = hdev->send(hdev, skb); 3018cdc52faaSMarcel Holtmann if (err < 0) { 30192064ee33SMarcel Holtmann bt_dev_err(hdev, "sending frame failed (%d)", err); 3020cdc52faaSMarcel Holtmann kfree_skb(skb); 3021cdc52faaSMarcel Holtmann } 30221da177e4SLinus Torvalds } 30231da177e4SLinus Torvalds 30241ca3a9d0SJohan Hedberg /* Send HCI command */ 302507dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 302607dc93ddSJohan Hedberg const void *param) 30271ca3a9d0SJohan Hedberg { 30281ca3a9d0SJohan Hedberg struct sk_buff *skb; 30291ca3a9d0SJohan Hedberg 30301ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 30311ca3a9d0SJohan Hedberg 30321ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 30331ca3a9d0SJohan Hedberg if (!skb) { 30342064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for command"); 30351ca3a9d0SJohan Hedberg return -ENOMEM; 30361ca3a9d0SJohan Hedberg } 30371ca3a9d0SJohan Hedberg 303849c922bbSStephen Hemminger /* Stand-alone HCI commands must be flagged as 303911714b3dSJohan Hedberg * single-command requests. 304011714b3dSJohan Hedberg */ 304144d27137SJohan Hedberg bt_cb(skb)->hci.req_flags |= HCI_REQ_START; 304211714b3dSJohan Hedberg 30431da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3044c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 30451da177e4SLinus Torvalds 30461da177e4SLinus Torvalds return 0; 30471da177e4SLinus Torvalds } 30481da177e4SLinus Torvalds 3049d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen, 3050d6ee6ad7SLoic Poulain const void *param) 3051d6ee6ad7SLoic Poulain { 3052d6ee6ad7SLoic Poulain struct sk_buff *skb; 3053d6ee6ad7SLoic Poulain 3054d6ee6ad7SLoic Poulain if (hci_opcode_ogf(opcode) != 0x3f) { 3055d6ee6ad7SLoic Poulain /* A controller receiving a command shall respond with either 3056d6ee6ad7SLoic Poulain * a Command Status Event or a Command Complete Event. 3057d6ee6ad7SLoic Poulain * Therefore, all standard HCI commands must be sent via the 3058d6ee6ad7SLoic Poulain * standard API, using hci_send_cmd or hci_cmd_sync helpers. 3059d6ee6ad7SLoic Poulain * Some vendors do not comply with this rule for vendor-specific 3060d6ee6ad7SLoic Poulain * commands and do not return any event. We want to support 3061d6ee6ad7SLoic Poulain * unresponded commands for such cases only. 3062d6ee6ad7SLoic Poulain */ 3063d6ee6ad7SLoic Poulain bt_dev_err(hdev, "unresponded command not supported"); 3064d6ee6ad7SLoic Poulain return -EINVAL; 3065d6ee6ad7SLoic Poulain } 3066d6ee6ad7SLoic Poulain 3067d6ee6ad7SLoic Poulain skb = hci_prepare_cmd(hdev, opcode, plen, param); 3068d6ee6ad7SLoic Poulain if (!skb) { 3069d6ee6ad7SLoic Poulain bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)", 3070d6ee6ad7SLoic Poulain opcode); 3071d6ee6ad7SLoic Poulain return -ENOMEM; 3072d6ee6ad7SLoic Poulain } 3073d6ee6ad7SLoic Poulain 3074d6ee6ad7SLoic Poulain hci_send_frame(hdev, skb); 3075d6ee6ad7SLoic Poulain 3076d6ee6ad7SLoic Poulain return 0; 3077d6ee6ad7SLoic Poulain } 3078d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send); 3079d6ee6ad7SLoic Poulain 30801da177e4SLinus Torvalds /* Get data from the previously sent command */ 3081a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 30821da177e4SLinus Torvalds { 30831da177e4SLinus Torvalds struct hci_command_hdr *hdr; 30841da177e4SLinus Torvalds 30851da177e4SLinus Torvalds if (!hdev->sent_cmd) 30861da177e4SLinus Torvalds return NULL; 30871da177e4SLinus Torvalds 30881da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 30891da177e4SLinus Torvalds 3090a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 30911da177e4SLinus Torvalds return NULL; 30921da177e4SLinus Torvalds 3093f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 30941da177e4SLinus Torvalds 30951da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 30961da177e4SLinus Torvalds } 30971da177e4SLinus Torvalds 30981da177e4SLinus Torvalds /* Send ACL data */ 30991da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 31001da177e4SLinus Torvalds { 31011da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 31021da177e4SLinus Torvalds int len = skb->len; 31031da177e4SLinus Torvalds 3104badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3105badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 31069c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3107aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3108aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 31091da177e4SLinus Torvalds } 31101da177e4SLinus Torvalds 3111ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 311273d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 31131da177e4SLinus Torvalds { 3114ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 31151da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 31161da177e4SLinus Torvalds struct sk_buff *list; 31171da177e4SLinus Torvalds 3118087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3119087bfd99SGustavo Padovan skb->data_len = 0; 3120087bfd99SGustavo Padovan 3121d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 3122204a6e54SAndrei Emeltchenko 3123204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3124ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 3125087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3126204a6e54SAndrei Emeltchenko break; 3127204a6e54SAndrei Emeltchenko case HCI_AMP: 3128204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3129204a6e54SAndrei Emeltchenko break; 3130204a6e54SAndrei Emeltchenko default: 31312064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type); 3132204a6e54SAndrei Emeltchenko return; 3133204a6e54SAndrei Emeltchenko } 3134087bfd99SGustavo Padovan 313570f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 313670f23020SAndrei Emeltchenko if (!list) { 31371da177e4SLinus Torvalds /* Non fragmented */ 31381da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 31391da177e4SLinus Torvalds 314073d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 31411da177e4SLinus Torvalds } else { 31421da177e4SLinus Torvalds /* Fragmented */ 31431da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 31441da177e4SLinus Torvalds 31451da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 31461da177e4SLinus Torvalds 31479cfd5a23SJukka Rissanen /* Queue all fragments atomically. We need to use spin_lock_bh 31489cfd5a23SJukka Rissanen * here because of 6LoWPAN links, as there this function is 31499cfd5a23SJukka Rissanen * called from softirq and using normal spin lock could cause 31509cfd5a23SJukka Rissanen * deadlocks. 31519cfd5a23SJukka Rissanen */ 31529cfd5a23SJukka Rissanen spin_lock_bh(&queue->lock); 31531da177e4SLinus Torvalds 315473d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3155e702112fSAndrei Emeltchenko 3156e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3157e702112fSAndrei Emeltchenko flags |= ACL_CONT; 31581da177e4SLinus Torvalds do { 31591da177e4SLinus Torvalds skb = list; list = list->next; 31601da177e4SLinus Torvalds 3161d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 3162e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 31631da177e4SLinus Torvalds 31641da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 31651da177e4SLinus Torvalds 316673d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 31671da177e4SLinus Torvalds } while (list); 31681da177e4SLinus Torvalds 31699cfd5a23SJukka Rissanen spin_unlock_bh(&queue->lock); 31701da177e4SLinus Torvalds } 317173d80debSLuiz Augusto von Dentz } 317273d80debSLuiz Augusto von Dentz 317373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 317473d80debSLuiz Augusto von Dentz { 3175ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 317673d80debSLuiz Augusto von Dentz 3177f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 317873d80debSLuiz Augusto von Dentz 3179ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 31801da177e4SLinus Torvalds 31813eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 31821da177e4SLinus Torvalds } 31831da177e4SLinus Torvalds 31841da177e4SLinus Torvalds /* Send SCO data */ 31850d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 31861da177e4SLinus Torvalds { 31871da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 31881da177e4SLinus Torvalds struct hci_sco_hdr hdr; 31891da177e4SLinus Torvalds 31901da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 31911da177e4SLinus Torvalds 3192aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 31931da177e4SLinus Torvalds hdr.dlen = skb->len; 31941da177e4SLinus Torvalds 3195badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 3196badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 31979c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 31981da177e4SLinus Torvalds 3199d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_SCODATA_PKT; 3200c78ae283SMarcel Holtmann 32011da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 32023eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 32031da177e4SLinus Torvalds } 32041da177e4SLinus Torvalds 32051da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 32061da177e4SLinus Torvalds 32071da177e4SLinus Torvalds /* HCI Connection scheduler */ 32086039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 3209a8c5fb1aSGustavo Padovan int *quote) 32101da177e4SLinus Torvalds { 32111da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 32128035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 3213abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 32141da177e4SLinus Torvalds 32151da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 32161da177e4SLinus Torvalds * added and removed with TX task disabled. */ 3217bf4c6325SGustavo F. Padovan 3218bf4c6325SGustavo F. Padovan rcu_read_lock(); 3219bf4c6325SGustavo F. Padovan 3220bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3221769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 32221da177e4SLinus Torvalds continue; 3223769be974SMarcel Holtmann 3224769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 3225769be974SMarcel Holtmann continue; 3226769be974SMarcel Holtmann 32271da177e4SLinus Torvalds num++; 32281da177e4SLinus Torvalds 32291da177e4SLinus Torvalds if (c->sent < min) { 32301da177e4SLinus Torvalds min = c->sent; 32311da177e4SLinus Torvalds conn = c; 32321da177e4SLinus Torvalds } 323352087a79SLuiz Augusto von Dentz 323452087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 323552087a79SLuiz Augusto von Dentz break; 32361da177e4SLinus Torvalds } 32371da177e4SLinus Torvalds 3238bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3239bf4c6325SGustavo F. Padovan 32401da177e4SLinus Torvalds if (conn) { 32416ed58ec5SVille Tervo int cnt, q; 32426ed58ec5SVille Tervo 32436ed58ec5SVille Tervo switch (conn->type) { 32446ed58ec5SVille Tervo case ACL_LINK: 32456ed58ec5SVille Tervo cnt = hdev->acl_cnt; 32466ed58ec5SVille Tervo break; 32476ed58ec5SVille Tervo case SCO_LINK: 32486ed58ec5SVille Tervo case ESCO_LINK: 32496ed58ec5SVille Tervo cnt = hdev->sco_cnt; 32506ed58ec5SVille Tervo break; 32516ed58ec5SVille Tervo case LE_LINK: 32526ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 32536ed58ec5SVille Tervo break; 32546ed58ec5SVille Tervo default: 32556ed58ec5SVille Tervo cnt = 0; 32562064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown link type %d", conn->type); 32576ed58ec5SVille Tervo } 32586ed58ec5SVille Tervo 32596ed58ec5SVille Tervo q = cnt / num; 32601da177e4SLinus Torvalds *quote = q ? q : 1; 32611da177e4SLinus Torvalds } else 32621da177e4SLinus Torvalds *quote = 0; 32631da177e4SLinus Torvalds 32641da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 32651da177e4SLinus Torvalds return conn; 32661da177e4SLinus Torvalds } 32671da177e4SLinus Torvalds 32686039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 32691da177e4SLinus Torvalds { 32701da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 32711da177e4SLinus Torvalds struct hci_conn *c; 32721da177e4SLinus Torvalds 32732064ee33SMarcel Holtmann bt_dev_err(hdev, "link tx timeout"); 32741da177e4SLinus Torvalds 3275bf4c6325SGustavo F. Padovan rcu_read_lock(); 3276bf4c6325SGustavo F. Padovan 32771da177e4SLinus Torvalds /* Kill stalled connections */ 3278bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3279bae1f5d9SVille Tervo if (c->type == type && c->sent) { 32802064ee33SMarcel Holtmann bt_dev_err(hdev, "killing stalled connection %pMR", 32812064ee33SMarcel Holtmann &c->dst); 3282bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 32831da177e4SLinus Torvalds } 32841da177e4SLinus Torvalds } 3285bf4c6325SGustavo F. Padovan 3286bf4c6325SGustavo F. Padovan rcu_read_unlock(); 32871da177e4SLinus Torvalds } 32881da177e4SLinus Torvalds 32896039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 329073d80debSLuiz Augusto von Dentz int *quote) 329173d80debSLuiz Augusto von Dentz { 329273d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 329373d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 3294abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 329573d80debSLuiz Augusto von Dentz struct hci_conn *conn; 329673d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 329773d80debSLuiz Augusto von Dentz 329873d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 329973d80debSLuiz Augusto von Dentz 3300bf4c6325SGustavo F. Padovan rcu_read_lock(); 3301bf4c6325SGustavo F. Padovan 3302bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 330373d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 330473d80debSLuiz Augusto von Dentz 330573d80debSLuiz Augusto von Dentz if (conn->type != type) 330673d80debSLuiz Augusto von Dentz continue; 330773d80debSLuiz Augusto von Dentz 330873d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 330973d80debSLuiz Augusto von Dentz continue; 331073d80debSLuiz Augusto von Dentz 331173d80debSLuiz Augusto von Dentz conn_num++; 331273d80debSLuiz Augusto von Dentz 33138192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 331473d80debSLuiz Augusto von Dentz struct sk_buff *skb; 331573d80debSLuiz Augusto von Dentz 331673d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 331773d80debSLuiz Augusto von Dentz continue; 331873d80debSLuiz Augusto von Dentz 331973d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 332073d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 332173d80debSLuiz Augusto von Dentz continue; 332273d80debSLuiz Augusto von Dentz 332373d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 332473d80debSLuiz Augusto von Dentz num = 0; 332573d80debSLuiz Augusto von Dentz min = ~0; 332673d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 332773d80debSLuiz Augusto von Dentz } 332873d80debSLuiz Augusto von Dentz 332973d80debSLuiz Augusto von Dentz num++; 333073d80debSLuiz Augusto von Dentz 333173d80debSLuiz Augusto von Dentz if (conn->sent < min) { 333273d80debSLuiz Augusto von Dentz min = conn->sent; 333373d80debSLuiz Augusto von Dentz chan = tmp; 333473d80debSLuiz Augusto von Dentz } 333573d80debSLuiz Augusto von Dentz } 333673d80debSLuiz Augusto von Dentz 333773d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 333873d80debSLuiz Augusto von Dentz break; 333973d80debSLuiz Augusto von Dentz } 334073d80debSLuiz Augusto von Dentz 3341bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3342bf4c6325SGustavo F. Padovan 334373d80debSLuiz Augusto von Dentz if (!chan) 334473d80debSLuiz Augusto von Dentz return NULL; 334573d80debSLuiz Augusto von Dentz 334673d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 334773d80debSLuiz Augusto von Dentz case ACL_LINK: 334873d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 334973d80debSLuiz Augusto von Dentz break; 3350bd1eb66bSAndrei Emeltchenko case AMP_LINK: 3351bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 3352bd1eb66bSAndrei Emeltchenko break; 335373d80debSLuiz Augusto von Dentz case SCO_LINK: 335473d80debSLuiz Augusto von Dentz case ESCO_LINK: 335573d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 335673d80debSLuiz Augusto von Dentz break; 335773d80debSLuiz Augusto von Dentz case LE_LINK: 335873d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 335973d80debSLuiz Augusto von Dentz break; 336073d80debSLuiz Augusto von Dentz default: 336173d80debSLuiz Augusto von Dentz cnt = 0; 33622064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown link type %d", chan->conn->type); 336373d80debSLuiz Augusto von Dentz } 336473d80debSLuiz Augusto von Dentz 336573d80debSLuiz Augusto von Dentz q = cnt / num; 336673d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 336773d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 336873d80debSLuiz Augusto von Dentz return chan; 336973d80debSLuiz Augusto von Dentz } 337073d80debSLuiz Augusto von Dentz 337102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 337202b20f0bSLuiz Augusto von Dentz { 337302b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 337402b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 337502b20f0bSLuiz Augusto von Dentz int num = 0; 337602b20f0bSLuiz Augusto von Dentz 337702b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 337802b20f0bSLuiz Augusto von Dentz 3379bf4c6325SGustavo F. Padovan rcu_read_lock(); 3380bf4c6325SGustavo F. Padovan 3381bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 338202b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 338302b20f0bSLuiz Augusto von Dentz 338402b20f0bSLuiz Augusto von Dentz if (conn->type != type) 338502b20f0bSLuiz Augusto von Dentz continue; 338602b20f0bSLuiz Augusto von Dentz 338702b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 338802b20f0bSLuiz Augusto von Dentz continue; 338902b20f0bSLuiz Augusto von Dentz 339002b20f0bSLuiz Augusto von Dentz num++; 339102b20f0bSLuiz Augusto von Dentz 33928192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 339302b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 339402b20f0bSLuiz Augusto von Dentz 339502b20f0bSLuiz Augusto von Dentz if (chan->sent) { 339602b20f0bSLuiz Augusto von Dentz chan->sent = 0; 339702b20f0bSLuiz Augusto von Dentz continue; 339802b20f0bSLuiz Augusto von Dentz } 339902b20f0bSLuiz Augusto von Dentz 340002b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 340102b20f0bSLuiz Augusto von Dentz continue; 340202b20f0bSLuiz Augusto von Dentz 340302b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 340402b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 340502b20f0bSLuiz Augusto von Dentz continue; 340602b20f0bSLuiz Augusto von Dentz 340702b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 340802b20f0bSLuiz Augusto von Dentz 340902b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 341002b20f0bSLuiz Augusto von Dentz skb->priority); 341102b20f0bSLuiz Augusto von Dentz } 341202b20f0bSLuiz Augusto von Dentz 341302b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 341402b20f0bSLuiz Augusto von Dentz break; 341502b20f0bSLuiz Augusto von Dentz } 3416bf4c6325SGustavo F. Padovan 3417bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3418bf4c6325SGustavo F. Padovan 341902b20f0bSLuiz Augusto von Dentz } 342002b20f0bSLuiz Augusto von Dentz 3421b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 3422b71d385aSAndrei Emeltchenko { 3423b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 3424b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 3425b71d385aSAndrei Emeltchenko } 3426b71d385aSAndrei Emeltchenko 34276039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 34281da177e4SLinus Torvalds { 3429d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 34301da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 34311da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 343263d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 34335f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 3434bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 34351da177e4SLinus Torvalds } 343663d2bc1bSAndrei Emeltchenko } 34371da177e4SLinus Torvalds 34387fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */ 34397fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev) 34407fedd3bbSAbhishek Pandit-Subedi { 34417fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn; 34427fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb; 34437fedd3bbSAbhishek Pandit-Subedi int quote; 34447fedd3bbSAbhishek Pandit-Subedi 34457fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name); 34467fedd3bbSAbhishek Pandit-Subedi 34477fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, SCO_LINK)) 34487fedd3bbSAbhishek Pandit-Subedi return; 34497fedd3bbSAbhishek Pandit-Subedi 34507fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 34517fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 34527fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len); 34537fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb); 34547fedd3bbSAbhishek Pandit-Subedi 34557fedd3bbSAbhishek Pandit-Subedi conn->sent++; 34567fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0) 34577fedd3bbSAbhishek Pandit-Subedi conn->sent = 0; 34587fedd3bbSAbhishek Pandit-Subedi } 34597fedd3bbSAbhishek Pandit-Subedi } 34607fedd3bbSAbhishek Pandit-Subedi } 34617fedd3bbSAbhishek Pandit-Subedi 34627fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev) 34637fedd3bbSAbhishek Pandit-Subedi { 34647fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn; 34657fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb; 34667fedd3bbSAbhishek Pandit-Subedi int quote; 34677fedd3bbSAbhishek Pandit-Subedi 34687fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name); 34697fedd3bbSAbhishek Pandit-Subedi 34707fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, ESCO_LINK)) 34717fedd3bbSAbhishek Pandit-Subedi return; 34727fedd3bbSAbhishek Pandit-Subedi 34737fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 34747fedd3bbSAbhishek Pandit-Subedi "e))) { 34757fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 34767fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len); 34777fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb); 34787fedd3bbSAbhishek Pandit-Subedi 34797fedd3bbSAbhishek Pandit-Subedi conn->sent++; 34807fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0) 34817fedd3bbSAbhishek Pandit-Subedi conn->sent = 0; 34827fedd3bbSAbhishek Pandit-Subedi } 34837fedd3bbSAbhishek Pandit-Subedi } 34847fedd3bbSAbhishek Pandit-Subedi } 34857fedd3bbSAbhishek Pandit-Subedi 34866039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 348763d2bc1bSAndrei Emeltchenko { 348863d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 348963d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 349063d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 349163d2bc1bSAndrei Emeltchenko int quote; 349263d2bc1bSAndrei Emeltchenko 349363d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 349404837f64SMarcel Holtmann 349573d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 349673d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 3497ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3498ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 349973d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 350073d80debSLuiz Augusto von Dentz skb->len, skb->priority); 350173d80debSLuiz Augusto von Dentz 3502ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3503ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3504ec1cce24SLuiz Augusto von Dentz break; 3505ec1cce24SLuiz Augusto von Dentz 3506ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3507ec1cce24SLuiz Augusto von Dentz 350873d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 350973d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 351004837f64SMarcel Holtmann 351157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 35121da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 35131da177e4SLinus Torvalds 35141da177e4SLinus Torvalds hdev->acl_cnt--; 351573d80debSLuiz Augusto von Dentz chan->sent++; 351673d80debSLuiz Augusto von Dentz chan->conn->sent++; 35177fedd3bbSAbhishek Pandit-Subedi 35187fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */ 35197fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev); 35207fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev); 35211da177e4SLinus Torvalds } 35221da177e4SLinus Torvalds } 352302b20f0bSLuiz Augusto von Dentz 352402b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 352502b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 35261da177e4SLinus Torvalds } 35271da177e4SLinus Torvalds 35286039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 3529b71d385aSAndrei Emeltchenko { 353063d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 3531b71d385aSAndrei Emeltchenko struct hci_chan *chan; 3532b71d385aSAndrei Emeltchenko struct sk_buff *skb; 3533b71d385aSAndrei Emeltchenko int quote; 3534bd1eb66bSAndrei Emeltchenko u8 type; 3535b71d385aSAndrei Emeltchenko 353663d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 3537b71d385aSAndrei Emeltchenko 3538bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3539bd1eb66bSAndrei Emeltchenko 3540bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 3541bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 3542bd1eb66bSAndrei Emeltchenko else 3543bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 3544bd1eb66bSAndrei Emeltchenko 3545b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 3546bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 3547b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 3548b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 3549b71d385aSAndrei Emeltchenko int blocks; 3550b71d385aSAndrei Emeltchenko 3551b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 3552b71d385aSAndrei Emeltchenko skb->len, skb->priority); 3553b71d385aSAndrei Emeltchenko 3554b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 3555b71d385aSAndrei Emeltchenko if (skb->priority < priority) 3556b71d385aSAndrei Emeltchenko break; 3557b71d385aSAndrei Emeltchenko 3558b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 3559b71d385aSAndrei Emeltchenko 3560b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 3561b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 3562b71d385aSAndrei Emeltchenko return; 3563b71d385aSAndrei Emeltchenko 3564b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 3565b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 3566b71d385aSAndrei Emeltchenko 356757d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 3568b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 3569b71d385aSAndrei Emeltchenko 3570b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 3571b71d385aSAndrei Emeltchenko quote -= blocks; 3572b71d385aSAndrei Emeltchenko 3573b71d385aSAndrei Emeltchenko chan->sent += blocks; 3574b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 3575b71d385aSAndrei Emeltchenko } 3576b71d385aSAndrei Emeltchenko } 3577b71d385aSAndrei Emeltchenko 3578b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 3579bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 3580b71d385aSAndrei Emeltchenko } 3581b71d385aSAndrei Emeltchenko 35826039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 3583b71d385aSAndrei Emeltchenko { 3584b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3585b71d385aSAndrei Emeltchenko 3586bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 3587ca8bee5dSMarcel Holtmann if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY) 3588bd1eb66bSAndrei Emeltchenko return; 3589bd1eb66bSAndrei Emeltchenko 3590bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 3591bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 3592b71d385aSAndrei Emeltchenko return; 3593b71d385aSAndrei Emeltchenko 3594b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 3595b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 3596b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 3597b71d385aSAndrei Emeltchenko break; 3598b71d385aSAndrei Emeltchenko 3599b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 3600b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 3601b71d385aSAndrei Emeltchenko break; 3602b71d385aSAndrei Emeltchenko } 3603b71d385aSAndrei Emeltchenko } 3604b71d385aSAndrei Emeltchenko 36056039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 36066ed58ec5SVille Tervo { 360773d80debSLuiz Augusto von Dentz struct hci_chan *chan; 36086ed58ec5SVille Tervo struct sk_buff *skb; 360902b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 36106ed58ec5SVille Tervo 36116ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 36126ed58ec5SVille Tervo 361352087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 361452087a79SLuiz Augusto von Dentz return; 361552087a79SLuiz Augusto von Dentz 36166ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 36171b1d29e5SLuiz Augusto von Dentz 36181b1d29e5SLuiz Augusto von Dentz __check_timeout(hdev, cnt); 36191b1d29e5SLuiz Augusto von Dentz 362002b20f0bSLuiz Augusto von Dentz tmp = cnt; 362173d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 3622ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3623ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 362473d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 362573d80debSLuiz Augusto von Dentz skb->len, skb->priority); 36266ed58ec5SVille Tervo 3627ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3628ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3629ec1cce24SLuiz Augusto von Dentz break; 3630ec1cce24SLuiz Augusto von Dentz 3631ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3632ec1cce24SLuiz Augusto von Dentz 363357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 36346ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 36356ed58ec5SVille Tervo 36366ed58ec5SVille Tervo cnt--; 363773d80debSLuiz Augusto von Dentz chan->sent++; 363873d80debSLuiz Augusto von Dentz chan->conn->sent++; 36397fedd3bbSAbhishek Pandit-Subedi 36407fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */ 36417fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev); 36427fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev); 36436ed58ec5SVille Tervo } 36446ed58ec5SVille Tervo } 364573d80debSLuiz Augusto von Dentz 36466ed58ec5SVille Tervo if (hdev->le_pkts) 36476ed58ec5SVille Tervo hdev->le_cnt = cnt; 36486ed58ec5SVille Tervo else 36496ed58ec5SVille Tervo hdev->acl_cnt = cnt; 365002b20f0bSLuiz Augusto von Dentz 365102b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 365202b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 36536ed58ec5SVille Tervo } 36546ed58ec5SVille Tervo 36553eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 36561da177e4SLinus Torvalds { 36573eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 36581da177e4SLinus Torvalds struct sk_buff *skb; 36591da177e4SLinus Torvalds 36606ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 36616ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 36621da177e4SLinus Torvalds 3663d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 36641da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 36651da177e4SLinus Torvalds hci_sched_sco(hdev); 3666b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 36677fedd3bbSAbhishek Pandit-Subedi hci_sched_acl(hdev); 36686ed58ec5SVille Tervo hci_sched_le(hdev); 366952de599eSMarcel Holtmann } 36706ed58ec5SVille Tervo 36711da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 36721da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 367357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 36741da177e4SLinus Torvalds } 36751da177e4SLinus Torvalds 367625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 36771da177e4SLinus Torvalds 36781da177e4SLinus Torvalds /* ACL data packet */ 36796039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 36801da177e4SLinus Torvalds { 36811da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 36821da177e4SLinus Torvalds struct hci_conn *conn; 36831da177e4SLinus Torvalds __u16 handle, flags; 36841da177e4SLinus Torvalds 36851da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 36861da177e4SLinus Torvalds 36871da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 36881da177e4SLinus Torvalds flags = hci_flags(handle); 36891da177e4SLinus Torvalds handle = hci_handle(handle); 36901da177e4SLinus Torvalds 3691f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 3692a8c5fb1aSGustavo Padovan handle, flags); 36931da177e4SLinus Torvalds 36941da177e4SLinus Torvalds hdev->stat.acl_rx++; 36951da177e4SLinus Torvalds 36961da177e4SLinus Torvalds hci_dev_lock(hdev); 36971da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 36981da177e4SLinus Torvalds hci_dev_unlock(hdev); 36991da177e4SLinus Torvalds 37001da177e4SLinus Torvalds if (conn) { 370165983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 370204837f64SMarcel Holtmann 37031da177e4SLinus Torvalds /* Send to upper protocol */ 3704686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 37051da177e4SLinus Torvalds return; 37061da177e4SLinus Torvalds } else { 37072064ee33SMarcel Holtmann bt_dev_err(hdev, "ACL packet for unknown connection handle %d", 37082064ee33SMarcel Holtmann handle); 37091da177e4SLinus Torvalds } 37101da177e4SLinus Torvalds 37111da177e4SLinus Torvalds kfree_skb(skb); 37121da177e4SLinus Torvalds } 37131da177e4SLinus Torvalds 37141da177e4SLinus Torvalds /* SCO data packet */ 37156039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 37161da177e4SLinus Torvalds { 37171da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 37181da177e4SLinus Torvalds struct hci_conn *conn; 3719debdedf2SMarcel Holtmann __u16 handle, flags; 37201da177e4SLinus Torvalds 37211da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 37221da177e4SLinus Torvalds 37231da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 3724debdedf2SMarcel Holtmann flags = hci_flags(handle); 3725debdedf2SMarcel Holtmann handle = hci_handle(handle); 37261da177e4SLinus Torvalds 3727debdedf2SMarcel Holtmann BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 3728debdedf2SMarcel Holtmann handle, flags); 37291da177e4SLinus Torvalds 37301da177e4SLinus Torvalds hdev->stat.sco_rx++; 37311da177e4SLinus Torvalds 37321da177e4SLinus Torvalds hci_dev_lock(hdev); 37331da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 37341da177e4SLinus Torvalds hci_dev_unlock(hdev); 37351da177e4SLinus Torvalds 37361da177e4SLinus Torvalds if (conn) { 37371da177e4SLinus Torvalds /* Send to upper protocol */ 373800398e1dSAlain Michaud bt_cb(skb)->sco.pkt_status = flags & 0x03; 3739686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 37401da177e4SLinus Torvalds return; 37411da177e4SLinus Torvalds } else { 37422064ee33SMarcel Holtmann bt_dev_err(hdev, "SCO packet for unknown connection handle %d", 37432064ee33SMarcel Holtmann handle); 37441da177e4SLinus Torvalds } 37451da177e4SLinus Torvalds 37461da177e4SLinus Torvalds kfree_skb(skb); 37471da177e4SLinus Torvalds } 37481da177e4SLinus Torvalds 37499238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 37509238f36aSJohan Hedberg { 37519238f36aSJohan Hedberg struct sk_buff *skb; 37529238f36aSJohan Hedberg 37539238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 37549238f36aSJohan Hedberg if (!skb) 37559238f36aSJohan Hedberg return true; 37569238f36aSJohan Hedberg 375744d27137SJohan Hedberg return (bt_cb(skb)->hci.req_flags & HCI_REQ_START); 37589238f36aSJohan Hedberg } 37599238f36aSJohan Hedberg 376042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 376142c6b129SJohan Hedberg { 376242c6b129SJohan Hedberg struct hci_command_hdr *sent; 376342c6b129SJohan Hedberg struct sk_buff *skb; 376442c6b129SJohan Hedberg u16 opcode; 376542c6b129SJohan Hedberg 376642c6b129SJohan Hedberg if (!hdev->sent_cmd) 376742c6b129SJohan Hedberg return; 376842c6b129SJohan Hedberg 376942c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 377042c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 377142c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 377242c6b129SJohan Hedberg return; 377342c6b129SJohan Hedberg 377442c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 377542c6b129SJohan Hedberg if (!skb) 377642c6b129SJohan Hedberg return; 377742c6b129SJohan Hedberg 377842c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 377942c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 378042c6b129SJohan Hedberg } 378142c6b129SJohan Hedberg 3782e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, 3783e6214487SJohan Hedberg hci_req_complete_t *req_complete, 3784e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 37859238f36aSJohan Hedberg { 37869238f36aSJohan Hedberg struct sk_buff *skb; 37879238f36aSJohan Hedberg unsigned long flags; 37889238f36aSJohan Hedberg 37899238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 37909238f36aSJohan Hedberg 379142c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 379242c6b129SJohan Hedberg * sent we need to do special handling of it. 37939238f36aSJohan Hedberg */ 379442c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 379542c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 379642c6b129SJohan Hedberg * reset complete event during init and any pending 379742c6b129SJohan Hedberg * command will never be completed. In such a case we 379842c6b129SJohan Hedberg * need to resend whatever was the last sent 379942c6b129SJohan Hedberg * command. 380042c6b129SJohan Hedberg */ 380142c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 380242c6b129SJohan Hedberg hci_resend_last(hdev); 380342c6b129SJohan Hedberg 38049238f36aSJohan Hedberg return; 380542c6b129SJohan Hedberg } 38069238f36aSJohan Hedberg 3807f80c5dadSJoão Paulo Rechi Vita /* If we reach this point this event matches the last command sent */ 3808f80c5dadSJoão Paulo Rechi Vita hci_dev_clear_flag(hdev, HCI_CMD_PENDING); 3809f80c5dadSJoão Paulo Rechi Vita 38109238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 38119238f36aSJohan Hedberg * this request the request is not yet complete. 38129238f36aSJohan Hedberg */ 38139238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 38149238f36aSJohan Hedberg return; 38159238f36aSJohan Hedberg 38169238f36aSJohan Hedberg /* If this was the last command in a request the complete 38179238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 38189238f36aSJohan Hedberg * command queue (hdev->cmd_q). 38199238f36aSJohan Hedberg */ 382044d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) { 382144d27137SJohan Hedberg *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb; 3822e6214487SJohan Hedberg return; 38239238f36aSJohan Hedberg } 3824e6214487SJohan Hedberg 382544d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_complete) { 382644d27137SJohan Hedberg *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete; 3827e6214487SJohan Hedberg return; 382853e21fbcSJohan Hedberg } 38299238f36aSJohan Hedberg 38309238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 38319238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 38329238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 383344d27137SJohan Hedberg if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) { 38349238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 38359238f36aSJohan Hedberg break; 38369238f36aSJohan Hedberg } 38379238f36aSJohan Hedberg 38383bd7594eSDouglas Anderson if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) 3839242c0ebdSMarcel Holtmann *req_complete_skb = bt_cb(skb)->hci.req_complete_skb; 38403bd7594eSDouglas Anderson else 38413bd7594eSDouglas Anderson *req_complete = bt_cb(skb)->hci.req_complete; 38429238f36aSJohan Hedberg kfree_skb(skb); 38439238f36aSJohan Hedberg } 38449238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 38459238f36aSJohan Hedberg } 38469238f36aSJohan Hedberg 3847b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 38481da177e4SLinus Torvalds { 3849b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 38501da177e4SLinus Torvalds struct sk_buff *skb; 38511da177e4SLinus Torvalds 38521da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 38531da177e4SLinus Torvalds 38541da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 3855cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3856cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3857cd82e61cSMarcel Holtmann 38581da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 38591da177e4SLinus Torvalds /* Send copy to the sockets */ 3860470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 38611da177e4SLinus Torvalds } 38621da177e4SLinus Torvalds 3863eb8c101eSMattijs Korpershoek /* If the device has been opened in HCI_USER_CHANNEL, 3864eb8c101eSMattijs Korpershoek * the userspace has exclusive access to device. 3865eb8c101eSMattijs Korpershoek * When device is HCI_INIT, we still need to process 3866eb8c101eSMattijs Korpershoek * the data packets to the driver in order 3867eb8c101eSMattijs Korpershoek * to complete its setup(). 3868eb8c101eSMattijs Korpershoek */ 3869eb8c101eSMattijs Korpershoek if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 3870eb8c101eSMattijs Korpershoek !test_bit(HCI_INIT, &hdev->flags)) { 38711da177e4SLinus Torvalds kfree_skb(skb); 38721da177e4SLinus Torvalds continue; 38731da177e4SLinus Torvalds } 38741da177e4SLinus Torvalds 38751da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 38761da177e4SLinus Torvalds /* Don't process data packets in this states. */ 3877d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 38781da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 38791da177e4SLinus Torvalds case HCI_SCODATA_PKT: 3880cc974003SMarcel Holtmann case HCI_ISODATA_PKT: 38811da177e4SLinus Torvalds kfree_skb(skb); 38821da177e4SLinus Torvalds continue; 38833ff50b79SStephen Hemminger } 38841da177e4SLinus Torvalds } 38851da177e4SLinus Torvalds 38861da177e4SLinus Torvalds /* Process frame */ 3887d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 38881da177e4SLinus Torvalds case HCI_EVENT_PKT: 3889b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 38901da177e4SLinus Torvalds hci_event_packet(hdev, skb); 38911da177e4SLinus Torvalds break; 38921da177e4SLinus Torvalds 38931da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 38941da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 38951da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 38961da177e4SLinus Torvalds break; 38971da177e4SLinus Torvalds 38981da177e4SLinus Torvalds case HCI_SCODATA_PKT: 38991da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 39001da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 39011da177e4SLinus Torvalds break; 39021da177e4SLinus Torvalds 39031da177e4SLinus Torvalds default: 39041da177e4SLinus Torvalds kfree_skb(skb); 39051da177e4SLinus Torvalds break; 39061da177e4SLinus Torvalds } 39071da177e4SLinus Torvalds } 39081da177e4SLinus Torvalds } 39091da177e4SLinus Torvalds 3910c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 39111da177e4SLinus Torvalds { 3912c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 39131da177e4SLinus Torvalds struct sk_buff *skb; 39141da177e4SLinus Torvalds 39152104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 39162104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 39171da177e4SLinus Torvalds 39181da177e4SLinus Torvalds /* Send queued commands */ 39195a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 39205a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 39215a08ecceSAndrei Emeltchenko if (!skb) 39225a08ecceSAndrei Emeltchenko return; 39235a08ecceSAndrei Emeltchenko 39241da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 39251da177e4SLinus Torvalds 3926a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 392770f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 3928f80c5dadSJoão Paulo Rechi Vita if (hci_req_status_pend(hdev)) 3929f80c5dadSJoão Paulo Rechi Vita hci_dev_set_flag(hdev, HCI_CMD_PENDING); 39301da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 393157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 39327bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 393365cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 39347bdb8a5cSSzymon Janc else 393565cc2b49SMarcel Holtmann schedule_delayed_work(&hdev->cmd_timer, 393665cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT); 39371da177e4SLinus Torvalds } else { 39381da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 3939c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 39401da177e4SLinus Torvalds } 39411da177e4SLinus Torvalds } 39421da177e4SLinus Torvalds } 3943