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> 329f30de9eSTamas Koczka #include <linux/kcov.h> 337a0e5b15SMatthias Kaehlcke #include <linux/property.h> 349952d90eSAbhishek Pandit-Subedi #include <linux/suspend.h> 359952d90eSAbhishek Pandit-Subedi #include <linux/wait.h> 3647219839SMarcel Holtmann #include <asm/unaligned.h> 371da177e4SLinus Torvalds 381da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 391da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 404bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h> 41af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h> 421da177e4SLinus Torvalds 430857dd3bSJohan Hedberg #include "hci_request.h" 4460c5f5fbSMarcel Holtmann #include "hci_debugfs.h" 45970c4e46SJohan Hedberg #include "smp.h" 466d5d2ee6SHeiner Kallweit #include "leds.h" 47145373cbSMiao-chen Chou #include "msft.h" 48f67743f9SMarcel Holtmann #include "aosp.h" 498961987fSKiran K #include "hci_codec.h" 50970c4e46SJohan Hedberg 51b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 52c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 533eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds /* HCI device list */ 561da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 571da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds /* HCI callback list */ 601da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 61fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock); 621da177e4SLinus Torvalds 633df92b31SSasha Levin /* HCI ID Numbering */ 643df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 653df92b31SSasha Levin 66a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt) 671da177e4SLinus Torvalds { 681da177e4SLinus Torvalds __u8 scan = opt; 691da177e4SLinus Torvalds 7042c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds /* Inquiry and Page scans */ 7342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 74a1d01db1SJohan Hedberg return 0; 751da177e4SLinus Torvalds } 761da177e4SLinus Torvalds 77a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt) 781da177e4SLinus Torvalds { 791da177e4SLinus Torvalds __u8 auth = opt; 801da177e4SLinus Torvalds 8142c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 821da177e4SLinus Torvalds 831da177e4SLinus Torvalds /* Authentication */ 8442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 85a1d01db1SJohan Hedberg return 0; 861da177e4SLinus Torvalds } 871da177e4SLinus Torvalds 88a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt) 891da177e4SLinus Torvalds { 901da177e4SLinus Torvalds __u8 encrypt = opt; 911da177e4SLinus Torvalds 9242c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 931da177e4SLinus Torvalds 94e4e8e37cSMarcel Holtmann /* Encryption */ 9542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 96a1d01db1SJohan Hedberg return 0; 971da177e4SLinus Torvalds } 981da177e4SLinus Torvalds 99a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt) 100e4e8e37cSMarcel Holtmann { 101e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 102e4e8e37cSMarcel Holtmann 10342c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 104e4e8e37cSMarcel Holtmann 105e4e8e37cSMarcel Holtmann /* Default link policy */ 10642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 107a1d01db1SJohan Hedberg return 0; 108e4e8e37cSMarcel Holtmann } 109e4e8e37cSMarcel Holtmann 1101da177e4SLinus Torvalds /* Get HCI device by index. 1111da177e4SLinus Torvalds * Device is held on return. */ 1121da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 1131da177e4SLinus Torvalds { 1148035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 1151da177e4SLinus Torvalds 1161da177e4SLinus Torvalds BT_DBG("%d", index); 1171da177e4SLinus Torvalds 1181da177e4SLinus Torvalds if (index < 0) 1191da177e4SLinus Torvalds return NULL; 1201da177e4SLinus Torvalds 1211da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 1228035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 1231da177e4SLinus Torvalds if (d->id == index) { 1241da177e4SLinus Torvalds hdev = hci_dev_hold(d); 1251da177e4SLinus Torvalds break; 1261da177e4SLinus Torvalds } 1271da177e4SLinus Torvalds } 1281da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 1291da177e4SLinus Torvalds return hdev; 1301da177e4SLinus Torvalds } 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 133ff9ef578SJohan Hedberg 13430dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 13530dc78e1SJohan Hedberg { 13630dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 13730dc78e1SJohan Hedberg 1386fbe195dSAndre Guedes switch (discov->state) { 139343f935bSAndre Guedes case DISCOVERY_FINDING: 1406fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 14130dc78e1SJohan Hedberg return true; 14230dc78e1SJohan Hedberg 1436fbe195dSAndre Guedes default: 14430dc78e1SJohan Hedberg return false; 14530dc78e1SJohan Hedberg } 1466fbe195dSAndre Guedes } 14730dc78e1SJohan Hedberg 148ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 149ff9ef578SJohan Hedberg { 150bb3e0a33SJohan Hedberg int old_state = hdev->discovery.state; 151bb3e0a33SJohan Hedberg 152ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 153ff9ef578SJohan Hedberg 154bb3e0a33SJohan Hedberg if (old_state == state) 155ff9ef578SJohan Hedberg return; 156ff9ef578SJohan Hedberg 157bb3e0a33SJohan Hedberg hdev->discovery.state = state; 158bb3e0a33SJohan Hedberg 159ff9ef578SJohan Hedberg switch (state) { 160ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 1615bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev); 162c54c3860SAndre Guedes 163bb3e0a33SJohan Hedberg if (old_state != DISCOVERY_STARTING) 164ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 165ff9ef578SJohan Hedberg break; 166ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 167ff9ef578SJohan Hedberg break; 168343f935bSAndre Guedes case DISCOVERY_FINDING: 169ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 170ff9ef578SJohan Hedberg break; 17130dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 17230dc78e1SJohan Hedberg break; 173ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 174ff9ef578SJohan Hedberg break; 175ff9ef578SJohan Hedberg } 176ff9ef578SJohan Hedberg } 177ff9ef578SJohan Hedberg 1781f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 1791da177e4SLinus Torvalds { 18030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 181b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 1821da177e4SLinus Torvalds 183561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 184561aafbcSJohan Hedberg list_del(&p->all); 185b57c1a56SJohan Hedberg kfree(p); 1861da177e4SLinus Torvalds } 187561aafbcSJohan Hedberg 188561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 189561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 1901da177e4SLinus Torvalds } 1911da177e4SLinus Torvalds 192a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 193a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 1941da177e4SLinus Torvalds { 19530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 1961da177e4SLinus Torvalds struct inquiry_entry *e; 1971da177e4SLinus Torvalds 1986ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 1991da177e4SLinus Torvalds 200561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 2011da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 2021da177e4SLinus Torvalds return e; 2031da177e4SLinus Torvalds } 2041da177e4SLinus Torvalds 205b57c1a56SJohan Hedberg return NULL; 206b57c1a56SJohan Hedberg } 207b57c1a56SJohan Hedberg 208561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 209561aafbcSJohan Hedberg bdaddr_t *bdaddr) 210561aafbcSJohan Hedberg { 21130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 212561aafbcSJohan Hedberg struct inquiry_entry *e; 213561aafbcSJohan Hedberg 2146ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 215561aafbcSJohan Hedberg 216561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 217561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 218561aafbcSJohan Hedberg return e; 219561aafbcSJohan Hedberg } 220561aafbcSJohan Hedberg 221561aafbcSJohan Hedberg return NULL; 222561aafbcSJohan Hedberg } 223561aafbcSJohan Hedberg 22430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 22530dc78e1SJohan Hedberg bdaddr_t *bdaddr, 22630dc78e1SJohan Hedberg int state) 22730dc78e1SJohan Hedberg { 22830dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 22930dc78e1SJohan Hedberg struct inquiry_entry *e; 23030dc78e1SJohan Hedberg 2316ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 23230dc78e1SJohan Hedberg 23330dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 23430dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 23530dc78e1SJohan Hedberg return e; 23630dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 23730dc78e1SJohan Hedberg return e; 23830dc78e1SJohan Hedberg } 23930dc78e1SJohan Hedberg 24030dc78e1SJohan Hedberg return NULL; 24130dc78e1SJohan Hedberg } 24230dc78e1SJohan Hedberg 243a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 244a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 245a3d4e20aSJohan Hedberg { 246a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 247a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 248a3d4e20aSJohan Hedberg struct inquiry_entry *p; 249a3d4e20aSJohan Hedberg 250a3d4e20aSJohan Hedberg list_del(&ie->list); 251a3d4e20aSJohan Hedberg 252a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 253a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 254a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 255a3d4e20aSJohan Hedberg break; 256a3d4e20aSJohan Hedberg pos = &p->list; 257a3d4e20aSJohan Hedberg } 258a3d4e20aSJohan Hedberg 259a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 260a3d4e20aSJohan Hedberg } 261a3d4e20aSJohan Hedberg 262af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 263af58925cSMarcel Holtmann bool name_known) 2641da177e4SLinus Torvalds { 26530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 26670f23020SAndrei Emeltchenko struct inquiry_entry *ie; 267af58925cSMarcel Holtmann u32 flags = 0; 2681da177e4SLinus Torvalds 2696ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 2701da177e4SLinus Torvalds 2716928a924SJohan Hedberg hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR); 2722b2fec4dSSzymon Janc 273af58925cSMarcel Holtmann if (!data->ssp_mode) 274af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 275388fc8faSJohan Hedberg 27670f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 277a3d4e20aSJohan Hedberg if (ie) { 278af58925cSMarcel Holtmann if (!ie->data.ssp_mode) 279af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING; 280388fc8faSJohan Hedberg 281a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 282a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 283a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 284a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 285a3d4e20aSJohan Hedberg } 286a3d4e20aSJohan Hedberg 287561aafbcSJohan Hedberg goto update; 288a3d4e20aSJohan Hedberg } 289561aafbcSJohan Hedberg 2901da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 29127f70f3eSJohan Hedberg ie = kzalloc(sizeof(*ie), GFP_KERNEL); 292af58925cSMarcel Holtmann if (!ie) { 293af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 294af58925cSMarcel Holtmann goto done; 295af58925cSMarcel Holtmann } 29670f23020SAndrei Emeltchenko 297561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 298561aafbcSJohan Hedberg 299561aafbcSJohan Hedberg if (name_known) { 300561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 301561aafbcSJohan Hedberg } else { 302561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 303561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 304561aafbcSJohan Hedberg } 305561aafbcSJohan Hedberg 306561aafbcSJohan Hedberg update: 307561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 308561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 309561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 310561aafbcSJohan Hedberg list_del(&ie->list); 3111da177e4SLinus Torvalds } 3121da177e4SLinus Torvalds 31370f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 31470f23020SAndrei Emeltchenko ie->timestamp = jiffies; 3151da177e4SLinus Torvalds cache->timestamp = jiffies; 3163175405bSJohan Hedberg 3173175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 318af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME; 3193175405bSJohan Hedberg 320af58925cSMarcel Holtmann done: 321af58925cSMarcel Holtmann return flags; 3221da177e4SLinus Torvalds } 3231da177e4SLinus Torvalds 3241da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 3251da177e4SLinus Torvalds { 32630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 3271da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 3281da177e4SLinus Torvalds struct inquiry_entry *e; 3291da177e4SLinus Torvalds int copied = 0; 3301da177e4SLinus Torvalds 331561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 3321da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 333b57c1a56SJohan Hedberg 334b57c1a56SJohan Hedberg if (copied >= num) 335b57c1a56SJohan Hedberg break; 336b57c1a56SJohan Hedberg 3371da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 3381da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 3391da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 3401da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 3411da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 3421da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 343b57c1a56SJohan Hedberg 3441da177e4SLinus Torvalds info++; 345b57c1a56SJohan Hedberg copied++; 3461da177e4SLinus Torvalds } 3471da177e4SLinus Torvalds 3481da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 3491da177e4SLinus Torvalds return copied; 3501da177e4SLinus Torvalds } 3511da177e4SLinus Torvalds 352a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt) 3531da177e4SLinus Torvalds { 3541da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 35542c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 3561da177e4SLinus Torvalds struct hci_cp_inquiry cp; 3571da177e4SLinus Torvalds 3581da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 3591da177e4SLinus Torvalds 3601da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 361a1d01db1SJohan Hedberg return 0; 3621da177e4SLinus Torvalds 3631da177e4SLinus Torvalds /* Start Inquiry */ 3641da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 3651da177e4SLinus Torvalds cp.length = ir->length; 3661da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 36742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 368a1d01db1SJohan Hedberg 369a1d01db1SJohan Hedberg return 0; 3701da177e4SLinus Torvalds } 3711da177e4SLinus Torvalds 3721da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 3731da177e4SLinus Torvalds { 3741da177e4SLinus Torvalds __u8 __user *ptr = arg; 3751da177e4SLinus Torvalds struct hci_inquiry_req ir; 3761da177e4SLinus Torvalds struct hci_dev *hdev; 3771da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 3781da177e4SLinus Torvalds long timeo; 3791da177e4SLinus Torvalds __u8 *buf; 3801da177e4SLinus Torvalds 3811da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 3821da177e4SLinus Torvalds return -EFAULT; 3831da177e4SLinus Torvalds 3845a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 3855a08ecceSAndrei Emeltchenko if (!hdev) 3861da177e4SLinus Torvalds return -ENODEV; 3871da177e4SLinus Torvalds 388d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 3890736cfa8SMarcel Holtmann err = -EBUSY; 3900736cfa8SMarcel Holtmann goto done; 3910736cfa8SMarcel Holtmann } 3920736cfa8SMarcel Holtmann 393d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 394fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 395fee746b0SMarcel Holtmann goto done; 396fee746b0SMarcel Holtmann } 397fee746b0SMarcel Holtmann 398ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 3995b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 4005b69bef5SMarcel Holtmann goto done; 4015b69bef5SMarcel Holtmann } 4025b69bef5SMarcel Holtmann 403d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 40456f87901SJohan Hedberg err = -EOPNOTSUPP; 40556f87901SJohan Hedberg goto done; 40656f87901SJohan Hedberg } 40756f87901SJohan Hedberg 408f41a4b2bSPavel Skripkin /* Restrict maximum inquiry length to 60 seconds */ 409f41a4b2bSPavel Skripkin if (ir.length > 60) { 410f41a4b2bSPavel Skripkin err = -EINVAL; 411f41a4b2bSPavel Skripkin goto done; 412f41a4b2bSPavel Skripkin } 413f41a4b2bSPavel Skripkin 41409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4151da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 416a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 4171f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 4181da177e4SLinus Torvalds do_inquiry = 1; 4191da177e4SLinus Torvalds } 42009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 4211da177e4SLinus Torvalds 42204837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 42370f23020SAndrei Emeltchenko 42470f23020SAndrei Emeltchenko if (do_inquiry) { 42501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 4264ebeee2dSJohan Hedberg timeo, NULL); 42770f23020SAndrei Emeltchenko if (err < 0) 4281da177e4SLinus Torvalds goto done; 4293e13fa1eSAndre Guedes 4303e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 4313e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 4323e13fa1eSAndre Guedes */ 43374316201SNeilBrown if (wait_on_bit(&hdev->flags, HCI_INQUIRY, 43428a758c8SPan Bian TASK_INTERRUPTIBLE)) { 43528a758c8SPan Bian err = -EINTR; 43628a758c8SPan Bian goto done; 43728a758c8SPan Bian } 43870f23020SAndrei Emeltchenko } 4391da177e4SLinus Torvalds 4408fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 4418fc9ced3SGustavo Padovan * 255 entries 4428fc9ced3SGustavo Padovan */ 4431da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 4441da177e4SLinus Torvalds 4451da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 4461da177e4SLinus Torvalds * copy it to the user space. 4471da177e4SLinus Torvalds */ 4486da2ec56SKees Cook buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL); 44970f23020SAndrei Emeltchenko if (!buf) { 4501da177e4SLinus Torvalds err = -ENOMEM; 4511da177e4SLinus Torvalds goto done; 4521da177e4SLinus Torvalds } 4531da177e4SLinus Torvalds 45409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 4551da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 45609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 4571da177e4SLinus Torvalds 4581da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 4591da177e4SLinus Torvalds 4601da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 4611da177e4SLinus Torvalds ptr += sizeof(ir); 4621da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 4631da177e4SLinus Torvalds ir.num_rsp)) 4641da177e4SLinus Torvalds err = -EFAULT; 4651da177e4SLinus Torvalds } else 4661da177e4SLinus Torvalds err = -EFAULT; 4671da177e4SLinus Torvalds 4681da177e4SLinus Torvalds kfree(buf); 4691da177e4SLinus Torvalds 4701da177e4SLinus Torvalds done: 4711da177e4SLinus Torvalds hci_dev_put(hdev); 4721da177e4SLinus Torvalds return err; 4731da177e4SLinus Torvalds } 4741da177e4SLinus Torvalds 475cf75ad8bSLuiz Augusto von Dentz static int hci_dev_do_open(struct hci_dev *hdev) 476cf75ad8bSLuiz Augusto von Dentz { 477cf75ad8bSLuiz Augusto von Dentz int ret = 0; 478cf75ad8bSLuiz Augusto von Dentz 479cf75ad8bSLuiz Augusto von Dentz BT_DBG("%s %p", hdev->name, hdev); 480cf75ad8bSLuiz Augusto von Dentz 481cf75ad8bSLuiz Augusto von Dentz hci_req_sync_lock(hdev); 482cf75ad8bSLuiz Augusto von Dentz 483cf75ad8bSLuiz Augusto von Dentz ret = hci_dev_open_sync(hdev); 484cf75ad8bSLuiz Augusto von Dentz 485b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 4861da177e4SLinus Torvalds return ret; 4871da177e4SLinus Torvalds } 4881da177e4SLinus Torvalds 489cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 490cbed0ca1SJohan Hedberg 491cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 492cbed0ca1SJohan Hedberg { 493cbed0ca1SJohan Hedberg struct hci_dev *hdev; 494cbed0ca1SJohan Hedberg int err; 495cbed0ca1SJohan Hedberg 496cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 497cbed0ca1SJohan Hedberg if (!hdev) 498cbed0ca1SJohan Hedberg return -ENODEV; 499cbed0ca1SJohan Hedberg 5004a964404SMarcel Holtmann /* Devices that are marked as unconfigured can only be powered 501fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices 502fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is 503fee746b0SMarcel Holtmann * possible. 504fee746b0SMarcel Holtmann * 505fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag 506fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to 507fee746b0SMarcel Holtmann * open the device. 508fee746b0SMarcel Holtmann */ 509d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && 510d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 511fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 512fee746b0SMarcel Holtmann goto done; 513fee746b0SMarcel Holtmann } 514fee746b0SMarcel Holtmann 515e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 516e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 517e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 518e1d08f40SJohan Hedberg * completed. 519e1d08f40SJohan Hedberg */ 520a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 521e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 522e1d08f40SJohan Hedberg 523a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 524a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 525a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 526a5c8f270SMarcel Holtmann */ 527e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 528e1d08f40SJohan Hedberg 52912aa4f0aSMarcel Holtmann /* For controllers not using the management interface and that 530b6ae8457SJohan Hedberg * are brought up using legacy ioctl, set the HCI_BONDABLE bit 53112aa4f0aSMarcel Holtmann * so that pairing works for them. Once the management interface 53212aa4f0aSMarcel Holtmann * is in use this bit will be cleared again and userspace has 53312aa4f0aSMarcel Holtmann * to explicitly enable it. 53412aa4f0aSMarcel Holtmann */ 535d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 536d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_MGMT)) 537a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BONDABLE); 53812aa4f0aSMarcel Holtmann 539cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 540cbed0ca1SJohan Hedberg 541fee746b0SMarcel Holtmann done: 542cbed0ca1SJohan Hedberg hci_dev_put(hdev); 543cbed0ca1SJohan Hedberg return err; 544cbed0ca1SJohan Hedberg } 545cbed0ca1SJohan Hedberg 546cf75ad8bSLuiz Augusto von Dentz int hci_dev_do_close(struct hci_dev *hdev) 547cf75ad8bSLuiz Augusto von Dentz { 548cf75ad8bSLuiz Augusto von Dentz int err; 549cf75ad8bSLuiz Augusto von Dentz 550cf75ad8bSLuiz Augusto von Dentz BT_DBG("%s %p", hdev->name, hdev); 551cf75ad8bSLuiz Augusto von Dentz 552cf75ad8bSLuiz Augusto von Dentz hci_req_sync_lock(hdev); 553cf75ad8bSLuiz Augusto von Dentz 554cf75ad8bSLuiz Augusto von Dentz err = hci_dev_close_sync(hdev); 555cf75ad8bSLuiz Augusto von Dentz 556b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 5571da177e4SLinus Torvalds 55861969ef8SKangmin Park return err; 5591da177e4SLinus Torvalds } 5601da177e4SLinus Torvalds 5611da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 5621da177e4SLinus Torvalds { 5631da177e4SLinus Torvalds struct hci_dev *hdev; 5641da177e4SLinus Torvalds int err; 5651da177e4SLinus Torvalds 56670f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 56770f23020SAndrei Emeltchenko if (!hdev) 5681da177e4SLinus Torvalds return -ENODEV; 5698ee56540SMarcel Holtmann 570d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 5710736cfa8SMarcel Holtmann err = -EBUSY; 5720736cfa8SMarcel Holtmann goto done; 5730736cfa8SMarcel Holtmann } 5740736cfa8SMarcel Holtmann 575e36bea6eSVasyl Vavrychuk cancel_work_sync(&hdev->power_on); 576a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) 5778ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 5788ee56540SMarcel Holtmann 5791da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 5808ee56540SMarcel Holtmann 5810736cfa8SMarcel Holtmann done: 5821da177e4SLinus Torvalds hci_dev_put(hdev); 5831da177e4SLinus Torvalds return err; 5841da177e4SLinus Torvalds } 5851da177e4SLinus Torvalds 5865c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev) 5871da177e4SLinus Torvalds { 5885c912495SMarcel Holtmann int ret; 5891da177e4SLinus Torvalds 5905c912495SMarcel Holtmann BT_DBG("%s %p", hdev->name, hdev); 5911da177e4SLinus Torvalds 592b504430cSJohan Hedberg hci_req_sync_lock(hdev); 5931da177e4SLinus Torvalds 5941da177e4SLinus Torvalds /* Drop queues */ 5951da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 5961da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 5971da177e4SLinus Torvalds 598877afadaSSchspa Shi /* Cancel these to avoid queueing non-chained pending work */ 599877afadaSSchspa Shi hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE); 600deee93d1STetsuo Handa /* Wait for 601deee93d1STetsuo Handa * 602deee93d1STetsuo Handa * if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) 603deee93d1STetsuo Handa * queue_delayed_work(&hdev->{cmd,ncmd}_timer) 604deee93d1STetsuo Handa * 605deee93d1STetsuo Handa * inside RCU section to see the flag or complete scheduling. 606deee93d1STetsuo Handa */ 607deee93d1STetsuo Handa synchronize_rcu(); 608deee93d1STetsuo Handa /* Explicitly cancel works in case scheduled after setting the flag. */ 609877afadaSSchspa Shi cancel_delayed_work(&hdev->cmd_timer); 610877afadaSSchspa Shi cancel_delayed_work(&hdev->ncmd_timer); 611877afadaSSchspa Shi 61276727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by 61376727c02SJohan Hedberg * ensuring the workqueue is empty up front. 61476727c02SJohan Hedberg */ 61576727c02SJohan Hedberg drain_workqueue(hdev->workqueue); 61676727c02SJohan Hedberg 61709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 6181f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 6191da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 62009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 6211da177e4SLinus Torvalds 6221da177e4SLinus Torvalds if (hdev->flush) 6231da177e4SLinus Torvalds hdev->flush(hdev); 6241da177e4SLinus Torvalds 625877afadaSSchspa Shi hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE); 626877afadaSSchspa Shi 6271da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 62826afbd82SLuiz Augusto von Dentz hdev->acl_cnt = 0; 62926afbd82SLuiz Augusto von Dentz hdev->sco_cnt = 0; 63026afbd82SLuiz Augusto von Dentz hdev->le_cnt = 0; 63126afbd82SLuiz Augusto von Dentz hdev->iso_cnt = 0; 6321da177e4SLinus Torvalds 633d0b13706SLuiz Augusto von Dentz ret = hci_reset_sync(hdev); 6341da177e4SLinus Torvalds 635b504430cSJohan Hedberg hci_req_sync_unlock(hdev); 6361da177e4SLinus Torvalds return ret; 6371da177e4SLinus Torvalds } 6381da177e4SLinus Torvalds 6395c912495SMarcel Holtmann int hci_dev_reset(__u16 dev) 6405c912495SMarcel Holtmann { 6415c912495SMarcel Holtmann struct hci_dev *hdev; 6425c912495SMarcel Holtmann int err; 6435c912495SMarcel Holtmann 6445c912495SMarcel Holtmann hdev = hci_dev_get(dev); 6455c912495SMarcel Holtmann if (!hdev) 6465c912495SMarcel Holtmann return -ENODEV; 6475c912495SMarcel Holtmann 6485c912495SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 6495c912495SMarcel Holtmann err = -ENETDOWN; 6505c912495SMarcel Holtmann goto done; 6515c912495SMarcel Holtmann } 6525c912495SMarcel Holtmann 653d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 6545c912495SMarcel Holtmann err = -EBUSY; 6555c912495SMarcel Holtmann goto done; 6565c912495SMarcel Holtmann } 6575c912495SMarcel Holtmann 658d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 6595c912495SMarcel Holtmann err = -EOPNOTSUPP; 6605c912495SMarcel Holtmann goto done; 6615c912495SMarcel Holtmann } 6625c912495SMarcel Holtmann 6635c912495SMarcel Holtmann err = hci_dev_do_reset(hdev); 6645c912495SMarcel Holtmann 6655c912495SMarcel Holtmann done: 6665c912495SMarcel Holtmann hci_dev_put(hdev); 6675c912495SMarcel Holtmann return err; 6685c912495SMarcel Holtmann } 6695c912495SMarcel Holtmann 6701da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 6711da177e4SLinus Torvalds { 6721da177e4SLinus Torvalds struct hci_dev *hdev; 6731da177e4SLinus Torvalds int ret = 0; 6741da177e4SLinus Torvalds 67570f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 67670f23020SAndrei Emeltchenko if (!hdev) 6771da177e4SLinus Torvalds return -ENODEV; 6781da177e4SLinus Torvalds 679d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 6800736cfa8SMarcel Holtmann ret = -EBUSY; 6810736cfa8SMarcel Holtmann goto done; 6820736cfa8SMarcel Holtmann } 6830736cfa8SMarcel Holtmann 684d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 685fee746b0SMarcel Holtmann ret = -EOPNOTSUPP; 686fee746b0SMarcel Holtmann goto done; 687fee746b0SMarcel Holtmann } 688fee746b0SMarcel Holtmann 6891da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 6901da177e4SLinus Torvalds 6910736cfa8SMarcel Holtmann done: 6921da177e4SLinus Torvalds hci_dev_put(hdev); 6931da177e4SLinus Torvalds return ret; 6941da177e4SLinus Torvalds } 6951da177e4SLinus Torvalds 6965bee2fd6SLuiz Augusto von Dentz static void hci_update_passive_scan_state(struct hci_dev *hdev, u8 scan) 697123abc08SJohan Hedberg { 698bc6d2d04SJohan Hedberg bool conn_changed, discov_changed; 699123abc08SJohan Hedberg 700123abc08SJohan Hedberg BT_DBG("%s scan 0x%02x", hdev->name, scan); 701123abc08SJohan Hedberg 702123abc08SJohan Hedberg if ((scan & SCAN_PAGE)) 703238be788SMarcel Holtmann conn_changed = !hci_dev_test_and_set_flag(hdev, 704238be788SMarcel Holtmann HCI_CONNECTABLE); 705123abc08SJohan Hedberg else 706a69d8927SMarcel Holtmann conn_changed = hci_dev_test_and_clear_flag(hdev, 707a69d8927SMarcel Holtmann HCI_CONNECTABLE); 708123abc08SJohan Hedberg 709bc6d2d04SJohan Hedberg if ((scan & SCAN_INQUIRY)) { 710238be788SMarcel Holtmann discov_changed = !hci_dev_test_and_set_flag(hdev, 711238be788SMarcel Holtmann HCI_DISCOVERABLE); 712bc6d2d04SJohan Hedberg } else { 713a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); 714a69d8927SMarcel Holtmann discov_changed = hci_dev_test_and_clear_flag(hdev, 715a69d8927SMarcel Holtmann HCI_DISCOVERABLE); 716bc6d2d04SJohan Hedberg } 717bc6d2d04SJohan Hedberg 718d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 719123abc08SJohan Hedberg return; 720123abc08SJohan Hedberg 721bc6d2d04SJohan Hedberg if (conn_changed || discov_changed) { 722bc6d2d04SJohan Hedberg /* In case this was disabled through mgmt */ 723a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 724bc6d2d04SJohan Hedberg 725d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 726651cd3d6SBrian Gix hci_update_adv_data(hdev, hdev->cur_adv_instance); 727bc6d2d04SJohan Hedberg 728123abc08SJohan Hedberg mgmt_new_settings(hdev); 729123abc08SJohan Hedberg } 730bc6d2d04SJohan Hedberg } 731123abc08SJohan Hedberg 7321da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 7331da177e4SLinus Torvalds { 7341da177e4SLinus Torvalds struct hci_dev *hdev; 7351da177e4SLinus Torvalds struct hci_dev_req dr; 7361da177e4SLinus Torvalds int err = 0; 7371da177e4SLinus Torvalds 7381da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 7391da177e4SLinus Torvalds return -EFAULT; 7401da177e4SLinus Torvalds 74170f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 74270f23020SAndrei Emeltchenko if (!hdev) 7431da177e4SLinus Torvalds return -ENODEV; 7441da177e4SLinus Torvalds 745d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 7460736cfa8SMarcel Holtmann err = -EBUSY; 7470736cfa8SMarcel Holtmann goto done; 7480736cfa8SMarcel Holtmann } 7490736cfa8SMarcel Holtmann 750d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { 751fee746b0SMarcel Holtmann err = -EOPNOTSUPP; 752fee746b0SMarcel Holtmann goto done; 753fee746b0SMarcel Holtmann } 754fee746b0SMarcel Holtmann 755ca8bee5dSMarcel Holtmann if (hdev->dev_type != HCI_PRIMARY) { 7565b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 7575b69bef5SMarcel Holtmann goto done; 7585b69bef5SMarcel Holtmann } 7595b69bef5SMarcel Holtmann 760d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { 76156f87901SJohan Hedberg err = -EOPNOTSUPP; 76256f87901SJohan Hedberg goto done; 76356f87901SJohan Hedberg } 76456f87901SJohan Hedberg 7651da177e4SLinus Torvalds switch (cmd) { 7661da177e4SLinus Torvalds case HCISETAUTH: 76701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 7684ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 7691da177e4SLinus Torvalds break; 7701da177e4SLinus Torvalds 7711da177e4SLinus Torvalds case HCISETENCRYPT: 7721da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 7731da177e4SLinus Torvalds err = -EOPNOTSUPP; 7741da177e4SLinus Torvalds break; 7751da177e4SLinus Torvalds } 7761da177e4SLinus Torvalds 7771da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 7781da177e4SLinus Torvalds /* Auth must be enabled first */ 77901178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 7804ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 7811da177e4SLinus Torvalds if (err) 7821da177e4SLinus Torvalds break; 7831da177e4SLinus Torvalds } 7841da177e4SLinus Torvalds 78501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 7864ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 7871da177e4SLinus Torvalds break; 7881da177e4SLinus Torvalds 7891da177e4SLinus Torvalds case HCISETSCAN: 79001178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 7914ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 79291a668b0SJohan Hedberg 793bc6d2d04SJohan Hedberg /* Ensure that the connectable and discoverable states 794bc6d2d04SJohan Hedberg * get correctly modified as this was a non-mgmt change. 79591a668b0SJohan Hedberg */ 796123abc08SJohan Hedberg if (!err) 7975bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan_state(hdev, dr.dev_opt); 7981da177e4SLinus Torvalds break; 7991da177e4SLinus Torvalds 8001da177e4SLinus Torvalds case HCISETLINKPOL: 80101178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 8024ebeee2dSJohan Hedberg HCI_INIT_TIMEOUT, NULL); 8031da177e4SLinus Torvalds break; 8041da177e4SLinus Torvalds 8051da177e4SLinus Torvalds case HCISETLINKMODE: 806e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 807e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 808e4e8e37cSMarcel Holtmann break; 809e4e8e37cSMarcel Holtmann 810e4e8e37cSMarcel Holtmann case HCISETPTYPE: 811b7c23df8SJaganath Kanakkassery if (hdev->pkt_type == (__u16) dr.dev_opt) 812b7c23df8SJaganath Kanakkassery break; 813b7c23df8SJaganath Kanakkassery 814e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 815b7c23df8SJaganath Kanakkassery mgmt_phy_configuration_changed(hdev, NULL); 8161da177e4SLinus Torvalds break; 8171da177e4SLinus Torvalds 8181da177e4SLinus Torvalds case HCISETACLMTU: 8191da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 8201da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 8211da177e4SLinus Torvalds break; 8221da177e4SLinus Torvalds 8231da177e4SLinus Torvalds case HCISETSCOMTU: 8241da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 8251da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 8261da177e4SLinus Torvalds break; 8271da177e4SLinus Torvalds 8281da177e4SLinus Torvalds default: 8291da177e4SLinus Torvalds err = -EINVAL; 8301da177e4SLinus Torvalds break; 8311da177e4SLinus Torvalds } 832e4e8e37cSMarcel Holtmann 8330736cfa8SMarcel Holtmann done: 8341da177e4SLinus Torvalds hci_dev_put(hdev); 8351da177e4SLinus Torvalds return err; 8361da177e4SLinus Torvalds } 8371da177e4SLinus Torvalds 8381da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 8391da177e4SLinus Torvalds { 8408035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 8411da177e4SLinus Torvalds struct hci_dev_list_req *dl; 8421da177e4SLinus Torvalds struct hci_dev_req *dr; 8431da177e4SLinus Torvalds int n = 0, size, err; 8441da177e4SLinus Torvalds __u16 dev_num; 8451da177e4SLinus Torvalds 8461da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 8471da177e4SLinus Torvalds return -EFAULT; 8481da177e4SLinus Torvalds 8491da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 8501da177e4SLinus Torvalds return -EINVAL; 8511da177e4SLinus Torvalds 8521da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 8531da177e4SLinus Torvalds 85470f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 85570f23020SAndrei Emeltchenko if (!dl) 8561da177e4SLinus Torvalds return -ENOMEM; 8571da177e4SLinus Torvalds 8581da177e4SLinus Torvalds dr = dl->dev_req; 8591da177e4SLinus Torvalds 860f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 8618035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 8622e84d8dbSMarcel Holtmann unsigned long flags = hdev->flags; 863c542a06cSJohan Hedberg 8642e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 8652e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 8662e84d8dbSMarcel Holtmann * device is actually down. 8672e84d8dbSMarcel Holtmann */ 868d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 8692e84d8dbSMarcel Holtmann flags &= ~BIT(HCI_UP); 870c542a06cSJohan Hedberg 8711da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 8722e84d8dbSMarcel Holtmann (dr + n)->dev_opt = flags; 873c542a06cSJohan Hedberg 8741da177e4SLinus Torvalds if (++n >= dev_num) 8751da177e4SLinus Torvalds break; 8761da177e4SLinus Torvalds } 877f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 8781da177e4SLinus Torvalds 8791da177e4SLinus Torvalds dl->dev_num = n; 8801da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 8811da177e4SLinus Torvalds 8821da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 8831da177e4SLinus Torvalds kfree(dl); 8841da177e4SLinus Torvalds 8851da177e4SLinus Torvalds return err ? -EFAULT : 0; 8861da177e4SLinus Torvalds } 8871da177e4SLinus Torvalds 8881da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 8891da177e4SLinus Torvalds { 8901da177e4SLinus Torvalds struct hci_dev *hdev; 8911da177e4SLinus Torvalds struct hci_dev_info di; 8922e84d8dbSMarcel Holtmann unsigned long flags; 8931da177e4SLinus Torvalds int err = 0; 8941da177e4SLinus Torvalds 8951da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 8961da177e4SLinus Torvalds return -EFAULT; 8971da177e4SLinus Torvalds 89870f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 89970f23020SAndrei Emeltchenko if (!hdev) 9001da177e4SLinus Torvalds return -ENODEV; 9011da177e4SLinus Torvalds 9022e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport 9032e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the 9042e84d8dbSMarcel Holtmann * device is actually down. 9052e84d8dbSMarcel Holtmann */ 906d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) 9072e84d8dbSMarcel Holtmann flags = hdev->flags & ~BIT(HCI_UP); 9082e84d8dbSMarcel Holtmann else 9092e84d8dbSMarcel Holtmann flags = hdev->flags; 910c542a06cSJohan Hedberg 9111da177e4SLinus Torvalds strcpy(di.name, hdev->name); 9121da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 91360f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 9142e84d8dbSMarcel Holtmann di.flags = flags; 9151da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 916572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 9171da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 9181da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 9191da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 9201da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 921572c7f84SJohan Hedberg } else { 922572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 923572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 924572c7f84SJohan Hedberg di.sco_mtu = 0; 925572c7f84SJohan Hedberg di.sco_pkts = 0; 926572c7f84SJohan Hedberg } 9271da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 9281da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 9291da177e4SLinus Torvalds 9301da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 9311da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 9321da177e4SLinus Torvalds 9331da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 9341da177e4SLinus Torvalds err = -EFAULT; 9351da177e4SLinus Torvalds 9361da177e4SLinus Torvalds hci_dev_put(hdev); 9371da177e4SLinus Torvalds 9381da177e4SLinus Torvalds return err; 9391da177e4SLinus Torvalds } 9401da177e4SLinus Torvalds 9411da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 9421da177e4SLinus Torvalds 943611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 944611b30f7SMarcel Holtmann { 945611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 946611b30f7SMarcel Holtmann 947611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 948611b30f7SMarcel Holtmann 949d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) 9500736cfa8SMarcel Holtmann return -EBUSY; 9510736cfa8SMarcel Holtmann 9525e130367SJohan Hedberg if (blocked) { 953a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 954d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) && 955d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) 956611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 9575e130367SJohan Hedberg } else { 958a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_RFKILLED); 9595e130367SJohan Hedberg } 960611b30f7SMarcel Holtmann 961611b30f7SMarcel Holtmann return 0; 962611b30f7SMarcel Holtmann } 963611b30f7SMarcel Holtmann 964611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 965611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 966611b30f7SMarcel Holtmann }; 967611b30f7SMarcel Holtmann 968ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 969ab81cbf9SJohan Hedberg { 970ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 97196570ffcSJohan Hedberg int err; 972ab81cbf9SJohan Hedberg 973ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 974ab81cbf9SJohan Hedberg 9752ff13894SJohan Hedberg if (test_bit(HCI_UP, &hdev->flags) && 9762ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) && 9772ff13894SJohan Hedberg hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) { 978d82142a8SWei-Ning Huang cancel_delayed_work(&hdev->power_off); 979cf75ad8bSLuiz Augusto von Dentz err = hci_powered_update_sync(hdev); 9802ff13894SJohan Hedberg mgmt_power_on(hdev, err); 9812ff13894SJohan Hedberg return; 9822ff13894SJohan Hedberg } 9832ff13894SJohan Hedberg 984cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 98596570ffcSJohan Hedberg if (err < 0) { 9863ad67582SJaganath Kanakkassery hci_dev_lock(hdev); 98796570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 9883ad67582SJaganath Kanakkassery hci_dev_unlock(hdev); 989ab81cbf9SJohan Hedberg return; 99096570ffcSJohan Hedberg } 991ab81cbf9SJohan Hedberg 992a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 993a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 994a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 995a5c8f270SMarcel Holtmann */ 996d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED) || 997d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_UNCONFIGURED) || 998ca8bee5dSMarcel Holtmann (hdev->dev_type == HCI_PRIMARY && 999a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1000a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 1001a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_AUTO_OFF); 1002bf543036SJohan Hedberg hci_dev_do_close(hdev); 1003d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) { 100419202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 100519202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 1006bf543036SJohan Hedberg } 1007ab81cbf9SJohan Hedberg 1008a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) { 10094a964404SMarcel Holtmann /* For unconfigured devices, set the HCI_RAW flag 10104a964404SMarcel Holtmann * so that userspace can easily identify them. 10114a964404SMarcel Holtmann */ 1012d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 10134a964404SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 10140602a8adSMarcel Holtmann 10150602a8adSMarcel Holtmann /* For fully configured devices, this will send 10160602a8adSMarcel Holtmann * the Index Added event. For unconfigured devices, 10170602a8adSMarcel Holtmann * it will send Unconfigued Index Added event. 10180602a8adSMarcel Holtmann * 10190602a8adSMarcel Holtmann * Devices with HCI_QUIRK_RAW_DEVICE are ignored 10200602a8adSMarcel Holtmann * and no event will be send. 10210602a8adSMarcel Holtmann */ 1022744cf19eSJohan Hedberg mgmt_index_added(hdev); 1023a69d8927SMarcel Holtmann } else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) { 10245ea234d3SMarcel Holtmann /* When the controller is now configured, then it 10255ea234d3SMarcel Holtmann * is important to clear the HCI_RAW flag. 10265ea234d3SMarcel Holtmann */ 1027d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 10285ea234d3SMarcel Holtmann clear_bit(HCI_RAW, &hdev->flags); 10295ea234d3SMarcel Holtmann 1030d603b76bSMarcel Holtmann /* Powering on the controller with HCI_CONFIG set only 1031d603b76bSMarcel Holtmann * happens with the transition from unconfigured to 1032d603b76bSMarcel Holtmann * configured. This will send the Index Added event. 1033d603b76bSMarcel Holtmann */ 1034d603b76bSMarcel Holtmann mgmt_index_added(hdev); 1035ab81cbf9SJohan Hedberg } 1036ab81cbf9SJohan Hedberg } 1037ab81cbf9SJohan Hedberg 1038ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1039ab81cbf9SJohan Hedberg { 10403243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 10413243553fSJohan Hedberg power_off.work); 1042ab81cbf9SJohan Hedberg 1043ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1044ab81cbf9SJohan Hedberg 10458ee56540SMarcel Holtmann hci_dev_do_close(hdev); 1046ab81cbf9SJohan Hedberg } 1047ab81cbf9SJohan Hedberg 1048c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work) 1049c7741d16SMarcel Holtmann { 1050c7741d16SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset); 1051c7741d16SMarcel Holtmann 1052c7741d16SMarcel Holtmann BT_DBG("%s", hdev->name); 1053c7741d16SMarcel Holtmann 1054c7741d16SMarcel Holtmann if (hdev->hw_error) 1055c7741d16SMarcel Holtmann hdev->hw_error(hdev, hdev->hw_error_code); 1056c7741d16SMarcel Holtmann else 10572064ee33SMarcel Holtmann bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code); 1058c7741d16SMarcel Holtmann 1059c7741d16SMarcel Holtmann if (hci_dev_do_close(hdev)) 1060c7741d16SMarcel Holtmann return; 1061c7741d16SMarcel Holtmann 1062c7741d16SMarcel Holtmann hci_dev_do_open(hdev); 1063c7741d16SMarcel Holtmann } 1064c7741d16SMarcel Holtmann 106535f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev) 10662aeb9a1aSJohan Hedberg { 10674821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 10682aeb9a1aSJohan Hedberg 10694821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 10704821002cSJohan Hedberg list_del(&uuid->list); 10712aeb9a1aSJohan Hedberg kfree(uuid); 10722aeb9a1aSJohan Hedberg } 10732aeb9a1aSJohan Hedberg } 10742aeb9a1aSJohan Hedberg 107535f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev) 107655ed8ca1SJohan Hedberg { 10773673952cSMin Li struct link_key *key, *tmp; 107855ed8ca1SJohan Hedberg 10793673952cSMin Li list_for_each_entry_safe(key, tmp, &hdev->link_keys, list) { 10800378b597SJohan Hedberg list_del_rcu(&key->list); 10810378b597SJohan Hedberg kfree_rcu(key, rcu); 108255ed8ca1SJohan Hedberg } 108355ed8ca1SJohan Hedberg } 108455ed8ca1SJohan Hedberg 108535f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev) 1086b899efafSVinicius Costa Gomes { 10873673952cSMin Li struct smp_ltk *k, *tmp; 1088b899efafSVinicius Costa Gomes 10893673952cSMin Li list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1090970d0f1bSJohan Hedberg list_del_rcu(&k->list); 1091970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 1092b899efafSVinicius Costa Gomes } 1093b899efafSVinicius Costa Gomes } 1094b899efafSVinicius Costa Gomes 1095970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev) 1096970c4e46SJohan Hedberg { 10973673952cSMin Li struct smp_irk *k, *tmp; 1098970c4e46SJohan Hedberg 10993673952cSMin Li list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { 1100adae20cbSJohan Hedberg list_del_rcu(&k->list); 1101adae20cbSJohan Hedberg kfree_rcu(k, rcu); 1102970c4e46SJohan Hedberg } 1103970c4e46SJohan Hedberg } 1104970c4e46SJohan Hedberg 1105600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev) 1106600a8749SAlain Michaud { 11073673952cSMin Li struct blocked_key *b, *tmp; 1108600a8749SAlain Michaud 11093673952cSMin Li list_for_each_entry_safe(b, tmp, &hdev->blocked_keys, list) { 1110600a8749SAlain Michaud list_del_rcu(&b->list); 1111600a8749SAlain Michaud kfree_rcu(b, rcu); 1112600a8749SAlain Michaud } 1113600a8749SAlain Michaud } 1114600a8749SAlain Michaud 1115600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16]) 1116600a8749SAlain Michaud { 1117600a8749SAlain Michaud bool blocked = false; 1118600a8749SAlain Michaud struct blocked_key *b; 1119600a8749SAlain Michaud 1120600a8749SAlain Michaud rcu_read_lock(); 11210c2ac7d4SMadhuparna Bhowmik list_for_each_entry_rcu(b, &hdev->blocked_keys, list) { 1122600a8749SAlain Michaud if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) { 1123600a8749SAlain Michaud blocked = true; 1124600a8749SAlain Michaud break; 1125600a8749SAlain Michaud } 1126600a8749SAlain Michaud } 1127600a8749SAlain Michaud 1128600a8749SAlain Michaud rcu_read_unlock(); 1129600a8749SAlain Michaud return blocked; 1130600a8749SAlain Michaud } 1131600a8749SAlain Michaud 113255ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 113355ed8ca1SJohan Hedberg { 113455ed8ca1SJohan Hedberg struct link_key *k; 113555ed8ca1SJohan Hedberg 11360378b597SJohan Hedberg rcu_read_lock(); 11370378b597SJohan Hedberg list_for_each_entry_rcu(k, &hdev->link_keys, list) { 11380378b597SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) { 11390378b597SJohan Hedberg rcu_read_unlock(); 1140600a8749SAlain Michaud 1141600a8749SAlain Michaud if (hci_is_blocked_key(hdev, 1142600a8749SAlain Michaud HCI_BLOCKED_KEY_TYPE_LINKKEY, 1143600a8749SAlain Michaud k->val)) { 1144600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, 1145600a8749SAlain Michaud "Link key blocked for %pMR", 1146600a8749SAlain Michaud &k->bdaddr); 1147600a8749SAlain Michaud return NULL; 1148600a8749SAlain Michaud } 1149600a8749SAlain Michaud 115055ed8ca1SJohan Hedberg return k; 11510378b597SJohan Hedberg } 11520378b597SJohan Hedberg } 11530378b597SJohan Hedberg rcu_read_unlock(); 115455ed8ca1SJohan Hedberg 115555ed8ca1SJohan Hedberg return NULL; 115655ed8ca1SJohan Hedberg } 115755ed8ca1SJohan Hedberg 1158745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 1159d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 1160d25e28abSJohan Hedberg { 1161d25e28abSJohan Hedberg /* Legacy key */ 1162d25e28abSJohan Hedberg if (key_type < 0x03) 1163745c0ce3SVishal Agarwal return true; 1164d25e28abSJohan Hedberg 1165d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 1166d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 1167745c0ce3SVishal Agarwal return false; 1168d25e28abSJohan Hedberg 1169d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 1170d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 1171745c0ce3SVishal Agarwal return false; 1172d25e28abSJohan Hedberg 1173d25e28abSJohan Hedberg /* Security mode 3 case */ 1174d25e28abSJohan Hedberg if (!conn) 1175745c0ce3SVishal Agarwal return true; 1176d25e28abSJohan Hedberg 1177e3befab9SJohan Hedberg /* BR/EDR key derived using SC from an LE link */ 1178e3befab9SJohan Hedberg if (conn->type == LE_LINK) 1179e3befab9SJohan Hedberg return true; 1180e3befab9SJohan Hedberg 1181d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 1182d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 1183745c0ce3SVishal Agarwal return true; 1184d25e28abSJohan Hedberg 1185d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 1186d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 1187745c0ce3SVishal Agarwal return true; 1188d25e28abSJohan Hedberg 1189d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 1190d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 1191745c0ce3SVishal Agarwal return true; 1192d25e28abSJohan Hedberg 1193d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 1194d25e28abSJohan Hedberg * persistently */ 1195745c0ce3SVishal Agarwal return false; 1196d25e28abSJohan Hedberg } 1197d25e28abSJohan Hedberg 1198e804d25dSJohan Hedberg static u8 ltk_role(u8 type) 119998a0b845SJohan Hedberg { 1200e804d25dSJohan Hedberg if (type == SMP_LTK) 1201e804d25dSJohan Hedberg return HCI_ROLE_MASTER; 120298a0b845SJohan Hedberg 1203e804d25dSJohan Hedberg return HCI_ROLE_SLAVE; 120498a0b845SJohan Hedberg } 120598a0b845SJohan Hedberg 1206f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 1207e804d25dSJohan Hedberg u8 addr_type, u8 role) 120875d262c2SVinicius Costa Gomes { 1209c9839a11SVinicius Costa Gomes struct smp_ltk *k; 121075d262c2SVinicius Costa Gomes 1211970d0f1bSJohan Hedberg rcu_read_lock(); 1212970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 12135378bc56SJohan Hedberg if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr)) 12145378bc56SJohan Hedberg continue; 12155378bc56SJohan Hedberg 1216923e2414SJohan Hedberg if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) { 1217970d0f1bSJohan Hedberg rcu_read_unlock(); 1218600a8749SAlain Michaud 1219600a8749SAlain Michaud if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK, 1220600a8749SAlain Michaud k->val)) { 1221600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, 1222600a8749SAlain Michaud "LTK blocked for %pMR", 1223600a8749SAlain Michaud &k->bdaddr); 1224600a8749SAlain Michaud return NULL; 1225600a8749SAlain Michaud } 1226600a8749SAlain Michaud 122775d262c2SVinicius Costa Gomes return k; 1228970d0f1bSJohan Hedberg } 1229970d0f1bSJohan Hedberg } 1230970d0f1bSJohan Hedberg rcu_read_unlock(); 123175d262c2SVinicius Costa Gomes 123275d262c2SVinicius Costa Gomes return NULL; 123375d262c2SVinicius Costa Gomes } 123475d262c2SVinicius Costa Gomes 1235970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) 1236970c4e46SJohan Hedberg { 1237600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL; 1238970c4e46SJohan Hedberg struct smp_irk *irk; 1239970c4e46SJohan Hedberg 1240adae20cbSJohan Hedberg rcu_read_lock(); 1241adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 1242adae20cbSJohan Hedberg if (!bacmp(&irk->rpa, rpa)) { 1243600a8749SAlain Michaud irk_to_return = irk; 1244600a8749SAlain Michaud goto done; 1245970c4e46SJohan Hedberg } 1246adae20cbSJohan Hedberg } 1247970c4e46SJohan Hedberg 1248adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 1249defce9e8SJohan Hedberg if (smp_irk_matches(hdev, irk->val, rpa)) { 1250970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 1251600a8749SAlain Michaud irk_to_return = irk; 1252600a8749SAlain Michaud goto done; 1253970c4e46SJohan Hedberg } 1254970c4e46SJohan Hedberg } 1255600a8749SAlain Michaud 1256600a8749SAlain Michaud done: 1257600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK, 1258600a8749SAlain Michaud irk_to_return->val)) { 1259600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR", 1260600a8749SAlain Michaud &irk_to_return->bdaddr); 1261600a8749SAlain Michaud irk_to_return = NULL; 1262600a8749SAlain Michaud } 1263600a8749SAlain Michaud 1264adae20cbSJohan Hedberg rcu_read_unlock(); 1265970c4e46SJohan Hedberg 1266600a8749SAlain Michaud return irk_to_return; 1267970c4e46SJohan Hedberg } 1268970c4e46SJohan Hedberg 1269970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1270970c4e46SJohan Hedberg u8 addr_type) 1271970c4e46SJohan Hedberg { 1272600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL; 1273970c4e46SJohan Hedberg struct smp_irk *irk; 1274970c4e46SJohan Hedberg 12756cfc9988SJohan Hedberg /* Identity Address must be public or static random */ 12766cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) 12776cfc9988SJohan Hedberg return NULL; 12786cfc9988SJohan Hedberg 1279adae20cbSJohan Hedberg rcu_read_lock(); 1280adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { 1281970c4e46SJohan Hedberg if (addr_type == irk->addr_type && 1282adae20cbSJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) { 1283600a8749SAlain Michaud irk_to_return = irk; 1284600a8749SAlain Michaud goto done; 1285970c4e46SJohan Hedberg } 1286adae20cbSJohan Hedberg } 1287600a8749SAlain Michaud 1288600a8749SAlain Michaud done: 1289600a8749SAlain Michaud 1290600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK, 1291600a8749SAlain Michaud irk_to_return->val)) { 1292600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR", 1293600a8749SAlain Michaud &irk_to_return->bdaddr); 1294600a8749SAlain Michaud irk_to_return = NULL; 1295600a8749SAlain Michaud } 1296600a8749SAlain Michaud 1297adae20cbSJohan Hedberg rcu_read_unlock(); 1298970c4e46SJohan Hedberg 1299600a8749SAlain Michaud return irk_to_return; 1300970c4e46SJohan Hedberg } 1301970c4e46SJohan Hedberg 1302567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 13037652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 13047652ff6aSJohan Hedberg u8 pin_len, bool *persistent) 130555ed8ca1SJohan Hedberg { 130655ed8ca1SJohan Hedberg struct link_key *key, *old_key; 1307745c0ce3SVishal Agarwal u8 old_key_type; 130855ed8ca1SJohan Hedberg 130955ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 131055ed8ca1SJohan Hedberg if (old_key) { 131155ed8ca1SJohan Hedberg old_key_type = old_key->type; 131255ed8ca1SJohan Hedberg key = old_key; 131355ed8ca1SJohan Hedberg } else { 131412adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 13150a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 131655ed8ca1SJohan Hedberg if (!key) 1317567fa2aaSJohan Hedberg return NULL; 13180378b597SJohan Hedberg list_add_rcu(&key->list, &hdev->link_keys); 131955ed8ca1SJohan Hedberg } 132055ed8ca1SJohan Hedberg 13216ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 132255ed8ca1SJohan Hedberg 1323d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1324d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1325d25e28abSJohan Hedberg * previous key */ 1326d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1327a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 1328d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1329655fe6ecSJohan Hedberg if (conn) 1330655fe6ecSJohan Hedberg conn->key_type = type; 1331655fe6ecSJohan Hedberg } 1332d25e28abSJohan Hedberg 133355ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 13349b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 133555ed8ca1SJohan Hedberg key->pin_len = pin_len; 133655ed8ca1SJohan Hedberg 1337b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 133855ed8ca1SJohan Hedberg key->type = old_key_type; 13394748fed2SJohan Hedberg else 13404748fed2SJohan Hedberg key->type = type; 13414748fed2SJohan Hedberg 13427652ff6aSJohan Hedberg if (persistent) 13437652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type, 13447652ff6aSJohan Hedberg old_key_type); 13454df378a1SJohan Hedberg 1346567fa2aaSJohan Hedberg return key; 134755ed8ca1SJohan Hedberg } 134855ed8ca1SJohan Hedberg 1349ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 135035d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 1351fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand) 135275d262c2SVinicius Costa Gomes { 1353c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 1354e804d25dSJohan Hedberg u8 role = ltk_role(type); 135575d262c2SVinicius Costa Gomes 1356f3a73d97SJohan Hedberg old_key = hci_find_ltk(hdev, bdaddr, addr_type, role); 1357c9839a11SVinicius Costa Gomes if (old_key) 135875d262c2SVinicius Costa Gomes key = old_key; 1359c9839a11SVinicius Costa Gomes else { 13600a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL); 136175d262c2SVinicius Costa Gomes if (!key) 1362ca9142b8SJohan Hedberg return NULL; 1363970d0f1bSJohan Hedberg list_add_rcu(&key->list, &hdev->long_term_keys); 136475d262c2SVinicius Costa Gomes } 136575d262c2SVinicius Costa Gomes 136675d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 1367c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 1368c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 1369c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 1370c9839a11SVinicius Costa Gomes key->ediv = ediv; 1371fe39c7b2SMarcel Holtmann key->rand = rand; 1372c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 1373c9839a11SVinicius Costa Gomes key->type = type; 137475d262c2SVinicius Costa Gomes 1375ca9142b8SJohan Hedberg return key; 137675d262c2SVinicius Costa Gomes } 137775d262c2SVinicius Costa Gomes 1378ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 1379ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa) 1380970c4e46SJohan Hedberg { 1381970c4e46SJohan Hedberg struct smp_irk *irk; 1382970c4e46SJohan Hedberg 1383970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); 1384970c4e46SJohan Hedberg if (!irk) { 1385970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL); 1386970c4e46SJohan Hedberg if (!irk) 1387ca9142b8SJohan Hedberg return NULL; 1388970c4e46SJohan Hedberg 1389970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr); 1390970c4e46SJohan Hedberg irk->addr_type = addr_type; 1391970c4e46SJohan Hedberg 1392adae20cbSJohan Hedberg list_add_rcu(&irk->list, &hdev->identity_resolving_keys); 1393970c4e46SJohan Hedberg } 1394970c4e46SJohan Hedberg 1395970c4e46SJohan Hedberg memcpy(irk->val, val, 16); 1396970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa); 1397970c4e46SJohan Hedberg 1398ca9142b8SJohan Hedberg return irk; 1399970c4e46SJohan Hedberg } 1400970c4e46SJohan Hedberg 140155ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 140255ed8ca1SJohan Hedberg { 140355ed8ca1SJohan Hedberg struct link_key *key; 140455ed8ca1SJohan Hedberg 140555ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 140655ed8ca1SJohan Hedberg if (!key) 140755ed8ca1SJohan Hedberg return -ENOENT; 140855ed8ca1SJohan Hedberg 14096ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 141055ed8ca1SJohan Hedberg 14110378b597SJohan Hedberg list_del_rcu(&key->list); 14120378b597SJohan Hedberg kfree_rcu(key, rcu); 141355ed8ca1SJohan Hedberg 141455ed8ca1SJohan Hedberg return 0; 141555ed8ca1SJohan Hedberg } 141655ed8ca1SJohan Hedberg 1417e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) 1418b899efafSVinicius Costa Gomes { 1419c5d2b6faSLuiz Augusto von Dentz struct smp_ltk *k, *tmp; 1420c51ffa0bSJohan Hedberg int removed = 0; 1421b899efafSVinicius Costa Gomes 1422c5d2b6faSLuiz Augusto von Dentz list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1423e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) 1424b899efafSVinicius Costa Gomes continue; 1425b899efafSVinicius Costa Gomes 14266ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 1427b899efafSVinicius Costa Gomes 1428970d0f1bSJohan Hedberg list_del_rcu(&k->list); 1429970d0f1bSJohan Hedberg kfree_rcu(k, rcu); 1430c51ffa0bSJohan Hedberg removed++; 1431b899efafSVinicius Costa Gomes } 1432b899efafSVinicius Costa Gomes 1433c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT; 1434b899efafSVinicius Costa Gomes } 1435b899efafSVinicius Costa Gomes 1436a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) 1437a7ec7338SJohan Hedberg { 1438c5d2b6faSLuiz Augusto von Dentz struct smp_irk *k, *tmp; 1439a7ec7338SJohan Hedberg 1440c5d2b6faSLuiz Augusto von Dentz list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { 1441a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) 1442a7ec7338SJohan Hedberg continue; 1443a7ec7338SJohan Hedberg 1444a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr); 1445a7ec7338SJohan Hedberg 1446adae20cbSJohan Hedberg list_del_rcu(&k->list); 1447adae20cbSJohan Hedberg kfree_rcu(k, rcu); 1448a7ec7338SJohan Hedberg } 1449a7ec7338SJohan Hedberg } 1450a7ec7338SJohan Hedberg 145155e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 145255e76b38SJohan Hedberg { 145355e76b38SJohan Hedberg struct smp_ltk *k; 14544ba9faf3SJohan Hedberg struct smp_irk *irk; 145555e76b38SJohan Hedberg u8 addr_type; 145655e76b38SJohan Hedberg 145755e76b38SJohan Hedberg if (type == BDADDR_BREDR) { 145855e76b38SJohan Hedberg if (hci_find_link_key(hdev, bdaddr)) 145955e76b38SJohan Hedberg return true; 146055e76b38SJohan Hedberg return false; 146155e76b38SJohan Hedberg } 146255e76b38SJohan Hedberg 146355e76b38SJohan Hedberg /* Convert to HCI addr type which struct smp_ltk uses */ 146455e76b38SJohan Hedberg if (type == BDADDR_LE_PUBLIC) 146555e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_PUBLIC; 146655e76b38SJohan Hedberg else 146755e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_RANDOM; 146855e76b38SJohan Hedberg 14694ba9faf3SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, addr_type); 14704ba9faf3SJohan Hedberg if (irk) { 14714ba9faf3SJohan Hedberg bdaddr = &irk->bdaddr; 14724ba9faf3SJohan Hedberg addr_type = irk->addr_type; 14734ba9faf3SJohan Hedberg } 14744ba9faf3SJohan Hedberg 147555e76b38SJohan Hedberg rcu_read_lock(); 147655e76b38SJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { 147787c8b28dSJohan Hedberg if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) { 147887c8b28dSJohan Hedberg rcu_read_unlock(); 147955e76b38SJohan Hedberg return true; 148055e76b38SJohan Hedberg } 148187c8b28dSJohan Hedberg } 148255e76b38SJohan Hedberg rcu_read_unlock(); 148355e76b38SJohan Hedberg 148455e76b38SJohan Hedberg return false; 148555e76b38SJohan Hedberg } 148655e76b38SJohan Hedberg 14876bd32326SVille Tervo /* HCI command timer function */ 148865cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work) 14896bd32326SVille Tervo { 149065cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, 149165cc2b49SMarcel Holtmann cmd_timer.work); 14926bd32326SVille Tervo 1493bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 1494bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 1495bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 1496bda4f23aSAndrei Emeltchenko 14972064ee33SMarcel Holtmann bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); 1498bda4f23aSAndrei Emeltchenko } else { 14992064ee33SMarcel Holtmann bt_dev_err(hdev, "command tx timeout"); 1500bda4f23aSAndrei Emeltchenko } 1501bda4f23aSAndrei Emeltchenko 1502e2bef384SRajat Jain if (hdev->cmd_timeout) 1503e2bef384SRajat Jain hdev->cmd_timeout(hdev); 1504e2bef384SRajat Jain 15056bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 1506c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 15076bd32326SVille Tervo } 15086bd32326SVille Tervo 1509de75cd0dSManish Mandlik /* HCI ncmd timer function */ 1510de75cd0dSManish Mandlik static void hci_ncmd_timeout(struct work_struct *work) 1511de75cd0dSManish Mandlik { 1512de75cd0dSManish Mandlik struct hci_dev *hdev = container_of(work, struct hci_dev, 1513de75cd0dSManish Mandlik ncmd_timer.work); 1514de75cd0dSManish Mandlik 1515de75cd0dSManish Mandlik bt_dev_err(hdev, "Controller not accepting commands anymore: ncmd = 0"); 1516de75cd0dSManish Mandlik 1517de75cd0dSManish Mandlik /* During HCI_INIT phase no events can be injected if the ncmd timer 1518de75cd0dSManish Mandlik * triggers since the procedure has its own timeout handling. 1519de75cd0dSManish Mandlik */ 1520de75cd0dSManish Mandlik if (test_bit(HCI_INIT, &hdev->flags)) 1521de75cd0dSManish Mandlik return; 1522de75cd0dSManish Mandlik 1523de75cd0dSManish Mandlik /* This is an irrecoverable state, inject hardware error event */ 1524de75cd0dSManish Mandlik hci_reset_dev(hdev); 1525de75cd0dSManish Mandlik } 1526de75cd0dSManish Mandlik 15272763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 15286928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type) 15292763eda6SSzymon Janc { 15302763eda6SSzymon Janc struct oob_data *data; 15312763eda6SSzymon Janc 15326928a924SJohan Hedberg list_for_each_entry(data, &hdev->remote_oob_data, list) { 15336928a924SJohan Hedberg if (bacmp(bdaddr, &data->bdaddr) != 0) 15346928a924SJohan Hedberg continue; 15356928a924SJohan Hedberg if (data->bdaddr_type != bdaddr_type) 15366928a924SJohan Hedberg continue; 15372763eda6SSzymon Janc return data; 15386928a924SJohan Hedberg } 15392763eda6SSzymon Janc 15402763eda6SSzymon Janc return NULL; 15412763eda6SSzymon Janc } 15422763eda6SSzymon Janc 15436928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 15446928a924SJohan Hedberg u8 bdaddr_type) 15452763eda6SSzymon Janc { 15462763eda6SSzymon Janc struct oob_data *data; 15472763eda6SSzymon Janc 15486928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 15492763eda6SSzymon Janc if (!data) 15502763eda6SSzymon Janc return -ENOENT; 15512763eda6SSzymon Janc 15526928a924SJohan Hedberg BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type); 15532763eda6SSzymon Janc 15542763eda6SSzymon Janc list_del(&data->list); 15552763eda6SSzymon Janc kfree(data); 15562763eda6SSzymon Janc 15572763eda6SSzymon Janc return 0; 15582763eda6SSzymon Janc } 15592763eda6SSzymon Janc 156035f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev) 15612763eda6SSzymon Janc { 15622763eda6SSzymon Janc struct oob_data *data, *n; 15632763eda6SSzymon Janc 15642763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 15652763eda6SSzymon Janc list_del(&data->list); 15662763eda6SSzymon Janc kfree(data); 15672763eda6SSzymon Janc } 15682763eda6SSzymon Janc } 15692763eda6SSzymon Janc 15700798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 15716928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192, 157238da1703SJohan Hedberg u8 *hash256, u8 *rand256) 15730798872eSMarcel Holtmann { 15740798872eSMarcel Holtmann struct oob_data *data; 15750798872eSMarcel Holtmann 15766928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); 15770798872eSMarcel Holtmann if (!data) { 15780a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL); 15790798872eSMarcel Holtmann if (!data) 15800798872eSMarcel Holtmann return -ENOMEM; 15810798872eSMarcel Holtmann 15820798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr); 15836928a924SJohan Hedberg data->bdaddr_type = bdaddr_type; 15840798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data); 15850798872eSMarcel Holtmann } 15860798872eSMarcel Holtmann 158781328d5cSJohan Hedberg if (hash192 && rand192) { 15880798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192)); 158938da1703SJohan Hedberg memcpy(data->rand192, rand192, sizeof(data->rand192)); 1590f7697b16SMarcel Holtmann if (hash256 && rand256) 1591f7697b16SMarcel Holtmann data->present = 0x03; 159281328d5cSJohan Hedberg } else { 159381328d5cSJohan Hedberg memset(data->hash192, 0, sizeof(data->hash192)); 159481328d5cSJohan Hedberg memset(data->rand192, 0, sizeof(data->rand192)); 1595f7697b16SMarcel Holtmann if (hash256 && rand256) 1596f7697b16SMarcel Holtmann data->present = 0x02; 1597f7697b16SMarcel Holtmann else 1598f7697b16SMarcel Holtmann data->present = 0x00; 159981328d5cSJohan Hedberg } 16000798872eSMarcel Holtmann 160181328d5cSJohan Hedberg if (hash256 && rand256) { 16020798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256)); 160338da1703SJohan Hedberg memcpy(data->rand256, rand256, sizeof(data->rand256)); 160481328d5cSJohan Hedberg } else { 160581328d5cSJohan Hedberg memset(data->hash256, 0, sizeof(data->hash256)); 160681328d5cSJohan Hedberg memset(data->rand256, 0, sizeof(data->rand256)); 1607f7697b16SMarcel Holtmann if (hash192 && rand192) 1608f7697b16SMarcel Holtmann data->present = 0x01; 160981328d5cSJohan Hedberg } 16100798872eSMarcel Holtmann 16116ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 16122763eda6SSzymon Janc 16132763eda6SSzymon Janc return 0; 16142763eda6SSzymon Janc } 16152763eda6SSzymon Janc 1616d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 1617d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance) 1618d2609b34SFlorian Grandel { 1619d2609b34SFlorian Grandel struct adv_info *adv_instance; 1620d2609b34SFlorian Grandel 1621d2609b34SFlorian Grandel list_for_each_entry(adv_instance, &hdev->adv_instances, list) { 1622d2609b34SFlorian Grandel if (adv_instance->instance == instance) 1623d2609b34SFlorian Grandel return adv_instance; 1624d2609b34SFlorian Grandel } 1625d2609b34SFlorian Grandel 1626d2609b34SFlorian Grandel return NULL; 1627d2609b34SFlorian Grandel } 1628d2609b34SFlorian Grandel 1629d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 163074b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance) 163174b93e9fSPrasanna Karthik { 1632d2609b34SFlorian Grandel struct adv_info *cur_instance; 1633d2609b34SFlorian Grandel 1634d2609b34SFlorian Grandel cur_instance = hci_find_adv_instance(hdev, instance); 1635d2609b34SFlorian Grandel if (!cur_instance) 1636d2609b34SFlorian Grandel return NULL; 1637d2609b34SFlorian Grandel 1638d2609b34SFlorian Grandel if (cur_instance == list_last_entry(&hdev->adv_instances, 1639d2609b34SFlorian Grandel struct adv_info, list)) 1640d2609b34SFlorian Grandel return list_first_entry(&hdev->adv_instances, 1641d2609b34SFlorian Grandel struct adv_info, list); 1642d2609b34SFlorian Grandel else 1643d2609b34SFlorian Grandel return list_next_entry(cur_instance, list); 1644d2609b34SFlorian Grandel } 1645d2609b34SFlorian Grandel 1646d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 1647d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance) 1648d2609b34SFlorian Grandel { 1649d2609b34SFlorian Grandel struct adv_info *adv_instance; 1650d2609b34SFlorian Grandel 1651d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance); 1652d2609b34SFlorian Grandel if (!adv_instance) 1653d2609b34SFlorian Grandel return -ENOENT; 1654d2609b34SFlorian Grandel 1655d2609b34SFlorian Grandel BT_DBG("%s removing %dMR", hdev->name, instance); 1656d2609b34SFlorian Grandel 1657cab054abSJohan Hedberg if (hdev->cur_adv_instance == instance) { 1658cab054abSJohan Hedberg if (hdev->adv_instance_timeout) { 16595d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 16605d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 16615d900e46SFlorian Grandel } 1662cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 1663cab054abSJohan Hedberg } 16645d900e46SFlorian Grandel 1665a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 1666a73c046aSJaganath Kanakkassery 1667d2609b34SFlorian Grandel list_del(&adv_instance->list); 1668d2609b34SFlorian Grandel kfree(adv_instance); 1669d2609b34SFlorian Grandel 1670d2609b34SFlorian Grandel hdev->adv_instance_cnt--; 1671d2609b34SFlorian Grandel 1672d2609b34SFlorian Grandel return 0; 1673d2609b34SFlorian Grandel } 1674d2609b34SFlorian Grandel 1675a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired) 1676a73c046aSJaganath Kanakkassery { 1677a73c046aSJaganath Kanakkassery struct adv_info *adv_instance, *n; 1678a73c046aSJaganath Kanakkassery 1679a73c046aSJaganath Kanakkassery list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) 1680a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = rpa_expired; 1681a73c046aSJaganath Kanakkassery } 1682a73c046aSJaganath Kanakkassery 1683d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 1684d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev) 1685d2609b34SFlorian Grandel { 1686d2609b34SFlorian Grandel struct adv_info *adv_instance, *n; 1687d2609b34SFlorian Grandel 16885d900e46SFlorian Grandel if (hdev->adv_instance_timeout) { 16895d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire); 16905d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 16915d900e46SFlorian Grandel } 16925d900e46SFlorian Grandel 1693d2609b34SFlorian Grandel list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) { 1694a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); 1695d2609b34SFlorian Grandel list_del(&adv_instance->list); 1696d2609b34SFlorian Grandel kfree(adv_instance); 1697d2609b34SFlorian Grandel } 1698d2609b34SFlorian Grandel 1699d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 1700cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00; 1701d2609b34SFlorian Grandel } 1702d2609b34SFlorian Grandel 1703a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work) 1704a73c046aSJaganath Kanakkassery { 1705a73c046aSJaganath Kanakkassery struct adv_info *adv_instance = container_of(work, struct adv_info, 1706a73c046aSJaganath Kanakkassery rpa_expired_cb.work); 1707a73c046aSJaganath Kanakkassery 1708a73c046aSJaganath Kanakkassery BT_DBG(""); 1709a73c046aSJaganath Kanakkassery 1710a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = true; 1711a73c046aSJaganath Kanakkassery } 1712a73c046aSJaganath Kanakkassery 1713d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */ 1714eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance, 1715eca0ae4aSLuiz Augusto von Dentz u32 flags, u16 adv_data_len, u8 *adv_data, 1716d2609b34SFlorian Grandel u16 scan_rsp_len, u8 *scan_rsp_data, 17179bf9f4b6SDaniel Winkler u16 timeout, u16 duration, s8 tx_power, 1718b338d917SBrian Gix u32 min_interval, u32 max_interval, 1719b338d917SBrian Gix u8 mesh_handle) 1720d2609b34SFlorian Grandel { 1721eca0ae4aSLuiz Augusto von Dentz struct adv_info *adv; 1722d2609b34SFlorian Grandel 1723eca0ae4aSLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, instance); 1724eca0ae4aSLuiz Augusto von Dentz if (adv) { 1725eca0ae4aSLuiz Augusto von Dentz memset(adv->adv_data, 0, sizeof(adv->adv_data)); 1726eca0ae4aSLuiz Augusto von Dentz memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data)); 1727eca0ae4aSLuiz Augusto von Dentz memset(adv->per_adv_data, 0, sizeof(adv->per_adv_data)); 1728d2609b34SFlorian Grandel } else { 17291d0fac2cSLuiz Augusto von Dentz if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets || 1730b338d917SBrian Gix instance < 1 || instance > hdev->le_num_of_adv_sets + 1) 1731eca0ae4aSLuiz Augusto von Dentz return ERR_PTR(-EOVERFLOW); 1732d2609b34SFlorian Grandel 1733eca0ae4aSLuiz Augusto von Dentz adv = kzalloc(sizeof(*adv), GFP_KERNEL); 1734eca0ae4aSLuiz Augusto von Dentz if (!adv) 1735eca0ae4aSLuiz Augusto von Dentz return ERR_PTR(-ENOMEM); 1736d2609b34SFlorian Grandel 1737eca0ae4aSLuiz Augusto von Dentz adv->pending = true; 1738eca0ae4aSLuiz Augusto von Dentz adv->instance = instance; 1739eca0ae4aSLuiz Augusto von Dentz list_add(&adv->list, &hdev->adv_instances); 1740d2609b34SFlorian Grandel hdev->adv_instance_cnt++; 1741d2609b34SFlorian Grandel } 1742d2609b34SFlorian Grandel 1743eca0ae4aSLuiz Augusto von Dentz adv->flags = flags; 1744eca0ae4aSLuiz Augusto von Dentz adv->min_interval = min_interval; 1745eca0ae4aSLuiz Augusto von Dentz adv->max_interval = max_interval; 1746eca0ae4aSLuiz Augusto von Dentz adv->tx_power = tx_power; 1747b338d917SBrian Gix /* Defining a mesh_handle changes the timing units to ms, 1748b338d917SBrian Gix * rather than seconds, and ties the instance to the requested 1749b338d917SBrian Gix * mesh_tx queue. 1750b338d917SBrian Gix */ 1751b338d917SBrian Gix adv->mesh = mesh_handle; 1752d2609b34SFlorian Grandel 175334a718bcSLuiz Augusto von Dentz hci_set_adv_instance_data(hdev, instance, adv_data_len, adv_data, 175434a718bcSLuiz Augusto von Dentz scan_rsp_len, scan_rsp_data); 1755d2609b34SFlorian Grandel 1756eca0ae4aSLuiz Augusto von Dentz adv->timeout = timeout; 1757eca0ae4aSLuiz Augusto von Dentz adv->remaining_time = timeout; 1758d2609b34SFlorian Grandel 1759d2609b34SFlorian Grandel if (duration == 0) 1760eca0ae4aSLuiz Augusto von Dentz adv->duration = hdev->def_multi_adv_rotation_duration; 1761d2609b34SFlorian Grandel else 1762eca0ae4aSLuiz Augusto von Dentz adv->duration = duration; 1763d2609b34SFlorian Grandel 1764eca0ae4aSLuiz Augusto von Dentz INIT_DELAYED_WORK(&adv->rpa_expired_cb, adv_instance_rpa_expired); 1765a73c046aSJaganath Kanakkassery 1766d2609b34SFlorian Grandel BT_DBG("%s for %dMR", hdev->name, instance); 1767d2609b34SFlorian Grandel 1768eca0ae4aSLuiz Augusto von Dentz return adv; 1769eca0ae4aSLuiz Augusto von Dentz } 1770eca0ae4aSLuiz Augusto von Dentz 1771eca0ae4aSLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */ 1772eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance, 1773eca0ae4aSLuiz Augusto von Dentz u32 flags, u8 data_len, u8 *data, 1774eca0ae4aSLuiz Augusto von Dentz u32 min_interval, u32 max_interval) 1775eca0ae4aSLuiz Augusto von Dentz { 1776eca0ae4aSLuiz Augusto von Dentz struct adv_info *adv; 1777eca0ae4aSLuiz Augusto von Dentz 1778eca0ae4aSLuiz Augusto von Dentz adv = hci_add_adv_instance(hdev, instance, flags, 0, NULL, 0, NULL, 1779eca0ae4aSLuiz Augusto von Dentz 0, 0, HCI_ADV_TX_POWER_NO_PREFERENCE, 1780b338d917SBrian Gix min_interval, max_interval, 0); 1781eca0ae4aSLuiz Augusto von Dentz if (IS_ERR(adv)) 1782eca0ae4aSLuiz Augusto von Dentz return adv; 1783eca0ae4aSLuiz Augusto von Dentz 1784eca0ae4aSLuiz Augusto von Dentz adv->periodic = true; 1785eca0ae4aSLuiz Augusto von Dentz adv->per_adv_data_len = data_len; 1786eca0ae4aSLuiz Augusto von Dentz 1787eca0ae4aSLuiz Augusto von Dentz if (data) 1788eca0ae4aSLuiz Augusto von Dentz memcpy(adv->per_adv_data, data, data_len); 1789eca0ae4aSLuiz Augusto von Dentz 1790eca0ae4aSLuiz Augusto von Dentz return adv; 1791d2609b34SFlorian Grandel } 1792d2609b34SFlorian Grandel 1793e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */ 179431aab5c2SDaniel Winkler int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance, 179531aab5c2SDaniel Winkler u16 adv_data_len, u8 *adv_data, 179631aab5c2SDaniel Winkler u16 scan_rsp_len, u8 *scan_rsp_data) 179731aab5c2SDaniel Winkler { 179834a718bcSLuiz Augusto von Dentz struct adv_info *adv; 179931aab5c2SDaniel Winkler 180034a718bcSLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, instance); 180131aab5c2SDaniel Winkler 180231aab5c2SDaniel Winkler /* If advertisement doesn't exist, we can't modify its data */ 180334a718bcSLuiz Augusto von Dentz if (!adv) 180431aab5c2SDaniel Winkler return -ENOENT; 180531aab5c2SDaniel Winkler 180634a718bcSLuiz Augusto von Dentz if (adv_data_len && ADV_DATA_CMP(adv, adv_data, adv_data_len)) { 180734a718bcSLuiz Augusto von Dentz memset(adv->adv_data, 0, sizeof(adv->adv_data)); 180834a718bcSLuiz Augusto von Dentz memcpy(adv->adv_data, adv_data, adv_data_len); 180934a718bcSLuiz Augusto von Dentz adv->adv_data_len = adv_data_len; 181034a718bcSLuiz Augusto von Dentz adv->adv_data_changed = true; 181131aab5c2SDaniel Winkler } 181231aab5c2SDaniel Winkler 181334a718bcSLuiz Augusto von Dentz if (scan_rsp_len && SCAN_RSP_CMP(adv, scan_rsp_data, scan_rsp_len)) { 181434a718bcSLuiz Augusto von Dentz memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data)); 181534a718bcSLuiz Augusto von Dentz memcpy(adv->scan_rsp_data, scan_rsp_data, scan_rsp_len); 181634a718bcSLuiz Augusto von Dentz adv->scan_rsp_len = scan_rsp_len; 181734a718bcSLuiz Augusto von Dentz adv->scan_rsp_changed = true; 181831aab5c2SDaniel Winkler } 181931aab5c2SDaniel Winkler 182034a718bcSLuiz Augusto von Dentz /* Mark as changed if there are flags which would affect it */ 182134a718bcSLuiz Augusto von Dentz if (((adv->flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) || 182234a718bcSLuiz Augusto von Dentz adv->flags & MGMT_ADV_FLAG_LOCAL_NAME) 182334a718bcSLuiz Augusto von Dentz adv->scan_rsp_changed = true; 182434a718bcSLuiz Augusto von Dentz 182531aab5c2SDaniel Winkler return 0; 182631aab5c2SDaniel Winkler } 182731aab5c2SDaniel Winkler 182831aab5c2SDaniel Winkler /* This function requires the caller holds hdev->lock */ 182901ce70b0SLuiz Augusto von Dentz u32 hci_adv_instance_flags(struct hci_dev *hdev, u8 instance) 183001ce70b0SLuiz Augusto von Dentz { 183101ce70b0SLuiz Augusto von Dentz u32 flags; 183201ce70b0SLuiz Augusto von Dentz struct adv_info *adv; 183301ce70b0SLuiz Augusto von Dentz 183401ce70b0SLuiz Augusto von Dentz if (instance == 0x00) { 183501ce70b0SLuiz Augusto von Dentz /* Instance 0 always manages the "Tx Power" and "Flags" 183601ce70b0SLuiz Augusto von Dentz * fields 183701ce70b0SLuiz Augusto von Dentz */ 183801ce70b0SLuiz Augusto von Dentz flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS; 183901ce70b0SLuiz Augusto von Dentz 184001ce70b0SLuiz Augusto von Dentz /* For instance 0, the HCI_ADVERTISING_CONNECTABLE setting 184101ce70b0SLuiz Augusto von Dentz * corresponds to the "connectable" instance flag. 184201ce70b0SLuiz Augusto von Dentz */ 184301ce70b0SLuiz Augusto von Dentz if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE)) 184401ce70b0SLuiz Augusto von Dentz flags |= MGMT_ADV_FLAG_CONNECTABLE; 184501ce70b0SLuiz Augusto von Dentz 184601ce70b0SLuiz Augusto von Dentz if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) 184701ce70b0SLuiz Augusto von Dentz flags |= MGMT_ADV_FLAG_LIMITED_DISCOV; 184801ce70b0SLuiz Augusto von Dentz else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE)) 184901ce70b0SLuiz Augusto von Dentz flags |= MGMT_ADV_FLAG_DISCOV; 185001ce70b0SLuiz Augusto von Dentz 185101ce70b0SLuiz Augusto von Dentz return flags; 185201ce70b0SLuiz Augusto von Dentz } 185301ce70b0SLuiz Augusto von Dentz 185401ce70b0SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, instance); 185501ce70b0SLuiz Augusto von Dentz 185601ce70b0SLuiz Augusto von Dentz /* Return 0 when we got an invalid instance identifier. */ 185701ce70b0SLuiz Augusto von Dentz if (!adv) 185801ce70b0SLuiz Augusto von Dentz return 0; 185901ce70b0SLuiz Augusto von Dentz 186001ce70b0SLuiz Augusto von Dentz return adv->flags; 186101ce70b0SLuiz Augusto von Dentz } 186201ce70b0SLuiz Augusto von Dentz 186301ce70b0SLuiz Augusto von Dentz bool hci_adv_instance_is_scannable(struct hci_dev *hdev, u8 instance) 186401ce70b0SLuiz Augusto von Dentz { 186501ce70b0SLuiz Augusto von Dentz struct adv_info *adv; 186601ce70b0SLuiz Augusto von Dentz 186701ce70b0SLuiz Augusto von Dentz /* Instance 0x00 always set local name */ 186801ce70b0SLuiz Augusto von Dentz if (instance == 0x00) 186901ce70b0SLuiz Augusto von Dentz return true; 187001ce70b0SLuiz Augusto von Dentz 187101ce70b0SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, instance); 187201ce70b0SLuiz Augusto von Dentz if (!adv) 187301ce70b0SLuiz Augusto von Dentz return false; 187401ce70b0SLuiz Augusto von Dentz 187501ce70b0SLuiz Augusto von Dentz if (adv->flags & MGMT_ADV_FLAG_APPEARANCE || 187601ce70b0SLuiz Augusto von Dentz adv->flags & MGMT_ADV_FLAG_LOCAL_NAME) 187701ce70b0SLuiz Augusto von Dentz return true; 187801ce70b0SLuiz Augusto von Dentz 187901ce70b0SLuiz Augusto von Dentz return adv->scan_rsp_len ? true : false; 188001ce70b0SLuiz Augusto von Dentz } 188101ce70b0SLuiz Augusto von Dentz 188201ce70b0SLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */ 1883e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev) 1884e5e1e7fdSMiao-chen Chou { 1885b139553dSMiao-chen Chou struct adv_monitor *monitor; 1886b139553dSMiao-chen Chou int handle; 1887b139553dSMiao-chen Chou 1888b139553dSMiao-chen Chou idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle) 188966bd095aSArchie Pusaka hci_free_adv_monitor(hdev, monitor); 1890b139553dSMiao-chen Chou 1891e5e1e7fdSMiao-chen Chou idr_destroy(&hdev->adv_monitors_idr); 1892e5e1e7fdSMiao-chen Chou } 1893e5e1e7fdSMiao-chen Chou 189466bd095aSArchie Pusaka /* Frees the monitor structure and do some bookkeepings. 189566bd095aSArchie Pusaka * This function requires the caller holds hdev->lock. 189666bd095aSArchie Pusaka */ 189766bd095aSArchie Pusaka void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor) 1898b139553dSMiao-chen Chou { 1899b139553dSMiao-chen Chou struct adv_pattern *pattern; 1900b139553dSMiao-chen Chou struct adv_pattern *tmp; 1901b139553dSMiao-chen Chou 1902b139553dSMiao-chen Chou if (!monitor) 1903b139553dSMiao-chen Chou return; 1904b139553dSMiao-chen Chou 190566bd095aSArchie Pusaka list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) { 190666bd095aSArchie Pusaka list_del(&pattern->list); 1907b139553dSMiao-chen Chou kfree(pattern); 190866bd095aSArchie Pusaka } 190966bd095aSArchie Pusaka 191066bd095aSArchie Pusaka if (monitor->handle) 191166bd095aSArchie Pusaka idr_remove(&hdev->adv_monitors_idr, monitor->handle); 191266bd095aSArchie Pusaka 191366bd095aSArchie Pusaka if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) { 191466bd095aSArchie Pusaka hdev->adv_monitors_cnt--; 191566bd095aSArchie Pusaka mgmt_adv_monitor_removed(hdev, monitor->handle); 191666bd095aSArchie Pusaka } 1917b139553dSMiao-chen Chou 1918b139553dSMiao-chen Chou kfree(monitor); 1919b139553dSMiao-chen Chou } 1920b139553dSMiao-chen Chou 1921a2a4dedfSArchie Pusaka /* Assigns handle to a monitor, and if offloading is supported and power is on, 1922a2a4dedfSArchie Pusaka * also attempts to forward the request to the controller. 1923b747a836SManish Mandlik * This function requires the caller holds hci_req_sync_lock. 1924a2a4dedfSArchie Pusaka */ 1925b747a836SManish Mandlik int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor) 1926b139553dSMiao-chen Chou { 1927b139553dSMiao-chen Chou int min, max, handle; 1928b747a836SManish Mandlik int status = 0; 1929b139553dSMiao-chen Chou 1930b747a836SManish Mandlik if (!monitor) 1931b747a836SManish Mandlik return -EINVAL; 1932a2a4dedfSArchie Pusaka 1933b747a836SManish Mandlik hci_dev_lock(hdev); 1934b139553dSMiao-chen Chou 1935b139553dSMiao-chen Chou min = HCI_MIN_ADV_MONITOR_HANDLE; 1936b139553dSMiao-chen Chou max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES; 1937b139553dSMiao-chen Chou handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max, 1938b139553dSMiao-chen Chou GFP_KERNEL); 1939b747a836SManish Mandlik 1940b747a836SManish Mandlik hci_dev_unlock(hdev); 1941b747a836SManish Mandlik 1942b747a836SManish Mandlik if (handle < 0) 1943b747a836SManish Mandlik return handle; 1944b139553dSMiao-chen Chou 1945b139553dSMiao-chen Chou monitor->handle = handle; 19468208f5a9SMiao-chen Chou 1947a2a4dedfSArchie Pusaka if (!hdev_is_powered(hdev)) 1948b747a836SManish Mandlik return status; 19498208f5a9SMiao-chen Chou 1950a2a4dedfSArchie Pusaka switch (hci_get_adv_monitor_offload_ext(hdev)) { 1951a2a4dedfSArchie Pusaka case HCI_ADV_MONITOR_EXT_NONE: 19526f55eea1SDouglas Anderson bt_dev_dbg(hdev, "add monitor %d status %d", 1953b747a836SManish Mandlik monitor->handle, status); 1954a2a4dedfSArchie Pusaka /* Message was not forwarded to controller - not an error */ 1955b747a836SManish Mandlik break; 1956b747a836SManish Mandlik 1957a2a4dedfSArchie Pusaka case HCI_ADV_MONITOR_EXT_MSFT: 1958b747a836SManish Mandlik status = msft_add_monitor_pattern(hdev, monitor); 19596f55eea1SDouglas Anderson bt_dev_dbg(hdev, "add monitor %d msft status %d", 1960a2bcd2b6SManish Mandlik handle, status); 1961a2a4dedfSArchie Pusaka break; 1962a2a4dedfSArchie Pusaka } 1963a2a4dedfSArchie Pusaka 1964b747a836SManish Mandlik return status; 1965b139553dSMiao-chen Chou } 1966b139553dSMiao-chen Chou 196766bd095aSArchie Pusaka /* Attempts to tell the controller and free the monitor. If somehow the 196866bd095aSArchie Pusaka * controller doesn't have a corresponding handle, remove anyway. 19697cf5c297SManish Mandlik * This function requires the caller holds hci_req_sync_lock. 197066bd095aSArchie Pusaka */ 19717cf5c297SManish Mandlik static int hci_remove_adv_monitor(struct hci_dev *hdev, 19727cf5c297SManish Mandlik struct adv_monitor *monitor) 1973bd2fbc6cSMiao-chen Chou { 19747cf5c297SManish Mandlik int status = 0; 1975de6dfcefSDouglas Anderson int handle; 1976bd2fbc6cSMiao-chen Chou 197766bd095aSArchie Pusaka switch (hci_get_adv_monitor_offload_ext(hdev)) { 197866bd095aSArchie Pusaka case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */ 19796f55eea1SDouglas Anderson bt_dev_dbg(hdev, "remove monitor %d status %d", 19807cf5c297SManish Mandlik monitor->handle, status); 198166bd095aSArchie Pusaka goto free_monitor; 19827cf5c297SManish Mandlik 198366bd095aSArchie Pusaka case HCI_ADV_MONITOR_EXT_MSFT: 1984de6dfcefSDouglas Anderson handle = monitor->handle; 19857cf5c297SManish Mandlik status = msft_remove_monitor(hdev, monitor); 19866f55eea1SDouglas Anderson bt_dev_dbg(hdev, "remove monitor %d msft status %d", 19876f55eea1SDouglas Anderson handle, status); 198866bd095aSArchie Pusaka break; 1989bd2fbc6cSMiao-chen Chou } 1990bd2fbc6cSMiao-chen Chou 199166bd095aSArchie Pusaka /* In case no matching handle registered, just free the monitor */ 19927cf5c297SManish Mandlik if (status == -ENOENT) 199366bd095aSArchie Pusaka goto free_monitor; 1994bd2fbc6cSMiao-chen Chou 19957cf5c297SManish Mandlik return status; 1996bd2fbc6cSMiao-chen Chou 199766bd095aSArchie Pusaka free_monitor: 19987cf5c297SManish Mandlik if (status == -ENOENT) 199966bd095aSArchie Pusaka bt_dev_warn(hdev, "Removing monitor with no matching handle %d", 200066bd095aSArchie Pusaka monitor->handle); 200166bd095aSArchie Pusaka hci_free_adv_monitor(hdev, monitor); 200266bd095aSArchie Pusaka 20037cf5c297SManish Mandlik return status; 2004bd2fbc6cSMiao-chen Chou } 2005bd2fbc6cSMiao-chen Chou 20067cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */ 20077cf5c297SManish Mandlik int hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle) 200866bd095aSArchie Pusaka { 200966bd095aSArchie Pusaka struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle); 201066bd095aSArchie Pusaka 20117cf5c297SManish Mandlik if (!monitor) 20127cf5c297SManish Mandlik return -EINVAL; 20137cf5c297SManish Mandlik 20147cf5c297SManish Mandlik return hci_remove_adv_monitor(hdev, monitor); 201566bd095aSArchie Pusaka } 201666bd095aSArchie Pusaka 20177cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */ 20187cf5c297SManish Mandlik int hci_remove_all_adv_monitor(struct hci_dev *hdev) 201966bd095aSArchie Pusaka { 202066bd095aSArchie Pusaka struct adv_monitor *monitor; 202166bd095aSArchie Pusaka int idr_next_id = 0; 20227cf5c297SManish Mandlik int status = 0; 202366bd095aSArchie Pusaka 20247cf5c297SManish Mandlik while (1) { 202566bd095aSArchie Pusaka monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id); 202666bd095aSArchie Pusaka if (!monitor) 202766bd095aSArchie Pusaka break; 202866bd095aSArchie Pusaka 20297cf5c297SManish Mandlik status = hci_remove_adv_monitor(hdev, monitor); 20307cf5c297SManish Mandlik if (status) 20317cf5c297SManish Mandlik return status; 203266bd095aSArchie Pusaka 20337cf5c297SManish Mandlik idr_next_id++; 203466bd095aSArchie Pusaka } 203566bd095aSArchie Pusaka 20367cf5c297SManish Mandlik return status; 2037bd2fbc6cSMiao-chen Chou } 2038bd2fbc6cSMiao-chen Chou 20398208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */ 20408208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev) 20418208f5a9SMiao-chen Chou { 20428208f5a9SMiao-chen Chou return !idr_is_empty(&hdev->adv_monitors_idr); 20438208f5a9SMiao-chen Chou } 20448208f5a9SMiao-chen Chou 2045a2a4dedfSArchie Pusaka int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev) 2046a2a4dedfSArchie Pusaka { 2047a2a4dedfSArchie Pusaka if (msft_monitor_supported(hdev)) 2048a2a4dedfSArchie Pusaka return HCI_ADV_MONITOR_EXT_MSFT; 2049a2a4dedfSArchie Pusaka 2050a2a4dedfSArchie Pusaka return HCI_ADV_MONITOR_EXT_NONE; 2051a2a4dedfSArchie Pusaka } 2052a2a4dedfSArchie Pusaka 2053dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list, 2054b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type) 2055b2a66aadSAntti Julku { 2056b2a66aadSAntti Julku struct bdaddr_list *b; 2057b2a66aadSAntti Julku 2058dcc36c16SJohan Hedberg list_for_each_entry(b, bdaddr_list, list) { 2059b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2060b2a66aadSAntti Julku return b; 2061b9ee0a78SMarcel Holtmann } 2062b2a66aadSAntti Julku 2063b2a66aadSAntti Julku return NULL; 2064b2a66aadSAntti Julku } 2065b2a66aadSAntti Julku 2066b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk( 2067b950aa88SAnkit Navik struct list_head *bdaddr_list, bdaddr_t *bdaddr, 2068b950aa88SAnkit Navik u8 type) 2069b950aa88SAnkit Navik { 2070b950aa88SAnkit Navik struct bdaddr_list_with_irk *b; 2071b950aa88SAnkit Navik 2072b950aa88SAnkit Navik list_for_each_entry(b, bdaddr_list, list) { 2073b950aa88SAnkit Navik if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 2074b950aa88SAnkit Navik return b; 2075b950aa88SAnkit Navik } 2076b950aa88SAnkit Navik 2077b950aa88SAnkit Navik return NULL; 2078b950aa88SAnkit Navik } 2079b950aa88SAnkit Navik 20808baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags * 20818baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list, 20828baaa403SAbhishek Pandit-Subedi bdaddr_t *bdaddr, u8 type) 20838baaa403SAbhishek Pandit-Subedi { 20848baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *b; 20858baaa403SAbhishek Pandit-Subedi 20868baaa403SAbhishek Pandit-Subedi list_for_each_entry(b, bdaddr_list, list) { 20878baaa403SAbhishek Pandit-Subedi if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) 20888baaa403SAbhishek Pandit-Subedi return b; 20898baaa403SAbhishek Pandit-Subedi } 20908baaa403SAbhishek Pandit-Subedi 20918baaa403SAbhishek Pandit-Subedi return NULL; 20928baaa403SAbhishek Pandit-Subedi } 20938baaa403SAbhishek Pandit-Subedi 2094dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list) 2095b2a66aadSAntti Julku { 20967eb7404fSGeliang Tang struct bdaddr_list *b, *n; 2097b2a66aadSAntti Julku 20987eb7404fSGeliang Tang list_for_each_entry_safe(b, n, bdaddr_list, list) { 20997eb7404fSGeliang Tang list_del(&b->list); 2100b2a66aadSAntti Julku kfree(b); 2101b2a66aadSAntti Julku } 2102b2a66aadSAntti Julku } 2103b2a66aadSAntti Julku 2104dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type) 2105b2a66aadSAntti Julku { 2106b2a66aadSAntti Julku struct bdaddr_list *entry; 2107b2a66aadSAntti Julku 2108b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY)) 2109b2a66aadSAntti Julku return -EBADF; 2110b2a66aadSAntti Julku 2111dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(list, bdaddr, type)) 21125e762444SAntti Julku return -EEXIST; 2113b2a66aadSAntti Julku 211427f70f3eSJohan Hedberg entry = kzalloc(sizeof(*entry), GFP_KERNEL); 21155e762444SAntti Julku if (!entry) 21165e762444SAntti Julku return -ENOMEM; 2117b2a66aadSAntti Julku 2118b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 2119b9ee0a78SMarcel Holtmann entry->bdaddr_type = type; 2120b2a66aadSAntti Julku 2121dcc36c16SJohan Hedberg list_add(&entry->list, list); 2122b2a66aadSAntti Julku 21232a8357f2SJohan Hedberg return 0; 2124b2a66aadSAntti Julku } 2125b2a66aadSAntti Julku 2126b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr, 2127b950aa88SAnkit Navik u8 type, u8 *peer_irk, u8 *local_irk) 2128b950aa88SAnkit Navik { 2129b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 2130b950aa88SAnkit Navik 2131b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) 2132b950aa88SAnkit Navik return -EBADF; 2133b950aa88SAnkit Navik 2134b950aa88SAnkit Navik if (hci_bdaddr_list_lookup(list, bdaddr, type)) 2135b950aa88SAnkit Navik return -EEXIST; 2136b950aa88SAnkit Navik 2137b950aa88SAnkit Navik entry = kzalloc(sizeof(*entry), GFP_KERNEL); 2138b950aa88SAnkit Navik if (!entry) 2139b950aa88SAnkit Navik return -ENOMEM; 2140b950aa88SAnkit Navik 2141b950aa88SAnkit Navik bacpy(&entry->bdaddr, bdaddr); 2142b950aa88SAnkit Navik entry->bdaddr_type = type; 2143b950aa88SAnkit Navik 2144b950aa88SAnkit Navik if (peer_irk) 2145b950aa88SAnkit Navik memcpy(entry->peer_irk, peer_irk, 16); 2146b950aa88SAnkit Navik 2147b950aa88SAnkit Navik if (local_irk) 2148b950aa88SAnkit Navik memcpy(entry->local_irk, local_irk, 16); 2149b950aa88SAnkit Navik 2150b950aa88SAnkit Navik list_add(&entry->list, list); 2151b950aa88SAnkit Navik 2152b950aa88SAnkit Navik return 0; 2153b950aa88SAnkit Navik } 2154b950aa88SAnkit Navik 21558baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr, 21568baaa403SAbhishek Pandit-Subedi u8 type, u32 flags) 21578baaa403SAbhishek Pandit-Subedi { 21588baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *entry; 21598baaa403SAbhishek Pandit-Subedi 21608baaa403SAbhishek Pandit-Subedi if (!bacmp(bdaddr, BDADDR_ANY)) 21618baaa403SAbhishek Pandit-Subedi return -EBADF; 21628baaa403SAbhishek Pandit-Subedi 21638baaa403SAbhishek Pandit-Subedi if (hci_bdaddr_list_lookup(list, bdaddr, type)) 21648baaa403SAbhishek Pandit-Subedi return -EEXIST; 21658baaa403SAbhishek Pandit-Subedi 21668baaa403SAbhishek Pandit-Subedi entry = kzalloc(sizeof(*entry), GFP_KERNEL); 21678baaa403SAbhishek Pandit-Subedi if (!entry) 21688baaa403SAbhishek Pandit-Subedi return -ENOMEM; 21698baaa403SAbhishek Pandit-Subedi 21708baaa403SAbhishek Pandit-Subedi bacpy(&entry->bdaddr, bdaddr); 21718baaa403SAbhishek Pandit-Subedi entry->bdaddr_type = type; 2172e1cff700SLinus Torvalds entry->flags = flags; 21738baaa403SAbhishek Pandit-Subedi 21748baaa403SAbhishek Pandit-Subedi list_add(&entry->list, list); 21758baaa403SAbhishek Pandit-Subedi 21768baaa403SAbhishek Pandit-Subedi return 0; 21778baaa403SAbhishek Pandit-Subedi } 21788baaa403SAbhishek Pandit-Subedi 2179dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type) 2180b2a66aadSAntti Julku { 2181b2a66aadSAntti Julku struct bdaddr_list *entry; 2182b2a66aadSAntti Julku 218335f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) { 2184dcc36c16SJohan Hedberg hci_bdaddr_list_clear(list); 218535f7498aSJohan Hedberg return 0; 218635f7498aSJohan Hedberg } 2187b2a66aadSAntti Julku 2188dcc36c16SJohan Hedberg entry = hci_bdaddr_list_lookup(list, bdaddr, type); 2189d2ab0ac1SMarcel Holtmann if (!entry) 2190d2ab0ac1SMarcel Holtmann return -ENOENT; 2191d2ab0ac1SMarcel Holtmann 2192d2ab0ac1SMarcel Holtmann list_del(&entry->list); 2193d2ab0ac1SMarcel Holtmann kfree(entry); 2194d2ab0ac1SMarcel Holtmann 2195d2ab0ac1SMarcel Holtmann return 0; 2196d2ab0ac1SMarcel Holtmann } 2197d2ab0ac1SMarcel Holtmann 2198b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr, 2199b950aa88SAnkit Navik u8 type) 2200b950aa88SAnkit Navik { 2201b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry; 2202b950aa88SAnkit Navik 2203b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) { 2204b950aa88SAnkit Navik hci_bdaddr_list_clear(list); 2205b950aa88SAnkit Navik return 0; 2206b950aa88SAnkit Navik } 2207b950aa88SAnkit Navik 2208b950aa88SAnkit Navik entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type); 2209b950aa88SAnkit Navik if (!entry) 2210b950aa88SAnkit Navik return -ENOENT; 2211b950aa88SAnkit Navik 2212b950aa88SAnkit Navik list_del(&entry->list); 2213b950aa88SAnkit Navik kfree(entry); 2214b950aa88SAnkit Navik 2215b950aa88SAnkit Navik return 0; 2216b950aa88SAnkit Navik } 2217b950aa88SAnkit Navik 22188baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr, 22198baaa403SAbhishek Pandit-Subedi u8 type) 22208baaa403SAbhishek Pandit-Subedi { 22218baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *entry; 22228baaa403SAbhishek Pandit-Subedi 22238baaa403SAbhishek Pandit-Subedi if (!bacmp(bdaddr, BDADDR_ANY)) { 22248baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_clear(list); 22258baaa403SAbhishek Pandit-Subedi return 0; 22268baaa403SAbhishek Pandit-Subedi } 22278baaa403SAbhishek Pandit-Subedi 22288baaa403SAbhishek Pandit-Subedi entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type); 22298baaa403SAbhishek Pandit-Subedi if (!entry) 22308baaa403SAbhishek Pandit-Subedi return -ENOENT; 22318baaa403SAbhishek Pandit-Subedi 22328baaa403SAbhishek Pandit-Subedi list_del(&entry->list); 22338baaa403SAbhishek Pandit-Subedi kfree(entry); 22348baaa403SAbhishek Pandit-Subedi 22358baaa403SAbhishek Pandit-Subedi return 0; 22368baaa403SAbhishek Pandit-Subedi } 22378baaa403SAbhishek Pandit-Subedi 223815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 223915819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 224015819a70SAndre Guedes bdaddr_t *addr, u8 addr_type) 224115819a70SAndre Guedes { 224215819a70SAndre Guedes struct hci_conn_params *params; 224315819a70SAndre Guedes 224415819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) { 224515819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 && 224615819a70SAndre Guedes params->addr_type == addr_type) { 224715819a70SAndre Guedes return params; 224815819a70SAndre Guedes } 224915819a70SAndre Guedes } 225015819a70SAndre Guedes 225115819a70SAndre Guedes return NULL; 225215819a70SAndre Guedes } 225315819a70SAndre Guedes 2254195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock or rcu_read_lock */ 2255501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 22564b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type) 2257a9b0a04cSAndre Guedes { 2258912b42efSJohan Hedberg struct hci_conn_params *param; 2259a9b0a04cSAndre Guedes 2260195ef75eSPauli Virtanen rcu_read_lock(); 2261195ef75eSPauli Virtanen 2262195ef75eSPauli Virtanen list_for_each_entry_rcu(param, list, action) { 2263912b42efSJohan Hedberg if (bacmp(¶m->addr, addr) == 0 && 2264195ef75eSPauli Virtanen param->addr_type == addr_type) { 2265195ef75eSPauli Virtanen rcu_read_unlock(); 2266912b42efSJohan Hedberg return param; 22674b10966fSMarcel Holtmann } 2268195ef75eSPauli Virtanen } 2269195ef75eSPauli Virtanen 2270195ef75eSPauli Virtanen rcu_read_unlock(); 22714b10966fSMarcel Holtmann 22724b10966fSMarcel Holtmann return NULL; 2273a9b0a04cSAndre Guedes } 2274a9b0a04cSAndre Guedes 227515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 2276195ef75eSPauli Virtanen void hci_pend_le_list_del_init(struct hci_conn_params *param) 2277195ef75eSPauli Virtanen { 2278195ef75eSPauli Virtanen if (list_empty(¶m->action)) 2279195ef75eSPauli Virtanen return; 2280195ef75eSPauli Virtanen 2281195ef75eSPauli Virtanen list_del_rcu(¶m->action); 2282195ef75eSPauli Virtanen synchronize_rcu(); 2283195ef75eSPauli Virtanen INIT_LIST_HEAD(¶m->action); 2284195ef75eSPauli Virtanen } 2285195ef75eSPauli Virtanen 2286195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock */ 2287195ef75eSPauli Virtanen void hci_pend_le_list_add(struct hci_conn_params *param, 2288195ef75eSPauli Virtanen struct list_head *list) 2289195ef75eSPauli Virtanen { 2290195ef75eSPauli Virtanen list_add_rcu(¶m->action, list); 2291195ef75eSPauli Virtanen } 2292195ef75eSPauli Virtanen 2293195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock */ 229451d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 229551d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type) 229615819a70SAndre Guedes { 229715819a70SAndre Guedes struct hci_conn_params *params; 229815819a70SAndre Guedes 229915819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 2300cef952ceSAndre Guedes if (params) 230151d167c0SMarcel Holtmann return params; 230215819a70SAndre Guedes 230315819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL); 230415819a70SAndre Guedes if (!params) { 23052064ee33SMarcel Holtmann bt_dev_err(hdev, "out of memory"); 230651d167c0SMarcel Holtmann return NULL; 230715819a70SAndre Guedes } 230815819a70SAndre Guedes 230915819a70SAndre Guedes bacpy(¶ms->addr, addr); 231015819a70SAndre Guedes params->addr_type = addr_type; 2311cef952ceSAndre Guedes 2312cef952ceSAndre Guedes list_add(¶ms->list, &hdev->le_conn_params); 231393450c75SJohan Hedberg INIT_LIST_HEAD(¶ms->action); 2314cef952ceSAndre Guedes 2315bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval; 2316bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval; 2317bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency; 2318bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout; 2319bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED; 2320bf5b3c8bSMarcel Holtmann 2321bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type); 2322bf5b3c8bSMarcel Holtmann 232351d167c0SMarcel Holtmann return params; 2324bf5b3c8bSMarcel Holtmann } 2325bf5b3c8bSMarcel Holtmann 2326195ef75eSPauli Virtanen void hci_conn_params_free(struct hci_conn_params *params) 2327f6c63249SJohan Hedberg { 2328195ef75eSPauli Virtanen hci_pend_le_list_del_init(params); 2329195ef75eSPauli Virtanen 2330f6c63249SJohan Hedberg if (params->conn) { 2331f6c63249SJohan Hedberg hci_conn_drop(params->conn); 2332f6c63249SJohan Hedberg hci_conn_put(params->conn); 2333f6c63249SJohan Hedberg } 2334f6c63249SJohan Hedberg 2335f6c63249SJohan Hedberg list_del(¶ms->list); 2336f6c63249SJohan Hedberg kfree(params); 2337f6c63249SJohan Hedberg } 2338f6c63249SJohan Hedberg 233915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 234015819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) 234115819a70SAndre Guedes { 234215819a70SAndre Guedes struct hci_conn_params *params; 234315819a70SAndre Guedes 234415819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type); 234515819a70SAndre Guedes if (!params) 234615819a70SAndre Guedes return; 234715819a70SAndre Guedes 2348f6c63249SJohan Hedberg hci_conn_params_free(params); 234915819a70SAndre Guedes 23505bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev); 235195305baaSJohan Hedberg 235215819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type); 235315819a70SAndre Guedes } 235415819a70SAndre Guedes 235515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */ 235655af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev) 235715819a70SAndre Guedes { 235815819a70SAndre Guedes struct hci_conn_params *params, *tmp; 235915819a70SAndre Guedes 236015819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { 236155af49a8SJohan Hedberg if (params->auto_connect != HCI_AUTO_CONN_DISABLED) 236255af49a8SJohan Hedberg continue; 2363f75113a2SJakub Pawlowski 236491641b79SZheng Yongjun /* If trying to establish one time connection to disabled 2365f75113a2SJakub Pawlowski * device, leave the params, but mark them as just once. 2366f75113a2SJakub Pawlowski */ 2367f75113a2SJakub Pawlowski if (params->explicit_connect) { 2368f75113a2SJakub Pawlowski params->auto_connect = HCI_AUTO_CONN_EXPLICIT; 2369f75113a2SJakub Pawlowski continue; 2370f75113a2SJakub Pawlowski } 2371f75113a2SJakub Pawlowski 2372195ef75eSPauli Virtanen hci_conn_params_free(params); 237315819a70SAndre Guedes } 237415819a70SAndre Guedes 237555af49a8SJohan Hedberg BT_DBG("All LE disabled connection parameters were removed"); 237655af49a8SJohan Hedberg } 237755af49a8SJohan Hedberg 237855af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */ 2379030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev) 238015819a70SAndre Guedes { 238115819a70SAndre Guedes struct hci_conn_params *params, *tmp; 238215819a70SAndre Guedes 2383f6c63249SJohan Hedberg list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) 2384f6c63249SJohan Hedberg hci_conn_params_free(params); 238515819a70SAndre Guedes 238615819a70SAndre Guedes BT_DBG("All LE connection parameters were removed"); 238715819a70SAndre Guedes } 238815819a70SAndre Guedes 2389a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller. 2390a1f4c318SJohan Hedberg * 2391a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one. 2392a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to 2393a1f4c318SJohan Hedberg * the static random address. 2394a1f4c318SJohan Hedberg * 2395a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a 2396a1f4c318SJohan Hedberg * public address to use the static random address instead. 239750b5b952SMarcel Holtmann * 239850b5b952SMarcel Holtmann * In case BR/EDR has been disabled on a dual-mode controller and 239950b5b952SMarcel Holtmann * userspace has configured a static address, then that address 240050b5b952SMarcel Holtmann * becomes the identity address instead of the public BR/EDR address. 2401a1f4c318SJohan Hedberg */ 2402a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 2403a1f4c318SJohan Hedberg u8 *bdaddr_type) 2404a1f4c318SJohan Hedberg { 2405b7cb93e5SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) || 240650b5b952SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) || 2407d7a5a11dSMarcel Holtmann (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) && 240850b5b952SMarcel Holtmann bacmp(&hdev->static_addr, BDADDR_ANY))) { 2409a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr); 2410a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM; 2411a1f4c318SJohan Hedberg } else { 2412a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr); 2413a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC; 2414a1f4c318SJohan Hedberg } 2415a1f4c318SJohan Hedberg } 2416a1f4c318SJohan Hedberg 24172f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev) 24182f20216cSAbhishek Pandit-Subedi { 24192f20216cSAbhishek Pandit-Subedi hci_dev_lock(hdev); 24202f20216cSAbhishek Pandit-Subedi 24212f20216cSAbhishek Pandit-Subedi hdev->wake_reason = 0; 24222f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, BDADDR_ANY); 24232f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = 0; 24242f20216cSAbhishek Pandit-Subedi 24252f20216cSAbhishek Pandit-Subedi hci_dev_unlock(hdev); 24262f20216cSAbhishek Pandit-Subedi } 24272f20216cSAbhishek Pandit-Subedi 24289952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, 24299952d90eSAbhishek Pandit-Subedi void *data) 24309952d90eSAbhishek Pandit-Subedi { 24319952d90eSAbhishek Pandit-Subedi struct hci_dev *hdev = 24329952d90eSAbhishek Pandit-Subedi container_of(nb, struct hci_dev, suspend_notifier); 24339952d90eSAbhishek Pandit-Subedi int ret = 0; 24349952d90eSAbhishek Pandit-Subedi 24354b8af331SAbhishek Pandit-Subedi /* Userspace has full control of this device. Do nothing. */ 24364b8af331SAbhishek Pandit-Subedi if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) 24374b8af331SAbhishek Pandit-Subedi return NOTIFY_DONE; 24384b8af331SAbhishek Pandit-Subedi 2439573ebae1SYing Hsu /* To avoid a potential race with hci_unregister_dev. */ 2440573ebae1SYing Hsu hci_dev_hold(hdev); 2441573ebae1SYing Hsu 2442e1b77d68SLuiz Augusto von Dentz if (action == PM_SUSPEND_PREPARE) 2443e1b77d68SLuiz Augusto von Dentz ret = hci_suspend_dev(hdev); 2444e1b77d68SLuiz Augusto von Dentz else if (action == PM_POST_SUSPEND) 2445e1b77d68SLuiz Augusto von Dentz ret = hci_resume_dev(hdev); 24469952d90eSAbhishek Pandit-Subedi 2447a9ec8423SAbhishek Pandit-Subedi if (ret) 2448a9ec8423SAbhishek Pandit-Subedi bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d", 2449a9ec8423SAbhishek Pandit-Subedi action, ret); 2450a9ec8423SAbhishek Pandit-Subedi 2451573ebae1SYing Hsu hci_dev_put(hdev); 245224b06572SMax Chou return NOTIFY_DONE; 24539952d90eSAbhishek Pandit-Subedi } 24548731840aSAbhishek Pandit-Subedi 24559be0dab7SDavid Herrmann /* Alloc HCI device */ 24566ec56613STedd Ho-Jeong An struct hci_dev *hci_alloc_dev_priv(int sizeof_priv) 24579be0dab7SDavid Herrmann { 24589be0dab7SDavid Herrmann struct hci_dev *hdev; 24596ec56613STedd Ho-Jeong An unsigned int alloc_size; 24609be0dab7SDavid Herrmann 24616ec56613STedd Ho-Jeong An alloc_size = sizeof(*hdev); 24626ec56613STedd Ho-Jeong An if (sizeof_priv) { 24636ec56613STedd Ho-Jeong An /* Fixme: May need ALIGN-ment? */ 24646ec56613STedd Ho-Jeong An alloc_size += sizeof_priv; 24656ec56613STedd Ho-Jeong An } 24666ec56613STedd Ho-Jeong An 24676ec56613STedd Ho-Jeong An hdev = kzalloc(alloc_size, GFP_KERNEL); 24689be0dab7SDavid Herrmann if (!hdev) 24699be0dab7SDavid Herrmann return NULL; 24709be0dab7SDavid Herrmann 2471b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 2472b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 2473b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 2474b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 2475b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 247696c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */ 2477bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 2478bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2479d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0; 2480d2609b34SFlorian Grandel hdev->cur_adv_instance = 0x00; 24815d900e46SFlorian Grandel hdev->adv_instance_timeout = 0; 2482b1b813d4SDavid Herrmann 2483c4f1f408SHoward Chung hdev->advmon_allowlist_duration = 300; 2484c4f1f408SHoward Chung hdev->advmon_no_filter_duration = 500; 248580af16a3SHoward Chung hdev->enable_advmon_interleave_scan = 0x00; /* Default to disable */ 2486c4f1f408SHoward Chung 2487b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 2488b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 2489b1b813d4SDavid Herrmann 24903f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07; 2491628531c9SGeorg Lukas hdev->le_adv_min_interval = 0x0800; 2492628531c9SGeorg Lukas hdev->le_adv_max_interval = 0x0800; 2493bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 2494bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 249510873f99SAlain Michaud hdev->le_scan_int_suspend = 0x0400; 249610873f99SAlain Michaud hdev->le_scan_window_suspend = 0x0012; 249710873f99SAlain Michaud hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT; 249810873f99SAlain Michaud hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN; 2499ba29d036SMarcel Holtmann hdev->le_scan_int_adv_monitor = 0x0060; 2500ba29d036SMarcel Holtmann hdev->le_scan_window_adv_monitor = 0x0030; 250110873f99SAlain Michaud hdev->le_scan_int_connect = 0x0060; 250210873f99SAlain Michaud hdev->le_scan_window_connect = 0x0060; 2503b48c3b59SJonas Holmberg hdev->le_conn_min_interval = 0x0018; 2504b48c3b59SJonas Holmberg hdev->le_conn_max_interval = 0x0028; 250504fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000; 250604fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a; 2507a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = 0x001b; 2508a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = 0x0148; 2509a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = 0x001b; 2510a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = 0x0148; 2511a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = 0x001b; 2512a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = 0x0148; 251330d65e08SMatias Karhumaa hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE; 251430d65e08SMatias Karhumaa hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE; 25156decb5b4SJaganath Kanakkassery hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M; 25166decb5b4SJaganath Kanakkassery hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M; 25171d0fac2cSLuiz Augusto von Dentz hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES; 251810873f99SAlain Michaud hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION; 251949b020c1SAlain Michaud hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT; 25207c395ea5SDaniel Winkler hdev->min_le_tx_power = HCI_TX_POWER_INVALID; 25217c395ea5SDaniel Winkler hdev->max_le_tx_power = HCI_TX_POWER_INVALID; 2522bef64738SMarcel Holtmann 2523d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; 2524b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 252531ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 252631ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 2527302975cbSSpoorthi Ravishankar Koppad hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT; 252858a96fc3SMarcel Holtmann hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE; 2529d6bfd59cSJohan Hedberg 253010873f99SAlain Michaud /* default 1.28 sec page scan */ 253110873f99SAlain Michaud hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD; 253210873f99SAlain Michaud hdev->def_page_scan_int = 0x0800; 253310873f99SAlain Michaud hdev->def_page_scan_window = 0x0012; 253410873f99SAlain Michaud 2535b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 2536b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 2537b1b813d4SDavid Herrmann 2538b338d917SBrian Gix INIT_LIST_HEAD(&hdev->mesh_pending); 2539b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 25403d4f9c00SArchie Pusaka INIT_LIST_HEAD(&hdev->reject_list); 25413d4f9c00SArchie Pusaka INIT_LIST_HEAD(&hdev->accept_list); 2542b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 2543b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 2544b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 2545970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys); 2546b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 25473d4f9c00SArchie Pusaka INIT_LIST_HEAD(&hdev->le_accept_list); 2548cfdb0c2dSAnkit Navik INIT_LIST_HEAD(&hdev->le_resolv_list); 254915819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params); 255077a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns); 255166f8455aSJohan Hedberg INIT_LIST_HEAD(&hdev->pend_le_reports); 25526b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 2553d2609b34SFlorian Grandel INIT_LIST_HEAD(&hdev->adv_instances); 2554600a8749SAlain Michaud INIT_LIST_HEAD(&hdev->blocked_keys); 25553368aa35SManish Mandlik INIT_LIST_HEAD(&hdev->monitored_devices); 2556b1b813d4SDavid Herrmann 25578961987fSKiran K INIT_LIST_HEAD(&hdev->local_codecs); 2558b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 2559b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 2560b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 2561b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 2562c7741d16SMarcel Holtmann INIT_WORK(&hdev->error_reset, hci_error_reset); 2563b1b813d4SDavid Herrmann 25646a98e383SMarcel Holtmann hci_cmd_sync_init(hdev); 25656a98e383SMarcel Holtmann 2566b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 2567b1b813d4SDavid Herrmann 2568b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 2569b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 2570b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 2571b1b813d4SDavid Herrmann 2572b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 2573b1b813d4SDavid Herrmann 257465cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout); 2575de75cd0dSManish Mandlik INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout); 2576b1b813d4SDavid Herrmann 25779695ef87SAbhishek Pandit-Subedi hci_devcd_setup(hdev); 25785fc16cc4SJohan Hedberg hci_request_setup(hdev); 25795fc16cc4SJohan Hedberg 2580b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 2581b1b813d4SDavid Herrmann discovery_init(hdev); 25829be0dab7SDavid Herrmann 25839be0dab7SDavid Herrmann return hdev; 25849be0dab7SDavid Herrmann } 25856ec56613STedd Ho-Jeong An EXPORT_SYMBOL(hci_alloc_dev_priv); 25869be0dab7SDavid Herrmann 25879be0dab7SDavid Herrmann /* Free HCI device */ 25889be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 25899be0dab7SDavid Herrmann { 25909be0dab7SDavid Herrmann /* will free via device release */ 25919be0dab7SDavid Herrmann put_device(&hdev->dev); 25929be0dab7SDavid Herrmann } 25939be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 25949be0dab7SDavid Herrmann 25951da177e4SLinus Torvalds /* Register HCI device */ 25961da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 25971da177e4SLinus Torvalds { 2598b1b813d4SDavid Herrmann int id, error; 25991da177e4SLinus Torvalds 260074292d5aSMarcel Holtmann if (!hdev->open || !hdev->close || !hdev->send) 26011da177e4SLinus Torvalds return -EINVAL; 26021da177e4SLinus Torvalds 260308add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 260408add513SMat Martineau * so the index can be used as the AMP controller ID. 260508add513SMat Martineau */ 26063df92b31SSasha Levin switch (hdev->dev_type) { 2607ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 2608103a2f32SItay Iellin id = ida_simple_get(&hci_index_ida, 0, HCI_MAX_ID, GFP_KERNEL); 26091da177e4SLinus Torvalds break; 26103df92b31SSasha Levin case HCI_AMP: 2611103a2f32SItay Iellin id = ida_simple_get(&hci_index_ida, 1, HCI_MAX_ID, GFP_KERNEL); 26123df92b31SSasha Levin break; 26133df92b31SSasha Levin default: 26143df92b31SSasha Levin return -EINVAL; 26151da177e4SLinus Torvalds } 26161da177e4SLinus Torvalds 26173df92b31SSasha Levin if (id < 0) 26183df92b31SSasha Levin return id; 26193df92b31SSasha Levin 2620103a2f32SItay Iellin snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); 26211da177e4SLinus Torvalds hdev->id = id; 26222d8b3a11SAndrei Emeltchenko 26232d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 26242d8b3a11SAndrei Emeltchenko 262529e2dd0dSTejun Heo hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name); 262633ca954dSDavid Herrmann if (!hdev->workqueue) { 262733ca954dSDavid Herrmann error = -ENOMEM; 262833ca954dSDavid Herrmann goto err; 262933ca954dSDavid Herrmann } 2630f48fd9c8SMarcel Holtmann 263129e2dd0dSTejun Heo hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, 263229e2dd0dSTejun Heo hdev->name); 26336ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 26346ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 26356ead1bbcSJohan Hedberg error = -ENOMEM; 26366ead1bbcSJohan Hedberg goto err; 26376ead1bbcSJohan Hedberg } 26386ead1bbcSJohan Hedberg 26390153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs)) 26400153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); 26410153e2ecSMarcel Holtmann 2642bdc3e0f1SMarcel Holtmann dev_set_name(&hdev->dev, "%s", hdev->name); 2643bdc3e0f1SMarcel Holtmann 2644bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev); 264533ca954dSDavid Herrmann if (error < 0) 264654506918SJohan Hedberg goto err_wqueue; 26471da177e4SLinus Torvalds 26486d5d2ee6SHeiner Kallweit hci_leds_init(hdev); 26496d5d2ee6SHeiner Kallweit 2650611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 2651a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 2652a8c5fb1aSGustavo Padovan hdev); 2653611b30f7SMarcel Holtmann if (hdev->rfkill) { 2654611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 2655611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2656611b30f7SMarcel Holtmann hdev->rfkill = NULL; 2657611b30f7SMarcel Holtmann } 2658611b30f7SMarcel Holtmann } 2659611b30f7SMarcel Holtmann 26605e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 2661a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED); 26625e130367SJohan Hedberg 2663a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SETUP); 2664a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_AUTO_OFF); 2665ce2be9acSAndrei Emeltchenko 2666ca8bee5dSMarcel Holtmann if (hdev->dev_type == HCI_PRIMARY) { 266756f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 266856f87901SJohan Hedberg * through reading supported features during init. 266956f87901SJohan Hedberg */ 2670a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED); 267156f87901SJohan Hedberg } 2672ce2be9acSAndrei Emeltchenko 2673fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 2674fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 2675fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 2676fcee3377SGustavo Padovan 26774a964404SMarcel Holtmann /* Devices that are marked for raw-only usage are unconfigured 26784a964404SMarcel Holtmann * and should not be included in normal operation. 2679fee746b0SMarcel Holtmann */ 2680fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 2681a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 2682fee746b0SMarcel Holtmann 2683fe92ee64SLuiz Augusto von Dentz /* Mark Remote Wakeup connection flag as supported if driver has wakeup 2684fe92ee64SLuiz Augusto von Dentz * callback. 2685fe92ee64SLuiz Augusto von Dentz */ 2686fe92ee64SLuiz Augusto von Dentz if (hdev->wakeup) 2687e1cff700SLinus Torvalds hdev->conn_flags |= HCI_CONN_FLAG_REMOTE_WAKEUP; 2688fe92ee64SLuiz Augusto von Dentz 268905fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_REG); 2690dc946bd8SDavid Herrmann hci_dev_hold(hdev); 26911da177e4SLinus Torvalds 269291117864SDan Carpenter error = hci_register_suspend_notifier(hdev); 269391117864SDan Carpenter if (error) 26940d75da38SYang Yingliang BT_WARN("register suspend notifier failed error:%d\n", error); 26959952d90eSAbhishek Pandit-Subedi 269619202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 2697fbe96d6fSMarcel Holtmann 2698e5e1e7fdSMiao-chen Chou idr_init(&hdev->adv_monitors_idr); 26995031ffccSMiao-chen Chou msft_register(hdev); 2700e5e1e7fdSMiao-chen Chou 27011da177e4SLinus Torvalds return id; 2702f48fd9c8SMarcel Holtmann 270333ca954dSDavid Herrmann err_wqueue: 27045a4bb6a8SWei Yongjun debugfs_remove_recursive(hdev->debugfs); 270533ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 27066ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 270733ca954dSDavid Herrmann err: 27083df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 2709f48fd9c8SMarcel Holtmann 271033ca954dSDavid Herrmann return error; 27111da177e4SLinus Torvalds } 27121da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 27131da177e4SLinus Torvalds 27141da177e4SLinus Torvalds /* Unregister HCI device */ 271559735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 27161da177e4SLinus Torvalds { 2717c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 27181da177e4SLinus Torvalds 27191857c199SZhengping Jiang mutex_lock(&hdev->unregister_lock); 2720a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNREGISTER); 27211857c199SZhengping Jiang mutex_unlock(&hdev->unregister_lock); 272294324962SJohan Hovold 2723f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 27241da177e4SLinus Torvalds list_del(&hdev->list); 2725f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 27261da177e4SLinus Torvalds 2727e36bea6eSVasyl Vavrychuk cancel_work_sync(&hdev->power_on); 2728e36bea6eSVasyl Vavrychuk 27296a98e383SMarcel Holtmann hci_cmd_sync_clear(hdev); 27306a98e383SMarcel Holtmann 2731359ee4f8SAbhishek Pandit-Subedi hci_unregister_suspend_notifier(hdev); 27324e8c36c3SAbhishek Pandit-Subedi 27335031ffccSMiao-chen Chou msft_unregister(hdev); 27345031ffccSMiao-chen Chou 27354e8c36c3SAbhishek Pandit-Subedi hci_dev_do_close(hdev); 27369952d90eSAbhishek Pandit-Subedi 2737ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 2738d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_SETUP) && 2739d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) { 274009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2741744cf19eSJohan Hedberg mgmt_index_removed(hdev); 274209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 274356e5cb86SJohan Hedberg } 2744ab81cbf9SJohan Hedberg 27452e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 27462e58ef3eSJohan Hedberg * pending list */ 27472e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 27482e58ef3eSJohan Hedberg 274905fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UNREG); 27501da177e4SLinus Torvalds 2751611b30f7SMarcel Holtmann if (hdev->rfkill) { 2752611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 2753611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2754611b30f7SMarcel Holtmann } 2755611b30f7SMarcel Holtmann 2756bdc3e0f1SMarcel Holtmann device_del(&hdev->dev); 2757e61fbee7SDavid S. Miller /* Actual cleanup is deferred until hci_release_dev(). */ 2758e0448092STetsuo Handa hci_dev_put(hdev); 2759e0448092STetsuo Handa } 2760e0448092STetsuo Handa EXPORT_SYMBOL(hci_unregister_dev); 2761147e2d59SDave Young 276258ce6d5bSTetsuo Handa /* Release HCI device */ 276358ce6d5bSTetsuo Handa void hci_release_dev(struct hci_dev *hdev) 2764e0448092STetsuo Handa { 27650153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs); 27665177a838SMarcel Holtmann kfree_const(hdev->hw_info); 27675177a838SMarcel Holtmann kfree_const(hdev->fw_info); 27680153e2ecSMarcel Holtmann 2769f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 27706ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 2771f48fd9c8SMarcel Holtmann 277209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 27733d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->reject_list); 27743d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->accept_list); 27752aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 277655ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 2777b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 2778970c4e46SJohan Hedberg hci_smp_irks_clear(hdev); 27792763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 2780d2609b34SFlorian Grandel hci_adv_instances_clear(hdev); 2781e5e1e7fdSMiao-chen Chou hci_adv_monitors_clear(hdev); 27823d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->le_accept_list); 2783cfdb0c2dSAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 2784373110c5SJohan Hedberg hci_conn_params_clear_all(hdev); 278522078800SMarcel Holtmann hci_discovery_filter_clear(hdev); 2786600a8749SAlain Michaud hci_blocked_keys_clear(hdev); 278709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 2788e2e0cacbSJohan Hedberg 2789e0448092STetsuo Handa ida_simple_remove(&hci_index_ida, hdev->id); 2790dd3b1dc3SLuiz Augusto von Dentz kfree_skb(hdev->sent_cmd); 2791dfe6d5c3SLuiz Augusto von Dentz kfree_skb(hdev->recv_event); 279258ce6d5bSTetsuo Handa kfree(hdev); 27931da177e4SLinus Torvalds } 279458ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_release_dev); 27951da177e4SLinus Torvalds 2796359ee4f8SAbhishek Pandit-Subedi int hci_register_suspend_notifier(struct hci_dev *hdev) 2797359ee4f8SAbhishek Pandit-Subedi { 2798359ee4f8SAbhishek Pandit-Subedi int ret = 0; 2799359ee4f8SAbhishek Pandit-Subedi 2800b5ca3387SLuiz Augusto von Dentz if (!hdev->suspend_notifier.notifier_call && 2801b5ca3387SLuiz Augusto von Dentz !test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) { 2802359ee4f8SAbhishek Pandit-Subedi hdev->suspend_notifier.notifier_call = hci_suspend_notifier; 2803359ee4f8SAbhishek Pandit-Subedi ret = register_pm_notifier(&hdev->suspend_notifier); 2804359ee4f8SAbhishek Pandit-Subedi } 2805359ee4f8SAbhishek Pandit-Subedi 2806359ee4f8SAbhishek Pandit-Subedi return ret; 2807359ee4f8SAbhishek Pandit-Subedi } 2808359ee4f8SAbhishek Pandit-Subedi 2809359ee4f8SAbhishek Pandit-Subedi int hci_unregister_suspend_notifier(struct hci_dev *hdev) 2810359ee4f8SAbhishek Pandit-Subedi { 2811359ee4f8SAbhishek Pandit-Subedi int ret = 0; 2812359ee4f8SAbhishek Pandit-Subedi 2813b5ca3387SLuiz Augusto von Dentz if (hdev->suspend_notifier.notifier_call) { 2814359ee4f8SAbhishek Pandit-Subedi ret = unregister_pm_notifier(&hdev->suspend_notifier); 2815b5ca3387SLuiz Augusto von Dentz if (!ret) 2816b5ca3387SLuiz Augusto von Dentz hdev->suspend_notifier.notifier_call = NULL; 2817b5ca3387SLuiz Augusto von Dentz } 2818359ee4f8SAbhishek Pandit-Subedi 2819359ee4f8SAbhishek Pandit-Subedi return ret; 2820359ee4f8SAbhishek Pandit-Subedi } 2821359ee4f8SAbhishek Pandit-Subedi 28221da177e4SLinus Torvalds /* Suspend HCI device */ 28231da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 28241da177e4SLinus Torvalds { 2825e1b77d68SLuiz Augusto von Dentz int ret; 2826e1b77d68SLuiz Augusto von Dentz 2827e1b77d68SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 2828e1b77d68SLuiz Augusto von Dentz 2829e1b77d68SLuiz Augusto von Dentz /* Suspend should only act on when powered. */ 2830e1b77d68SLuiz Augusto von Dentz if (!hdev_is_powered(hdev) || 2831e1b77d68SLuiz Augusto von Dentz hci_dev_test_flag(hdev, HCI_UNREGISTER)) 28321da177e4SLinus Torvalds return 0; 2833e1b77d68SLuiz Augusto von Dentz 2834182ee45dSLuiz Augusto von Dentz /* If powering down don't attempt to suspend */ 2835182ee45dSLuiz Augusto von Dentz if (mgmt_powering_down(hdev)) 2836182ee45dSLuiz Augusto von Dentz return 0; 2837e1b77d68SLuiz Augusto von Dentz 2838f4198635SArchie Pusaka /* Cancel potentially blocking sync operation before suspend */ 2839f4198635SArchie Pusaka __hci_cmd_sync_cancel(hdev, -EHOSTDOWN); 2840f4198635SArchie Pusaka 2841182ee45dSLuiz Augusto von Dentz hci_req_sync_lock(hdev); 2842182ee45dSLuiz Augusto von Dentz ret = hci_suspend_sync(hdev); 2843182ee45dSLuiz Augusto von Dentz hci_req_sync_unlock(hdev); 28444539ca67SLuiz Augusto von Dentz 2845e1b77d68SLuiz Augusto von Dentz hci_clear_wake_reason(hdev); 2846182ee45dSLuiz Augusto von Dentz mgmt_suspending(hdev, hdev->suspend_state); 2847e1b77d68SLuiz Augusto von Dentz 2848e1b77d68SLuiz Augusto von Dentz hci_sock_dev_event(hdev, HCI_DEV_SUSPEND); 2849e1b77d68SLuiz Augusto von Dentz return ret; 28501da177e4SLinus Torvalds } 28511da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 28521da177e4SLinus Torvalds 28531da177e4SLinus Torvalds /* Resume HCI device */ 28541da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 28551da177e4SLinus Torvalds { 2856e1b77d68SLuiz Augusto von Dentz int ret; 2857e1b77d68SLuiz Augusto von Dentz 2858e1b77d68SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 2859e1b77d68SLuiz Augusto von Dentz 2860e1b77d68SLuiz Augusto von Dentz /* Resume should only act on when powered. */ 2861e1b77d68SLuiz Augusto von Dentz if (!hdev_is_powered(hdev) || 2862e1b77d68SLuiz Augusto von Dentz hci_dev_test_flag(hdev, HCI_UNREGISTER)) 28631da177e4SLinus Torvalds return 0; 2864e1b77d68SLuiz Augusto von Dentz 2865e1b77d68SLuiz Augusto von Dentz /* If powering down don't attempt to resume */ 2866e1b77d68SLuiz Augusto von Dentz if (mgmt_powering_down(hdev)) 2867e1b77d68SLuiz Augusto von Dentz return 0; 2868e1b77d68SLuiz Augusto von Dentz 2869182ee45dSLuiz Augusto von Dentz hci_req_sync_lock(hdev); 2870182ee45dSLuiz Augusto von Dentz ret = hci_resume_sync(hdev); 2871182ee45dSLuiz Augusto von Dentz hci_req_sync_unlock(hdev); 2872e1b77d68SLuiz Augusto von Dentz 2873e1b77d68SLuiz Augusto von Dentz mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr, 2874e1b77d68SLuiz Augusto von Dentz hdev->wake_addr_type); 2875e1b77d68SLuiz Augusto von Dentz 2876e1b77d68SLuiz Augusto von Dentz hci_sock_dev_event(hdev, HCI_DEV_RESUME); 2877e1b77d68SLuiz Augusto von Dentz return ret; 28781da177e4SLinus Torvalds } 28791da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 28801da177e4SLinus Torvalds 288175e0569fSMarcel Holtmann /* Reset HCI device */ 288275e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev) 288375e0569fSMarcel Holtmann { 28841e4b6e91SColin Ian King static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; 288575e0569fSMarcel Holtmann struct sk_buff *skb; 288675e0569fSMarcel Holtmann 288775e0569fSMarcel Holtmann skb = bt_skb_alloc(3, GFP_ATOMIC); 288875e0569fSMarcel Holtmann if (!skb) 288975e0569fSMarcel Holtmann return -ENOMEM; 289075e0569fSMarcel Holtmann 2891d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_EVENT_PKT; 289259ae1d12SJohannes Berg skb_put_data(skb, hw_err, 3); 289375e0569fSMarcel Holtmann 2894de75cd0dSManish Mandlik bt_dev_err(hdev, "Injecting HCI hardware error event"); 2895de75cd0dSManish Mandlik 289675e0569fSMarcel Holtmann /* Send Hardware Error to upper stack */ 289775e0569fSMarcel Holtmann return hci_recv_frame(hdev, skb); 289875e0569fSMarcel Holtmann } 289975e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev); 290075e0569fSMarcel Holtmann 290176bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 2902e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 290376bca880SMarcel Holtmann { 290476bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 290576bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 290676bca880SMarcel Holtmann kfree_skb(skb); 290776bca880SMarcel Holtmann return -ENXIO; 290876bca880SMarcel Holtmann } 290976bca880SMarcel Holtmann 2910876e7810SLuiz Augusto von Dentz switch (hci_skb_pkt_type(skb)) { 2911876e7810SLuiz Augusto von Dentz case HCI_EVENT_PKT: 2912876e7810SLuiz Augusto von Dentz break; 2913876e7810SLuiz Augusto von Dentz case HCI_ACLDATA_PKT: 2914876e7810SLuiz Augusto von Dentz /* Detect if ISO packet has been sent as ACL */ 2915876e7810SLuiz Augusto von Dentz if (hci_conn_num(hdev, ISO_LINK)) { 2916876e7810SLuiz Augusto von Dentz __u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle); 2917876e7810SLuiz Augusto von Dentz __u8 type; 2918876e7810SLuiz Augusto von Dentz 2919876e7810SLuiz Augusto von Dentz type = hci_conn_lookup_type(hdev, hci_handle(handle)); 2920876e7810SLuiz Augusto von Dentz if (type == ISO_LINK) 2921876e7810SLuiz Augusto von Dentz hci_skb_pkt_type(skb) = HCI_ISODATA_PKT; 2922876e7810SLuiz Augusto von Dentz } 2923876e7810SLuiz Augusto von Dentz break; 2924876e7810SLuiz Augusto von Dentz case HCI_SCODATA_PKT: 2925876e7810SLuiz Augusto von Dentz break; 2926876e7810SLuiz Augusto von Dentz case HCI_ISODATA_PKT: 2927876e7810SLuiz Augusto von Dentz break; 2928876e7810SLuiz Augusto von Dentz default: 2929fe806dceSMarcel Holtmann kfree_skb(skb); 2930fe806dceSMarcel Holtmann return -EINVAL; 2931fe806dceSMarcel Holtmann } 2932fe806dceSMarcel Holtmann 2933d82603c6SJorrit Schippers /* Incoming skb */ 293476bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 293576bca880SMarcel Holtmann 293676bca880SMarcel Holtmann /* Time stamp */ 293776bca880SMarcel Holtmann __net_timestamp(skb); 293876bca880SMarcel Holtmann 293976bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 2940b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 2941c78ae283SMarcel Holtmann 294276bca880SMarcel Holtmann return 0; 294376bca880SMarcel Holtmann } 294476bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 294576bca880SMarcel Holtmann 2946e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */ 2947e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb) 2948e875ff84SMarcel Holtmann { 2949581d6fd6SMarcel Holtmann /* Mark as diagnostic packet */ 2950d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_DIAG_PKT; 2951581d6fd6SMarcel Holtmann 2952e875ff84SMarcel Holtmann /* Time stamp */ 2953e875ff84SMarcel Holtmann __net_timestamp(skb); 2954e875ff84SMarcel Holtmann 2955581d6fd6SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 2956581d6fd6SMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 2957e875ff84SMarcel Holtmann 2958e875ff84SMarcel Holtmann return 0; 2959e875ff84SMarcel Holtmann } 2960e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag); 2961e875ff84SMarcel Holtmann 29625177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...) 29635177a838SMarcel Holtmann { 29645177a838SMarcel Holtmann va_list vargs; 29655177a838SMarcel Holtmann 29665177a838SMarcel Holtmann va_start(vargs, fmt); 29675177a838SMarcel Holtmann kfree_const(hdev->hw_info); 29685177a838SMarcel Holtmann hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 29695177a838SMarcel Holtmann va_end(vargs); 29705177a838SMarcel Holtmann } 29715177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info); 29725177a838SMarcel Holtmann 29735177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...) 29745177a838SMarcel Holtmann { 29755177a838SMarcel Holtmann va_list vargs; 29765177a838SMarcel Holtmann 29775177a838SMarcel Holtmann va_start(vargs, fmt); 29785177a838SMarcel Holtmann kfree_const(hdev->fw_info); 29795177a838SMarcel Holtmann hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs); 29805177a838SMarcel Holtmann va_end(vargs); 29815177a838SMarcel Holtmann } 29825177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info); 29835177a838SMarcel Holtmann 29841da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 29851da177e4SLinus Torvalds 29861da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 29871da177e4SLinus Torvalds { 29881da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 29891da177e4SLinus Torvalds 2990fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 299100629e0fSJohan Hedberg list_add_tail(&cb->list, &hci_cb_list); 2992fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 29931da177e4SLinus Torvalds 29941da177e4SLinus Torvalds return 0; 29951da177e4SLinus Torvalds } 29961da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 29971da177e4SLinus Torvalds 29981da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 29991da177e4SLinus Torvalds { 30001da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 30011da177e4SLinus Torvalds 3002fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 30031da177e4SLinus Torvalds list_del(&cb->list); 3004fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 30051da177e4SLinus Torvalds 30061da177e4SLinus Torvalds return 0; 30071da177e4SLinus Torvalds } 30081da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 30091da177e4SLinus Torvalds 30102250abadSBenjamin Berg static int hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 30111da177e4SLinus Torvalds { 3012cdc52faaSMarcel Holtmann int err; 3013cdc52faaSMarcel Holtmann 3014d79f34e3SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb), 3015d79f34e3SMarcel Holtmann skb->len); 30161da177e4SLinus Torvalds 30171da177e4SLinus Torvalds /* Time stamp */ 3018a61bbcf2SPatrick McHardy __net_timestamp(skb); 30191da177e4SLinus Torvalds 3020cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3021cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3022cd82e61cSMarcel Holtmann 3023cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 3024cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 3025470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 30261da177e4SLinus Torvalds } 30271da177e4SLinus Torvalds 30281da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 30291da177e4SLinus Torvalds skb_orphan(skb); 30301da177e4SLinus Torvalds 303173d0d3c8SMarcel Holtmann if (!test_bit(HCI_RUNNING, &hdev->flags)) { 303273d0d3c8SMarcel Holtmann kfree_skb(skb); 30332250abadSBenjamin Berg return -EINVAL; 303473d0d3c8SMarcel Holtmann } 303573d0d3c8SMarcel Holtmann 3036cdc52faaSMarcel Holtmann err = hdev->send(hdev, skb); 3037cdc52faaSMarcel Holtmann if (err < 0) { 30382064ee33SMarcel Holtmann bt_dev_err(hdev, "sending frame failed (%d)", err); 3039cdc52faaSMarcel Holtmann kfree_skb(skb); 30402250abadSBenjamin Berg return err; 3041cdc52faaSMarcel Holtmann } 30422250abadSBenjamin Berg 30432250abadSBenjamin Berg return 0; 30441da177e4SLinus Torvalds } 30451da177e4SLinus Torvalds 30461ca3a9d0SJohan Hedberg /* Send HCI command */ 304707dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 304807dc93ddSJohan Hedberg const void *param) 30491ca3a9d0SJohan Hedberg { 30501ca3a9d0SJohan Hedberg struct sk_buff *skb; 30511ca3a9d0SJohan Hedberg 30521ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 30531ca3a9d0SJohan Hedberg 30541ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 30551ca3a9d0SJohan Hedberg if (!skb) { 30562064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for command"); 30571ca3a9d0SJohan Hedberg return -ENOMEM; 30581ca3a9d0SJohan Hedberg } 30591ca3a9d0SJohan Hedberg 306049c922bbSStephen Hemminger /* Stand-alone HCI commands must be flagged as 306111714b3dSJohan Hedberg * single-command requests. 306211714b3dSJohan Hedberg */ 306344d27137SJohan Hedberg bt_cb(skb)->hci.req_flags |= HCI_REQ_START; 306411714b3dSJohan Hedberg 30651da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 3066c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 30671da177e4SLinus Torvalds 30681da177e4SLinus Torvalds return 0; 30691da177e4SLinus Torvalds } 30701da177e4SLinus Torvalds 3071d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen, 3072d6ee6ad7SLoic Poulain const void *param) 3073d6ee6ad7SLoic Poulain { 3074d6ee6ad7SLoic Poulain struct sk_buff *skb; 3075d6ee6ad7SLoic Poulain 3076d6ee6ad7SLoic Poulain if (hci_opcode_ogf(opcode) != 0x3f) { 3077d6ee6ad7SLoic Poulain /* A controller receiving a command shall respond with either 3078d6ee6ad7SLoic Poulain * a Command Status Event or a Command Complete Event. 3079d6ee6ad7SLoic Poulain * Therefore, all standard HCI commands must be sent via the 3080d6ee6ad7SLoic Poulain * standard API, using hci_send_cmd or hci_cmd_sync helpers. 3081d6ee6ad7SLoic Poulain * Some vendors do not comply with this rule for vendor-specific 3082d6ee6ad7SLoic Poulain * commands and do not return any event. We want to support 3083d6ee6ad7SLoic Poulain * unresponded commands for such cases only. 3084d6ee6ad7SLoic Poulain */ 3085d6ee6ad7SLoic Poulain bt_dev_err(hdev, "unresponded command not supported"); 3086d6ee6ad7SLoic Poulain return -EINVAL; 3087d6ee6ad7SLoic Poulain } 3088d6ee6ad7SLoic Poulain 3089d6ee6ad7SLoic Poulain skb = hci_prepare_cmd(hdev, opcode, plen, param); 3090d6ee6ad7SLoic Poulain if (!skb) { 3091d6ee6ad7SLoic Poulain bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)", 3092d6ee6ad7SLoic Poulain opcode); 3093d6ee6ad7SLoic Poulain return -ENOMEM; 3094d6ee6ad7SLoic Poulain } 3095d6ee6ad7SLoic Poulain 3096d6ee6ad7SLoic Poulain hci_send_frame(hdev, skb); 3097d6ee6ad7SLoic Poulain 3098d6ee6ad7SLoic Poulain return 0; 3099d6ee6ad7SLoic Poulain } 3100d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send); 3101d6ee6ad7SLoic Poulain 31021da177e4SLinus Torvalds /* Get data from the previously sent command */ 3103a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 31041da177e4SLinus Torvalds { 31051da177e4SLinus Torvalds struct hci_command_hdr *hdr; 31061da177e4SLinus Torvalds 31071da177e4SLinus Torvalds if (!hdev->sent_cmd) 31081da177e4SLinus Torvalds return NULL; 31091da177e4SLinus Torvalds 31101da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 31111da177e4SLinus Torvalds 3112a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 31131da177e4SLinus Torvalds return NULL; 31141da177e4SLinus Torvalds 3115f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 31161da177e4SLinus Torvalds 31171da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 31181da177e4SLinus Torvalds } 31191da177e4SLinus Torvalds 3120dfe6d5c3SLuiz Augusto von Dentz /* Get data from last received event */ 3121dfe6d5c3SLuiz Augusto von Dentz void *hci_recv_event_data(struct hci_dev *hdev, __u8 event) 3122dfe6d5c3SLuiz Augusto von Dentz { 3123dfe6d5c3SLuiz Augusto von Dentz struct hci_event_hdr *hdr; 3124dfe6d5c3SLuiz Augusto von Dentz int offset; 3125dfe6d5c3SLuiz Augusto von Dentz 3126dfe6d5c3SLuiz Augusto von Dentz if (!hdev->recv_event) 3127dfe6d5c3SLuiz Augusto von Dentz return NULL; 3128dfe6d5c3SLuiz Augusto von Dentz 3129dfe6d5c3SLuiz Augusto von Dentz hdr = (void *)hdev->recv_event->data; 3130dfe6d5c3SLuiz Augusto von Dentz offset = sizeof(*hdr); 3131dfe6d5c3SLuiz Augusto von Dentz 3132dfe6d5c3SLuiz Augusto von Dentz if (hdr->evt != event) { 3133dfe6d5c3SLuiz Augusto von Dentz /* In case of LE metaevent check the subevent match */ 3134dfe6d5c3SLuiz Augusto von Dentz if (hdr->evt == HCI_EV_LE_META) { 3135dfe6d5c3SLuiz Augusto von Dentz struct hci_ev_le_meta *ev; 3136dfe6d5c3SLuiz Augusto von Dentz 3137dfe6d5c3SLuiz Augusto von Dentz ev = (void *)hdev->recv_event->data + offset; 3138dfe6d5c3SLuiz Augusto von Dentz offset += sizeof(*ev); 3139dfe6d5c3SLuiz Augusto von Dentz if (ev->subevent == event) 3140dfe6d5c3SLuiz Augusto von Dentz goto found; 3141dfe6d5c3SLuiz Augusto von Dentz } 3142dfe6d5c3SLuiz Augusto von Dentz return NULL; 3143dfe6d5c3SLuiz Augusto von Dentz } 3144dfe6d5c3SLuiz Augusto von Dentz 3145dfe6d5c3SLuiz Augusto von Dentz found: 3146dfe6d5c3SLuiz Augusto von Dentz bt_dev_dbg(hdev, "event 0x%2.2x", event); 3147dfe6d5c3SLuiz Augusto von Dentz 3148dfe6d5c3SLuiz Augusto von Dentz return hdev->recv_event->data + offset; 3149dfe6d5c3SLuiz Augusto von Dentz } 3150dfe6d5c3SLuiz Augusto von Dentz 31511da177e4SLinus Torvalds /* Send ACL data */ 31521da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 31531da177e4SLinus Torvalds { 31541da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 31551da177e4SLinus Torvalds int len = skb->len; 31561da177e4SLinus Torvalds 3157badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 3158badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 31599c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 3160aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 3161aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 31621da177e4SLinus Torvalds } 31631da177e4SLinus Torvalds 3164ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 316573d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 31661da177e4SLinus Torvalds { 3167ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 31681da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 31691da177e4SLinus Torvalds struct sk_buff *list; 31701da177e4SLinus Torvalds 3171087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 3172087bfd99SGustavo Padovan skb->data_len = 0; 3173087bfd99SGustavo Padovan 3174d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 3175204a6e54SAndrei Emeltchenko 3176204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 3177ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 3178087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 3179204a6e54SAndrei Emeltchenko break; 3180204a6e54SAndrei Emeltchenko case HCI_AMP: 3181204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 3182204a6e54SAndrei Emeltchenko break; 3183204a6e54SAndrei Emeltchenko default: 31842064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type); 3185204a6e54SAndrei Emeltchenko return; 3186204a6e54SAndrei Emeltchenko } 3187087bfd99SGustavo Padovan 318870f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 318970f23020SAndrei Emeltchenko if (!list) { 31901da177e4SLinus Torvalds /* Non fragmented */ 31911da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 31921da177e4SLinus Torvalds 319373d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 31941da177e4SLinus Torvalds } else { 31951da177e4SLinus Torvalds /* Fragmented */ 31961da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 31971da177e4SLinus Torvalds 31981da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 31991da177e4SLinus Torvalds 32009cfd5a23SJukka Rissanen /* Queue all fragments atomically. We need to use spin_lock_bh 32019cfd5a23SJukka Rissanen * here because of 6LoWPAN links, as there this function is 32029cfd5a23SJukka Rissanen * called from softirq and using normal spin lock could cause 32039cfd5a23SJukka Rissanen * deadlocks. 32049cfd5a23SJukka Rissanen */ 32059cfd5a23SJukka Rissanen spin_lock_bh(&queue->lock); 32061da177e4SLinus Torvalds 320773d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 3208e702112fSAndrei Emeltchenko 3209e702112fSAndrei Emeltchenko flags &= ~ACL_START; 3210e702112fSAndrei Emeltchenko flags |= ACL_CONT; 32111da177e4SLinus Torvalds do { 32121da177e4SLinus Torvalds skb = list; list = list->next; 32131da177e4SLinus Torvalds 3214d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT; 3215e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 32161da177e4SLinus Torvalds 32171da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 32181da177e4SLinus Torvalds 321973d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 32201da177e4SLinus Torvalds } while (list); 32211da177e4SLinus Torvalds 32229cfd5a23SJukka Rissanen spin_unlock_bh(&queue->lock); 32231da177e4SLinus Torvalds } 322473d80debSLuiz Augusto von Dentz } 322573d80debSLuiz Augusto von Dentz 322673d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 322773d80debSLuiz Augusto von Dentz { 3228ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 322973d80debSLuiz Augusto von Dentz 3230f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 323173d80debSLuiz Augusto von Dentz 3232ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 32331da177e4SLinus Torvalds 32343eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 32351da177e4SLinus Torvalds } 32361da177e4SLinus Torvalds 32371da177e4SLinus Torvalds /* Send SCO data */ 32380d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 32391da177e4SLinus Torvalds { 32401da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 32411da177e4SLinus Torvalds struct hci_sco_hdr hdr; 32421da177e4SLinus Torvalds 32431da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 32441da177e4SLinus Torvalds 3245aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 32461da177e4SLinus Torvalds hdr.dlen = skb->len; 32471da177e4SLinus Torvalds 3248badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 3249badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 32509c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 32511da177e4SLinus Torvalds 3252d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_SCODATA_PKT; 3253c78ae283SMarcel Holtmann 32541da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 32553eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 32561da177e4SLinus Torvalds } 32571da177e4SLinus Torvalds 325826afbd82SLuiz Augusto von Dentz /* Send ISO data */ 325926afbd82SLuiz Augusto von Dentz static void hci_add_iso_hdr(struct sk_buff *skb, __u16 handle, __u8 flags) 326026afbd82SLuiz Augusto von Dentz { 326126afbd82SLuiz Augusto von Dentz struct hci_iso_hdr *hdr; 326226afbd82SLuiz Augusto von Dentz int len = skb->len; 326326afbd82SLuiz Augusto von Dentz 326426afbd82SLuiz Augusto von Dentz skb_push(skb, HCI_ISO_HDR_SIZE); 326526afbd82SLuiz Augusto von Dentz skb_reset_transport_header(skb); 326626afbd82SLuiz Augusto von Dentz hdr = (struct hci_iso_hdr *)skb_transport_header(skb); 326726afbd82SLuiz Augusto von Dentz hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 326826afbd82SLuiz Augusto von Dentz hdr->dlen = cpu_to_le16(len); 326926afbd82SLuiz Augusto von Dentz } 327026afbd82SLuiz Augusto von Dentz 327126afbd82SLuiz Augusto von Dentz static void hci_queue_iso(struct hci_conn *conn, struct sk_buff_head *queue, 327226afbd82SLuiz Augusto von Dentz struct sk_buff *skb) 327326afbd82SLuiz Augusto von Dentz { 327426afbd82SLuiz Augusto von Dentz struct hci_dev *hdev = conn->hdev; 327526afbd82SLuiz Augusto von Dentz struct sk_buff *list; 327626afbd82SLuiz Augusto von Dentz __u16 flags; 327726afbd82SLuiz Augusto von Dentz 327826afbd82SLuiz Augusto von Dentz skb->len = skb_headlen(skb); 327926afbd82SLuiz Augusto von Dentz skb->data_len = 0; 328026afbd82SLuiz Augusto von Dentz 328126afbd82SLuiz Augusto von Dentz hci_skb_pkt_type(skb) = HCI_ISODATA_PKT; 328226afbd82SLuiz Augusto von Dentz 328326afbd82SLuiz Augusto von Dentz list = skb_shinfo(skb)->frag_list; 328426afbd82SLuiz Augusto von Dentz 328526afbd82SLuiz Augusto von Dentz flags = hci_iso_flags_pack(list ? ISO_START : ISO_SINGLE, 0x00); 328626afbd82SLuiz Augusto von Dentz hci_add_iso_hdr(skb, conn->handle, flags); 328726afbd82SLuiz Augusto von Dentz 328826afbd82SLuiz Augusto von Dentz if (!list) { 328926afbd82SLuiz Augusto von Dentz /* Non fragmented */ 329026afbd82SLuiz Augusto von Dentz BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 329126afbd82SLuiz Augusto von Dentz 329226afbd82SLuiz Augusto von Dentz skb_queue_tail(queue, skb); 329326afbd82SLuiz Augusto von Dentz } else { 329426afbd82SLuiz Augusto von Dentz /* Fragmented */ 329526afbd82SLuiz Augusto von Dentz BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 329626afbd82SLuiz Augusto von Dentz 329726afbd82SLuiz Augusto von Dentz skb_shinfo(skb)->frag_list = NULL; 329826afbd82SLuiz Augusto von Dentz 329926afbd82SLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 330026afbd82SLuiz Augusto von Dentz 330126afbd82SLuiz Augusto von Dentz do { 330226afbd82SLuiz Augusto von Dentz skb = list; list = list->next; 330326afbd82SLuiz Augusto von Dentz 330426afbd82SLuiz Augusto von Dentz hci_skb_pkt_type(skb) = HCI_ISODATA_PKT; 330526afbd82SLuiz Augusto von Dentz flags = hci_iso_flags_pack(list ? ISO_CONT : ISO_END, 330626afbd82SLuiz Augusto von Dentz 0x00); 330726afbd82SLuiz Augusto von Dentz hci_add_iso_hdr(skb, conn->handle, flags); 330826afbd82SLuiz Augusto von Dentz 330926afbd82SLuiz Augusto von Dentz BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 331026afbd82SLuiz Augusto von Dentz 331126afbd82SLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 331226afbd82SLuiz Augusto von Dentz } while (list); 331326afbd82SLuiz Augusto von Dentz } 331426afbd82SLuiz Augusto von Dentz } 331526afbd82SLuiz Augusto von Dentz 331626afbd82SLuiz Augusto von Dentz void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb) 331726afbd82SLuiz Augusto von Dentz { 331826afbd82SLuiz Augusto von Dentz struct hci_dev *hdev = conn->hdev; 331926afbd82SLuiz Augusto von Dentz 332026afbd82SLuiz Augusto von Dentz BT_DBG("%s len %d", hdev->name, skb->len); 332126afbd82SLuiz Augusto von Dentz 332226afbd82SLuiz Augusto von Dentz hci_queue_iso(conn, &conn->data_q, skb); 332326afbd82SLuiz Augusto von Dentz 332426afbd82SLuiz Augusto von Dentz queue_work(hdev->workqueue, &hdev->tx_work); 332526afbd82SLuiz Augusto von Dentz } 332626afbd82SLuiz Augusto von Dentz 33271da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 33281da177e4SLinus Torvalds 33291da177e4SLinus Torvalds /* HCI Connection scheduler */ 333026afbd82SLuiz Augusto von Dentz static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote) 333126afbd82SLuiz Augusto von Dentz { 333226afbd82SLuiz Augusto von Dentz struct hci_dev *hdev; 333326afbd82SLuiz Augusto von Dentz int cnt, q; 333426afbd82SLuiz Augusto von Dentz 333526afbd82SLuiz Augusto von Dentz if (!conn) { 333626afbd82SLuiz Augusto von Dentz *quote = 0; 333726afbd82SLuiz Augusto von Dentz return; 333826afbd82SLuiz Augusto von Dentz } 333926afbd82SLuiz Augusto von Dentz 334026afbd82SLuiz Augusto von Dentz hdev = conn->hdev; 334126afbd82SLuiz Augusto von Dentz 334226afbd82SLuiz Augusto von Dentz switch (conn->type) { 334326afbd82SLuiz Augusto von Dentz case ACL_LINK: 334426afbd82SLuiz Augusto von Dentz cnt = hdev->acl_cnt; 334526afbd82SLuiz Augusto von Dentz break; 334626afbd82SLuiz Augusto von Dentz case AMP_LINK: 334726afbd82SLuiz Augusto von Dentz cnt = hdev->block_cnt; 334826afbd82SLuiz Augusto von Dentz break; 334926afbd82SLuiz Augusto von Dentz case SCO_LINK: 335026afbd82SLuiz Augusto von Dentz case ESCO_LINK: 335126afbd82SLuiz Augusto von Dentz cnt = hdev->sco_cnt; 335226afbd82SLuiz Augusto von Dentz break; 335326afbd82SLuiz Augusto von Dentz case LE_LINK: 335426afbd82SLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 335526afbd82SLuiz Augusto von Dentz break; 335626afbd82SLuiz Augusto von Dentz case ISO_LINK: 335726afbd82SLuiz Augusto von Dentz cnt = hdev->iso_mtu ? hdev->iso_cnt : 335826afbd82SLuiz Augusto von Dentz hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 335926afbd82SLuiz Augusto von Dentz break; 336026afbd82SLuiz Augusto von Dentz default: 336126afbd82SLuiz Augusto von Dentz cnt = 0; 336226afbd82SLuiz Augusto von Dentz bt_dev_err(hdev, "unknown link type %d", conn->type); 336326afbd82SLuiz Augusto von Dentz } 336426afbd82SLuiz Augusto von Dentz 336526afbd82SLuiz Augusto von Dentz q = cnt / num; 336626afbd82SLuiz Augusto von Dentz *quote = q ? q : 1; 336726afbd82SLuiz Augusto von Dentz } 336826afbd82SLuiz Augusto von Dentz 33696039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 3370a8c5fb1aSGustavo Padovan int *quote) 33711da177e4SLinus Torvalds { 33721da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 33738035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 3374abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 33751da177e4SLinus Torvalds 33761da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 33771da177e4SLinus Torvalds * added and removed with TX task disabled. */ 3378bf4c6325SGustavo F. Padovan 3379bf4c6325SGustavo F. Padovan rcu_read_lock(); 3380bf4c6325SGustavo F. Padovan 3381bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3382769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 33831da177e4SLinus Torvalds continue; 3384769be974SMarcel Holtmann 3385769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 3386769be974SMarcel Holtmann continue; 3387769be974SMarcel Holtmann 33881da177e4SLinus Torvalds num++; 33891da177e4SLinus Torvalds 33901da177e4SLinus Torvalds if (c->sent < min) { 33911da177e4SLinus Torvalds min = c->sent; 33921da177e4SLinus Torvalds conn = c; 33931da177e4SLinus Torvalds } 339452087a79SLuiz Augusto von Dentz 339552087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 339652087a79SLuiz Augusto von Dentz break; 33971da177e4SLinus Torvalds } 33981da177e4SLinus Torvalds 3399bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3400bf4c6325SGustavo F. Padovan 340126afbd82SLuiz Augusto von Dentz hci_quote_sent(conn, num, quote); 34021da177e4SLinus Torvalds 34031da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 34041da177e4SLinus Torvalds return conn; 34051da177e4SLinus Torvalds } 34061da177e4SLinus Torvalds 34076039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 34081da177e4SLinus Torvalds { 34091da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 34101da177e4SLinus Torvalds struct hci_conn *c; 34111da177e4SLinus Torvalds 34122064ee33SMarcel Holtmann bt_dev_err(hdev, "link tx timeout"); 34131da177e4SLinus Torvalds 3414bf4c6325SGustavo F. Padovan rcu_read_lock(); 3415bf4c6325SGustavo F. Padovan 34161da177e4SLinus Torvalds /* Kill stalled connections */ 3417bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3418bae1f5d9SVille Tervo if (c->type == type && c->sent) { 34192064ee33SMarcel Holtmann bt_dev_err(hdev, "killing stalled connection %pMR", 34202064ee33SMarcel Holtmann &c->dst); 3421*c7eaf80bSYing Hsu /* hci_disconnect might sleep, so, we have to release 3422*c7eaf80bSYing Hsu * the RCU read lock before calling it. 3423*c7eaf80bSYing Hsu */ 3424*c7eaf80bSYing Hsu rcu_read_unlock(); 3425bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 3426*c7eaf80bSYing Hsu rcu_read_lock(); 34271da177e4SLinus Torvalds } 34281da177e4SLinus Torvalds } 3429bf4c6325SGustavo F. Padovan 3430bf4c6325SGustavo F. Padovan rcu_read_unlock(); 34311da177e4SLinus Torvalds } 34321da177e4SLinus Torvalds 34336039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 343473d80debSLuiz Augusto von Dentz int *quote) 343573d80debSLuiz Augusto von Dentz { 343673d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 343773d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 3438abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 343973d80debSLuiz Augusto von Dentz struct hci_conn *conn; 344026afbd82SLuiz Augusto von Dentz int conn_num = 0; 344173d80debSLuiz Augusto von Dentz 344273d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 344373d80debSLuiz Augusto von Dentz 3444bf4c6325SGustavo F. Padovan rcu_read_lock(); 3445bf4c6325SGustavo F. Padovan 3446bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 344773d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 344873d80debSLuiz Augusto von Dentz 344973d80debSLuiz Augusto von Dentz if (conn->type != type) 345073d80debSLuiz Augusto von Dentz continue; 345173d80debSLuiz Augusto von Dentz 345273d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 345373d80debSLuiz Augusto von Dentz continue; 345473d80debSLuiz Augusto von Dentz 345573d80debSLuiz Augusto von Dentz conn_num++; 345673d80debSLuiz Augusto von Dentz 34578192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 345873d80debSLuiz Augusto von Dentz struct sk_buff *skb; 345973d80debSLuiz Augusto von Dentz 346073d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 346173d80debSLuiz Augusto von Dentz continue; 346273d80debSLuiz Augusto von Dentz 346373d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 346473d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 346573d80debSLuiz Augusto von Dentz continue; 346673d80debSLuiz Augusto von Dentz 346773d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 346873d80debSLuiz Augusto von Dentz num = 0; 346973d80debSLuiz Augusto von Dentz min = ~0; 347073d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 347173d80debSLuiz Augusto von Dentz } 347273d80debSLuiz Augusto von Dentz 347373d80debSLuiz Augusto von Dentz num++; 347473d80debSLuiz Augusto von Dentz 347573d80debSLuiz Augusto von Dentz if (conn->sent < min) { 347673d80debSLuiz Augusto von Dentz min = conn->sent; 347773d80debSLuiz Augusto von Dentz chan = tmp; 347873d80debSLuiz Augusto von Dentz } 347973d80debSLuiz Augusto von Dentz } 348073d80debSLuiz Augusto von Dentz 348173d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 348273d80debSLuiz Augusto von Dentz break; 348373d80debSLuiz Augusto von Dentz } 348473d80debSLuiz Augusto von Dentz 3485bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3486bf4c6325SGustavo F. Padovan 348773d80debSLuiz Augusto von Dentz if (!chan) 348873d80debSLuiz Augusto von Dentz return NULL; 348973d80debSLuiz Augusto von Dentz 349026afbd82SLuiz Augusto von Dentz hci_quote_sent(chan->conn, num, quote); 349173d80debSLuiz Augusto von Dentz 349273d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 349373d80debSLuiz Augusto von Dentz return chan; 349473d80debSLuiz Augusto von Dentz } 349573d80debSLuiz Augusto von Dentz 349602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 349702b20f0bSLuiz Augusto von Dentz { 349802b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 349902b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 350002b20f0bSLuiz Augusto von Dentz int num = 0; 350102b20f0bSLuiz Augusto von Dentz 350202b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 350302b20f0bSLuiz Augusto von Dentz 3504bf4c6325SGustavo F. Padovan rcu_read_lock(); 3505bf4c6325SGustavo F. Padovan 3506bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 350702b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 350802b20f0bSLuiz Augusto von Dentz 350902b20f0bSLuiz Augusto von Dentz if (conn->type != type) 351002b20f0bSLuiz Augusto von Dentz continue; 351102b20f0bSLuiz Augusto von Dentz 351202b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 351302b20f0bSLuiz Augusto von Dentz continue; 351402b20f0bSLuiz Augusto von Dentz 351502b20f0bSLuiz Augusto von Dentz num++; 351602b20f0bSLuiz Augusto von Dentz 35178192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 351802b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 351902b20f0bSLuiz Augusto von Dentz 352002b20f0bSLuiz Augusto von Dentz if (chan->sent) { 352102b20f0bSLuiz Augusto von Dentz chan->sent = 0; 352202b20f0bSLuiz Augusto von Dentz continue; 352302b20f0bSLuiz Augusto von Dentz } 352402b20f0bSLuiz Augusto von Dentz 352502b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 352602b20f0bSLuiz Augusto von Dentz continue; 352702b20f0bSLuiz Augusto von Dentz 352802b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 352902b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 353002b20f0bSLuiz Augusto von Dentz continue; 353102b20f0bSLuiz Augusto von Dentz 353202b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 353302b20f0bSLuiz Augusto von Dentz 353402b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 353502b20f0bSLuiz Augusto von Dentz skb->priority); 353602b20f0bSLuiz Augusto von Dentz } 353702b20f0bSLuiz Augusto von Dentz 353802b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 353902b20f0bSLuiz Augusto von Dentz break; 354002b20f0bSLuiz Augusto von Dentz } 3541bf4c6325SGustavo F. Padovan 3542bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3543bf4c6325SGustavo F. Padovan 354402b20f0bSLuiz Augusto von Dentz } 354502b20f0bSLuiz Augusto von Dentz 3546b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 3547b71d385aSAndrei Emeltchenko { 3548b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 3549b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 3550b71d385aSAndrei Emeltchenko } 3551b71d385aSAndrei Emeltchenko 3552116523c8SLuiz Augusto von Dentz static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type) 35531da177e4SLinus Torvalds { 3554116523c8SLuiz Augusto von Dentz unsigned long last_tx; 3555116523c8SLuiz Augusto von Dentz 3556116523c8SLuiz Augusto von Dentz if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) 3557116523c8SLuiz Augusto von Dentz return; 3558116523c8SLuiz Augusto von Dentz 3559116523c8SLuiz Augusto von Dentz switch (type) { 3560116523c8SLuiz Augusto von Dentz case LE_LINK: 3561116523c8SLuiz Augusto von Dentz last_tx = hdev->le_last_tx; 3562116523c8SLuiz Augusto von Dentz break; 3563116523c8SLuiz Augusto von Dentz default: 3564116523c8SLuiz Augusto von Dentz last_tx = hdev->acl_last_tx; 3565116523c8SLuiz Augusto von Dentz break; 35661da177e4SLinus Torvalds } 3567116523c8SLuiz Augusto von Dentz 3568116523c8SLuiz Augusto von Dentz /* tx timeout must be longer than maximum link supervision timeout 3569116523c8SLuiz Augusto von Dentz * (40.9 seconds) 3570116523c8SLuiz Augusto von Dentz */ 3571116523c8SLuiz Augusto von Dentz if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT)) 3572116523c8SLuiz Augusto von Dentz hci_link_tx_to(hdev, type); 357363d2bc1bSAndrei Emeltchenko } 35741da177e4SLinus Torvalds 35757fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */ 35767fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev) 35777fedd3bbSAbhishek Pandit-Subedi { 35787fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn; 35797fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb; 35807fedd3bbSAbhishek Pandit-Subedi int quote; 35817fedd3bbSAbhishek Pandit-Subedi 35827fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name); 35837fedd3bbSAbhishek Pandit-Subedi 35847fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, SCO_LINK)) 35857fedd3bbSAbhishek Pandit-Subedi return; 35867fedd3bbSAbhishek Pandit-Subedi 35877fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 35887fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 35897fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len); 35907fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb); 35917fedd3bbSAbhishek Pandit-Subedi 35927fedd3bbSAbhishek Pandit-Subedi conn->sent++; 35937fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0) 35947fedd3bbSAbhishek Pandit-Subedi conn->sent = 0; 35957fedd3bbSAbhishek Pandit-Subedi } 35967fedd3bbSAbhishek Pandit-Subedi } 35977fedd3bbSAbhishek Pandit-Subedi } 35987fedd3bbSAbhishek Pandit-Subedi 35997fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev) 36007fedd3bbSAbhishek Pandit-Subedi { 36017fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn; 36027fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb; 36037fedd3bbSAbhishek Pandit-Subedi int quote; 36047fedd3bbSAbhishek Pandit-Subedi 36057fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name); 36067fedd3bbSAbhishek Pandit-Subedi 36077fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, ESCO_LINK)) 36087fedd3bbSAbhishek Pandit-Subedi return; 36097fedd3bbSAbhishek Pandit-Subedi 36107fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 36117fedd3bbSAbhishek Pandit-Subedi "e))) { 36127fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 36137fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len); 36147fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb); 36157fedd3bbSAbhishek Pandit-Subedi 36167fedd3bbSAbhishek Pandit-Subedi conn->sent++; 36177fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0) 36187fedd3bbSAbhishek Pandit-Subedi conn->sent = 0; 36197fedd3bbSAbhishek Pandit-Subedi } 36207fedd3bbSAbhishek Pandit-Subedi } 36217fedd3bbSAbhishek Pandit-Subedi } 36227fedd3bbSAbhishek Pandit-Subedi 36236039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 362463d2bc1bSAndrei Emeltchenko { 362563d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 362663d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 362763d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 362863d2bc1bSAndrei Emeltchenko int quote; 362963d2bc1bSAndrei Emeltchenko 3630116523c8SLuiz Augusto von Dentz __check_timeout(hdev, cnt, ACL_LINK); 363104837f64SMarcel Holtmann 363273d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 363373d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 3634ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3635ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 363673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 363773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 363873d80debSLuiz Augusto von Dentz 3639ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3640ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3641ec1cce24SLuiz Augusto von Dentz break; 3642ec1cce24SLuiz Augusto von Dentz 3643ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3644ec1cce24SLuiz Augusto von Dentz 364573d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 364673d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 364704837f64SMarcel Holtmann 364857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 36491da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 36501da177e4SLinus Torvalds 36511da177e4SLinus Torvalds hdev->acl_cnt--; 365273d80debSLuiz Augusto von Dentz chan->sent++; 365373d80debSLuiz Augusto von Dentz chan->conn->sent++; 36547fedd3bbSAbhishek Pandit-Subedi 36557fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */ 36567fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev); 36577fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev); 36581da177e4SLinus Torvalds } 36591da177e4SLinus Torvalds } 366002b20f0bSLuiz Augusto von Dentz 366102b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 366202b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 36631da177e4SLinus Torvalds } 36641da177e4SLinus Torvalds 36656039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 3666b71d385aSAndrei Emeltchenko { 366763d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 3668b71d385aSAndrei Emeltchenko struct hci_chan *chan; 3669b71d385aSAndrei Emeltchenko struct sk_buff *skb; 3670b71d385aSAndrei Emeltchenko int quote; 3671bd1eb66bSAndrei Emeltchenko u8 type; 3672b71d385aSAndrei Emeltchenko 3673bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3674bd1eb66bSAndrei Emeltchenko 3675bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 3676bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 3677bd1eb66bSAndrei Emeltchenko else 3678bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 3679bd1eb66bSAndrei Emeltchenko 3680116523c8SLuiz Augusto von Dentz __check_timeout(hdev, cnt, type); 3681116523c8SLuiz Augusto von Dentz 3682b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 3683bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 3684b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 3685b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 3686b71d385aSAndrei Emeltchenko int blocks; 3687b71d385aSAndrei Emeltchenko 3688b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 3689b71d385aSAndrei Emeltchenko skb->len, skb->priority); 3690b71d385aSAndrei Emeltchenko 3691b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 3692b71d385aSAndrei Emeltchenko if (skb->priority < priority) 3693b71d385aSAndrei Emeltchenko break; 3694b71d385aSAndrei Emeltchenko 3695b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 3696b71d385aSAndrei Emeltchenko 3697b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 3698b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 3699b71d385aSAndrei Emeltchenko return; 3700b71d385aSAndrei Emeltchenko 3701b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 3702b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 3703b71d385aSAndrei Emeltchenko 370457d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 3705b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 3706b71d385aSAndrei Emeltchenko 3707b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 3708b71d385aSAndrei Emeltchenko quote -= blocks; 3709b71d385aSAndrei Emeltchenko 3710b71d385aSAndrei Emeltchenko chan->sent += blocks; 3711b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 3712b71d385aSAndrei Emeltchenko } 3713b71d385aSAndrei Emeltchenko } 3714b71d385aSAndrei Emeltchenko 3715b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 3716bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 3717b71d385aSAndrei Emeltchenko } 3718b71d385aSAndrei Emeltchenko 37196039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 3720b71d385aSAndrei Emeltchenko { 3721b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3722b71d385aSAndrei Emeltchenko 3723bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 3724ca8bee5dSMarcel Holtmann if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY) 3725bd1eb66bSAndrei Emeltchenko return; 3726bd1eb66bSAndrei Emeltchenko 3727bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 3728bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 3729b71d385aSAndrei Emeltchenko return; 3730b71d385aSAndrei Emeltchenko 3731b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 3732b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 3733b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 3734b71d385aSAndrei Emeltchenko break; 3735b71d385aSAndrei Emeltchenko 3736b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 3737b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 3738b71d385aSAndrei Emeltchenko break; 3739b71d385aSAndrei Emeltchenko } 3740b71d385aSAndrei Emeltchenko } 3741b71d385aSAndrei Emeltchenko 37426039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 37436ed58ec5SVille Tervo { 374473d80debSLuiz Augusto von Dentz struct hci_chan *chan; 37456ed58ec5SVille Tervo struct sk_buff *skb; 374602b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 37476ed58ec5SVille Tervo 37486ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 37496ed58ec5SVille Tervo 375052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 375152087a79SLuiz Augusto von Dentz return; 375252087a79SLuiz Augusto von Dentz 37536ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 37541b1d29e5SLuiz Augusto von Dentz 3755116523c8SLuiz Augusto von Dentz __check_timeout(hdev, cnt, LE_LINK); 37561b1d29e5SLuiz Augusto von Dentz 375702b20f0bSLuiz Augusto von Dentz tmp = cnt; 375873d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 3759ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3760ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 376173d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 376273d80debSLuiz Augusto von Dentz skb->len, skb->priority); 37636ed58ec5SVille Tervo 3764ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3765ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3766ec1cce24SLuiz Augusto von Dentz break; 3767ec1cce24SLuiz Augusto von Dentz 3768ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3769ec1cce24SLuiz Augusto von Dentz 377057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 37716ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 37726ed58ec5SVille Tervo 37736ed58ec5SVille Tervo cnt--; 377473d80debSLuiz Augusto von Dentz chan->sent++; 377573d80debSLuiz Augusto von Dentz chan->conn->sent++; 37767fedd3bbSAbhishek Pandit-Subedi 37777fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */ 37787fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev); 37797fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev); 37806ed58ec5SVille Tervo } 37816ed58ec5SVille Tervo } 378273d80debSLuiz Augusto von Dentz 37836ed58ec5SVille Tervo if (hdev->le_pkts) 37846ed58ec5SVille Tervo hdev->le_cnt = cnt; 37856ed58ec5SVille Tervo else 37866ed58ec5SVille Tervo hdev->acl_cnt = cnt; 378702b20f0bSLuiz Augusto von Dentz 378802b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 378902b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 37906ed58ec5SVille Tervo } 37916ed58ec5SVille Tervo 379226afbd82SLuiz Augusto von Dentz /* Schedule CIS */ 379326afbd82SLuiz Augusto von Dentz static void hci_sched_iso(struct hci_dev *hdev) 379426afbd82SLuiz Augusto von Dentz { 379526afbd82SLuiz Augusto von Dentz struct hci_conn *conn; 379626afbd82SLuiz Augusto von Dentz struct sk_buff *skb; 379726afbd82SLuiz Augusto von Dentz int quote, *cnt; 379826afbd82SLuiz Augusto von Dentz 379926afbd82SLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 380026afbd82SLuiz Augusto von Dentz 380126afbd82SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ISO_LINK)) 380226afbd82SLuiz Augusto von Dentz return; 380326afbd82SLuiz Augusto von Dentz 380426afbd82SLuiz Augusto von Dentz cnt = hdev->iso_pkts ? &hdev->iso_cnt : 380526afbd82SLuiz Augusto von Dentz hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt; 380626afbd82SLuiz Augusto von Dentz while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK, "e))) { 380726afbd82SLuiz Augusto von Dentz while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 380826afbd82SLuiz Augusto von Dentz BT_DBG("skb %p len %d", skb, skb->len); 380926afbd82SLuiz Augusto von Dentz hci_send_frame(hdev, skb); 381026afbd82SLuiz Augusto von Dentz 381126afbd82SLuiz Augusto von Dentz conn->sent++; 381226afbd82SLuiz Augusto von Dentz if (conn->sent == ~0) 381326afbd82SLuiz Augusto von Dentz conn->sent = 0; 381426afbd82SLuiz Augusto von Dentz (*cnt)--; 381526afbd82SLuiz Augusto von Dentz } 381626afbd82SLuiz Augusto von Dentz } 381726afbd82SLuiz Augusto von Dentz } 381826afbd82SLuiz Augusto von Dentz 38193eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 38201da177e4SLinus Torvalds { 38213eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 38221da177e4SLinus Torvalds struct sk_buff *skb; 38231da177e4SLinus Torvalds 382426afbd82SLuiz Augusto von Dentz BT_DBG("%s acl %d sco %d le %d iso %d", hdev->name, hdev->acl_cnt, 382526afbd82SLuiz Augusto von Dentz hdev->sco_cnt, hdev->le_cnt, hdev->iso_cnt); 38261da177e4SLinus Torvalds 3827d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) { 38281da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 38291da177e4SLinus Torvalds hci_sched_sco(hdev); 3830b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 383126afbd82SLuiz Augusto von Dentz hci_sched_iso(hdev); 38327fedd3bbSAbhishek Pandit-Subedi hci_sched_acl(hdev); 38336ed58ec5SVille Tervo hci_sched_le(hdev); 383452de599eSMarcel Holtmann } 38356ed58ec5SVille Tervo 38361da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 38371da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 383857d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 38391da177e4SLinus Torvalds } 38401da177e4SLinus Torvalds 384125985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 38421da177e4SLinus Torvalds 38431da177e4SLinus Torvalds /* ACL data packet */ 38446039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 38451da177e4SLinus Torvalds { 38461da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 38471da177e4SLinus Torvalds struct hci_conn *conn; 38481da177e4SLinus Torvalds __u16 handle, flags; 38491da177e4SLinus Torvalds 38501da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 38511da177e4SLinus Torvalds 38521da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 38531da177e4SLinus Torvalds flags = hci_flags(handle); 38541da177e4SLinus Torvalds handle = hci_handle(handle); 38551da177e4SLinus Torvalds 3856f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 3857a8c5fb1aSGustavo Padovan handle, flags); 38581da177e4SLinus Torvalds 38591da177e4SLinus Torvalds hdev->stat.acl_rx++; 38601da177e4SLinus Torvalds 38611da177e4SLinus Torvalds hci_dev_lock(hdev); 38621da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 38631da177e4SLinus Torvalds hci_dev_unlock(hdev); 38641da177e4SLinus Torvalds 38651da177e4SLinus Torvalds if (conn) { 386665983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 386704837f64SMarcel Holtmann 38681da177e4SLinus Torvalds /* Send to upper protocol */ 3869686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 38701da177e4SLinus Torvalds return; 38711da177e4SLinus Torvalds } else { 38722064ee33SMarcel Holtmann bt_dev_err(hdev, "ACL packet for unknown connection handle %d", 38732064ee33SMarcel Holtmann handle); 38741da177e4SLinus Torvalds } 38751da177e4SLinus Torvalds 38761da177e4SLinus Torvalds kfree_skb(skb); 38771da177e4SLinus Torvalds } 38781da177e4SLinus Torvalds 38791da177e4SLinus Torvalds /* SCO data packet */ 38806039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 38811da177e4SLinus Torvalds { 38821da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 38831da177e4SLinus Torvalds struct hci_conn *conn; 3884debdedf2SMarcel Holtmann __u16 handle, flags; 38851da177e4SLinus Torvalds 38861da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 38871da177e4SLinus Torvalds 38881da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 3889debdedf2SMarcel Holtmann flags = hci_flags(handle); 3890debdedf2SMarcel Holtmann handle = hci_handle(handle); 38911da177e4SLinus Torvalds 3892debdedf2SMarcel Holtmann BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 3893debdedf2SMarcel Holtmann handle, flags); 38941da177e4SLinus Torvalds 38951da177e4SLinus Torvalds hdev->stat.sco_rx++; 38961da177e4SLinus Torvalds 38971da177e4SLinus Torvalds hci_dev_lock(hdev); 38981da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 38991da177e4SLinus Torvalds hci_dev_unlock(hdev); 39001da177e4SLinus Torvalds 39011da177e4SLinus Torvalds if (conn) { 39021da177e4SLinus Torvalds /* Send to upper protocol */ 39033f19ffb2SLuiz Augusto von Dentz hci_skb_pkt_status(skb) = flags & 0x03; 3904686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 39051da177e4SLinus Torvalds return; 39061da177e4SLinus Torvalds } else { 39072d4b37b6SLuiz Augusto von Dentz bt_dev_err_ratelimited(hdev, "SCO packet for unknown connection handle %d", 39082064ee33SMarcel Holtmann handle); 39091da177e4SLinus Torvalds } 39101da177e4SLinus Torvalds 39111da177e4SLinus Torvalds kfree_skb(skb); 39121da177e4SLinus Torvalds } 39131da177e4SLinus Torvalds 391426afbd82SLuiz Augusto von Dentz static void hci_isodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 391526afbd82SLuiz Augusto von Dentz { 391626afbd82SLuiz Augusto von Dentz struct hci_iso_hdr *hdr; 391726afbd82SLuiz Augusto von Dentz struct hci_conn *conn; 391826afbd82SLuiz Augusto von Dentz __u16 handle, flags; 391926afbd82SLuiz Augusto von Dentz 392026afbd82SLuiz Augusto von Dentz hdr = skb_pull_data(skb, sizeof(*hdr)); 392126afbd82SLuiz Augusto von Dentz if (!hdr) { 392226afbd82SLuiz Augusto von Dentz bt_dev_err(hdev, "ISO packet too small"); 392326afbd82SLuiz Augusto von Dentz goto drop; 392426afbd82SLuiz Augusto von Dentz } 392526afbd82SLuiz Augusto von Dentz 392626afbd82SLuiz Augusto von Dentz handle = __le16_to_cpu(hdr->handle); 392726afbd82SLuiz Augusto von Dentz flags = hci_flags(handle); 392826afbd82SLuiz Augusto von Dentz handle = hci_handle(handle); 392926afbd82SLuiz Augusto von Dentz 393026afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "len %d handle 0x%4.4x flags 0x%4.4x", skb->len, 393126afbd82SLuiz Augusto von Dentz handle, flags); 393226afbd82SLuiz Augusto von Dentz 393326afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev); 393426afbd82SLuiz Augusto von Dentz conn = hci_conn_hash_lookup_handle(hdev, handle); 393526afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev); 393626afbd82SLuiz Augusto von Dentz 393726afbd82SLuiz Augusto von Dentz if (!conn) { 393826afbd82SLuiz Augusto von Dentz bt_dev_err(hdev, "ISO packet for unknown connection handle %d", 393926afbd82SLuiz Augusto von Dentz handle); 3940ccf74f23SLuiz Augusto von Dentz goto drop; 394126afbd82SLuiz Augusto von Dentz } 394226afbd82SLuiz Augusto von Dentz 3943ccf74f23SLuiz Augusto von Dentz /* Send to upper protocol */ 3944ccf74f23SLuiz Augusto von Dentz iso_recv(conn, skb, flags); 3945ccf74f23SLuiz Augusto von Dentz return; 3946ccf74f23SLuiz Augusto von Dentz 394726afbd82SLuiz Augusto von Dentz drop: 394826afbd82SLuiz Augusto von Dentz kfree_skb(skb); 394926afbd82SLuiz Augusto von Dentz } 395026afbd82SLuiz Augusto von Dentz 39519238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 39529238f36aSJohan Hedberg { 39539238f36aSJohan Hedberg struct sk_buff *skb; 39549238f36aSJohan Hedberg 39559238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 39569238f36aSJohan Hedberg if (!skb) 39579238f36aSJohan Hedberg return true; 39589238f36aSJohan Hedberg 395944d27137SJohan Hedberg return (bt_cb(skb)->hci.req_flags & HCI_REQ_START); 39609238f36aSJohan Hedberg } 39619238f36aSJohan Hedberg 396242c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 396342c6b129SJohan Hedberg { 396442c6b129SJohan Hedberg struct hci_command_hdr *sent; 396542c6b129SJohan Hedberg struct sk_buff *skb; 396642c6b129SJohan Hedberg u16 opcode; 396742c6b129SJohan Hedberg 396842c6b129SJohan Hedberg if (!hdev->sent_cmd) 396942c6b129SJohan Hedberg return; 397042c6b129SJohan Hedberg 397142c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 397242c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 397342c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 397442c6b129SJohan Hedberg return; 397542c6b129SJohan Hedberg 397642c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 397742c6b129SJohan Hedberg if (!skb) 397842c6b129SJohan Hedberg return; 397942c6b129SJohan Hedberg 398042c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 398142c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 398242c6b129SJohan Hedberg } 398342c6b129SJohan Hedberg 3984e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, 3985e6214487SJohan Hedberg hci_req_complete_t *req_complete, 3986e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 39879238f36aSJohan Hedberg { 39889238f36aSJohan Hedberg struct sk_buff *skb; 39899238f36aSJohan Hedberg unsigned long flags; 39909238f36aSJohan Hedberg 39919238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 39929238f36aSJohan Hedberg 399342c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 399442c6b129SJohan Hedberg * sent we need to do special handling of it. 39959238f36aSJohan Hedberg */ 399642c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 399742c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 399842c6b129SJohan Hedberg * reset complete event during init and any pending 399942c6b129SJohan Hedberg * command will never be completed. In such a case we 400042c6b129SJohan Hedberg * need to resend whatever was the last sent 400142c6b129SJohan Hedberg * command. 400242c6b129SJohan Hedberg */ 400342c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 400442c6b129SJohan Hedberg hci_resend_last(hdev); 400542c6b129SJohan Hedberg 40069238f36aSJohan Hedberg return; 400742c6b129SJohan Hedberg } 40089238f36aSJohan Hedberg 4009f80c5dadSJoão Paulo Rechi Vita /* If we reach this point this event matches the last command sent */ 4010f80c5dadSJoão Paulo Rechi Vita hci_dev_clear_flag(hdev, HCI_CMD_PENDING); 4011f80c5dadSJoão Paulo Rechi Vita 40129238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 40139238f36aSJohan Hedberg * this request the request is not yet complete. 40149238f36aSJohan Hedberg */ 40159238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 40169238f36aSJohan Hedberg return; 40179238f36aSJohan Hedberg 40189238f36aSJohan Hedberg /* If this was the last command in a request the complete 40199238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 40209238f36aSJohan Hedberg * command queue (hdev->cmd_q). 40219238f36aSJohan Hedberg */ 402244d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) { 402344d27137SJohan Hedberg *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb; 4024e6214487SJohan Hedberg return; 40259238f36aSJohan Hedberg } 4026e6214487SJohan Hedberg 402744d27137SJohan Hedberg if (bt_cb(hdev->sent_cmd)->hci.req_complete) { 402844d27137SJohan Hedberg *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete; 4029e6214487SJohan Hedberg return; 403053e21fbcSJohan Hedberg } 40319238f36aSJohan Hedberg 40329238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 40339238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 40349238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 403544d27137SJohan Hedberg if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) { 40369238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 40379238f36aSJohan Hedberg break; 40389238f36aSJohan Hedberg } 40399238f36aSJohan Hedberg 40403bd7594eSDouglas Anderson if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) 4041242c0ebdSMarcel Holtmann *req_complete_skb = bt_cb(skb)->hci.req_complete_skb; 40423bd7594eSDouglas Anderson else 40433bd7594eSDouglas Anderson *req_complete = bt_cb(skb)->hci.req_complete; 404439c1eb6fSYang Yingliang dev_kfree_skb_irq(skb); 40459238f36aSJohan Hedberg } 40469238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 40479238f36aSJohan Hedberg } 40489238f36aSJohan Hedberg 4049b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 40501da177e4SLinus Torvalds { 4051b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 40521da177e4SLinus Torvalds struct sk_buff *skb; 40531da177e4SLinus Torvalds 40541da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 40551da177e4SLinus Torvalds 40569f30de9eSTamas Koczka /* The kcov_remote functions used for collecting packet parsing 40579f30de9eSTamas Koczka * coverage information from this background thread and associate 40589f30de9eSTamas Koczka * the coverage with the syscall's thread which originally injected 40599f30de9eSTamas Koczka * the packet. This helps fuzzing the kernel. 40609f30de9eSTamas Koczka */ 40619f30de9eSTamas Koczka for (; (skb = skb_dequeue(&hdev->rx_q)); kcov_remote_stop()) { 40629f30de9eSTamas Koczka kcov_remote_start_common(skb_get_kcov_handle(skb)); 40639f30de9eSTamas Koczka 4064cd82e61cSMarcel Holtmann /* Send copy to monitor */ 4065cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 4066cd82e61cSMarcel Holtmann 40671da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 40681da177e4SLinus Torvalds /* Send copy to the sockets */ 4069470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 40701da177e4SLinus Torvalds } 40711da177e4SLinus Torvalds 4072eb8c101eSMattijs Korpershoek /* If the device has been opened in HCI_USER_CHANNEL, 4073eb8c101eSMattijs Korpershoek * the userspace has exclusive access to device. 4074eb8c101eSMattijs Korpershoek * When device is HCI_INIT, we still need to process 4075eb8c101eSMattijs Korpershoek * the data packets to the driver in order 4076eb8c101eSMattijs Korpershoek * to complete its setup(). 4077eb8c101eSMattijs Korpershoek */ 4078eb8c101eSMattijs Korpershoek if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && 4079eb8c101eSMattijs Korpershoek !test_bit(HCI_INIT, &hdev->flags)) { 40801da177e4SLinus Torvalds kfree_skb(skb); 40811da177e4SLinus Torvalds continue; 40821da177e4SLinus Torvalds } 40831da177e4SLinus Torvalds 40841da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 40851da177e4SLinus Torvalds /* Don't process data packets in this states. */ 4086d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 40871da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 40881da177e4SLinus Torvalds case HCI_SCODATA_PKT: 4089cc974003SMarcel Holtmann case HCI_ISODATA_PKT: 40901da177e4SLinus Torvalds kfree_skb(skb); 40911da177e4SLinus Torvalds continue; 40923ff50b79SStephen Hemminger } 40931da177e4SLinus Torvalds } 40941da177e4SLinus Torvalds 40951da177e4SLinus Torvalds /* Process frame */ 4096d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) { 40971da177e4SLinus Torvalds case HCI_EVENT_PKT: 4098b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 40991da177e4SLinus Torvalds hci_event_packet(hdev, skb); 41001da177e4SLinus Torvalds break; 41011da177e4SLinus Torvalds 41021da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 41031da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 41041da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 41051da177e4SLinus Torvalds break; 41061da177e4SLinus Torvalds 41071da177e4SLinus Torvalds case HCI_SCODATA_PKT: 41081da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 41091da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 41101da177e4SLinus Torvalds break; 41111da177e4SLinus Torvalds 411226afbd82SLuiz Augusto von Dentz case HCI_ISODATA_PKT: 411326afbd82SLuiz Augusto von Dentz BT_DBG("%s ISO data packet", hdev->name); 411426afbd82SLuiz Augusto von Dentz hci_isodata_packet(hdev, skb); 411526afbd82SLuiz Augusto von Dentz break; 411626afbd82SLuiz Augusto von Dentz 41171da177e4SLinus Torvalds default: 41181da177e4SLinus Torvalds kfree_skb(skb); 41191da177e4SLinus Torvalds break; 41201da177e4SLinus Torvalds } 41211da177e4SLinus Torvalds } 41221da177e4SLinus Torvalds } 41231da177e4SLinus Torvalds 4124c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 41251da177e4SLinus Torvalds { 4126c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 41271da177e4SLinus Torvalds struct sk_buff *skb; 41281da177e4SLinus Torvalds 41292104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 41302104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 41311da177e4SLinus Torvalds 41321da177e4SLinus Torvalds /* Send queued commands */ 41335a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 41345a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 41355a08ecceSAndrei Emeltchenko if (!skb) 41365a08ecceSAndrei Emeltchenko return; 41375a08ecceSAndrei Emeltchenko 41381da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 41391da177e4SLinus Torvalds 4140a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 414170f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 41422250abadSBenjamin Berg int res; 4143f80c5dadSJoão Paulo Rechi Vita if (hci_req_status_pend(hdev)) 4144f80c5dadSJoão Paulo Rechi Vita hci_dev_set_flag(hdev, HCI_CMD_PENDING); 41451da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 41462250abadSBenjamin Berg 41472250abadSBenjamin Berg res = hci_send_frame(hdev, skb); 41482250abadSBenjamin Berg if (res < 0) 4149744451c1SBenjamin Berg __hci_cmd_sync_cancel(hdev, -res); 41502250abadSBenjamin Berg 4151deee93d1STetsuo Handa rcu_read_lock(); 4152877afadaSSchspa Shi if (test_bit(HCI_RESET, &hdev->flags) || 4153877afadaSSchspa Shi hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) 415465cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 41557bdb8a5cSSzymon Janc else 4156deee93d1STetsuo Handa queue_delayed_work(hdev->workqueue, &hdev->cmd_timer, 415765cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT); 4158deee93d1STetsuo Handa rcu_read_unlock(); 41591da177e4SLinus Torvalds } else { 41601da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 4161c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 41621da177e4SLinus Torvalds } 41631da177e4SLinus Torvalds } 41641da177e4SLinus Torvalds } 4165