11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 31da177e4SLinus Torvalds Copyright (C) 2000-2001 Qualcomm Incorporated 4590051deSGustavo F. Padovan Copyright (C) 2011 ProFUSION Embedded Systems 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 91da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 101da177e4SLinus Torvalds published by the Free Software Foundation; 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 131da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 141da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 151da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 161da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 171da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 181da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 191da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 221da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 231da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 241da177e4SLinus Torvalds */ 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds /* Bluetooth HCI core. */ 271da177e4SLinus Torvalds 288c520a59SGustavo Padovan #include <linux/export.h> 293df92b31SSasha Levin #include <linux/idr.h> 301da177e4SLinus Torvalds 31611b30f7SMarcel Holtmann #include <linux/rfkill.h> 321da177e4SLinus Torvalds 331da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 341da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 351da177e4SLinus Torvalds 36b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 37c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 383eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 391da177e4SLinus Torvalds 401da177e4SLinus Torvalds /* HCI device list */ 411da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 421da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds /* HCI callback list */ 451da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 461da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 471da177e4SLinus Torvalds 483df92b31SSasha Levin /* HCI ID Numbering */ 493df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 503df92b31SSasha Levin 511da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 521da177e4SLinus Torvalds 536516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 541da177e4SLinus Torvalds { 55040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 561da177e4SLinus Torvalds } 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds /* ---- HCI requests ---- */ 591da177e4SLinus Torvalds 6023bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) 611da177e4SLinus Torvalds { 62f0e09510SAndrei Emeltchenko BT_DBG("%s command 0x%4.4x result 0x%2.2x", hdev->name, cmd, result); 6323bb5763SJohan Hedberg 64a5040efaSJohan Hedberg /* If this is the init phase check if the completed command matches 65a5040efaSJohan Hedberg * the last init command, and if not just return. 66a5040efaSJohan Hedberg */ 6775fb0e32SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) { 6875fb0e32SJohan Hedberg struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 691036b890SAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 7075fb0e32SJohan Hedberg struct sk_buff *skb; 7175fb0e32SJohan Hedberg 7275fb0e32SJohan Hedberg /* Some CSR based controllers generate a spontaneous 7375fb0e32SJohan Hedberg * reset complete event during init and any pending 7475fb0e32SJohan Hedberg * command will never be completed. In such a case we 7575fb0e32SJohan Hedberg * need to resend whatever was the last sent 7675fb0e32SJohan Hedberg * command. 7775fb0e32SJohan Hedberg */ 7875fb0e32SJohan Hedberg 791036b890SAndrei Emeltchenko if (cmd != HCI_OP_RESET || opcode == HCI_OP_RESET) 8023bb5763SJohan Hedberg return; 811da177e4SLinus Torvalds 8275fb0e32SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC); 8375fb0e32SJohan Hedberg if (skb) { 8475fb0e32SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 8575fb0e32SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 8675fb0e32SJohan Hedberg } 8775fb0e32SJohan Hedberg 8875fb0e32SJohan Hedberg return; 8975fb0e32SJohan Hedberg } 9075fb0e32SJohan Hedberg 911da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 921da177e4SLinus Torvalds hdev->req_result = result; 931da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 941da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 951da177e4SLinus Torvalds } 961da177e4SLinus Torvalds } 971da177e4SLinus Torvalds 981da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 991da177e4SLinus Torvalds { 1001da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 1011da177e4SLinus Torvalds 1021da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 1031da177e4SLinus Torvalds hdev->req_result = err; 1041da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 1051da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 1061da177e4SLinus Torvalds } 1071da177e4SLinus Torvalds } 1081da177e4SLinus Torvalds 1091da177e4SLinus Torvalds /* Execute request and wait for completion. */ 110a8c5fb1aSGustavo Padovan static int __hci_request(struct hci_dev *hdev, 111a8c5fb1aSGustavo Padovan void (*req)(struct hci_dev *hdev, unsigned long opt), 1121da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 1131da177e4SLinus Torvalds { 1141da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 1151da177e4SLinus Torvalds int err = 0; 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 1181da177e4SLinus Torvalds 1191da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 1201da177e4SLinus Torvalds 1211da177e4SLinus Torvalds add_wait_queue(&hdev->req_wait_q, &wait); 1221da177e4SLinus Torvalds set_current_state(TASK_INTERRUPTIBLE); 1231da177e4SLinus Torvalds 1241da177e4SLinus Torvalds req(hdev, opt); 1251da177e4SLinus Torvalds schedule_timeout(timeout); 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 1281da177e4SLinus Torvalds 1291da177e4SLinus Torvalds if (signal_pending(current)) 1301da177e4SLinus Torvalds return -EINTR; 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds switch (hdev->req_status) { 1331da177e4SLinus Torvalds case HCI_REQ_DONE: 134e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 1351da177e4SLinus Torvalds break; 1361da177e4SLinus Torvalds 1371da177e4SLinus Torvalds case HCI_REQ_CANCELED: 1381da177e4SLinus Torvalds err = -hdev->req_result; 1391da177e4SLinus Torvalds break; 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds default: 1421da177e4SLinus Torvalds err = -ETIMEDOUT; 1431da177e4SLinus Torvalds break; 1443ff50b79SStephen Hemminger } 1451da177e4SLinus Torvalds 146a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 1491da177e4SLinus Torvalds 1501da177e4SLinus Torvalds return err; 1511da177e4SLinus Torvalds } 1521da177e4SLinus Torvalds 1536039aa73SGustavo Padovan static int hci_request(struct hci_dev *hdev, 1546039aa73SGustavo Padovan void (*req)(struct hci_dev *hdev, unsigned long opt), 1551da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 1561da177e4SLinus Torvalds { 1571da177e4SLinus Torvalds int ret; 1581da177e4SLinus Torvalds 1597c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 1607c6a329eSMarcel Holtmann return -ENETDOWN; 1617c6a329eSMarcel Holtmann 1621da177e4SLinus Torvalds /* Serialize all requests */ 1631da177e4SLinus Torvalds hci_req_lock(hdev); 1641da177e4SLinus Torvalds ret = __hci_request(hdev, req, opt, timeout); 1651da177e4SLinus Torvalds hci_req_unlock(hdev); 1661da177e4SLinus Torvalds 1671da177e4SLinus Torvalds return ret; 1681da177e4SLinus Torvalds } 1691da177e4SLinus Torvalds 1701da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) 1711da177e4SLinus Torvalds { 1721da177e4SLinus Torvalds BT_DBG("%s %ld", hdev->name, opt); 1731da177e4SLinus Torvalds 1741da177e4SLinus Torvalds /* Reset device */ 175f630cf0dSGustavo F. Padovan set_bit(HCI_RESET, &hdev->flags); 176a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 1771da177e4SLinus Torvalds } 1781da177e4SLinus Torvalds 179e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev) 1801da177e4SLinus Torvalds { 1812455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 1822455a3eaSAndrei Emeltchenko 1831da177e4SLinus Torvalds /* Read Local Supported Features */ 184a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 1851da177e4SLinus Torvalds 1861143e5a6SMarcel Holtmann /* Read Local Version */ 187a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 1881da177e4SLinus Torvalds } 1891da177e4SLinus Torvalds 190e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev) 191e61ef499SAndrei Emeltchenko { 1922455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 1932455a3eaSAndrei Emeltchenko 194e61ef499SAndrei Emeltchenko /* Read Local Version */ 195e61ef499SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 1966bcbc489SAndrei Emeltchenko 1976bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 1986bcbc489SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 199e71dfabaSAndrei Emeltchenko 200e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 201e71dfabaSAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 202e61ef499SAndrei Emeltchenko } 203e61ef499SAndrei Emeltchenko 204e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt) 205e61ef499SAndrei Emeltchenko { 206e61ef499SAndrei Emeltchenko struct sk_buff *skb; 207e61ef499SAndrei Emeltchenko 208e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 209e61ef499SAndrei Emeltchenko 210e61ef499SAndrei Emeltchenko /* Driver initialization */ 211e61ef499SAndrei Emeltchenko 212e61ef499SAndrei Emeltchenko /* Special commands */ 213e61ef499SAndrei Emeltchenko while ((skb = skb_dequeue(&hdev->driver_init))) { 214e61ef499SAndrei Emeltchenko bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 215e61ef499SAndrei Emeltchenko skb->dev = (void *) hdev; 216e61ef499SAndrei Emeltchenko 217e61ef499SAndrei Emeltchenko skb_queue_tail(&hdev->cmd_q, skb); 218e61ef499SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->cmd_work); 219e61ef499SAndrei Emeltchenko } 220e61ef499SAndrei Emeltchenko skb_queue_purge(&hdev->driver_init); 221e61ef499SAndrei Emeltchenko 22211778716SAndrei Emeltchenko /* Reset */ 22311778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 22411778716SAndrei Emeltchenko hci_reset_req(hdev, 0); 22511778716SAndrei Emeltchenko 226e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 227e61ef499SAndrei Emeltchenko case HCI_BREDR: 228e61ef499SAndrei Emeltchenko bredr_init(hdev); 229e61ef499SAndrei Emeltchenko break; 230e61ef499SAndrei Emeltchenko 231e61ef499SAndrei Emeltchenko case HCI_AMP: 232e61ef499SAndrei Emeltchenko amp_init(hdev); 233e61ef499SAndrei Emeltchenko break; 234e61ef499SAndrei Emeltchenko 235e61ef499SAndrei Emeltchenko default: 236e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 237e61ef499SAndrei Emeltchenko break; 238e61ef499SAndrei Emeltchenko } 239e61ef499SAndrei Emeltchenko } 240e61ef499SAndrei Emeltchenko 2411da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) 2421da177e4SLinus Torvalds { 2431da177e4SLinus Torvalds __u8 scan = opt; 2441da177e4SLinus Torvalds 2451da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, scan); 2461da177e4SLinus Torvalds 2471da177e4SLinus Torvalds /* Inquiry and Page scans */ 248a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 2491da177e4SLinus Torvalds } 2501da177e4SLinus Torvalds 2511da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt) 2521da177e4SLinus Torvalds { 2531da177e4SLinus Torvalds __u8 auth = opt; 2541da177e4SLinus Torvalds 2551da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, auth); 2561da177e4SLinus Torvalds 2571da177e4SLinus Torvalds /* Authentication */ 258a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 2591da177e4SLinus Torvalds } 2601da177e4SLinus Torvalds 2611da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt) 2621da177e4SLinus Torvalds { 2631da177e4SLinus Torvalds __u8 encrypt = opt; 2641da177e4SLinus Torvalds 2651da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, encrypt); 2661da177e4SLinus Torvalds 267e4e8e37cSMarcel Holtmann /* Encryption */ 268a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 2691da177e4SLinus Torvalds } 2701da177e4SLinus Torvalds 271e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt) 272e4e8e37cSMarcel Holtmann { 273e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 274e4e8e37cSMarcel Holtmann 275a418b893SMarcel Holtmann BT_DBG("%s %x", hdev->name, policy); 276e4e8e37cSMarcel Holtmann 277e4e8e37cSMarcel Holtmann /* Default link policy */ 278e4e8e37cSMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 279e4e8e37cSMarcel Holtmann } 280e4e8e37cSMarcel Holtmann 2811da177e4SLinus Torvalds /* Get HCI device by index. 2821da177e4SLinus Torvalds * Device is held on return. */ 2831da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 2841da177e4SLinus Torvalds { 2858035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 2861da177e4SLinus Torvalds 2871da177e4SLinus Torvalds BT_DBG("%d", index); 2881da177e4SLinus Torvalds 2891da177e4SLinus Torvalds if (index < 0) 2901da177e4SLinus Torvalds return NULL; 2911da177e4SLinus Torvalds 2921da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 2938035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 2941da177e4SLinus Torvalds if (d->id == index) { 2951da177e4SLinus Torvalds hdev = hci_dev_hold(d); 2961da177e4SLinus Torvalds break; 2971da177e4SLinus Torvalds } 2981da177e4SLinus Torvalds } 2991da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 3001da177e4SLinus Torvalds return hdev; 3011da177e4SLinus Torvalds } 3021da177e4SLinus Torvalds 3031da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 304ff9ef578SJohan Hedberg 30530dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 30630dc78e1SJohan Hedberg { 30730dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 30830dc78e1SJohan Hedberg 3096fbe195dSAndre Guedes switch (discov->state) { 310343f935bSAndre Guedes case DISCOVERY_FINDING: 3116fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 31230dc78e1SJohan Hedberg return true; 31330dc78e1SJohan Hedberg 3146fbe195dSAndre Guedes default: 31530dc78e1SJohan Hedberg return false; 31630dc78e1SJohan Hedberg } 3176fbe195dSAndre Guedes } 31830dc78e1SJohan Hedberg 319ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 320ff9ef578SJohan Hedberg { 321ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 322ff9ef578SJohan Hedberg 323ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 324ff9ef578SJohan Hedberg return; 325ff9ef578SJohan Hedberg 326ff9ef578SJohan Hedberg switch (state) { 327ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 3287b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 329ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 330ff9ef578SJohan Hedberg break; 331ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 332ff9ef578SJohan Hedberg break; 333343f935bSAndre Guedes case DISCOVERY_FINDING: 334ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 335ff9ef578SJohan Hedberg break; 33630dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 33730dc78e1SJohan Hedberg break; 338ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 339ff9ef578SJohan Hedberg break; 340ff9ef578SJohan Hedberg } 341ff9ef578SJohan Hedberg 342ff9ef578SJohan Hedberg hdev->discovery.state = state; 343ff9ef578SJohan Hedberg } 344ff9ef578SJohan Hedberg 3451da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev) 3461da177e4SLinus Torvalds { 34730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 348b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 3491da177e4SLinus Torvalds 350561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 351561aafbcSJohan Hedberg list_del(&p->all); 352b57c1a56SJohan Hedberg kfree(p); 3531da177e4SLinus Torvalds } 354561aafbcSJohan Hedberg 355561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 356561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 3571da177e4SLinus Torvalds } 3581da177e4SLinus Torvalds 359a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 360a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 3611da177e4SLinus Torvalds { 36230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 3631da177e4SLinus Torvalds struct inquiry_entry *e; 3641da177e4SLinus Torvalds 3656ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 3661da177e4SLinus Torvalds 367561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 3681da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 3691da177e4SLinus Torvalds return e; 3701da177e4SLinus Torvalds } 3711da177e4SLinus Torvalds 372b57c1a56SJohan Hedberg return NULL; 373b57c1a56SJohan Hedberg } 374b57c1a56SJohan Hedberg 375561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 376561aafbcSJohan Hedberg bdaddr_t *bdaddr) 377561aafbcSJohan Hedberg { 37830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 379561aafbcSJohan Hedberg struct inquiry_entry *e; 380561aafbcSJohan Hedberg 3816ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 382561aafbcSJohan Hedberg 383561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 384561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 385561aafbcSJohan Hedberg return e; 386561aafbcSJohan Hedberg } 387561aafbcSJohan Hedberg 388561aafbcSJohan Hedberg return NULL; 389561aafbcSJohan Hedberg } 390561aafbcSJohan Hedberg 39130dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 39230dc78e1SJohan Hedberg bdaddr_t *bdaddr, 39330dc78e1SJohan Hedberg int state) 39430dc78e1SJohan Hedberg { 39530dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 39630dc78e1SJohan Hedberg struct inquiry_entry *e; 39730dc78e1SJohan Hedberg 3986ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 39930dc78e1SJohan Hedberg 40030dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 40130dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 40230dc78e1SJohan Hedberg return e; 40330dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 40430dc78e1SJohan Hedberg return e; 40530dc78e1SJohan Hedberg } 40630dc78e1SJohan Hedberg 40730dc78e1SJohan Hedberg return NULL; 40830dc78e1SJohan Hedberg } 40930dc78e1SJohan Hedberg 410a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 411a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 412a3d4e20aSJohan Hedberg { 413a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 414a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 415a3d4e20aSJohan Hedberg struct inquiry_entry *p; 416a3d4e20aSJohan Hedberg 417a3d4e20aSJohan Hedberg list_del(&ie->list); 418a3d4e20aSJohan Hedberg 419a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 420a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 421a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 422a3d4e20aSJohan Hedberg break; 423a3d4e20aSJohan Hedberg pos = &p->list; 424a3d4e20aSJohan Hedberg } 425a3d4e20aSJohan Hedberg 426a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 427a3d4e20aSJohan Hedberg } 428a3d4e20aSJohan Hedberg 4293175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 430388fc8faSJohan Hedberg bool name_known, bool *ssp) 4311da177e4SLinus Torvalds { 43230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 43370f23020SAndrei Emeltchenko struct inquiry_entry *ie; 4341da177e4SLinus Torvalds 4356ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 4361da177e4SLinus Torvalds 4372b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 4382b2fec4dSSzymon Janc 439388fc8faSJohan Hedberg if (ssp) 440388fc8faSJohan Hedberg *ssp = data->ssp_mode; 441388fc8faSJohan Hedberg 44270f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 443a3d4e20aSJohan Hedberg if (ie) { 444388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 445388fc8faSJohan Hedberg *ssp = true; 446388fc8faSJohan Hedberg 447a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 448a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 449a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 450a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 451a3d4e20aSJohan Hedberg } 452a3d4e20aSJohan Hedberg 453561aafbcSJohan Hedberg goto update; 454a3d4e20aSJohan Hedberg } 455561aafbcSJohan Hedberg 4561da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 45770f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 45870f23020SAndrei Emeltchenko if (!ie) 4593175405bSJohan Hedberg return false; 46070f23020SAndrei Emeltchenko 461561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 462561aafbcSJohan Hedberg 463561aafbcSJohan Hedberg if (name_known) { 464561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 465561aafbcSJohan Hedberg } else { 466561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 467561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 468561aafbcSJohan Hedberg } 469561aafbcSJohan Hedberg 470561aafbcSJohan Hedberg update: 471561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 472561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 473561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 474561aafbcSJohan Hedberg list_del(&ie->list); 4751da177e4SLinus Torvalds } 4761da177e4SLinus Torvalds 47770f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 47870f23020SAndrei Emeltchenko ie->timestamp = jiffies; 4791da177e4SLinus Torvalds cache->timestamp = jiffies; 4803175405bSJohan Hedberg 4813175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 4823175405bSJohan Hedberg return false; 4833175405bSJohan Hedberg 4843175405bSJohan Hedberg return true; 4851da177e4SLinus Torvalds } 4861da177e4SLinus Torvalds 4871da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 4881da177e4SLinus Torvalds { 48930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 4901da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 4911da177e4SLinus Torvalds struct inquiry_entry *e; 4921da177e4SLinus Torvalds int copied = 0; 4931da177e4SLinus Torvalds 494561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 4951da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 496b57c1a56SJohan Hedberg 497b57c1a56SJohan Hedberg if (copied >= num) 498b57c1a56SJohan Hedberg break; 499b57c1a56SJohan Hedberg 5001da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 5011da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 5021da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 5031da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 5041da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 5051da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 506b57c1a56SJohan Hedberg 5071da177e4SLinus Torvalds info++; 508b57c1a56SJohan Hedberg copied++; 5091da177e4SLinus Torvalds } 5101da177e4SLinus Torvalds 5111da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 5121da177e4SLinus Torvalds return copied; 5131da177e4SLinus Torvalds } 5141da177e4SLinus Torvalds 5151da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt) 5161da177e4SLinus Torvalds { 5171da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 5181da177e4SLinus Torvalds struct hci_cp_inquiry cp; 5191da177e4SLinus Torvalds 5201da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 5211da177e4SLinus Torvalds 5221da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 5231da177e4SLinus Torvalds return; 5241da177e4SLinus Torvalds 5251da177e4SLinus Torvalds /* Start Inquiry */ 5261da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 5271da177e4SLinus Torvalds cp.length = ir->length; 5281da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 529a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 5301da177e4SLinus Torvalds } 5311da177e4SLinus Torvalds 5321da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 5331da177e4SLinus Torvalds { 5341da177e4SLinus Torvalds __u8 __user *ptr = arg; 5351da177e4SLinus Torvalds struct hci_inquiry_req ir; 5361da177e4SLinus Torvalds struct hci_dev *hdev; 5371da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 5381da177e4SLinus Torvalds long timeo; 5391da177e4SLinus Torvalds __u8 *buf; 5401da177e4SLinus Torvalds 5411da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 5421da177e4SLinus Torvalds return -EFAULT; 5431da177e4SLinus Torvalds 5445a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 5455a08ecceSAndrei Emeltchenko if (!hdev) 5461da177e4SLinus Torvalds return -ENODEV; 5471da177e4SLinus Torvalds 54809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 5491da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 550a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 5511da177e4SLinus Torvalds inquiry_cache_flush(hdev); 5521da177e4SLinus Torvalds do_inquiry = 1; 5531da177e4SLinus Torvalds } 55409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 5551da177e4SLinus Torvalds 55604837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 55770f23020SAndrei Emeltchenko 55870f23020SAndrei Emeltchenko if (do_inquiry) { 55970f23020SAndrei Emeltchenko err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo); 56070f23020SAndrei Emeltchenko if (err < 0) 5611da177e4SLinus Torvalds goto done; 56270f23020SAndrei Emeltchenko } 5631da177e4SLinus Torvalds 5648fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 5658fc9ced3SGustavo Padovan * 255 entries 5668fc9ced3SGustavo Padovan */ 5671da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 5681da177e4SLinus Torvalds 5691da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 5701da177e4SLinus Torvalds * copy it to the user space. 5711da177e4SLinus Torvalds */ 57270f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 57370f23020SAndrei Emeltchenko if (!buf) { 5741da177e4SLinus Torvalds err = -ENOMEM; 5751da177e4SLinus Torvalds goto done; 5761da177e4SLinus Torvalds } 5771da177e4SLinus Torvalds 57809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 5791da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 58009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 5811da177e4SLinus Torvalds 5821da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 5831da177e4SLinus Torvalds 5841da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 5851da177e4SLinus Torvalds ptr += sizeof(ir); 5861da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 5871da177e4SLinus Torvalds ir.num_rsp)) 5881da177e4SLinus Torvalds err = -EFAULT; 5891da177e4SLinus Torvalds } else 5901da177e4SLinus Torvalds err = -EFAULT; 5911da177e4SLinus Torvalds 5921da177e4SLinus Torvalds kfree(buf); 5931da177e4SLinus Torvalds 5941da177e4SLinus Torvalds done: 5951da177e4SLinus Torvalds hci_dev_put(hdev); 5961da177e4SLinus Torvalds return err; 5971da177e4SLinus Torvalds } 5981da177e4SLinus Torvalds 5993f0f524bSJohan Hedberg static u8 create_ad(struct hci_dev *hdev, u8 *ptr) 6003f0f524bSJohan Hedberg { 6013f0f524bSJohan Hedberg u8 ad_len = 0, flags = 0; 6023f0f524bSJohan Hedberg size_t name_len; 6033f0f524bSJohan Hedberg 6043f0f524bSJohan Hedberg if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) 6053f0f524bSJohan Hedberg flags |= LE_AD_GENERAL; 6063f0f524bSJohan Hedberg 6073f0f524bSJohan Hedberg if (!lmp_bredr_capable(hdev)) 6083f0f524bSJohan Hedberg flags |= LE_AD_NO_BREDR; 6093f0f524bSJohan Hedberg 6103f0f524bSJohan Hedberg if (lmp_le_br_capable(hdev)) 6113f0f524bSJohan Hedberg flags |= LE_AD_SIM_LE_BREDR_CTRL; 6123f0f524bSJohan Hedberg 6133f0f524bSJohan Hedberg if (lmp_host_le_br_capable(hdev)) 6143f0f524bSJohan Hedberg flags |= LE_AD_SIM_LE_BREDR_HOST; 6153f0f524bSJohan Hedberg 6163f0f524bSJohan Hedberg if (flags) { 6173f0f524bSJohan Hedberg BT_DBG("adv flags 0x%02x", flags); 6183f0f524bSJohan Hedberg 6193f0f524bSJohan Hedberg ptr[0] = 2; 6203f0f524bSJohan Hedberg ptr[1] = EIR_FLAGS; 6213f0f524bSJohan Hedberg ptr[2] = flags; 6223f0f524bSJohan Hedberg 6233f0f524bSJohan Hedberg ad_len += 3; 6243f0f524bSJohan Hedberg ptr += 3; 6253f0f524bSJohan Hedberg } 6263f0f524bSJohan Hedberg 6273f0f524bSJohan Hedberg if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) { 6283f0f524bSJohan Hedberg ptr[0] = 2; 6293f0f524bSJohan Hedberg ptr[1] = EIR_TX_POWER; 6303f0f524bSJohan Hedberg ptr[2] = (u8) hdev->adv_tx_power; 6313f0f524bSJohan Hedberg 6323f0f524bSJohan Hedberg ad_len += 3; 6333f0f524bSJohan Hedberg ptr += 3; 6343f0f524bSJohan Hedberg } 6353f0f524bSJohan Hedberg 6363f0f524bSJohan Hedberg name_len = strlen(hdev->dev_name); 6373f0f524bSJohan Hedberg if (name_len > 0) { 6383f0f524bSJohan Hedberg size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2; 6393f0f524bSJohan Hedberg 6403f0f524bSJohan Hedberg if (name_len > max_len) { 6413f0f524bSJohan Hedberg name_len = max_len; 6423f0f524bSJohan Hedberg ptr[1] = EIR_NAME_SHORT; 6433f0f524bSJohan Hedberg } else 6443f0f524bSJohan Hedberg ptr[1] = EIR_NAME_COMPLETE; 6453f0f524bSJohan Hedberg 6463f0f524bSJohan Hedberg ptr[0] = name_len + 1; 6473f0f524bSJohan Hedberg 6483f0f524bSJohan Hedberg memcpy(ptr + 2, hdev->dev_name, name_len); 6493f0f524bSJohan Hedberg 6503f0f524bSJohan Hedberg ad_len += (name_len + 2); 6513f0f524bSJohan Hedberg ptr += (name_len + 2); 6523f0f524bSJohan Hedberg } 6533f0f524bSJohan Hedberg 6543f0f524bSJohan Hedberg return ad_len; 6553f0f524bSJohan Hedberg } 6563f0f524bSJohan Hedberg 6573f0f524bSJohan Hedberg int hci_update_ad(struct hci_dev *hdev) 6583f0f524bSJohan Hedberg { 6593f0f524bSJohan Hedberg struct hci_cp_le_set_adv_data cp; 6603f0f524bSJohan Hedberg u8 len; 6613f0f524bSJohan Hedberg int err; 6623f0f524bSJohan Hedberg 6633f0f524bSJohan Hedberg hci_dev_lock(hdev); 6643f0f524bSJohan Hedberg 6653f0f524bSJohan Hedberg if (!lmp_le_capable(hdev)) { 6663f0f524bSJohan Hedberg err = -EINVAL; 6673f0f524bSJohan Hedberg goto unlock; 6683f0f524bSJohan Hedberg } 6693f0f524bSJohan Hedberg 6703f0f524bSJohan Hedberg memset(&cp, 0, sizeof(cp)); 6713f0f524bSJohan Hedberg 6723f0f524bSJohan Hedberg len = create_ad(hdev, cp.data); 6733f0f524bSJohan Hedberg 6743f0f524bSJohan Hedberg if (hdev->adv_data_len == len && 6753f0f524bSJohan Hedberg memcmp(cp.data, hdev->adv_data, len) == 0) { 6763f0f524bSJohan Hedberg err = 0; 6773f0f524bSJohan Hedberg goto unlock; 6783f0f524bSJohan Hedberg } 6793f0f524bSJohan Hedberg 6803f0f524bSJohan Hedberg memcpy(hdev->adv_data, cp.data, sizeof(cp.data)); 6813f0f524bSJohan Hedberg hdev->adv_data_len = len; 6823f0f524bSJohan Hedberg 6833f0f524bSJohan Hedberg cp.length = len; 6843f0f524bSJohan Hedberg err = hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp); 6853f0f524bSJohan Hedberg 6863f0f524bSJohan Hedberg unlock: 6873f0f524bSJohan Hedberg hci_dev_unlock(hdev); 6883f0f524bSJohan Hedberg 6893f0f524bSJohan Hedberg return err; 6903f0f524bSJohan Hedberg } 6913f0f524bSJohan Hedberg 6921da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */ 6931da177e4SLinus Torvalds 6941da177e4SLinus Torvalds int hci_dev_open(__u16 dev) 6951da177e4SLinus Torvalds { 6961da177e4SLinus Torvalds struct hci_dev *hdev; 6971da177e4SLinus Torvalds int ret = 0; 6981da177e4SLinus Torvalds 6995a08ecceSAndrei Emeltchenko hdev = hci_dev_get(dev); 7005a08ecceSAndrei Emeltchenko if (!hdev) 7011da177e4SLinus Torvalds return -ENODEV; 7021da177e4SLinus Torvalds 7031da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 7041da177e4SLinus Torvalds 7051da177e4SLinus Torvalds hci_req_lock(hdev); 7061da177e4SLinus Torvalds 70794324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 70894324962SJohan Hovold ret = -ENODEV; 70994324962SJohan Hovold goto done; 71094324962SJohan Hovold } 71194324962SJohan Hovold 712611b30f7SMarcel Holtmann if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { 713611b30f7SMarcel Holtmann ret = -ERFKILL; 714611b30f7SMarcel Holtmann goto done; 715611b30f7SMarcel Holtmann } 716611b30f7SMarcel Holtmann 7171da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 7181da177e4SLinus Torvalds ret = -EALREADY; 7191da177e4SLinus Torvalds goto done; 7201da177e4SLinus Torvalds } 7211da177e4SLinus Torvalds 7221da177e4SLinus Torvalds if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 7231da177e4SLinus Torvalds set_bit(HCI_RAW, &hdev->flags); 7241da177e4SLinus Torvalds 72507e3b94aSAndrei Emeltchenko /* Treat all non BR/EDR controllers as raw devices if 72607e3b94aSAndrei Emeltchenko enable_hs is not set */ 72707e3b94aSAndrei Emeltchenko if (hdev->dev_type != HCI_BREDR && !enable_hs) 728943da25dSMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 729943da25dSMarcel Holtmann 7301da177e4SLinus Torvalds if (hdev->open(hdev)) { 7311da177e4SLinus Torvalds ret = -EIO; 7321da177e4SLinus Torvalds goto done; 7331da177e4SLinus Torvalds } 7341da177e4SLinus Torvalds 7351da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 7361da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 7371da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 738a5040efaSJohan Hedberg hdev->init_last_cmd = 0; 7391da177e4SLinus Torvalds 7405f246e89SAndrei Emeltchenko ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT); 7411da177e4SLinus Torvalds 7421da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7431da177e4SLinus Torvalds } 7441da177e4SLinus Torvalds 7451da177e4SLinus Torvalds if (!ret) { 7461da177e4SLinus Torvalds hci_dev_hold(hdev); 7471da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 7481da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 7493f0f524bSJohan Hedberg hci_update_ad(hdev); 750bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 751bb4b2a9aSAndrei Emeltchenko mgmt_valid_hdev(hdev)) { 75209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 753744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 75409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 75556e5cb86SJohan Hedberg } 7561da177e4SLinus Torvalds } else { 7571da177e4SLinus Torvalds /* Init failed, cleanup */ 7583eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 759c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 760b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7611da177e4SLinus Torvalds 7621da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7631da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7641da177e4SLinus Torvalds 7651da177e4SLinus Torvalds if (hdev->flush) 7661da177e4SLinus Torvalds hdev->flush(hdev); 7671da177e4SLinus Torvalds 7681da177e4SLinus Torvalds if (hdev->sent_cmd) { 7691da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 7701da177e4SLinus Torvalds hdev->sent_cmd = NULL; 7711da177e4SLinus Torvalds } 7721da177e4SLinus Torvalds 7731da177e4SLinus Torvalds hdev->close(hdev); 7741da177e4SLinus Torvalds hdev->flags = 0; 7751da177e4SLinus Torvalds } 7761da177e4SLinus Torvalds 7771da177e4SLinus Torvalds done: 7781da177e4SLinus Torvalds hci_req_unlock(hdev); 7791da177e4SLinus Torvalds hci_dev_put(hdev); 7801da177e4SLinus Torvalds return ret; 7811da177e4SLinus Torvalds } 7821da177e4SLinus Torvalds 7831da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 7841da177e4SLinus Torvalds { 7851da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 7861da177e4SLinus Torvalds 78728b75a89SAndre Guedes cancel_work_sync(&hdev->le_scan); 78828b75a89SAndre Guedes 78978c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 79078c04c0bSVinicius Costa Gomes 7911da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 7921da177e4SLinus Torvalds hci_req_lock(hdev); 7931da177e4SLinus Torvalds 7941da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 795b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 7961da177e4SLinus Torvalds hci_req_unlock(hdev); 7971da177e4SLinus Torvalds return 0; 7981da177e4SLinus Torvalds } 7991da177e4SLinus Torvalds 8003eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 8013eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 802b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 8031da177e4SLinus Torvalds 80416ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 805e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 80616ab91abSJohan Hedberg hdev->discov_timeout = 0; 8075e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 80816ab91abSJohan Hedberg } 80916ab91abSJohan Hedberg 810a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 8117d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 8127d78525dSJohan Hedberg 8137ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 8147ba8b4beSAndre Guedes 81509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 8161da177e4SLinus Torvalds inquiry_cache_flush(hdev); 8171da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 81809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8191da177e4SLinus Torvalds 8201da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 8211da177e4SLinus Torvalds 8221da177e4SLinus Torvalds if (hdev->flush) 8231da177e4SLinus Torvalds hdev->flush(hdev); 8241da177e4SLinus Torvalds 8251da177e4SLinus Torvalds /* Reset device */ 8261da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8271da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 8288af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 829a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 8301da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 8315f246e89SAndrei Emeltchenko __hci_request(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 8321da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 8331da177e4SLinus Torvalds } 8341da177e4SLinus Torvalds 835c347b765SGustavo F. Padovan /* flush cmd work */ 836c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 8371da177e4SLinus Torvalds 8381da177e4SLinus Torvalds /* Drop queues */ 8391da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 8401da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8411da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 8421da177e4SLinus Torvalds 8431da177e4SLinus Torvalds /* Drop last sent command */ 8441da177e4SLinus Torvalds if (hdev->sent_cmd) { 845b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 8461da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 8471da177e4SLinus Torvalds hdev->sent_cmd = NULL; 8481da177e4SLinus Torvalds } 8491da177e4SLinus Torvalds 8501da177e4SLinus Torvalds /* After this point our queues are empty 8511da177e4SLinus Torvalds * and no tasks are scheduled. */ 8521da177e4SLinus Torvalds hdev->close(hdev); 8531da177e4SLinus Torvalds 854bb4b2a9aSAndrei Emeltchenko if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 855bb4b2a9aSAndrei Emeltchenko mgmt_valid_hdev(hdev)) { 85609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 857744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 85809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8598ee56540SMarcel Holtmann } 8605add6af8SJohan Hedberg 8611da177e4SLinus Torvalds /* Clear flags */ 8621da177e4SLinus Torvalds hdev->flags = 0; 8631da177e4SLinus Torvalds 864ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 865ced5c338SAndrei Emeltchenko hdev->amp_status = 0; 866ced5c338SAndrei Emeltchenko 867e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 86809b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 869e59fda8dSJohan Hedberg 8701da177e4SLinus Torvalds hci_req_unlock(hdev); 8711da177e4SLinus Torvalds 8721da177e4SLinus Torvalds hci_dev_put(hdev); 8731da177e4SLinus Torvalds return 0; 8741da177e4SLinus Torvalds } 8751da177e4SLinus Torvalds 8761da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 8771da177e4SLinus Torvalds { 8781da177e4SLinus Torvalds struct hci_dev *hdev; 8791da177e4SLinus Torvalds int err; 8801da177e4SLinus Torvalds 88170f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 88270f23020SAndrei Emeltchenko if (!hdev) 8831da177e4SLinus Torvalds return -ENODEV; 8848ee56540SMarcel Holtmann 8858ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 8868ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 8878ee56540SMarcel Holtmann 8881da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 8898ee56540SMarcel Holtmann 8901da177e4SLinus Torvalds hci_dev_put(hdev); 8911da177e4SLinus Torvalds return err; 8921da177e4SLinus Torvalds } 8931da177e4SLinus Torvalds 8941da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 8951da177e4SLinus Torvalds { 8961da177e4SLinus Torvalds struct hci_dev *hdev; 8971da177e4SLinus Torvalds int ret = 0; 8981da177e4SLinus Torvalds 89970f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 90070f23020SAndrei Emeltchenko if (!hdev) 9011da177e4SLinus Torvalds return -ENODEV; 9021da177e4SLinus Torvalds 9031da177e4SLinus Torvalds hci_req_lock(hdev); 9041da177e4SLinus Torvalds 9051da177e4SLinus Torvalds if (!test_bit(HCI_UP, &hdev->flags)) 9061da177e4SLinus Torvalds goto done; 9071da177e4SLinus Torvalds 9081da177e4SLinus Torvalds /* Drop queues */ 9091da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 9101da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 9111da177e4SLinus Torvalds 91209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 9131da177e4SLinus Torvalds inquiry_cache_flush(hdev); 9141da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 91509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 9161da177e4SLinus Torvalds 9171da177e4SLinus Torvalds if (hdev->flush) 9181da177e4SLinus Torvalds hdev->flush(hdev); 9191da177e4SLinus Torvalds 9201da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 9216ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 9221da177e4SLinus Torvalds 9231da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 9245f246e89SAndrei Emeltchenko ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 9251da177e4SLinus Torvalds 9261da177e4SLinus Torvalds done: 9271da177e4SLinus Torvalds hci_req_unlock(hdev); 9281da177e4SLinus Torvalds hci_dev_put(hdev); 9291da177e4SLinus Torvalds return ret; 9301da177e4SLinus Torvalds } 9311da177e4SLinus Torvalds 9321da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 9331da177e4SLinus Torvalds { 9341da177e4SLinus Torvalds struct hci_dev *hdev; 9351da177e4SLinus Torvalds int ret = 0; 9361da177e4SLinus Torvalds 93770f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 93870f23020SAndrei Emeltchenko if (!hdev) 9391da177e4SLinus Torvalds return -ENODEV; 9401da177e4SLinus Torvalds 9411da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 9421da177e4SLinus Torvalds 9431da177e4SLinus Torvalds hci_dev_put(hdev); 9441da177e4SLinus Torvalds 9451da177e4SLinus Torvalds return ret; 9461da177e4SLinus Torvalds } 9471da177e4SLinus Torvalds 9481da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 9491da177e4SLinus Torvalds { 9501da177e4SLinus Torvalds struct hci_dev *hdev; 9511da177e4SLinus Torvalds struct hci_dev_req dr; 9521da177e4SLinus Torvalds int err = 0; 9531da177e4SLinus Torvalds 9541da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 9551da177e4SLinus Torvalds return -EFAULT; 9561da177e4SLinus Torvalds 95770f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 95870f23020SAndrei Emeltchenko if (!hdev) 9591da177e4SLinus Torvalds return -ENODEV; 9601da177e4SLinus Torvalds 9611da177e4SLinus Torvalds switch (cmd) { 9621da177e4SLinus Torvalds case HCISETAUTH: 96304837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 9645f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 9651da177e4SLinus Torvalds break; 9661da177e4SLinus Torvalds 9671da177e4SLinus Torvalds case HCISETENCRYPT: 9681da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 9691da177e4SLinus Torvalds err = -EOPNOTSUPP; 9701da177e4SLinus Torvalds break; 9711da177e4SLinus Torvalds } 9721da177e4SLinus Torvalds 9731da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 9741da177e4SLinus Torvalds /* Auth must be enabled first */ 97504837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 9765f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 9771da177e4SLinus Torvalds if (err) 9781da177e4SLinus Torvalds break; 9791da177e4SLinus Torvalds } 9801da177e4SLinus Torvalds 98104837f64SMarcel Holtmann err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, 9825f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 9831da177e4SLinus Torvalds break; 9841da177e4SLinus Torvalds 9851da177e4SLinus Torvalds case HCISETSCAN: 98604837f64SMarcel Holtmann err = hci_request(hdev, hci_scan_req, dr.dev_opt, 9875f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 9881da177e4SLinus Torvalds break; 9891da177e4SLinus Torvalds 9901da177e4SLinus Torvalds case HCISETLINKPOL: 991e4e8e37cSMarcel Holtmann err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, 9925f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 9931da177e4SLinus Torvalds break; 9941da177e4SLinus Torvalds 9951da177e4SLinus Torvalds case HCISETLINKMODE: 996e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 997e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 998e4e8e37cSMarcel Holtmann break; 999e4e8e37cSMarcel Holtmann 1000e4e8e37cSMarcel Holtmann case HCISETPTYPE: 1001e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 10021da177e4SLinus Torvalds break; 10031da177e4SLinus Torvalds 10041da177e4SLinus Torvalds case HCISETACLMTU: 10051da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 10061da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 10071da177e4SLinus Torvalds break; 10081da177e4SLinus Torvalds 10091da177e4SLinus Torvalds case HCISETSCOMTU: 10101da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 10111da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 10121da177e4SLinus Torvalds break; 10131da177e4SLinus Torvalds 10141da177e4SLinus Torvalds default: 10151da177e4SLinus Torvalds err = -EINVAL; 10161da177e4SLinus Torvalds break; 10171da177e4SLinus Torvalds } 1018e4e8e37cSMarcel Holtmann 10191da177e4SLinus Torvalds hci_dev_put(hdev); 10201da177e4SLinus Torvalds return err; 10211da177e4SLinus Torvalds } 10221da177e4SLinus Torvalds 10231da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 10241da177e4SLinus Torvalds { 10258035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 10261da177e4SLinus Torvalds struct hci_dev_list_req *dl; 10271da177e4SLinus Torvalds struct hci_dev_req *dr; 10281da177e4SLinus Torvalds int n = 0, size, err; 10291da177e4SLinus Torvalds __u16 dev_num; 10301da177e4SLinus Torvalds 10311da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 10321da177e4SLinus Torvalds return -EFAULT; 10331da177e4SLinus Torvalds 10341da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 10351da177e4SLinus Torvalds return -EINVAL; 10361da177e4SLinus Torvalds 10371da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 10381da177e4SLinus Torvalds 103970f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 104070f23020SAndrei Emeltchenko if (!dl) 10411da177e4SLinus Torvalds return -ENOMEM; 10421da177e4SLinus Torvalds 10431da177e4SLinus Torvalds dr = dl->dev_req; 10441da177e4SLinus Torvalds 1045f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 10468035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 1047a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1048e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 1049c542a06cSJohan Hedberg 1050a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1051a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1052c542a06cSJohan Hedberg 10531da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 10541da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 1055c542a06cSJohan Hedberg 10561da177e4SLinus Torvalds if (++n >= dev_num) 10571da177e4SLinus Torvalds break; 10581da177e4SLinus Torvalds } 1059f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 10601da177e4SLinus Torvalds 10611da177e4SLinus Torvalds dl->dev_num = n; 10621da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 10631da177e4SLinus Torvalds 10641da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 10651da177e4SLinus Torvalds kfree(dl); 10661da177e4SLinus Torvalds 10671da177e4SLinus Torvalds return err ? -EFAULT : 0; 10681da177e4SLinus Torvalds } 10691da177e4SLinus Torvalds 10701da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 10711da177e4SLinus Torvalds { 10721da177e4SLinus Torvalds struct hci_dev *hdev; 10731da177e4SLinus Torvalds struct hci_dev_info di; 10741da177e4SLinus Torvalds int err = 0; 10751da177e4SLinus Torvalds 10761da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 10771da177e4SLinus Torvalds return -EFAULT; 10781da177e4SLinus Torvalds 107970f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 108070f23020SAndrei Emeltchenko if (!hdev) 10811da177e4SLinus Torvalds return -ENODEV; 10821da177e4SLinus Torvalds 1083a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 10843243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 1085ab81cbf9SJohan Hedberg 1086a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1087a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1088c542a06cSJohan Hedberg 10891da177e4SLinus Torvalds strcpy(di.name, hdev->name); 10901da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 1091943da25dSMarcel Holtmann di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); 10921da177e4SLinus Torvalds di.flags = hdev->flags; 10931da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 1094572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 10951da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 10961da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 10971da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 10981da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 1099572c7f84SJohan Hedberg } else { 1100572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 1101572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 1102572c7f84SJohan Hedberg di.sco_mtu = 0; 1103572c7f84SJohan Hedberg di.sco_pkts = 0; 1104572c7f84SJohan Hedberg } 11051da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 11061da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 11071da177e4SLinus Torvalds 11081da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 11091da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 11101da177e4SLinus Torvalds 11111da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 11121da177e4SLinus Torvalds err = -EFAULT; 11131da177e4SLinus Torvalds 11141da177e4SLinus Torvalds hci_dev_put(hdev); 11151da177e4SLinus Torvalds 11161da177e4SLinus Torvalds return err; 11171da177e4SLinus Torvalds } 11181da177e4SLinus Torvalds 11191da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 11201da177e4SLinus Torvalds 1121611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 1122611b30f7SMarcel Holtmann { 1123611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 1124611b30f7SMarcel Holtmann 1125611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 1126611b30f7SMarcel Holtmann 1127611b30f7SMarcel Holtmann if (!blocked) 1128611b30f7SMarcel Holtmann return 0; 1129611b30f7SMarcel Holtmann 1130611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 1131611b30f7SMarcel Holtmann 1132611b30f7SMarcel Holtmann return 0; 1133611b30f7SMarcel Holtmann } 1134611b30f7SMarcel Holtmann 1135611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 1136611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 1137611b30f7SMarcel Holtmann }; 1138611b30f7SMarcel Holtmann 1139ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 1140ab81cbf9SJohan Hedberg { 1141ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 1142ab81cbf9SJohan Hedberg 1143ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1144ab81cbf9SJohan Hedberg 1145ab81cbf9SJohan Hedberg if (hci_dev_open(hdev->id) < 0) 1146ab81cbf9SJohan Hedberg return; 1147ab81cbf9SJohan Hedberg 1148a8b2d5c2SJohan Hedberg if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1149*19202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 1150*19202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 1151ab81cbf9SJohan Hedberg 1152a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 1153744cf19eSJohan Hedberg mgmt_index_added(hdev); 1154ab81cbf9SJohan Hedberg } 1155ab81cbf9SJohan Hedberg 1156ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1157ab81cbf9SJohan Hedberg { 11583243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 11593243553fSJohan Hedberg power_off.work); 1160ab81cbf9SJohan Hedberg 1161ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1162ab81cbf9SJohan Hedberg 11638ee56540SMarcel Holtmann hci_dev_do_close(hdev); 1164ab81cbf9SJohan Hedberg } 1165ab81cbf9SJohan Hedberg 116616ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 116716ab91abSJohan Hedberg { 116816ab91abSJohan Hedberg struct hci_dev *hdev; 116916ab91abSJohan Hedberg u8 scan = SCAN_PAGE; 117016ab91abSJohan Hedberg 117116ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 117216ab91abSJohan Hedberg 117316ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 117416ab91abSJohan Hedberg 117509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 117616ab91abSJohan Hedberg 117716ab91abSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); 117816ab91abSJohan Hedberg 117916ab91abSJohan Hedberg hdev->discov_timeout = 0; 118016ab91abSJohan Hedberg 118109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 118216ab91abSJohan Hedberg } 118316ab91abSJohan Hedberg 11842aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 11852aeb9a1aSJohan Hedberg { 11862aeb9a1aSJohan Hedberg struct list_head *p, *n; 11872aeb9a1aSJohan Hedberg 11882aeb9a1aSJohan Hedberg list_for_each_safe(p, n, &hdev->uuids) { 11892aeb9a1aSJohan Hedberg struct bt_uuid *uuid; 11902aeb9a1aSJohan Hedberg 11912aeb9a1aSJohan Hedberg uuid = list_entry(p, struct bt_uuid, list); 11922aeb9a1aSJohan Hedberg 11932aeb9a1aSJohan Hedberg list_del(p); 11942aeb9a1aSJohan Hedberg kfree(uuid); 11952aeb9a1aSJohan Hedberg } 11962aeb9a1aSJohan Hedberg 11972aeb9a1aSJohan Hedberg return 0; 11982aeb9a1aSJohan Hedberg } 11992aeb9a1aSJohan Hedberg 120055ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 120155ed8ca1SJohan Hedberg { 120255ed8ca1SJohan Hedberg struct list_head *p, *n; 120355ed8ca1SJohan Hedberg 120455ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 120555ed8ca1SJohan Hedberg struct link_key *key; 120655ed8ca1SJohan Hedberg 120755ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 120855ed8ca1SJohan Hedberg 120955ed8ca1SJohan Hedberg list_del(p); 121055ed8ca1SJohan Hedberg kfree(key); 121155ed8ca1SJohan Hedberg } 121255ed8ca1SJohan Hedberg 121355ed8ca1SJohan Hedberg return 0; 121455ed8ca1SJohan Hedberg } 121555ed8ca1SJohan Hedberg 1216b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 1217b899efafSVinicius Costa Gomes { 1218b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1219b899efafSVinicius Costa Gomes 1220b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1221b899efafSVinicius Costa Gomes list_del(&k->list); 1222b899efafSVinicius Costa Gomes kfree(k); 1223b899efafSVinicius Costa Gomes } 1224b899efafSVinicius Costa Gomes 1225b899efafSVinicius Costa Gomes return 0; 1226b899efafSVinicius Costa Gomes } 1227b899efafSVinicius Costa Gomes 122855ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 122955ed8ca1SJohan Hedberg { 123055ed8ca1SJohan Hedberg struct link_key *k; 123155ed8ca1SJohan Hedberg 12328035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 123355ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 123455ed8ca1SJohan Hedberg return k; 123555ed8ca1SJohan Hedberg 123655ed8ca1SJohan Hedberg return NULL; 123755ed8ca1SJohan Hedberg } 123855ed8ca1SJohan Hedberg 1239745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 1240d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 1241d25e28abSJohan Hedberg { 1242d25e28abSJohan Hedberg /* Legacy key */ 1243d25e28abSJohan Hedberg if (key_type < 0x03) 1244745c0ce3SVishal Agarwal return true; 1245d25e28abSJohan Hedberg 1246d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 1247d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 1248745c0ce3SVishal Agarwal return false; 1249d25e28abSJohan Hedberg 1250d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 1251d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 1252745c0ce3SVishal Agarwal return false; 1253d25e28abSJohan Hedberg 1254d25e28abSJohan Hedberg /* Security mode 3 case */ 1255d25e28abSJohan Hedberg if (!conn) 1256745c0ce3SVishal Agarwal return true; 1257d25e28abSJohan Hedberg 1258d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 1259d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 1260745c0ce3SVishal Agarwal return true; 1261d25e28abSJohan Hedberg 1262d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 1263d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 1264745c0ce3SVishal Agarwal return true; 1265d25e28abSJohan Hedberg 1266d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 1267d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 1268745c0ce3SVishal Agarwal return true; 1269d25e28abSJohan Hedberg 1270d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 1271d25e28abSJohan Hedberg * persistently */ 1272745c0ce3SVishal Agarwal return false; 1273d25e28abSJohan Hedberg } 1274d25e28abSJohan Hedberg 1275c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 127675d262c2SVinicius Costa Gomes { 1277c9839a11SVinicius Costa Gomes struct smp_ltk *k; 127875d262c2SVinicius Costa Gomes 1279c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 1280c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 1281c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 128275d262c2SVinicius Costa Gomes continue; 128375d262c2SVinicius Costa Gomes 128475d262c2SVinicius Costa Gomes return k; 128575d262c2SVinicius Costa Gomes } 128675d262c2SVinicius Costa Gomes 128775d262c2SVinicius Costa Gomes return NULL; 128875d262c2SVinicius Costa Gomes } 128975d262c2SVinicius Costa Gomes 1290c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1291c9839a11SVinicius Costa Gomes u8 addr_type) 129275d262c2SVinicius Costa Gomes { 1293c9839a11SVinicius Costa Gomes struct smp_ltk *k; 129475d262c2SVinicius Costa Gomes 1295c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 1296c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 1297c9839a11SVinicius Costa Gomes bacmp(bdaddr, &k->bdaddr) == 0) 129875d262c2SVinicius Costa Gomes return k; 129975d262c2SVinicius Costa Gomes 130075d262c2SVinicius Costa Gomes return NULL; 130175d262c2SVinicius Costa Gomes } 130275d262c2SVinicius Costa Gomes 1303d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 1304d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 130555ed8ca1SJohan Hedberg { 130655ed8ca1SJohan Hedberg struct link_key *key, *old_key; 1307745c0ce3SVishal Agarwal u8 old_key_type; 1308745c0ce3SVishal Agarwal bool persistent; 130955ed8ca1SJohan Hedberg 131055ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 131155ed8ca1SJohan Hedberg if (old_key) { 131255ed8ca1SJohan Hedberg old_key_type = old_key->type; 131355ed8ca1SJohan Hedberg key = old_key; 131455ed8ca1SJohan Hedberg } else { 131512adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 131655ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 131755ed8ca1SJohan Hedberg if (!key) 131855ed8ca1SJohan Hedberg return -ENOMEM; 131955ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 132055ed8ca1SJohan Hedberg } 132155ed8ca1SJohan Hedberg 13226ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 132355ed8ca1SJohan Hedberg 1324d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1325d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1326d25e28abSJohan Hedberg * previous key */ 1327d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1328a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 1329d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1330655fe6ecSJohan Hedberg if (conn) 1331655fe6ecSJohan Hedberg conn->key_type = type; 1332655fe6ecSJohan Hedberg } 1333d25e28abSJohan Hedberg 133455ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 13359b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 133655ed8ca1SJohan Hedberg key->pin_len = pin_len; 133755ed8ca1SJohan Hedberg 1338b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 133955ed8ca1SJohan Hedberg key->type = old_key_type; 13404748fed2SJohan Hedberg else 13414748fed2SJohan Hedberg key->type = type; 13424748fed2SJohan Hedberg 13434df378a1SJohan Hedberg if (!new_key) 13444df378a1SJohan Hedberg return 0; 13454df378a1SJohan Hedberg 13464df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 13474df378a1SJohan Hedberg 1348744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 13494df378a1SJohan Hedberg 13506ec5bcadSVishal Agarwal if (conn) 13516ec5bcadSVishal Agarwal conn->flush_key = !persistent; 135255ed8ca1SJohan Hedberg 135355ed8ca1SJohan Hedberg return 0; 135455ed8ca1SJohan Hedberg } 135555ed8ca1SJohan Hedberg 1356c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 13579a006657SAndrei Emeltchenko int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 135804124681SGustavo F. Padovan ediv, u8 rand[8]) 135975d262c2SVinicius Costa Gomes { 1360c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 136175d262c2SVinicius Costa Gomes 1362c9839a11SVinicius Costa Gomes if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 1363c9839a11SVinicius Costa Gomes return 0; 136475d262c2SVinicius Costa Gomes 1365c9839a11SVinicius Costa Gomes old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 1366c9839a11SVinicius Costa Gomes if (old_key) 136775d262c2SVinicius Costa Gomes key = old_key; 1368c9839a11SVinicius Costa Gomes else { 1369c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 137075d262c2SVinicius Costa Gomes if (!key) 137175d262c2SVinicius Costa Gomes return -ENOMEM; 1372c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 137375d262c2SVinicius Costa Gomes } 137475d262c2SVinicius Costa Gomes 137575d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 1376c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 1377c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 1378c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 1379c9839a11SVinicius Costa Gomes key->ediv = ediv; 1380c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 1381c9839a11SVinicius Costa Gomes key->type = type; 1382c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 138375d262c2SVinicius Costa Gomes 1384c9839a11SVinicius Costa Gomes if (!new_key) 1385c9839a11SVinicius Costa Gomes return 0; 138675d262c2SVinicius Costa Gomes 1387261cc5aaSVinicius Costa Gomes if (type & HCI_SMP_LTK) 1388261cc5aaSVinicius Costa Gomes mgmt_new_ltk(hdev, key, 1); 1389261cc5aaSVinicius Costa Gomes 139075d262c2SVinicius Costa Gomes return 0; 139175d262c2SVinicius Costa Gomes } 139275d262c2SVinicius Costa Gomes 139355ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 139455ed8ca1SJohan Hedberg { 139555ed8ca1SJohan Hedberg struct link_key *key; 139655ed8ca1SJohan Hedberg 139755ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 139855ed8ca1SJohan Hedberg if (!key) 139955ed8ca1SJohan Hedberg return -ENOENT; 140055ed8ca1SJohan Hedberg 14016ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 140255ed8ca1SJohan Hedberg 140355ed8ca1SJohan Hedberg list_del(&key->list); 140455ed8ca1SJohan Hedberg kfree(key); 140555ed8ca1SJohan Hedberg 140655ed8ca1SJohan Hedberg return 0; 140755ed8ca1SJohan Hedberg } 140855ed8ca1SJohan Hedberg 1409b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 1410b899efafSVinicius Costa Gomes { 1411b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1412b899efafSVinicius Costa Gomes 1413b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1414b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 1415b899efafSVinicius Costa Gomes continue; 1416b899efafSVinicius Costa Gomes 14176ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 1418b899efafSVinicius Costa Gomes 1419b899efafSVinicius Costa Gomes list_del(&k->list); 1420b899efafSVinicius Costa Gomes kfree(k); 1421b899efafSVinicius Costa Gomes } 1422b899efafSVinicius Costa Gomes 1423b899efafSVinicius Costa Gomes return 0; 1424b899efafSVinicius Costa Gomes } 1425b899efafSVinicius Costa Gomes 14266bd32326SVille Tervo /* HCI command timer function */ 1427bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg) 14286bd32326SVille Tervo { 14296bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 14306bd32326SVille Tervo 1431bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 1432bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 1433bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 1434bda4f23aSAndrei Emeltchenko 1435bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 1436bda4f23aSAndrei Emeltchenko } else { 14376bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 1438bda4f23aSAndrei Emeltchenko } 1439bda4f23aSAndrei Emeltchenko 14406bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 1441c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 14426bd32326SVille Tervo } 14436bd32326SVille Tervo 14442763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 14452763eda6SSzymon Janc bdaddr_t *bdaddr) 14462763eda6SSzymon Janc { 14472763eda6SSzymon Janc struct oob_data *data; 14482763eda6SSzymon Janc 14492763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 14502763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 14512763eda6SSzymon Janc return data; 14522763eda6SSzymon Janc 14532763eda6SSzymon Janc return NULL; 14542763eda6SSzymon Janc } 14552763eda6SSzymon Janc 14562763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 14572763eda6SSzymon Janc { 14582763eda6SSzymon Janc struct oob_data *data; 14592763eda6SSzymon Janc 14602763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14612763eda6SSzymon Janc if (!data) 14622763eda6SSzymon Janc return -ENOENT; 14632763eda6SSzymon Janc 14646ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 14652763eda6SSzymon Janc 14662763eda6SSzymon Janc list_del(&data->list); 14672763eda6SSzymon Janc kfree(data); 14682763eda6SSzymon Janc 14692763eda6SSzymon Janc return 0; 14702763eda6SSzymon Janc } 14712763eda6SSzymon Janc 14722763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 14732763eda6SSzymon Janc { 14742763eda6SSzymon Janc struct oob_data *data, *n; 14752763eda6SSzymon Janc 14762763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 14772763eda6SSzymon Janc list_del(&data->list); 14782763eda6SSzymon Janc kfree(data); 14792763eda6SSzymon Janc } 14802763eda6SSzymon Janc 14812763eda6SSzymon Janc return 0; 14822763eda6SSzymon Janc } 14832763eda6SSzymon Janc 14842763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 14852763eda6SSzymon Janc u8 *randomizer) 14862763eda6SSzymon Janc { 14872763eda6SSzymon Janc struct oob_data *data; 14882763eda6SSzymon Janc 14892763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14902763eda6SSzymon Janc 14912763eda6SSzymon Janc if (!data) { 14922763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 14932763eda6SSzymon Janc if (!data) 14942763eda6SSzymon Janc return -ENOMEM; 14952763eda6SSzymon Janc 14962763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 14972763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 14982763eda6SSzymon Janc } 14992763eda6SSzymon Janc 15002763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 15012763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 15022763eda6SSzymon Janc 15036ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 15042763eda6SSzymon Janc 15052763eda6SSzymon Janc return 0; 15062763eda6SSzymon Janc } 15072763eda6SSzymon Janc 150804124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 1509b2a66aadSAntti Julku { 1510b2a66aadSAntti Julku struct bdaddr_list *b; 1511b2a66aadSAntti Julku 15128035ded4SLuiz Augusto von Dentz list_for_each_entry(b, &hdev->blacklist, list) 1513b2a66aadSAntti Julku if (bacmp(bdaddr, &b->bdaddr) == 0) 1514b2a66aadSAntti Julku return b; 1515b2a66aadSAntti Julku 1516b2a66aadSAntti Julku return NULL; 1517b2a66aadSAntti Julku } 1518b2a66aadSAntti Julku 1519b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 1520b2a66aadSAntti Julku { 1521b2a66aadSAntti Julku struct list_head *p, *n; 1522b2a66aadSAntti Julku 1523b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 1524b2a66aadSAntti Julku struct bdaddr_list *b; 1525b2a66aadSAntti Julku 1526b2a66aadSAntti Julku b = list_entry(p, struct bdaddr_list, list); 1527b2a66aadSAntti Julku 1528b2a66aadSAntti Julku list_del(p); 1529b2a66aadSAntti Julku kfree(b); 1530b2a66aadSAntti Julku } 1531b2a66aadSAntti Julku 1532b2a66aadSAntti Julku return 0; 1533b2a66aadSAntti Julku } 1534b2a66aadSAntti Julku 153588c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1536b2a66aadSAntti Julku { 1537b2a66aadSAntti Julku struct bdaddr_list *entry; 1538b2a66aadSAntti Julku 1539b2a66aadSAntti Julku if (bacmp(bdaddr, BDADDR_ANY) == 0) 1540b2a66aadSAntti Julku return -EBADF; 1541b2a66aadSAntti Julku 15425e762444SAntti Julku if (hci_blacklist_lookup(hdev, bdaddr)) 15435e762444SAntti Julku return -EEXIST; 1544b2a66aadSAntti Julku 1545b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 15465e762444SAntti Julku if (!entry) 15475e762444SAntti Julku return -ENOMEM; 1548b2a66aadSAntti Julku 1549b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 1550b2a66aadSAntti Julku 1551b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 1552b2a66aadSAntti Julku 155388c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 1554b2a66aadSAntti Julku } 1555b2a66aadSAntti Julku 155688c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1557b2a66aadSAntti Julku { 1558b2a66aadSAntti Julku struct bdaddr_list *entry; 1559b2a66aadSAntti Julku 15601ec918ceSSzymon Janc if (bacmp(bdaddr, BDADDR_ANY) == 0) 15615e762444SAntti Julku return hci_blacklist_clear(hdev); 1562b2a66aadSAntti Julku 1563b2a66aadSAntti Julku entry = hci_blacklist_lookup(hdev, bdaddr); 15641ec918ceSSzymon Janc if (!entry) 15655e762444SAntti Julku return -ENOENT; 1566b2a66aadSAntti Julku 1567b2a66aadSAntti Julku list_del(&entry->list); 1568b2a66aadSAntti Julku kfree(entry); 1569b2a66aadSAntti Julku 157088c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 1571b2a66aadSAntti Julku } 1572b2a66aadSAntti Julku 15737ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt) 15747ba8b4beSAndre Guedes { 15757ba8b4beSAndre Guedes struct le_scan_params *param = (struct le_scan_params *) opt; 15767ba8b4beSAndre Guedes struct hci_cp_le_set_scan_param cp; 15777ba8b4beSAndre Guedes 15787ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 15797ba8b4beSAndre Guedes cp.type = param->type; 15807ba8b4beSAndre Guedes cp.interval = cpu_to_le16(param->interval); 15817ba8b4beSAndre Guedes cp.window = cpu_to_le16(param->window); 15827ba8b4beSAndre Guedes 15837ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); 15847ba8b4beSAndre Guedes } 15857ba8b4beSAndre Guedes 15867ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt) 15877ba8b4beSAndre Guedes { 15887ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 15897ba8b4beSAndre Guedes 15907ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 15917ba8b4beSAndre Guedes cp.enable = 1; 15920431a43cSAndre Guedes cp.filter_dup = 1; 15937ba8b4beSAndre Guedes 15947ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 15957ba8b4beSAndre Guedes } 15967ba8b4beSAndre Guedes 15977ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, 15987ba8b4beSAndre Guedes u16 window, int timeout) 15997ba8b4beSAndre Guedes { 16007ba8b4beSAndre Guedes long timeo = msecs_to_jiffies(3000); 16017ba8b4beSAndre Guedes struct le_scan_params param; 16027ba8b4beSAndre Guedes int err; 16037ba8b4beSAndre Guedes 16047ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 16057ba8b4beSAndre Guedes 16067ba8b4beSAndre Guedes if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 16077ba8b4beSAndre Guedes return -EINPROGRESS; 16087ba8b4beSAndre Guedes 16097ba8b4beSAndre Guedes param.type = type; 16107ba8b4beSAndre Guedes param.interval = interval; 16117ba8b4beSAndre Guedes param.window = window; 16127ba8b4beSAndre Guedes 16137ba8b4beSAndre Guedes hci_req_lock(hdev); 16147ba8b4beSAndre Guedes 16157ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_param_req, (unsigned long) ¶m, 16167ba8b4beSAndre Guedes timeo); 16177ba8b4beSAndre Guedes if (!err) 16187ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_enable_req, 0, timeo); 16197ba8b4beSAndre Guedes 16207ba8b4beSAndre Guedes hci_req_unlock(hdev); 16217ba8b4beSAndre Guedes 16227ba8b4beSAndre Guedes if (err < 0) 16237ba8b4beSAndre Guedes return err; 16247ba8b4beSAndre Guedes 16257ba8b4beSAndre Guedes schedule_delayed_work(&hdev->le_scan_disable, 16267ba8b4beSAndre Guedes msecs_to_jiffies(timeout)); 16277ba8b4beSAndre Guedes 16287ba8b4beSAndre Guedes return 0; 16297ba8b4beSAndre Guedes } 16307ba8b4beSAndre Guedes 16317dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev) 16327dbfac1dSAndre Guedes { 16337dbfac1dSAndre Guedes BT_DBG("%s", hdev->name); 16347dbfac1dSAndre Guedes 16357dbfac1dSAndre Guedes if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 16367dbfac1dSAndre Guedes return -EALREADY; 16377dbfac1dSAndre Guedes 16387dbfac1dSAndre Guedes if (cancel_delayed_work(&hdev->le_scan_disable)) { 16397dbfac1dSAndre Guedes struct hci_cp_le_set_scan_enable cp; 16407dbfac1dSAndre Guedes 16417dbfac1dSAndre Guedes /* Send HCI command to disable LE Scan */ 16427dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 16437dbfac1dSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 16447dbfac1dSAndre Guedes } 16457dbfac1dSAndre Guedes 16467dbfac1dSAndre Guedes return 0; 16477dbfac1dSAndre Guedes } 16487dbfac1dSAndre Guedes 16497ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 16507ba8b4beSAndre Guedes { 16517ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 16527ba8b4beSAndre Guedes le_scan_disable.work); 16537ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 16547ba8b4beSAndre Guedes 16557ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 16567ba8b4beSAndre Guedes 16577ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 16587ba8b4beSAndre Guedes 16597ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 16607ba8b4beSAndre Guedes } 16617ba8b4beSAndre Guedes 166228b75a89SAndre Guedes static void le_scan_work(struct work_struct *work) 166328b75a89SAndre Guedes { 166428b75a89SAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan); 166528b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 166628b75a89SAndre Guedes 166728b75a89SAndre Guedes BT_DBG("%s", hdev->name); 166828b75a89SAndre Guedes 166904124681SGustavo F. Padovan hci_do_le_scan(hdev, param->type, param->interval, param->window, 167004124681SGustavo F. Padovan param->timeout); 167128b75a89SAndre Guedes } 167228b75a89SAndre Guedes 167328b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, 167428b75a89SAndre Guedes int timeout) 167528b75a89SAndre Guedes { 167628b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 167728b75a89SAndre Guedes 167828b75a89SAndre Guedes BT_DBG("%s", hdev->name); 167928b75a89SAndre Guedes 1680f1550478SJohan Hedberg if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) 1681f1550478SJohan Hedberg return -ENOTSUPP; 1682f1550478SJohan Hedberg 168328b75a89SAndre Guedes if (work_busy(&hdev->le_scan)) 168428b75a89SAndre Guedes return -EINPROGRESS; 168528b75a89SAndre Guedes 168628b75a89SAndre Guedes param->type = type; 168728b75a89SAndre Guedes param->interval = interval; 168828b75a89SAndre Guedes param->window = window; 168928b75a89SAndre Guedes param->timeout = timeout; 169028b75a89SAndre Guedes 169128b75a89SAndre Guedes queue_work(system_long_wq, &hdev->le_scan); 169228b75a89SAndre Guedes 169328b75a89SAndre Guedes return 0; 169428b75a89SAndre Guedes } 169528b75a89SAndre Guedes 16969be0dab7SDavid Herrmann /* Alloc HCI device */ 16979be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 16989be0dab7SDavid Herrmann { 16999be0dab7SDavid Herrmann struct hci_dev *hdev; 17009be0dab7SDavid Herrmann 17019be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 17029be0dab7SDavid Herrmann if (!hdev) 17039be0dab7SDavid Herrmann return NULL; 17049be0dab7SDavid Herrmann 1705b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 1706b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 1707b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 1708b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 1709bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 1710bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 1711b1b813d4SDavid Herrmann 1712b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 1713b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 1714b1b813d4SDavid Herrmann 1715b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 1716b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 1717b1b813d4SDavid Herrmann 1718b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 1719b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 1720b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 1721b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 1722b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 1723b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 17246b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 1725b1b813d4SDavid Herrmann 1726b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 1727b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 1728b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 1729b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 1730b1b813d4SDavid Herrmann INIT_WORK(&hdev->le_scan, le_scan_work); 1731b1b813d4SDavid Herrmann 1732b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 1733b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 1734b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 1735b1b813d4SDavid Herrmann 17369be0dab7SDavid Herrmann skb_queue_head_init(&hdev->driver_init); 1737b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 1738b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 1739b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 1740b1b813d4SDavid Herrmann 1741b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 1742b1b813d4SDavid Herrmann 1743bda4f23aSAndrei Emeltchenko setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); 1744b1b813d4SDavid Herrmann 1745b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 1746b1b813d4SDavid Herrmann discovery_init(hdev); 17479be0dab7SDavid Herrmann 17489be0dab7SDavid Herrmann return hdev; 17499be0dab7SDavid Herrmann } 17509be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 17519be0dab7SDavid Herrmann 17529be0dab7SDavid Herrmann /* Free HCI device */ 17539be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 17549be0dab7SDavid Herrmann { 17559be0dab7SDavid Herrmann skb_queue_purge(&hdev->driver_init); 17569be0dab7SDavid Herrmann 17579be0dab7SDavid Herrmann /* will free via device release */ 17589be0dab7SDavid Herrmann put_device(&hdev->dev); 17599be0dab7SDavid Herrmann } 17609be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 17619be0dab7SDavid Herrmann 17621da177e4SLinus Torvalds /* Register HCI device */ 17631da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 17641da177e4SLinus Torvalds { 1765b1b813d4SDavid Herrmann int id, error; 17661da177e4SLinus Torvalds 1767010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 17681da177e4SLinus Torvalds return -EINVAL; 17691da177e4SLinus Torvalds 177008add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 177108add513SMat Martineau * so the index can be used as the AMP controller ID. 177208add513SMat Martineau */ 17733df92b31SSasha Levin switch (hdev->dev_type) { 17743df92b31SSasha Levin case HCI_BREDR: 17753df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 17761da177e4SLinus Torvalds break; 17773df92b31SSasha Levin case HCI_AMP: 17783df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 17793df92b31SSasha Levin break; 17803df92b31SSasha Levin default: 17813df92b31SSasha Levin return -EINVAL; 17821da177e4SLinus Torvalds } 17831da177e4SLinus Torvalds 17843df92b31SSasha Levin if (id < 0) 17853df92b31SSasha Levin return id; 17863df92b31SSasha Levin 17871da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 17881da177e4SLinus Torvalds hdev->id = id; 17892d8b3a11SAndrei Emeltchenko 17902d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 17912d8b3a11SAndrei Emeltchenko 17923df92b31SSasha Levin write_lock(&hci_dev_list_lock); 17933df92b31SSasha Levin list_add(&hdev->list, &hci_dev_list); 1794f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 17951da177e4SLinus Torvalds 179632845eb1SGustavo F. Padovan hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | 179732845eb1SGustavo F. Padovan WQ_MEM_RECLAIM, 1); 179833ca954dSDavid Herrmann if (!hdev->workqueue) { 179933ca954dSDavid Herrmann error = -ENOMEM; 180033ca954dSDavid Herrmann goto err; 180133ca954dSDavid Herrmann } 1802f48fd9c8SMarcel Holtmann 18036ead1bbcSJohan Hedberg hdev->req_workqueue = alloc_workqueue(hdev->name, 18046ead1bbcSJohan Hedberg WQ_HIGHPRI | WQ_UNBOUND | 18056ead1bbcSJohan Hedberg WQ_MEM_RECLAIM, 1); 18066ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 18076ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 18086ead1bbcSJohan Hedberg error = -ENOMEM; 18096ead1bbcSJohan Hedberg goto err; 18106ead1bbcSJohan Hedberg } 18116ead1bbcSJohan Hedberg 181233ca954dSDavid Herrmann error = hci_add_sysfs(hdev); 181333ca954dSDavid Herrmann if (error < 0) 181433ca954dSDavid Herrmann goto err_wqueue; 18151da177e4SLinus Torvalds 1816611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 1817a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 1818a8c5fb1aSGustavo Padovan hdev); 1819611b30f7SMarcel Holtmann if (hdev->rfkill) { 1820611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 1821611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1822611b30f7SMarcel Holtmann hdev->rfkill = NULL; 1823611b30f7SMarcel Holtmann } 1824611b30f7SMarcel Holtmann } 1825611b30f7SMarcel Holtmann 1826a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 1827ce2be9acSAndrei Emeltchenko 1828ce2be9acSAndrei Emeltchenko if (hdev->dev_type != HCI_AMP) 1829ce2be9acSAndrei Emeltchenko set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 1830ce2be9acSAndrei Emeltchenko 18311da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 1832dc946bd8SDavid Herrmann hci_dev_hold(hdev); 18331da177e4SLinus Torvalds 1834*19202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 1835fbe96d6fSMarcel Holtmann 18361da177e4SLinus Torvalds return id; 1837f48fd9c8SMarcel Holtmann 183833ca954dSDavid Herrmann err_wqueue: 183933ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 18406ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 184133ca954dSDavid Herrmann err: 18423df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 1843f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 1844f48fd9c8SMarcel Holtmann list_del(&hdev->list); 1845f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 1846f48fd9c8SMarcel Holtmann 184733ca954dSDavid Herrmann return error; 18481da177e4SLinus Torvalds } 18491da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 18501da177e4SLinus Torvalds 18511da177e4SLinus Torvalds /* Unregister HCI device */ 185259735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 18531da177e4SLinus Torvalds { 18543df92b31SSasha Levin int i, id; 1855ef222013SMarcel Holtmann 1856c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 18571da177e4SLinus Torvalds 185894324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 185994324962SJohan Hovold 18603df92b31SSasha Levin id = hdev->id; 18613df92b31SSasha Levin 1862f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 18631da177e4SLinus Torvalds list_del(&hdev->list); 1864f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 18651da177e4SLinus Torvalds 18661da177e4SLinus Torvalds hci_dev_do_close(hdev); 18671da177e4SLinus Torvalds 1868cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1869ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 1870ef222013SMarcel Holtmann 1871b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 1872b9b5ef18SGustavo Padovan 1873ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 1874a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 187509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1876744cf19eSJohan Hedberg mgmt_index_removed(hdev); 187709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 187856e5cb86SJohan Hedberg } 1879ab81cbf9SJohan Hedberg 18802e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 18812e58ef3eSJohan Hedberg * pending list */ 18822e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 18832e58ef3eSJohan Hedberg 18841da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 18851da177e4SLinus Torvalds 1886611b30f7SMarcel Holtmann if (hdev->rfkill) { 1887611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 1888611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1889611b30f7SMarcel Holtmann } 1890611b30f7SMarcel Holtmann 1891ce242970SDavid Herrmann hci_del_sysfs(hdev); 1892147e2d59SDave Young 1893f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 18946ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 1895f48fd9c8SMarcel Holtmann 189609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1897e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 18982aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 189955ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 1900b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 19012763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 190209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 1903e2e0cacbSJohan Hedberg 1904dc946bd8SDavid Herrmann hci_dev_put(hdev); 19053df92b31SSasha Levin 19063df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 19071da177e4SLinus Torvalds } 19081da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 19091da177e4SLinus Torvalds 19101da177e4SLinus Torvalds /* Suspend HCI device */ 19111da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 19121da177e4SLinus Torvalds { 19131da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 19141da177e4SLinus Torvalds return 0; 19151da177e4SLinus Torvalds } 19161da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 19171da177e4SLinus Torvalds 19181da177e4SLinus Torvalds /* Resume HCI device */ 19191da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 19201da177e4SLinus Torvalds { 19211da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 19221da177e4SLinus Torvalds return 0; 19231da177e4SLinus Torvalds } 19241da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 19251da177e4SLinus Torvalds 192676bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 192776bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb) 192876bca880SMarcel Holtmann { 192976bca880SMarcel Holtmann struct hci_dev *hdev = (struct hci_dev *) skb->dev; 193076bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 193176bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 193276bca880SMarcel Holtmann kfree_skb(skb); 193376bca880SMarcel Holtmann return -ENXIO; 193476bca880SMarcel Holtmann } 193576bca880SMarcel Holtmann 193676bca880SMarcel Holtmann /* Incomming skb */ 193776bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 193876bca880SMarcel Holtmann 193976bca880SMarcel Holtmann /* Time stamp */ 194076bca880SMarcel Holtmann __net_timestamp(skb); 194176bca880SMarcel Holtmann 194276bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 1943b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 1944c78ae283SMarcel Holtmann 194576bca880SMarcel Holtmann return 0; 194676bca880SMarcel Holtmann } 194776bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 194876bca880SMarcel Holtmann 194933e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 19501e429f38SGustavo F. Padovan int count, __u8 index) 195133e882a5SSuraj Sumangala { 195233e882a5SSuraj Sumangala int len = 0; 195333e882a5SSuraj Sumangala int hlen = 0; 195433e882a5SSuraj Sumangala int remain = count; 195533e882a5SSuraj Sumangala struct sk_buff *skb; 195633e882a5SSuraj Sumangala struct bt_skb_cb *scb; 195733e882a5SSuraj Sumangala 195833e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 195933e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 196033e882a5SSuraj Sumangala return -EILSEQ; 196133e882a5SSuraj Sumangala 196233e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 196333e882a5SSuraj Sumangala 196433e882a5SSuraj Sumangala if (!skb) { 196533e882a5SSuraj Sumangala switch (type) { 196633e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 196733e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 196833e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 196933e882a5SSuraj Sumangala break; 197033e882a5SSuraj Sumangala case HCI_EVENT_PKT: 197133e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 197233e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 197333e882a5SSuraj Sumangala break; 197433e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 197533e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 197633e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 197733e882a5SSuraj Sumangala break; 197833e882a5SSuraj Sumangala } 197933e882a5SSuraj Sumangala 19801e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 198133e882a5SSuraj Sumangala if (!skb) 198233e882a5SSuraj Sumangala return -ENOMEM; 198333e882a5SSuraj Sumangala 198433e882a5SSuraj Sumangala scb = (void *) skb->cb; 198533e882a5SSuraj Sumangala scb->expect = hlen; 198633e882a5SSuraj Sumangala scb->pkt_type = type; 198733e882a5SSuraj Sumangala 198833e882a5SSuraj Sumangala skb->dev = (void *) hdev; 198933e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 199033e882a5SSuraj Sumangala } 199133e882a5SSuraj Sumangala 199233e882a5SSuraj Sumangala while (count) { 199333e882a5SSuraj Sumangala scb = (void *) skb->cb; 199489bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 199533e882a5SSuraj Sumangala 199633e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 199733e882a5SSuraj Sumangala 199833e882a5SSuraj Sumangala count -= len; 199933e882a5SSuraj Sumangala data += len; 200033e882a5SSuraj Sumangala scb->expect -= len; 200133e882a5SSuraj Sumangala remain = count; 200233e882a5SSuraj Sumangala 200333e882a5SSuraj Sumangala switch (type) { 200433e882a5SSuraj Sumangala case HCI_EVENT_PKT: 200533e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 200633e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 200733e882a5SSuraj Sumangala scb->expect = h->plen; 200833e882a5SSuraj Sumangala 200933e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 201033e882a5SSuraj Sumangala kfree_skb(skb); 201133e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 201233e882a5SSuraj Sumangala return -ENOMEM; 201333e882a5SSuraj Sumangala } 201433e882a5SSuraj Sumangala } 201533e882a5SSuraj Sumangala break; 201633e882a5SSuraj Sumangala 201733e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 201833e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 201933e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 202033e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 202133e882a5SSuraj Sumangala 202233e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 202333e882a5SSuraj Sumangala kfree_skb(skb); 202433e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 202533e882a5SSuraj Sumangala return -ENOMEM; 202633e882a5SSuraj Sumangala } 202733e882a5SSuraj Sumangala } 202833e882a5SSuraj Sumangala break; 202933e882a5SSuraj Sumangala 203033e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 203133e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 203233e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 203333e882a5SSuraj Sumangala scb->expect = h->dlen; 203433e882a5SSuraj Sumangala 203533e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 203633e882a5SSuraj Sumangala kfree_skb(skb); 203733e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 203833e882a5SSuraj Sumangala return -ENOMEM; 203933e882a5SSuraj Sumangala } 204033e882a5SSuraj Sumangala } 204133e882a5SSuraj Sumangala break; 204233e882a5SSuraj Sumangala } 204333e882a5SSuraj Sumangala 204433e882a5SSuraj Sumangala if (scb->expect == 0) { 204533e882a5SSuraj Sumangala /* Complete frame */ 204633e882a5SSuraj Sumangala 204733e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 204833e882a5SSuraj Sumangala hci_recv_frame(skb); 204933e882a5SSuraj Sumangala 205033e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 205133e882a5SSuraj Sumangala return remain; 205233e882a5SSuraj Sumangala } 205333e882a5SSuraj Sumangala } 205433e882a5SSuraj Sumangala 205533e882a5SSuraj Sumangala return remain; 205633e882a5SSuraj Sumangala } 205733e882a5SSuraj Sumangala 2058ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 2059ef222013SMarcel Holtmann { 2060f39a3c06SSuraj Sumangala int rem = 0; 2061f39a3c06SSuraj Sumangala 2062ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 2063ef222013SMarcel Holtmann return -EILSEQ; 2064ef222013SMarcel Holtmann 2065da5f6c37SGustavo F. Padovan while (count) { 20661e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 2067f39a3c06SSuraj Sumangala if (rem < 0) 2068f39a3c06SSuraj Sumangala return rem; 2069ef222013SMarcel Holtmann 2070f39a3c06SSuraj Sumangala data += (count - rem); 2071f39a3c06SSuraj Sumangala count = rem; 2072f81c6224SJoe Perches } 2073ef222013SMarcel Holtmann 2074f39a3c06SSuraj Sumangala return rem; 2075ef222013SMarcel Holtmann } 2076ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 2077ef222013SMarcel Holtmann 207899811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 207999811510SSuraj Sumangala 208099811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 208199811510SSuraj Sumangala { 208299811510SSuraj Sumangala int type; 208399811510SSuraj Sumangala int rem = 0; 208499811510SSuraj Sumangala 2085da5f6c37SGustavo F. Padovan while (count) { 208699811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 208799811510SSuraj Sumangala 208899811510SSuraj Sumangala if (!skb) { 208999811510SSuraj Sumangala struct { char type; } *pkt; 209099811510SSuraj Sumangala 209199811510SSuraj Sumangala /* Start of the frame */ 209299811510SSuraj Sumangala pkt = data; 209399811510SSuraj Sumangala type = pkt->type; 209499811510SSuraj Sumangala 209599811510SSuraj Sumangala data++; 209699811510SSuraj Sumangala count--; 209799811510SSuraj Sumangala } else 209899811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 209999811510SSuraj Sumangala 21001e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 21011e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 210299811510SSuraj Sumangala if (rem < 0) 210399811510SSuraj Sumangala return rem; 210499811510SSuraj Sumangala 210599811510SSuraj Sumangala data += (count - rem); 210699811510SSuraj Sumangala count = rem; 2107f81c6224SJoe Perches } 210899811510SSuraj Sumangala 210999811510SSuraj Sumangala return rem; 211099811510SSuraj Sumangala } 211199811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 211299811510SSuraj Sumangala 21131da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 21141da177e4SLinus Torvalds 21151da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 21161da177e4SLinus Torvalds { 21171da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 21181da177e4SLinus Torvalds 2119f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 21201da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 2121f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 21221da177e4SLinus Torvalds 21231da177e4SLinus Torvalds return 0; 21241da177e4SLinus Torvalds } 21251da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 21261da177e4SLinus Torvalds 21271da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 21281da177e4SLinus Torvalds { 21291da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 21301da177e4SLinus Torvalds 2131f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 21321da177e4SLinus Torvalds list_del(&cb->list); 2133f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 21341da177e4SLinus Torvalds 21351da177e4SLinus Torvalds return 0; 21361da177e4SLinus Torvalds } 21371da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 21381da177e4SLinus Torvalds 21391da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb) 21401da177e4SLinus Torvalds { 21411da177e4SLinus Torvalds struct hci_dev *hdev = (struct hci_dev *) skb->dev; 21421da177e4SLinus Torvalds 21431da177e4SLinus Torvalds if (!hdev) { 21441da177e4SLinus Torvalds kfree_skb(skb); 21451da177e4SLinus Torvalds return -ENODEV; 21461da177e4SLinus Torvalds } 21471da177e4SLinus Torvalds 21480d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 21491da177e4SLinus Torvalds 21501da177e4SLinus Torvalds /* Time stamp */ 2151a61bbcf2SPatrick McHardy __net_timestamp(skb); 21521da177e4SLinus Torvalds 2153cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2154cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2155cd82e61cSMarcel Holtmann 2156cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 2157cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 2158470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 21591da177e4SLinus Torvalds } 21601da177e4SLinus Torvalds 21611da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 21621da177e4SLinus Torvalds skb_orphan(skb); 21631da177e4SLinus Torvalds 21641da177e4SLinus Torvalds return hdev->send(skb); 21651da177e4SLinus Torvalds } 21661da177e4SLinus Torvalds 21671da177e4SLinus Torvalds /* Send HCI command */ 2168a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) 21691da177e4SLinus Torvalds { 21701da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 21711da177e4SLinus Torvalds struct hci_command_hdr *hdr; 21721da177e4SLinus Torvalds struct sk_buff *skb; 21731da177e4SLinus Torvalds 2174f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 21751da177e4SLinus Torvalds 21761da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 21771da177e4SLinus Torvalds if (!skb) { 2178ef222013SMarcel Holtmann BT_ERR("%s no memory for command", hdev->name); 21791da177e4SLinus Torvalds return -ENOMEM; 21801da177e4SLinus Torvalds } 21811da177e4SLinus Torvalds 21821da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 2183a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 21841da177e4SLinus Torvalds hdr->plen = plen; 21851da177e4SLinus Torvalds 21861da177e4SLinus Torvalds if (plen) 21871da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 21881da177e4SLinus Torvalds 21891da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 21901da177e4SLinus Torvalds 21910d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 21921da177e4SLinus Torvalds skb->dev = (void *) hdev; 2193c78ae283SMarcel Holtmann 2194a5040efaSJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags)) 2195a5040efaSJohan Hedberg hdev->init_last_cmd = opcode; 2196a5040efaSJohan Hedberg 21971da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 2198c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 21991da177e4SLinus Torvalds 22001da177e4SLinus Torvalds return 0; 22011da177e4SLinus Torvalds } 22021da177e4SLinus Torvalds 22031da177e4SLinus Torvalds /* Get data from the previously sent command */ 2204a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 22051da177e4SLinus Torvalds { 22061da177e4SLinus Torvalds struct hci_command_hdr *hdr; 22071da177e4SLinus Torvalds 22081da177e4SLinus Torvalds if (!hdev->sent_cmd) 22091da177e4SLinus Torvalds return NULL; 22101da177e4SLinus Torvalds 22111da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 22121da177e4SLinus Torvalds 2213a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 22141da177e4SLinus Torvalds return NULL; 22151da177e4SLinus Torvalds 2216f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 22171da177e4SLinus Torvalds 22181da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 22191da177e4SLinus Torvalds } 22201da177e4SLinus Torvalds 22211da177e4SLinus Torvalds /* Send ACL data */ 22221da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 22231da177e4SLinus Torvalds { 22241da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 22251da177e4SLinus Torvalds int len = skb->len; 22261da177e4SLinus Torvalds 2227badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 2228badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 22299c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 2230aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 2231aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 22321da177e4SLinus Torvalds } 22331da177e4SLinus Torvalds 2234ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 223573d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 22361da177e4SLinus Torvalds { 2237ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 22381da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 22391da177e4SLinus Torvalds struct sk_buff *list; 22401da177e4SLinus Torvalds 2241087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 2242087bfd99SGustavo Padovan skb->data_len = 0; 2243087bfd99SGustavo Padovan 2244087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2245204a6e54SAndrei Emeltchenko 2246204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 2247204a6e54SAndrei Emeltchenko case HCI_BREDR: 2248087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 2249204a6e54SAndrei Emeltchenko break; 2250204a6e54SAndrei Emeltchenko case HCI_AMP: 2251204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 2252204a6e54SAndrei Emeltchenko break; 2253204a6e54SAndrei Emeltchenko default: 2254204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 2255204a6e54SAndrei Emeltchenko return; 2256204a6e54SAndrei Emeltchenko } 2257087bfd99SGustavo Padovan 225870f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 225970f23020SAndrei Emeltchenko if (!list) { 22601da177e4SLinus Torvalds /* Non fragmented */ 22611da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 22621da177e4SLinus Torvalds 226373d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 22641da177e4SLinus Torvalds } else { 22651da177e4SLinus Torvalds /* Fragmented */ 22661da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 22671da177e4SLinus Torvalds 22681da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 22691da177e4SLinus Torvalds 22701da177e4SLinus Torvalds /* Queue all fragments atomically */ 2271af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 22721da177e4SLinus Torvalds 227373d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 2274e702112fSAndrei Emeltchenko 2275e702112fSAndrei Emeltchenko flags &= ~ACL_START; 2276e702112fSAndrei Emeltchenko flags |= ACL_CONT; 22771da177e4SLinus Torvalds do { 22781da177e4SLinus Torvalds skb = list; list = list->next; 22791da177e4SLinus Torvalds 22801da177e4SLinus Torvalds skb->dev = (void *) hdev; 22810d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2282e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 22831da177e4SLinus Torvalds 22841da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 22851da177e4SLinus Torvalds 228673d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 22871da177e4SLinus Torvalds } while (list); 22881da177e4SLinus Torvalds 2289af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 22901da177e4SLinus Torvalds } 229173d80debSLuiz Augusto von Dentz } 229273d80debSLuiz Augusto von Dentz 229373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 229473d80debSLuiz Augusto von Dentz { 2295ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 229673d80debSLuiz Augusto von Dentz 2297f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 229873d80debSLuiz Augusto von Dentz 229973d80debSLuiz Augusto von Dentz skb->dev = (void *) hdev; 230073d80debSLuiz Augusto von Dentz 2301ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 23021da177e4SLinus Torvalds 23033eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 23041da177e4SLinus Torvalds } 23051da177e4SLinus Torvalds 23061da177e4SLinus Torvalds /* Send SCO data */ 23070d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 23081da177e4SLinus Torvalds { 23091da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 23101da177e4SLinus Torvalds struct hci_sco_hdr hdr; 23111da177e4SLinus Torvalds 23121da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 23131da177e4SLinus Torvalds 2314aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 23151da177e4SLinus Torvalds hdr.dlen = skb->len; 23161da177e4SLinus Torvalds 2317badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 2318badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 23199c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 23201da177e4SLinus Torvalds 23211da177e4SLinus Torvalds skb->dev = (void *) hdev; 23220d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 2323c78ae283SMarcel Holtmann 23241da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 23253eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 23261da177e4SLinus Torvalds } 23271da177e4SLinus Torvalds 23281da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 23291da177e4SLinus Torvalds 23301da177e4SLinus Torvalds /* HCI Connection scheduler */ 23316039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 2332a8c5fb1aSGustavo Padovan int *quote) 23331da177e4SLinus Torvalds { 23341da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 23358035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 2336abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 23371da177e4SLinus Torvalds 23381da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 23391da177e4SLinus Torvalds * added and removed with TX task disabled. */ 2340bf4c6325SGustavo F. Padovan 2341bf4c6325SGustavo F. Padovan rcu_read_lock(); 2342bf4c6325SGustavo F. Padovan 2343bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2344769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 23451da177e4SLinus Torvalds continue; 2346769be974SMarcel Holtmann 2347769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 2348769be974SMarcel Holtmann continue; 2349769be974SMarcel Holtmann 23501da177e4SLinus Torvalds num++; 23511da177e4SLinus Torvalds 23521da177e4SLinus Torvalds if (c->sent < min) { 23531da177e4SLinus Torvalds min = c->sent; 23541da177e4SLinus Torvalds conn = c; 23551da177e4SLinus Torvalds } 235652087a79SLuiz Augusto von Dentz 235752087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 235852087a79SLuiz Augusto von Dentz break; 23591da177e4SLinus Torvalds } 23601da177e4SLinus Torvalds 2361bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2362bf4c6325SGustavo F. Padovan 23631da177e4SLinus Torvalds if (conn) { 23646ed58ec5SVille Tervo int cnt, q; 23656ed58ec5SVille Tervo 23666ed58ec5SVille Tervo switch (conn->type) { 23676ed58ec5SVille Tervo case ACL_LINK: 23686ed58ec5SVille Tervo cnt = hdev->acl_cnt; 23696ed58ec5SVille Tervo break; 23706ed58ec5SVille Tervo case SCO_LINK: 23716ed58ec5SVille Tervo case ESCO_LINK: 23726ed58ec5SVille Tervo cnt = hdev->sco_cnt; 23736ed58ec5SVille Tervo break; 23746ed58ec5SVille Tervo case LE_LINK: 23756ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 23766ed58ec5SVille Tervo break; 23776ed58ec5SVille Tervo default: 23786ed58ec5SVille Tervo cnt = 0; 23796ed58ec5SVille Tervo BT_ERR("Unknown link type"); 23806ed58ec5SVille Tervo } 23816ed58ec5SVille Tervo 23826ed58ec5SVille Tervo q = cnt / num; 23831da177e4SLinus Torvalds *quote = q ? q : 1; 23841da177e4SLinus Torvalds } else 23851da177e4SLinus Torvalds *quote = 0; 23861da177e4SLinus Torvalds 23871da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 23881da177e4SLinus Torvalds return conn; 23891da177e4SLinus Torvalds } 23901da177e4SLinus Torvalds 23916039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 23921da177e4SLinus Torvalds { 23931da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 23941da177e4SLinus Torvalds struct hci_conn *c; 23951da177e4SLinus Torvalds 2396bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 23971da177e4SLinus Torvalds 2398bf4c6325SGustavo F. Padovan rcu_read_lock(); 2399bf4c6325SGustavo F. Padovan 24001da177e4SLinus Torvalds /* Kill stalled connections */ 2401bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2402bae1f5d9SVille Tervo if (c->type == type && c->sent) { 24036ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 24046ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 24057490c6c2SAndrei Emeltchenko hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM); 24061da177e4SLinus Torvalds } 24071da177e4SLinus Torvalds } 2408bf4c6325SGustavo F. Padovan 2409bf4c6325SGustavo F. Padovan rcu_read_unlock(); 24101da177e4SLinus Torvalds } 24111da177e4SLinus Torvalds 24126039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 241373d80debSLuiz Augusto von Dentz int *quote) 241473d80debSLuiz Augusto von Dentz { 241573d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 241673d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 2417abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 241873d80debSLuiz Augusto von Dentz struct hci_conn *conn; 241973d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 242073d80debSLuiz Augusto von Dentz 242173d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 242273d80debSLuiz Augusto von Dentz 2423bf4c6325SGustavo F. Padovan rcu_read_lock(); 2424bf4c6325SGustavo F. Padovan 2425bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 242673d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 242773d80debSLuiz Augusto von Dentz 242873d80debSLuiz Augusto von Dentz if (conn->type != type) 242973d80debSLuiz Augusto von Dentz continue; 243073d80debSLuiz Augusto von Dentz 243173d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 243273d80debSLuiz Augusto von Dentz continue; 243373d80debSLuiz Augusto von Dentz 243473d80debSLuiz Augusto von Dentz conn_num++; 243573d80debSLuiz Augusto von Dentz 24368192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 243773d80debSLuiz Augusto von Dentz struct sk_buff *skb; 243873d80debSLuiz Augusto von Dentz 243973d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 244073d80debSLuiz Augusto von Dentz continue; 244173d80debSLuiz Augusto von Dentz 244273d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 244373d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 244473d80debSLuiz Augusto von Dentz continue; 244573d80debSLuiz Augusto von Dentz 244673d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 244773d80debSLuiz Augusto von Dentz num = 0; 244873d80debSLuiz Augusto von Dentz min = ~0; 244973d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 245073d80debSLuiz Augusto von Dentz } 245173d80debSLuiz Augusto von Dentz 245273d80debSLuiz Augusto von Dentz num++; 245373d80debSLuiz Augusto von Dentz 245473d80debSLuiz Augusto von Dentz if (conn->sent < min) { 245573d80debSLuiz Augusto von Dentz min = conn->sent; 245673d80debSLuiz Augusto von Dentz chan = tmp; 245773d80debSLuiz Augusto von Dentz } 245873d80debSLuiz Augusto von Dentz } 245973d80debSLuiz Augusto von Dentz 246073d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 246173d80debSLuiz Augusto von Dentz break; 246273d80debSLuiz Augusto von Dentz } 246373d80debSLuiz Augusto von Dentz 2464bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2465bf4c6325SGustavo F. Padovan 246673d80debSLuiz Augusto von Dentz if (!chan) 246773d80debSLuiz Augusto von Dentz return NULL; 246873d80debSLuiz Augusto von Dentz 246973d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 247073d80debSLuiz Augusto von Dentz case ACL_LINK: 247173d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 247273d80debSLuiz Augusto von Dentz break; 2473bd1eb66bSAndrei Emeltchenko case AMP_LINK: 2474bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 2475bd1eb66bSAndrei Emeltchenko break; 247673d80debSLuiz Augusto von Dentz case SCO_LINK: 247773d80debSLuiz Augusto von Dentz case ESCO_LINK: 247873d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 247973d80debSLuiz Augusto von Dentz break; 248073d80debSLuiz Augusto von Dentz case LE_LINK: 248173d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 248273d80debSLuiz Augusto von Dentz break; 248373d80debSLuiz Augusto von Dentz default: 248473d80debSLuiz Augusto von Dentz cnt = 0; 248573d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 248673d80debSLuiz Augusto von Dentz } 248773d80debSLuiz Augusto von Dentz 248873d80debSLuiz Augusto von Dentz q = cnt / num; 248973d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 249073d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 249173d80debSLuiz Augusto von Dentz return chan; 249273d80debSLuiz Augusto von Dentz } 249373d80debSLuiz Augusto von Dentz 249402b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 249502b20f0bSLuiz Augusto von Dentz { 249602b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 249702b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 249802b20f0bSLuiz Augusto von Dentz int num = 0; 249902b20f0bSLuiz Augusto von Dentz 250002b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 250102b20f0bSLuiz Augusto von Dentz 2502bf4c6325SGustavo F. Padovan rcu_read_lock(); 2503bf4c6325SGustavo F. Padovan 2504bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 250502b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 250602b20f0bSLuiz Augusto von Dentz 250702b20f0bSLuiz Augusto von Dentz if (conn->type != type) 250802b20f0bSLuiz Augusto von Dentz continue; 250902b20f0bSLuiz Augusto von Dentz 251002b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 251102b20f0bSLuiz Augusto von Dentz continue; 251202b20f0bSLuiz Augusto von Dentz 251302b20f0bSLuiz Augusto von Dentz num++; 251402b20f0bSLuiz Augusto von Dentz 25158192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 251602b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 251702b20f0bSLuiz Augusto von Dentz 251802b20f0bSLuiz Augusto von Dentz if (chan->sent) { 251902b20f0bSLuiz Augusto von Dentz chan->sent = 0; 252002b20f0bSLuiz Augusto von Dentz continue; 252102b20f0bSLuiz Augusto von Dentz } 252202b20f0bSLuiz Augusto von Dentz 252302b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 252402b20f0bSLuiz Augusto von Dentz continue; 252502b20f0bSLuiz Augusto von Dentz 252602b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 252702b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 252802b20f0bSLuiz Augusto von Dentz continue; 252902b20f0bSLuiz Augusto von Dentz 253002b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 253102b20f0bSLuiz Augusto von Dentz 253202b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 253302b20f0bSLuiz Augusto von Dentz skb->priority); 253402b20f0bSLuiz Augusto von Dentz } 253502b20f0bSLuiz Augusto von Dentz 253602b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 253702b20f0bSLuiz Augusto von Dentz break; 253802b20f0bSLuiz Augusto von Dentz } 2539bf4c6325SGustavo F. Padovan 2540bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2541bf4c6325SGustavo F. Padovan 254202b20f0bSLuiz Augusto von Dentz } 254302b20f0bSLuiz Augusto von Dentz 2544b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 2545b71d385aSAndrei Emeltchenko { 2546b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 2547b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 2548b71d385aSAndrei Emeltchenko } 2549b71d385aSAndrei Emeltchenko 25506039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 25511da177e4SLinus Torvalds { 25521da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 25531da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 25541da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 255563d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 25565f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 2557bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 25581da177e4SLinus Torvalds } 255963d2bc1bSAndrei Emeltchenko } 25601da177e4SLinus Torvalds 25616039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 256263d2bc1bSAndrei Emeltchenko { 256363d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 256463d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 256563d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 256663d2bc1bSAndrei Emeltchenko int quote; 256763d2bc1bSAndrei Emeltchenko 256863d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 256904837f64SMarcel Holtmann 257073d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 257173d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2572ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2573ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 257473d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 257573d80debSLuiz Augusto von Dentz skb->len, skb->priority); 257673d80debSLuiz Augusto von Dentz 2577ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2578ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2579ec1cce24SLuiz Augusto von Dentz break; 2580ec1cce24SLuiz Augusto von Dentz 2581ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2582ec1cce24SLuiz Augusto von Dentz 258373d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 258473d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 258504837f64SMarcel Holtmann 25861da177e4SLinus Torvalds hci_send_frame(skb); 25871da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 25881da177e4SLinus Torvalds 25891da177e4SLinus Torvalds hdev->acl_cnt--; 259073d80debSLuiz Augusto von Dentz chan->sent++; 259173d80debSLuiz Augusto von Dentz chan->conn->sent++; 25921da177e4SLinus Torvalds } 25931da177e4SLinus Torvalds } 259402b20f0bSLuiz Augusto von Dentz 259502b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 259602b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 25971da177e4SLinus Torvalds } 25981da177e4SLinus Torvalds 25996039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 2600b71d385aSAndrei Emeltchenko { 260163d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 2602b71d385aSAndrei Emeltchenko struct hci_chan *chan; 2603b71d385aSAndrei Emeltchenko struct sk_buff *skb; 2604b71d385aSAndrei Emeltchenko int quote; 2605bd1eb66bSAndrei Emeltchenko u8 type; 2606b71d385aSAndrei Emeltchenko 260763d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 2608b71d385aSAndrei Emeltchenko 2609bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 2610bd1eb66bSAndrei Emeltchenko 2611bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 2612bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 2613bd1eb66bSAndrei Emeltchenko else 2614bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 2615bd1eb66bSAndrei Emeltchenko 2616b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 2617bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 2618b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 2619b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 2620b71d385aSAndrei Emeltchenko int blocks; 2621b71d385aSAndrei Emeltchenko 2622b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 2623b71d385aSAndrei Emeltchenko skb->len, skb->priority); 2624b71d385aSAndrei Emeltchenko 2625b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 2626b71d385aSAndrei Emeltchenko if (skb->priority < priority) 2627b71d385aSAndrei Emeltchenko break; 2628b71d385aSAndrei Emeltchenko 2629b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 2630b71d385aSAndrei Emeltchenko 2631b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 2632b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 2633b71d385aSAndrei Emeltchenko return; 2634b71d385aSAndrei Emeltchenko 2635b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 2636b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 2637b71d385aSAndrei Emeltchenko 2638b71d385aSAndrei Emeltchenko hci_send_frame(skb); 2639b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 2640b71d385aSAndrei Emeltchenko 2641b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 2642b71d385aSAndrei Emeltchenko quote -= blocks; 2643b71d385aSAndrei Emeltchenko 2644b71d385aSAndrei Emeltchenko chan->sent += blocks; 2645b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 2646b71d385aSAndrei Emeltchenko } 2647b71d385aSAndrei Emeltchenko } 2648b71d385aSAndrei Emeltchenko 2649b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 2650bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 2651b71d385aSAndrei Emeltchenko } 2652b71d385aSAndrei Emeltchenko 26536039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 2654b71d385aSAndrei Emeltchenko { 2655b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 2656b71d385aSAndrei Emeltchenko 2657bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 2658bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 2659bd1eb66bSAndrei Emeltchenko return; 2660bd1eb66bSAndrei Emeltchenko 2661bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 2662bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 2663b71d385aSAndrei Emeltchenko return; 2664b71d385aSAndrei Emeltchenko 2665b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 2666b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 2667b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 2668b71d385aSAndrei Emeltchenko break; 2669b71d385aSAndrei Emeltchenko 2670b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 2671b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 2672b71d385aSAndrei Emeltchenko break; 2673b71d385aSAndrei Emeltchenko } 2674b71d385aSAndrei Emeltchenko } 2675b71d385aSAndrei Emeltchenko 26761da177e4SLinus Torvalds /* Schedule SCO */ 26776039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 26781da177e4SLinus Torvalds { 26791da177e4SLinus Torvalds struct hci_conn *conn; 26801da177e4SLinus Torvalds struct sk_buff *skb; 26811da177e4SLinus Torvalds int quote; 26821da177e4SLinus Torvalds 26831da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 26841da177e4SLinus Torvalds 268552087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 268652087a79SLuiz Augusto von Dentz return; 268752087a79SLuiz Augusto von Dentz 26881da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 26891da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 26901da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 26911da177e4SLinus Torvalds hci_send_frame(skb); 26921da177e4SLinus Torvalds 26931da177e4SLinus Torvalds conn->sent++; 26941da177e4SLinus Torvalds if (conn->sent == ~0) 26951da177e4SLinus Torvalds conn->sent = 0; 26961da177e4SLinus Torvalds } 26971da177e4SLinus Torvalds } 26981da177e4SLinus Torvalds } 26991da177e4SLinus Torvalds 27006039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 2701b6a0dc82SMarcel Holtmann { 2702b6a0dc82SMarcel Holtmann struct hci_conn *conn; 2703b6a0dc82SMarcel Holtmann struct sk_buff *skb; 2704b6a0dc82SMarcel Holtmann int quote; 2705b6a0dc82SMarcel Holtmann 2706b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 2707b6a0dc82SMarcel Holtmann 270852087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 270952087a79SLuiz Augusto von Dentz return; 271052087a79SLuiz Augusto von Dentz 27118fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 27128fc9ced3SGustavo Padovan "e))) { 2713b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 2714b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 2715b6a0dc82SMarcel Holtmann hci_send_frame(skb); 2716b6a0dc82SMarcel Holtmann 2717b6a0dc82SMarcel Holtmann conn->sent++; 2718b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 2719b6a0dc82SMarcel Holtmann conn->sent = 0; 2720b6a0dc82SMarcel Holtmann } 2721b6a0dc82SMarcel Holtmann } 2722b6a0dc82SMarcel Holtmann } 2723b6a0dc82SMarcel Holtmann 27246039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 27256ed58ec5SVille Tervo { 272673d80debSLuiz Augusto von Dentz struct hci_chan *chan; 27276ed58ec5SVille Tervo struct sk_buff *skb; 272802b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 27296ed58ec5SVille Tervo 27306ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 27316ed58ec5SVille Tervo 273252087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 273352087a79SLuiz Augusto von Dentz return; 273452087a79SLuiz Augusto von Dentz 27356ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 27366ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 27376ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 2738bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 27396ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 2740bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 27416ed58ec5SVille Tervo } 27426ed58ec5SVille Tervo 27436ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 274402b20f0bSLuiz Augusto von Dentz tmp = cnt; 274573d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 2746ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2747ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 274873d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 274973d80debSLuiz Augusto von Dentz skb->len, skb->priority); 27506ed58ec5SVille Tervo 2751ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2752ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2753ec1cce24SLuiz Augusto von Dentz break; 2754ec1cce24SLuiz Augusto von Dentz 2755ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2756ec1cce24SLuiz Augusto von Dentz 27576ed58ec5SVille Tervo hci_send_frame(skb); 27586ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 27596ed58ec5SVille Tervo 27606ed58ec5SVille Tervo cnt--; 276173d80debSLuiz Augusto von Dentz chan->sent++; 276273d80debSLuiz Augusto von Dentz chan->conn->sent++; 27636ed58ec5SVille Tervo } 27646ed58ec5SVille Tervo } 276573d80debSLuiz Augusto von Dentz 27666ed58ec5SVille Tervo if (hdev->le_pkts) 27676ed58ec5SVille Tervo hdev->le_cnt = cnt; 27686ed58ec5SVille Tervo else 27696ed58ec5SVille Tervo hdev->acl_cnt = cnt; 277002b20f0bSLuiz Augusto von Dentz 277102b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 277202b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 27736ed58ec5SVille Tervo } 27746ed58ec5SVille Tervo 27753eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 27761da177e4SLinus Torvalds { 27773eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 27781da177e4SLinus Torvalds struct sk_buff *skb; 27791da177e4SLinus Torvalds 27806ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 27816ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 27821da177e4SLinus Torvalds 27831da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 27841da177e4SLinus Torvalds 27851da177e4SLinus Torvalds hci_sched_acl(hdev); 27861da177e4SLinus Torvalds 27871da177e4SLinus Torvalds hci_sched_sco(hdev); 27881da177e4SLinus Torvalds 2789b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 2790b6a0dc82SMarcel Holtmann 27916ed58ec5SVille Tervo hci_sched_le(hdev); 27926ed58ec5SVille Tervo 27931da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 27941da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 27951da177e4SLinus Torvalds hci_send_frame(skb); 27961da177e4SLinus Torvalds } 27971da177e4SLinus Torvalds 279825985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 27991da177e4SLinus Torvalds 28001da177e4SLinus Torvalds /* ACL data packet */ 28016039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 28021da177e4SLinus Torvalds { 28031da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 28041da177e4SLinus Torvalds struct hci_conn *conn; 28051da177e4SLinus Torvalds __u16 handle, flags; 28061da177e4SLinus Torvalds 28071da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 28081da177e4SLinus Torvalds 28091da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 28101da177e4SLinus Torvalds flags = hci_flags(handle); 28111da177e4SLinus Torvalds handle = hci_handle(handle); 28121da177e4SLinus Torvalds 2813f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 2814a8c5fb1aSGustavo Padovan handle, flags); 28151da177e4SLinus Torvalds 28161da177e4SLinus Torvalds hdev->stat.acl_rx++; 28171da177e4SLinus Torvalds 28181da177e4SLinus Torvalds hci_dev_lock(hdev); 28191da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 28201da177e4SLinus Torvalds hci_dev_unlock(hdev); 28211da177e4SLinus Torvalds 28221da177e4SLinus Torvalds if (conn) { 282365983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 282404837f64SMarcel Holtmann 2825671267bfSJohan Hedberg hci_dev_lock(hdev); 2826671267bfSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags) && 2827671267bfSJohan Hedberg !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 2828671267bfSJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 2829671267bfSJohan Hedberg conn->dst_type, 0, NULL, 0, 2830671267bfSJohan Hedberg conn->dev_class); 2831671267bfSJohan Hedberg hci_dev_unlock(hdev); 2832671267bfSJohan Hedberg 28331da177e4SLinus Torvalds /* Send to upper protocol */ 2834686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 28351da177e4SLinus Torvalds return; 28361da177e4SLinus Torvalds } else { 28371da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 28381da177e4SLinus Torvalds hdev->name, handle); 28391da177e4SLinus Torvalds } 28401da177e4SLinus Torvalds 28411da177e4SLinus Torvalds kfree_skb(skb); 28421da177e4SLinus Torvalds } 28431da177e4SLinus Torvalds 28441da177e4SLinus Torvalds /* SCO data packet */ 28456039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 28461da177e4SLinus Torvalds { 28471da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 28481da177e4SLinus Torvalds struct hci_conn *conn; 28491da177e4SLinus Torvalds __u16 handle; 28501da177e4SLinus Torvalds 28511da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 28521da177e4SLinus Torvalds 28531da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 28541da177e4SLinus Torvalds 2855f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 28561da177e4SLinus Torvalds 28571da177e4SLinus Torvalds hdev->stat.sco_rx++; 28581da177e4SLinus Torvalds 28591da177e4SLinus Torvalds hci_dev_lock(hdev); 28601da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 28611da177e4SLinus Torvalds hci_dev_unlock(hdev); 28621da177e4SLinus Torvalds 28631da177e4SLinus Torvalds if (conn) { 28641da177e4SLinus Torvalds /* Send to upper protocol */ 2865686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 28661da177e4SLinus Torvalds return; 28671da177e4SLinus Torvalds } else { 28681da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 28691da177e4SLinus Torvalds hdev->name, handle); 28701da177e4SLinus Torvalds } 28711da177e4SLinus Torvalds 28721da177e4SLinus Torvalds kfree_skb(skb); 28731da177e4SLinus Torvalds } 28741da177e4SLinus Torvalds 2875b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 28761da177e4SLinus Torvalds { 2877b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 28781da177e4SLinus Torvalds struct sk_buff *skb; 28791da177e4SLinus Torvalds 28801da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 28811da177e4SLinus Torvalds 28821da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 2883cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2884cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2885cd82e61cSMarcel Holtmann 28861da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 28871da177e4SLinus Torvalds /* Send copy to the sockets */ 2888470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 28891da177e4SLinus Torvalds } 28901da177e4SLinus Torvalds 28911da177e4SLinus Torvalds if (test_bit(HCI_RAW, &hdev->flags)) { 28921da177e4SLinus Torvalds kfree_skb(skb); 28931da177e4SLinus Torvalds continue; 28941da177e4SLinus Torvalds } 28951da177e4SLinus Torvalds 28961da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 28971da177e4SLinus Torvalds /* Don't process data packets in this states. */ 28980d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 28991da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 29001da177e4SLinus Torvalds case HCI_SCODATA_PKT: 29011da177e4SLinus Torvalds kfree_skb(skb); 29021da177e4SLinus Torvalds continue; 29033ff50b79SStephen Hemminger } 29041da177e4SLinus Torvalds } 29051da177e4SLinus Torvalds 29061da177e4SLinus Torvalds /* Process frame */ 29070d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 29081da177e4SLinus Torvalds case HCI_EVENT_PKT: 2909b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 29101da177e4SLinus Torvalds hci_event_packet(hdev, skb); 29111da177e4SLinus Torvalds break; 29121da177e4SLinus Torvalds 29131da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 29141da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 29151da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 29161da177e4SLinus Torvalds break; 29171da177e4SLinus Torvalds 29181da177e4SLinus Torvalds case HCI_SCODATA_PKT: 29191da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 29201da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 29211da177e4SLinus Torvalds break; 29221da177e4SLinus Torvalds 29231da177e4SLinus Torvalds default: 29241da177e4SLinus Torvalds kfree_skb(skb); 29251da177e4SLinus Torvalds break; 29261da177e4SLinus Torvalds } 29271da177e4SLinus Torvalds } 29281da177e4SLinus Torvalds } 29291da177e4SLinus Torvalds 2930c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 29311da177e4SLinus Torvalds { 2932c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 29331da177e4SLinus Torvalds struct sk_buff *skb; 29341da177e4SLinus Torvalds 29352104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 29362104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 29371da177e4SLinus Torvalds 29381da177e4SLinus Torvalds /* Send queued commands */ 29395a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 29405a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 29415a08ecceSAndrei Emeltchenko if (!skb) 29425a08ecceSAndrei Emeltchenko return; 29435a08ecceSAndrei Emeltchenko 29441da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 29451da177e4SLinus Torvalds 294670f23020SAndrei Emeltchenko hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC); 294770f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 29481da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 29491da177e4SLinus Torvalds hci_send_frame(skb); 29507bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 29517bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 29527bdb8a5cSSzymon Janc else 29536bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 29545f246e89SAndrei Emeltchenko jiffies + HCI_CMD_TIMEOUT); 29551da177e4SLinus Torvalds } else { 29561da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 2957c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 29581da177e4SLinus Torvalds } 29591da177e4SLinus Torvalds } 29601da177e4SLinus Torvalds } 29612519a1fcSAndre Guedes 29622519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length) 29632519a1fcSAndre Guedes { 29642519a1fcSAndre Guedes /* General inquiry access code (GIAC) */ 29652519a1fcSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 29662519a1fcSAndre Guedes struct hci_cp_inquiry cp; 29672519a1fcSAndre Guedes 29682519a1fcSAndre Guedes BT_DBG("%s", hdev->name); 29692519a1fcSAndre Guedes 29702519a1fcSAndre Guedes if (test_bit(HCI_INQUIRY, &hdev->flags)) 29712519a1fcSAndre Guedes return -EINPROGRESS; 29722519a1fcSAndre Guedes 29734663262cSJohan Hedberg inquiry_cache_flush(hdev); 29744663262cSJohan Hedberg 29752519a1fcSAndre Guedes memset(&cp, 0, sizeof(cp)); 29762519a1fcSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 29772519a1fcSAndre Guedes cp.length = length; 29782519a1fcSAndre Guedes 29792519a1fcSAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 29802519a1fcSAndre Guedes } 2981023d5049SAndre Guedes 2982023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev) 2983023d5049SAndre Guedes { 2984023d5049SAndre Guedes BT_DBG("%s", hdev->name); 2985023d5049SAndre Guedes 2986023d5049SAndre Guedes if (!test_bit(HCI_INQUIRY, &hdev->flags)) 29877537e5c3SAndre Guedes return -EALREADY; 2988023d5049SAndre Guedes 2989023d5049SAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); 2990023d5049SAndre Guedes } 299131f7956cSAndre Guedes 299231f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type) 299331f7956cSAndre Guedes { 299431f7956cSAndre Guedes switch (bdaddr_type) { 299531f7956cSAndre Guedes case BDADDR_LE_PUBLIC: 299631f7956cSAndre Guedes return ADDR_LE_DEV_PUBLIC; 299731f7956cSAndre Guedes 299831f7956cSAndre Guedes default: 299931f7956cSAndre Guedes /* Fallback to LE Random address type */ 300031f7956cSAndre Guedes return ADDR_LE_DEV_RANDOM; 300131f7956cSAndre Guedes } 300231f7956cSAndre Guedes } 3003