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 { 181b0916ea0SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 1821ebb9252SMarcel Holtmann __le16 param; 18389f2783dSMarcel Holtmann __u8 flt_type; 1841da177e4SLinus Torvalds 1852455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 1862455a3eaSAndrei Emeltchenko 1871da177e4SLinus Torvalds /* Mandatory initialization */ 1881da177e4SLinus Torvalds 1891da177e4SLinus Torvalds /* Read Local Supported Features */ 190a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 1911da177e4SLinus Torvalds 1921143e5a6SMarcel Holtmann /* Read Local Version */ 193a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 1941143e5a6SMarcel Holtmann 1951da177e4SLinus Torvalds /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 196a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 1971da177e4SLinus Torvalds 1981da177e4SLinus Torvalds /* Read BD Address */ 199a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); 200a9de9248SMarcel Holtmann 201a9de9248SMarcel Holtmann /* Read Class of Device */ 202a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 203a9de9248SMarcel Holtmann 204a9de9248SMarcel Holtmann /* Read Local Name */ 205a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); 2061da177e4SLinus Torvalds 2071da177e4SLinus Torvalds /* Read Voice Setting */ 208a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); 2091da177e4SLinus Torvalds 2101da177e4SLinus Torvalds /* Optional initialization */ 2111da177e4SLinus Torvalds 2121da177e4SLinus Torvalds /* Clear Event Filters */ 21389f2783dSMarcel Holtmann flt_type = HCI_FLT_CLEAR_ALL; 214a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 2151da177e4SLinus Torvalds 2161da177e4SLinus Torvalds /* Connection accept timeout ~20 secs */ 21782781e63SAndrei Emeltchenko param = __constant_cpu_to_le16(0x7d00); 218a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 219b0916ea0SJohan Hedberg 220b0916ea0SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 221b0916ea0SJohan Hedberg cp.delete_all = 1; 222b0916ea0SJohan Hedberg hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); 2231da177e4SLinus Torvalds } 2241da177e4SLinus Torvalds 225e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev) 226e61ef499SAndrei Emeltchenko { 2272455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 2282455a3eaSAndrei Emeltchenko 229e61ef499SAndrei Emeltchenko /* Read Local Version */ 230e61ef499SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2316bcbc489SAndrei Emeltchenko 2326bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 2336bcbc489SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 234e71dfabaSAndrei Emeltchenko 235e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 236e71dfabaSAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 237e61ef499SAndrei Emeltchenko } 238e61ef499SAndrei Emeltchenko 239e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt) 240e61ef499SAndrei Emeltchenko { 241e61ef499SAndrei Emeltchenko struct sk_buff *skb; 242e61ef499SAndrei Emeltchenko 243e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 244e61ef499SAndrei Emeltchenko 245e61ef499SAndrei Emeltchenko /* Driver initialization */ 246e61ef499SAndrei Emeltchenko 247e61ef499SAndrei Emeltchenko /* Special commands */ 248e61ef499SAndrei Emeltchenko while ((skb = skb_dequeue(&hdev->driver_init))) { 249e61ef499SAndrei Emeltchenko bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 250e61ef499SAndrei Emeltchenko skb->dev = (void *) hdev; 251e61ef499SAndrei Emeltchenko 252e61ef499SAndrei Emeltchenko skb_queue_tail(&hdev->cmd_q, skb); 253e61ef499SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->cmd_work); 254e61ef499SAndrei Emeltchenko } 255e61ef499SAndrei Emeltchenko skb_queue_purge(&hdev->driver_init); 256e61ef499SAndrei Emeltchenko 25711778716SAndrei Emeltchenko /* Reset */ 25811778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 25911778716SAndrei Emeltchenko hci_reset_req(hdev, 0); 26011778716SAndrei Emeltchenko 261e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 262e61ef499SAndrei Emeltchenko case HCI_BREDR: 263e61ef499SAndrei Emeltchenko bredr_init(hdev); 264e61ef499SAndrei Emeltchenko break; 265e61ef499SAndrei Emeltchenko 266e61ef499SAndrei Emeltchenko case HCI_AMP: 267e61ef499SAndrei Emeltchenko amp_init(hdev); 268e61ef499SAndrei Emeltchenko break; 269e61ef499SAndrei Emeltchenko 270e61ef499SAndrei Emeltchenko default: 271e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 272e61ef499SAndrei Emeltchenko break; 273e61ef499SAndrei Emeltchenko } 274e61ef499SAndrei Emeltchenko } 275e61ef499SAndrei Emeltchenko 2766ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) 2776ed58ec5SVille Tervo { 2786ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 2796ed58ec5SVille Tervo 2806ed58ec5SVille Tervo /* Read LE buffer size */ 2816ed58ec5SVille Tervo hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 2826ed58ec5SVille Tervo } 2836ed58ec5SVille Tervo 2841da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) 2851da177e4SLinus Torvalds { 2861da177e4SLinus Torvalds __u8 scan = opt; 2871da177e4SLinus Torvalds 2881da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, scan); 2891da177e4SLinus Torvalds 2901da177e4SLinus Torvalds /* Inquiry and Page scans */ 291a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 2921da177e4SLinus Torvalds } 2931da177e4SLinus Torvalds 2941da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt) 2951da177e4SLinus Torvalds { 2961da177e4SLinus Torvalds __u8 auth = opt; 2971da177e4SLinus Torvalds 2981da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, auth); 2991da177e4SLinus Torvalds 3001da177e4SLinus Torvalds /* Authentication */ 301a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 3021da177e4SLinus Torvalds } 3031da177e4SLinus Torvalds 3041da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt) 3051da177e4SLinus Torvalds { 3061da177e4SLinus Torvalds __u8 encrypt = opt; 3071da177e4SLinus Torvalds 3081da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, encrypt); 3091da177e4SLinus Torvalds 310e4e8e37cSMarcel Holtmann /* Encryption */ 311a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 3121da177e4SLinus Torvalds } 3131da177e4SLinus Torvalds 314e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt) 315e4e8e37cSMarcel Holtmann { 316e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 317e4e8e37cSMarcel Holtmann 318a418b893SMarcel Holtmann BT_DBG("%s %x", hdev->name, policy); 319e4e8e37cSMarcel Holtmann 320e4e8e37cSMarcel Holtmann /* Default link policy */ 321e4e8e37cSMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 322e4e8e37cSMarcel Holtmann } 323e4e8e37cSMarcel Holtmann 3241da177e4SLinus Torvalds /* Get HCI device by index. 3251da177e4SLinus Torvalds * Device is held on return. */ 3261da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 3271da177e4SLinus Torvalds { 3288035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 3291da177e4SLinus Torvalds 3301da177e4SLinus Torvalds BT_DBG("%d", index); 3311da177e4SLinus Torvalds 3321da177e4SLinus Torvalds if (index < 0) 3331da177e4SLinus Torvalds return NULL; 3341da177e4SLinus Torvalds 3351da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 3368035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 3371da177e4SLinus Torvalds if (d->id == index) { 3381da177e4SLinus Torvalds hdev = hci_dev_hold(d); 3391da177e4SLinus Torvalds break; 3401da177e4SLinus Torvalds } 3411da177e4SLinus Torvalds } 3421da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 3431da177e4SLinus Torvalds return hdev; 3441da177e4SLinus Torvalds } 3451da177e4SLinus Torvalds 3461da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 347ff9ef578SJohan Hedberg 34830dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 34930dc78e1SJohan Hedberg { 35030dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 35130dc78e1SJohan Hedberg 3526fbe195dSAndre Guedes switch (discov->state) { 353343f935bSAndre Guedes case DISCOVERY_FINDING: 3546fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 35530dc78e1SJohan Hedberg return true; 35630dc78e1SJohan Hedberg 3576fbe195dSAndre Guedes default: 35830dc78e1SJohan Hedberg return false; 35930dc78e1SJohan Hedberg } 3606fbe195dSAndre Guedes } 36130dc78e1SJohan Hedberg 362ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 363ff9ef578SJohan Hedberg { 364ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 365ff9ef578SJohan Hedberg 366ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 367ff9ef578SJohan Hedberg return; 368ff9ef578SJohan Hedberg 369ff9ef578SJohan Hedberg switch (state) { 370ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 3717b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 372ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 373ff9ef578SJohan Hedberg break; 374ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 375ff9ef578SJohan Hedberg break; 376343f935bSAndre Guedes case DISCOVERY_FINDING: 377ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 378ff9ef578SJohan Hedberg break; 37930dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 38030dc78e1SJohan Hedberg break; 381ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 382ff9ef578SJohan Hedberg break; 383ff9ef578SJohan Hedberg } 384ff9ef578SJohan Hedberg 385ff9ef578SJohan Hedberg hdev->discovery.state = state; 386ff9ef578SJohan Hedberg } 387ff9ef578SJohan Hedberg 3881da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev) 3891da177e4SLinus Torvalds { 39030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 391b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 3921da177e4SLinus Torvalds 393561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 394561aafbcSJohan Hedberg list_del(&p->all); 395b57c1a56SJohan Hedberg kfree(p); 3961da177e4SLinus Torvalds } 397561aafbcSJohan Hedberg 398561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 399561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 4001da177e4SLinus Torvalds } 4011da177e4SLinus Torvalds 402a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 403a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 4041da177e4SLinus Torvalds { 40530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 4061da177e4SLinus Torvalds struct inquiry_entry *e; 4071da177e4SLinus Torvalds 4081da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 4091da177e4SLinus Torvalds 410561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 4111da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 4121da177e4SLinus Torvalds return e; 4131da177e4SLinus Torvalds } 4141da177e4SLinus Torvalds 415b57c1a56SJohan Hedberg return NULL; 416b57c1a56SJohan Hedberg } 417b57c1a56SJohan Hedberg 418561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 419561aafbcSJohan Hedberg bdaddr_t *bdaddr) 420561aafbcSJohan Hedberg { 42130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 422561aafbcSJohan Hedberg struct inquiry_entry *e; 423561aafbcSJohan Hedberg 424561aafbcSJohan Hedberg BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 425561aafbcSJohan Hedberg 426561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 427561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 428561aafbcSJohan Hedberg return e; 429561aafbcSJohan Hedberg } 430561aafbcSJohan Hedberg 431561aafbcSJohan Hedberg return NULL; 432561aafbcSJohan Hedberg } 433561aafbcSJohan Hedberg 43430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 43530dc78e1SJohan Hedberg bdaddr_t *bdaddr, 43630dc78e1SJohan Hedberg int state) 43730dc78e1SJohan Hedberg { 43830dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 43930dc78e1SJohan Hedberg struct inquiry_entry *e; 44030dc78e1SJohan Hedberg 44130dc78e1SJohan Hedberg BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state); 44230dc78e1SJohan Hedberg 44330dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 44430dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 44530dc78e1SJohan Hedberg return e; 44630dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 44730dc78e1SJohan Hedberg return e; 44830dc78e1SJohan Hedberg } 44930dc78e1SJohan Hedberg 45030dc78e1SJohan Hedberg return NULL; 45130dc78e1SJohan Hedberg } 45230dc78e1SJohan Hedberg 453a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 454a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 455a3d4e20aSJohan Hedberg { 456a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 457a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 458a3d4e20aSJohan Hedberg struct inquiry_entry *p; 459a3d4e20aSJohan Hedberg 460a3d4e20aSJohan Hedberg list_del(&ie->list); 461a3d4e20aSJohan Hedberg 462a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 463a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 464a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 465a3d4e20aSJohan Hedberg break; 466a3d4e20aSJohan Hedberg pos = &p->list; 467a3d4e20aSJohan Hedberg } 468a3d4e20aSJohan Hedberg 469a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 470a3d4e20aSJohan Hedberg } 471a3d4e20aSJohan Hedberg 4723175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 473388fc8faSJohan Hedberg bool name_known, bool *ssp) 4741da177e4SLinus Torvalds { 47530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 47670f23020SAndrei Emeltchenko struct inquiry_entry *ie; 4771da177e4SLinus Torvalds 4781da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr)); 4791da177e4SLinus Torvalds 480388fc8faSJohan Hedberg if (ssp) 481388fc8faSJohan Hedberg *ssp = data->ssp_mode; 482388fc8faSJohan Hedberg 48370f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 484a3d4e20aSJohan Hedberg if (ie) { 485388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 486388fc8faSJohan Hedberg *ssp = true; 487388fc8faSJohan Hedberg 488a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 489a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 490a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 491a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 492a3d4e20aSJohan Hedberg } 493a3d4e20aSJohan Hedberg 494561aafbcSJohan Hedberg goto update; 495a3d4e20aSJohan Hedberg } 496561aafbcSJohan Hedberg 4971da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 49870f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 49970f23020SAndrei Emeltchenko if (!ie) 5003175405bSJohan Hedberg return false; 50170f23020SAndrei Emeltchenko 502561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 503561aafbcSJohan Hedberg 504561aafbcSJohan Hedberg if (name_known) { 505561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 506561aafbcSJohan Hedberg } else { 507561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 508561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 509561aafbcSJohan Hedberg } 510561aafbcSJohan Hedberg 511561aafbcSJohan Hedberg update: 512561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 513561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 514561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 515561aafbcSJohan Hedberg list_del(&ie->list); 5161da177e4SLinus Torvalds } 5171da177e4SLinus Torvalds 51870f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 51970f23020SAndrei Emeltchenko ie->timestamp = jiffies; 5201da177e4SLinus Torvalds cache->timestamp = jiffies; 5213175405bSJohan Hedberg 5223175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 5233175405bSJohan Hedberg return false; 5243175405bSJohan Hedberg 5253175405bSJohan Hedberg return true; 5261da177e4SLinus Torvalds } 5271da177e4SLinus Torvalds 5281da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 5291da177e4SLinus Torvalds { 53030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 5311da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 5321da177e4SLinus Torvalds struct inquiry_entry *e; 5331da177e4SLinus Torvalds int copied = 0; 5341da177e4SLinus Torvalds 535561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 5361da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 537b57c1a56SJohan Hedberg 538b57c1a56SJohan Hedberg if (copied >= num) 539b57c1a56SJohan Hedberg break; 540b57c1a56SJohan Hedberg 5411da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 5421da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 5431da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 5441da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 5451da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 5461da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 547b57c1a56SJohan Hedberg 5481da177e4SLinus Torvalds info++; 549b57c1a56SJohan Hedberg copied++; 5501da177e4SLinus Torvalds } 5511da177e4SLinus Torvalds 5521da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 5531da177e4SLinus Torvalds return copied; 5541da177e4SLinus Torvalds } 5551da177e4SLinus Torvalds 5561da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt) 5571da177e4SLinus Torvalds { 5581da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 5591da177e4SLinus Torvalds struct hci_cp_inquiry cp; 5601da177e4SLinus Torvalds 5611da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 5621da177e4SLinus Torvalds 5631da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 5641da177e4SLinus Torvalds return; 5651da177e4SLinus Torvalds 5661da177e4SLinus Torvalds /* Start Inquiry */ 5671da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 5681da177e4SLinus Torvalds cp.length = ir->length; 5691da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 570a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 5711da177e4SLinus Torvalds } 5721da177e4SLinus Torvalds 5731da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 5741da177e4SLinus Torvalds { 5751da177e4SLinus Torvalds __u8 __user *ptr = arg; 5761da177e4SLinus Torvalds struct hci_inquiry_req ir; 5771da177e4SLinus Torvalds struct hci_dev *hdev; 5781da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 5791da177e4SLinus Torvalds long timeo; 5801da177e4SLinus Torvalds __u8 *buf; 5811da177e4SLinus Torvalds 5821da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 5831da177e4SLinus Torvalds return -EFAULT; 5841da177e4SLinus Torvalds 5855a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 5865a08ecceSAndrei Emeltchenko if (!hdev) 5871da177e4SLinus Torvalds return -ENODEV; 5881da177e4SLinus Torvalds 58909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 5901da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 591a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 5921da177e4SLinus Torvalds inquiry_cache_flush(hdev); 5931da177e4SLinus Torvalds do_inquiry = 1; 5941da177e4SLinus Torvalds } 59509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 5961da177e4SLinus Torvalds 59704837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 59870f23020SAndrei Emeltchenko 59970f23020SAndrei Emeltchenko if (do_inquiry) { 60070f23020SAndrei Emeltchenko err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo); 60170f23020SAndrei Emeltchenko if (err < 0) 6021da177e4SLinus Torvalds goto done; 60370f23020SAndrei Emeltchenko } 6041da177e4SLinus Torvalds 6058fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 6068fc9ced3SGustavo Padovan * 255 entries 6078fc9ced3SGustavo Padovan */ 6081da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 6091da177e4SLinus Torvalds 6101da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 6111da177e4SLinus Torvalds * copy it to the user space. 6121da177e4SLinus Torvalds */ 61370f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 61470f23020SAndrei Emeltchenko if (!buf) { 6151da177e4SLinus Torvalds err = -ENOMEM; 6161da177e4SLinus Torvalds goto done; 6171da177e4SLinus Torvalds } 6181da177e4SLinus Torvalds 61909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 6201da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 62109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 6221da177e4SLinus Torvalds 6231da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 6241da177e4SLinus Torvalds 6251da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 6261da177e4SLinus Torvalds ptr += sizeof(ir); 6271da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 6281da177e4SLinus Torvalds ir.num_rsp)) 6291da177e4SLinus Torvalds err = -EFAULT; 6301da177e4SLinus Torvalds } else 6311da177e4SLinus Torvalds err = -EFAULT; 6321da177e4SLinus Torvalds 6331da177e4SLinus Torvalds kfree(buf); 6341da177e4SLinus Torvalds 6351da177e4SLinus Torvalds done: 6361da177e4SLinus Torvalds hci_dev_put(hdev); 6371da177e4SLinus Torvalds return err; 6381da177e4SLinus Torvalds } 6391da177e4SLinus Torvalds 6401da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */ 6411da177e4SLinus Torvalds 6421da177e4SLinus Torvalds int hci_dev_open(__u16 dev) 6431da177e4SLinus Torvalds { 6441da177e4SLinus Torvalds struct hci_dev *hdev; 6451da177e4SLinus Torvalds int ret = 0; 6461da177e4SLinus Torvalds 6475a08ecceSAndrei Emeltchenko hdev = hci_dev_get(dev); 6485a08ecceSAndrei Emeltchenko if (!hdev) 6491da177e4SLinus Torvalds return -ENODEV; 6501da177e4SLinus Torvalds 6511da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 6521da177e4SLinus Torvalds 6531da177e4SLinus Torvalds hci_req_lock(hdev); 6541da177e4SLinus Torvalds 65594324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 65694324962SJohan Hovold ret = -ENODEV; 65794324962SJohan Hovold goto done; 65894324962SJohan Hovold } 65994324962SJohan Hovold 660611b30f7SMarcel Holtmann if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { 661611b30f7SMarcel Holtmann ret = -ERFKILL; 662611b30f7SMarcel Holtmann goto done; 663611b30f7SMarcel Holtmann } 664611b30f7SMarcel Holtmann 6651da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 6661da177e4SLinus Torvalds ret = -EALREADY; 6671da177e4SLinus Torvalds goto done; 6681da177e4SLinus Torvalds } 6691da177e4SLinus Torvalds 6701da177e4SLinus Torvalds if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 6711da177e4SLinus Torvalds set_bit(HCI_RAW, &hdev->flags); 6721da177e4SLinus Torvalds 67307e3b94aSAndrei Emeltchenko /* Treat all non BR/EDR controllers as raw devices if 67407e3b94aSAndrei Emeltchenko enable_hs is not set */ 67507e3b94aSAndrei Emeltchenko if (hdev->dev_type != HCI_BREDR && !enable_hs) 676943da25dSMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 677943da25dSMarcel Holtmann 6781da177e4SLinus Torvalds if (hdev->open(hdev)) { 6791da177e4SLinus Torvalds ret = -EIO; 6801da177e4SLinus Torvalds goto done; 6811da177e4SLinus Torvalds } 6821da177e4SLinus Torvalds 6831da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 6841da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 6851da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 686a5040efaSJohan Hedberg hdev->init_last_cmd = 0; 6871da177e4SLinus Torvalds 6885f246e89SAndrei Emeltchenko ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT); 6891da177e4SLinus Torvalds 690eead27daSAndre Guedes if (lmp_host_le_capable(hdev)) 6916ed58ec5SVille Tervo ret = __hci_request(hdev, hci_le_init_req, 0, 6925f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 6936ed58ec5SVille Tervo 6941da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 6951da177e4SLinus Torvalds } 6961da177e4SLinus Torvalds 6971da177e4SLinus Torvalds if (!ret) { 6981da177e4SLinus Torvalds hci_dev_hold(hdev); 6991da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 7001da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 701bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 702bb4b2a9aSAndrei Emeltchenko mgmt_valid_hdev(hdev)) { 70309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 704744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 70509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 70656e5cb86SJohan Hedberg } 7071da177e4SLinus Torvalds } else { 7081da177e4SLinus Torvalds /* Init failed, cleanup */ 7093eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 710c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 711b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7121da177e4SLinus Torvalds 7131da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7141da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7151da177e4SLinus Torvalds 7161da177e4SLinus Torvalds if (hdev->flush) 7171da177e4SLinus Torvalds hdev->flush(hdev); 7181da177e4SLinus Torvalds 7191da177e4SLinus Torvalds if (hdev->sent_cmd) { 7201da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 7211da177e4SLinus Torvalds hdev->sent_cmd = NULL; 7221da177e4SLinus Torvalds } 7231da177e4SLinus Torvalds 7241da177e4SLinus Torvalds hdev->close(hdev); 7251da177e4SLinus Torvalds hdev->flags = 0; 7261da177e4SLinus Torvalds } 7271da177e4SLinus Torvalds 7281da177e4SLinus Torvalds done: 7291da177e4SLinus Torvalds hci_req_unlock(hdev); 7301da177e4SLinus Torvalds hci_dev_put(hdev); 7311da177e4SLinus Torvalds return ret; 7321da177e4SLinus Torvalds } 7331da177e4SLinus Torvalds 7341da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 7351da177e4SLinus Torvalds { 7361da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 7371da177e4SLinus Torvalds 73828b75a89SAndre Guedes cancel_work_sync(&hdev->le_scan); 73928b75a89SAndre Guedes 74078c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 74178c04c0bSVinicius Costa Gomes 7421da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 7431da177e4SLinus Torvalds hci_req_lock(hdev); 7441da177e4SLinus Torvalds 7451da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 746b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 7471da177e4SLinus Torvalds hci_req_unlock(hdev); 7481da177e4SLinus Torvalds return 0; 7491da177e4SLinus Torvalds } 7501da177e4SLinus Torvalds 7513eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 7523eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 753b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7541da177e4SLinus Torvalds 75516ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 756e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 75716ab91abSJohan Hedberg hdev->discov_timeout = 0; 7585e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 75916ab91abSJohan Hedberg } 76016ab91abSJohan Hedberg 761a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 7627d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 7637d78525dSJohan Hedberg 7647ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 7657ba8b4beSAndre Guedes 76609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 7671da177e4SLinus Torvalds inquiry_cache_flush(hdev); 7681da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 76909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 7701da177e4SLinus Torvalds 7711da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 7721da177e4SLinus Torvalds 7731da177e4SLinus Torvalds if (hdev->flush) 7741da177e4SLinus Torvalds hdev->flush(hdev); 7751da177e4SLinus Torvalds 7761da177e4SLinus Torvalds /* Reset device */ 7771da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7781da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 7798af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 780a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 7811da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 7825f246e89SAndrei Emeltchenko __hci_request(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 7831da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7841da177e4SLinus Torvalds } 7851da177e4SLinus Torvalds 786c347b765SGustavo F. Padovan /* flush cmd work */ 787c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 7881da177e4SLinus Torvalds 7891da177e4SLinus Torvalds /* Drop queues */ 7901da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7911da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7921da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 7931da177e4SLinus Torvalds 7941da177e4SLinus Torvalds /* Drop last sent command */ 7951da177e4SLinus Torvalds if (hdev->sent_cmd) { 796b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 7971da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 7981da177e4SLinus Torvalds hdev->sent_cmd = NULL; 7991da177e4SLinus Torvalds } 8001da177e4SLinus Torvalds 8011da177e4SLinus Torvalds /* After this point our queues are empty 8021da177e4SLinus Torvalds * and no tasks are scheduled. */ 8031da177e4SLinus Torvalds hdev->close(hdev); 8041da177e4SLinus Torvalds 805bb4b2a9aSAndrei Emeltchenko if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 806bb4b2a9aSAndrei Emeltchenko mgmt_valid_hdev(hdev)) { 80709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 808744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 80909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8108ee56540SMarcel Holtmann } 8115add6af8SJohan Hedberg 8121da177e4SLinus Torvalds /* Clear flags */ 8131da177e4SLinus Torvalds hdev->flags = 0; 8141da177e4SLinus Torvalds 815e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 81609b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 817e59fda8dSJohan Hedberg 8181da177e4SLinus Torvalds hci_req_unlock(hdev); 8191da177e4SLinus Torvalds 8201da177e4SLinus Torvalds hci_dev_put(hdev); 8211da177e4SLinus Torvalds return 0; 8221da177e4SLinus Torvalds } 8231da177e4SLinus Torvalds 8241da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 8251da177e4SLinus Torvalds { 8261da177e4SLinus Torvalds struct hci_dev *hdev; 8271da177e4SLinus Torvalds int err; 8281da177e4SLinus Torvalds 82970f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 83070f23020SAndrei Emeltchenko if (!hdev) 8311da177e4SLinus Torvalds return -ENODEV; 8328ee56540SMarcel Holtmann 8338ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 8348ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 8358ee56540SMarcel Holtmann 8361da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 8378ee56540SMarcel Holtmann 8381da177e4SLinus Torvalds hci_dev_put(hdev); 8391da177e4SLinus Torvalds return err; 8401da177e4SLinus Torvalds } 8411da177e4SLinus Torvalds 8421da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 8431da177e4SLinus Torvalds { 8441da177e4SLinus Torvalds struct hci_dev *hdev; 8451da177e4SLinus Torvalds int ret = 0; 8461da177e4SLinus Torvalds 84770f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 84870f23020SAndrei Emeltchenko if (!hdev) 8491da177e4SLinus Torvalds return -ENODEV; 8501da177e4SLinus Torvalds 8511da177e4SLinus Torvalds hci_req_lock(hdev); 8521da177e4SLinus Torvalds 8531da177e4SLinus Torvalds if (!test_bit(HCI_UP, &hdev->flags)) 8541da177e4SLinus Torvalds goto done; 8551da177e4SLinus Torvalds 8561da177e4SLinus Torvalds /* Drop queues */ 8571da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 8581da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8591da177e4SLinus Torvalds 86009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 8611da177e4SLinus Torvalds inquiry_cache_flush(hdev); 8621da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 86309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8641da177e4SLinus Torvalds 8651da177e4SLinus Torvalds if (hdev->flush) 8661da177e4SLinus Torvalds hdev->flush(hdev); 8671da177e4SLinus Torvalds 8681da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 8696ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 8701da177e4SLinus Torvalds 8711da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 8725f246e89SAndrei Emeltchenko ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 8731da177e4SLinus Torvalds 8741da177e4SLinus Torvalds done: 8751da177e4SLinus Torvalds hci_req_unlock(hdev); 8761da177e4SLinus Torvalds hci_dev_put(hdev); 8771da177e4SLinus Torvalds return ret; 8781da177e4SLinus Torvalds } 8791da177e4SLinus Torvalds 8801da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 8811da177e4SLinus Torvalds { 8821da177e4SLinus Torvalds struct hci_dev *hdev; 8831da177e4SLinus Torvalds int ret = 0; 8841da177e4SLinus Torvalds 88570f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 88670f23020SAndrei Emeltchenko if (!hdev) 8871da177e4SLinus Torvalds return -ENODEV; 8881da177e4SLinus Torvalds 8891da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 8901da177e4SLinus Torvalds 8911da177e4SLinus Torvalds hci_dev_put(hdev); 8921da177e4SLinus Torvalds 8931da177e4SLinus Torvalds return ret; 8941da177e4SLinus Torvalds } 8951da177e4SLinus Torvalds 8961da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 8971da177e4SLinus Torvalds { 8981da177e4SLinus Torvalds struct hci_dev *hdev; 8991da177e4SLinus Torvalds struct hci_dev_req dr; 9001da177e4SLinus Torvalds int err = 0; 9011da177e4SLinus Torvalds 9021da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 9031da177e4SLinus Torvalds return -EFAULT; 9041da177e4SLinus Torvalds 90570f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 90670f23020SAndrei Emeltchenko if (!hdev) 9071da177e4SLinus Torvalds return -ENODEV; 9081da177e4SLinus Torvalds 9091da177e4SLinus Torvalds switch (cmd) { 9101da177e4SLinus Torvalds case HCISETAUTH: 91104837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 9125f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 9131da177e4SLinus Torvalds break; 9141da177e4SLinus Torvalds 9151da177e4SLinus Torvalds case HCISETENCRYPT: 9161da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 9171da177e4SLinus Torvalds err = -EOPNOTSUPP; 9181da177e4SLinus Torvalds break; 9191da177e4SLinus Torvalds } 9201da177e4SLinus Torvalds 9211da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 9221da177e4SLinus Torvalds /* Auth must be enabled first */ 92304837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 9245f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 9251da177e4SLinus Torvalds if (err) 9261da177e4SLinus Torvalds break; 9271da177e4SLinus Torvalds } 9281da177e4SLinus Torvalds 92904837f64SMarcel Holtmann err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, 9305f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 9311da177e4SLinus Torvalds break; 9321da177e4SLinus Torvalds 9331da177e4SLinus Torvalds case HCISETSCAN: 93404837f64SMarcel Holtmann err = hci_request(hdev, hci_scan_req, dr.dev_opt, 9355f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 9361da177e4SLinus Torvalds break; 9371da177e4SLinus Torvalds 9381da177e4SLinus Torvalds case HCISETLINKPOL: 939e4e8e37cSMarcel Holtmann err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, 9405f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 9411da177e4SLinus Torvalds break; 9421da177e4SLinus Torvalds 9431da177e4SLinus Torvalds case HCISETLINKMODE: 944e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 945e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 946e4e8e37cSMarcel Holtmann break; 947e4e8e37cSMarcel Holtmann 948e4e8e37cSMarcel Holtmann case HCISETPTYPE: 949e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 9501da177e4SLinus Torvalds break; 9511da177e4SLinus Torvalds 9521da177e4SLinus Torvalds case HCISETACLMTU: 9531da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 9541da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 9551da177e4SLinus Torvalds break; 9561da177e4SLinus Torvalds 9571da177e4SLinus Torvalds case HCISETSCOMTU: 9581da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 9591da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 9601da177e4SLinus Torvalds break; 9611da177e4SLinus Torvalds 9621da177e4SLinus Torvalds default: 9631da177e4SLinus Torvalds err = -EINVAL; 9641da177e4SLinus Torvalds break; 9651da177e4SLinus Torvalds } 966e4e8e37cSMarcel Holtmann 9671da177e4SLinus Torvalds hci_dev_put(hdev); 9681da177e4SLinus Torvalds return err; 9691da177e4SLinus Torvalds } 9701da177e4SLinus Torvalds 9711da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 9721da177e4SLinus Torvalds { 9738035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 9741da177e4SLinus Torvalds struct hci_dev_list_req *dl; 9751da177e4SLinus Torvalds struct hci_dev_req *dr; 9761da177e4SLinus Torvalds int n = 0, size, err; 9771da177e4SLinus Torvalds __u16 dev_num; 9781da177e4SLinus Torvalds 9791da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 9801da177e4SLinus Torvalds return -EFAULT; 9811da177e4SLinus Torvalds 9821da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 9831da177e4SLinus Torvalds return -EINVAL; 9841da177e4SLinus Torvalds 9851da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 9861da177e4SLinus Torvalds 98770f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 98870f23020SAndrei Emeltchenko if (!dl) 9891da177e4SLinus Torvalds return -ENOMEM; 9901da177e4SLinus Torvalds 9911da177e4SLinus Torvalds dr = dl->dev_req; 9921da177e4SLinus Torvalds 993f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 9948035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 995a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 996e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 997c542a06cSJohan Hedberg 998a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 999a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1000c542a06cSJohan Hedberg 10011da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 10021da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 1003c542a06cSJohan Hedberg 10041da177e4SLinus Torvalds if (++n >= dev_num) 10051da177e4SLinus Torvalds break; 10061da177e4SLinus Torvalds } 1007f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 10081da177e4SLinus Torvalds 10091da177e4SLinus Torvalds dl->dev_num = n; 10101da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 10111da177e4SLinus Torvalds 10121da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 10131da177e4SLinus Torvalds kfree(dl); 10141da177e4SLinus Torvalds 10151da177e4SLinus Torvalds return err ? -EFAULT : 0; 10161da177e4SLinus Torvalds } 10171da177e4SLinus Torvalds 10181da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 10191da177e4SLinus Torvalds { 10201da177e4SLinus Torvalds struct hci_dev *hdev; 10211da177e4SLinus Torvalds struct hci_dev_info di; 10221da177e4SLinus Torvalds int err = 0; 10231da177e4SLinus Torvalds 10241da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 10251da177e4SLinus Torvalds return -EFAULT; 10261da177e4SLinus Torvalds 102770f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 102870f23020SAndrei Emeltchenko if (!hdev) 10291da177e4SLinus Torvalds return -ENODEV; 10301da177e4SLinus Torvalds 1031a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 10323243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 1033ab81cbf9SJohan Hedberg 1034a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1035a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1036c542a06cSJohan Hedberg 10371da177e4SLinus Torvalds strcpy(di.name, hdev->name); 10381da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 1039943da25dSMarcel Holtmann di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); 10401da177e4SLinus Torvalds di.flags = hdev->flags; 10411da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 10421da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 10431da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 10441da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 10451da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 10461da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 10471da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 10481da177e4SLinus Torvalds 10491da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 10501da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 10511da177e4SLinus Torvalds 10521da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 10531da177e4SLinus Torvalds err = -EFAULT; 10541da177e4SLinus Torvalds 10551da177e4SLinus Torvalds hci_dev_put(hdev); 10561da177e4SLinus Torvalds 10571da177e4SLinus Torvalds return err; 10581da177e4SLinus Torvalds } 10591da177e4SLinus Torvalds 10601da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 10611da177e4SLinus Torvalds 1062611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 1063611b30f7SMarcel Holtmann { 1064611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 1065611b30f7SMarcel Holtmann 1066611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 1067611b30f7SMarcel Holtmann 1068611b30f7SMarcel Holtmann if (!blocked) 1069611b30f7SMarcel Holtmann return 0; 1070611b30f7SMarcel Holtmann 1071611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 1072611b30f7SMarcel Holtmann 1073611b30f7SMarcel Holtmann return 0; 1074611b30f7SMarcel Holtmann } 1075611b30f7SMarcel Holtmann 1076611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 1077611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 1078611b30f7SMarcel Holtmann }; 1079611b30f7SMarcel Holtmann 1080ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 1081ab81cbf9SJohan Hedberg { 1082ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 1083ab81cbf9SJohan Hedberg 1084ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1085ab81cbf9SJohan Hedberg 1086ab81cbf9SJohan Hedberg if (hci_dev_open(hdev->id) < 0) 1087ab81cbf9SJohan Hedberg return; 1088ab81cbf9SJohan Hedberg 1089a8b2d5c2SJohan Hedberg if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 10909345d40cSAndrei Emeltchenko schedule_delayed_work(&hdev->power_off, HCI_AUTO_OFF_TIMEOUT); 1091ab81cbf9SJohan Hedberg 1092a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 1093744cf19eSJohan Hedberg mgmt_index_added(hdev); 1094ab81cbf9SJohan Hedberg } 1095ab81cbf9SJohan Hedberg 1096ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1097ab81cbf9SJohan Hedberg { 10983243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 10993243553fSJohan Hedberg power_off.work); 1100ab81cbf9SJohan Hedberg 1101ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1102ab81cbf9SJohan Hedberg 11038ee56540SMarcel Holtmann hci_dev_do_close(hdev); 1104ab81cbf9SJohan Hedberg } 1105ab81cbf9SJohan Hedberg 110616ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 110716ab91abSJohan Hedberg { 110816ab91abSJohan Hedberg struct hci_dev *hdev; 110916ab91abSJohan Hedberg u8 scan = SCAN_PAGE; 111016ab91abSJohan Hedberg 111116ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 111216ab91abSJohan Hedberg 111316ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 111416ab91abSJohan Hedberg 111509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 111616ab91abSJohan Hedberg 111716ab91abSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); 111816ab91abSJohan Hedberg 111916ab91abSJohan Hedberg hdev->discov_timeout = 0; 112016ab91abSJohan Hedberg 112109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 112216ab91abSJohan Hedberg } 112316ab91abSJohan Hedberg 11242aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 11252aeb9a1aSJohan Hedberg { 11262aeb9a1aSJohan Hedberg struct list_head *p, *n; 11272aeb9a1aSJohan Hedberg 11282aeb9a1aSJohan Hedberg list_for_each_safe(p, n, &hdev->uuids) { 11292aeb9a1aSJohan Hedberg struct bt_uuid *uuid; 11302aeb9a1aSJohan Hedberg 11312aeb9a1aSJohan Hedberg uuid = list_entry(p, struct bt_uuid, list); 11322aeb9a1aSJohan Hedberg 11332aeb9a1aSJohan Hedberg list_del(p); 11342aeb9a1aSJohan Hedberg kfree(uuid); 11352aeb9a1aSJohan Hedberg } 11362aeb9a1aSJohan Hedberg 11372aeb9a1aSJohan Hedberg return 0; 11382aeb9a1aSJohan Hedberg } 11392aeb9a1aSJohan Hedberg 114055ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 114155ed8ca1SJohan Hedberg { 114255ed8ca1SJohan Hedberg struct list_head *p, *n; 114355ed8ca1SJohan Hedberg 114455ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 114555ed8ca1SJohan Hedberg struct link_key *key; 114655ed8ca1SJohan Hedberg 114755ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 114855ed8ca1SJohan Hedberg 114955ed8ca1SJohan Hedberg list_del(p); 115055ed8ca1SJohan Hedberg kfree(key); 115155ed8ca1SJohan Hedberg } 115255ed8ca1SJohan Hedberg 115355ed8ca1SJohan Hedberg return 0; 115455ed8ca1SJohan Hedberg } 115555ed8ca1SJohan Hedberg 1156b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 1157b899efafSVinicius Costa Gomes { 1158b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1159b899efafSVinicius Costa Gomes 1160b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1161b899efafSVinicius Costa Gomes list_del(&k->list); 1162b899efafSVinicius Costa Gomes kfree(k); 1163b899efafSVinicius Costa Gomes } 1164b899efafSVinicius Costa Gomes 1165b899efafSVinicius Costa Gomes return 0; 1166b899efafSVinicius Costa Gomes } 1167b899efafSVinicius Costa Gomes 116855ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 116955ed8ca1SJohan Hedberg { 117055ed8ca1SJohan Hedberg struct link_key *k; 117155ed8ca1SJohan Hedberg 11728035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 117355ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 117455ed8ca1SJohan Hedberg return k; 117555ed8ca1SJohan Hedberg 117655ed8ca1SJohan Hedberg return NULL; 117755ed8ca1SJohan Hedberg } 117855ed8ca1SJohan Hedberg 1179745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 1180d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 1181d25e28abSJohan Hedberg { 1182d25e28abSJohan Hedberg /* Legacy key */ 1183d25e28abSJohan Hedberg if (key_type < 0x03) 1184745c0ce3SVishal Agarwal return true; 1185d25e28abSJohan Hedberg 1186d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 1187d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 1188745c0ce3SVishal Agarwal return false; 1189d25e28abSJohan Hedberg 1190d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 1191d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 1192745c0ce3SVishal Agarwal return false; 1193d25e28abSJohan Hedberg 1194d25e28abSJohan Hedberg /* Security mode 3 case */ 1195d25e28abSJohan Hedberg if (!conn) 1196745c0ce3SVishal Agarwal return true; 1197d25e28abSJohan Hedberg 1198d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 1199d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 1200745c0ce3SVishal Agarwal return true; 1201d25e28abSJohan Hedberg 1202d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 1203d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 1204745c0ce3SVishal Agarwal return true; 1205d25e28abSJohan Hedberg 1206d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 1207d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 1208745c0ce3SVishal Agarwal return true; 1209d25e28abSJohan Hedberg 1210d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 1211d25e28abSJohan Hedberg * persistently */ 1212745c0ce3SVishal Agarwal return false; 1213d25e28abSJohan Hedberg } 1214d25e28abSJohan Hedberg 1215c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 121675d262c2SVinicius Costa Gomes { 1217c9839a11SVinicius Costa Gomes struct smp_ltk *k; 121875d262c2SVinicius Costa Gomes 1219c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 1220c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 1221c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 122275d262c2SVinicius Costa Gomes continue; 122375d262c2SVinicius Costa Gomes 122475d262c2SVinicius Costa Gomes return k; 122575d262c2SVinicius Costa Gomes } 122675d262c2SVinicius Costa Gomes 122775d262c2SVinicius Costa Gomes return NULL; 122875d262c2SVinicius Costa Gomes } 122975d262c2SVinicius Costa Gomes 1230c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1231c9839a11SVinicius Costa Gomes u8 addr_type) 123275d262c2SVinicius Costa Gomes { 1233c9839a11SVinicius Costa Gomes struct smp_ltk *k; 123475d262c2SVinicius Costa Gomes 1235c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 1236c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 1237c9839a11SVinicius Costa Gomes bacmp(bdaddr, &k->bdaddr) == 0) 123875d262c2SVinicius Costa Gomes return k; 123975d262c2SVinicius Costa Gomes 124075d262c2SVinicius Costa Gomes return NULL; 124175d262c2SVinicius Costa Gomes } 124275d262c2SVinicius Costa Gomes 1243d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 1244d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 124555ed8ca1SJohan Hedberg { 124655ed8ca1SJohan Hedberg struct link_key *key, *old_key; 1247745c0ce3SVishal Agarwal u8 old_key_type; 1248745c0ce3SVishal Agarwal bool persistent; 124955ed8ca1SJohan Hedberg 125055ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 125155ed8ca1SJohan Hedberg if (old_key) { 125255ed8ca1SJohan Hedberg old_key_type = old_key->type; 125355ed8ca1SJohan Hedberg key = old_key; 125455ed8ca1SJohan Hedberg } else { 125512adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 125655ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 125755ed8ca1SJohan Hedberg if (!key) 125855ed8ca1SJohan Hedberg return -ENOMEM; 125955ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 126055ed8ca1SJohan Hedberg } 126155ed8ca1SJohan Hedberg 126255ed8ca1SJohan Hedberg BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); 126355ed8ca1SJohan Hedberg 1264d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1265d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1266d25e28abSJohan Hedberg * previous key */ 1267d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1268a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 1269d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1270655fe6ecSJohan Hedberg if (conn) 1271655fe6ecSJohan Hedberg conn->key_type = type; 1272655fe6ecSJohan Hedberg } 1273d25e28abSJohan Hedberg 127455ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 12759b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 127655ed8ca1SJohan Hedberg key->pin_len = pin_len; 127755ed8ca1SJohan Hedberg 1278b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 127955ed8ca1SJohan Hedberg key->type = old_key_type; 12804748fed2SJohan Hedberg else 12814748fed2SJohan Hedberg key->type = type; 12824748fed2SJohan Hedberg 12834df378a1SJohan Hedberg if (!new_key) 12844df378a1SJohan Hedberg return 0; 12854df378a1SJohan Hedberg 12864df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 12874df378a1SJohan Hedberg 1288744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 12894df378a1SJohan Hedberg 12906ec5bcadSVishal Agarwal if (conn) 12916ec5bcadSVishal Agarwal conn->flush_key = !persistent; 129255ed8ca1SJohan Hedberg 129355ed8ca1SJohan Hedberg return 0; 129455ed8ca1SJohan Hedberg } 129555ed8ca1SJohan Hedberg 1296c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 12979a006657SAndrei Emeltchenko int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 129804124681SGustavo F. Padovan ediv, u8 rand[8]) 129975d262c2SVinicius Costa Gomes { 1300c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 130175d262c2SVinicius Costa Gomes 1302c9839a11SVinicius Costa Gomes if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 1303c9839a11SVinicius Costa Gomes return 0; 130475d262c2SVinicius Costa Gomes 1305c9839a11SVinicius Costa Gomes old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 1306c9839a11SVinicius Costa Gomes if (old_key) 130775d262c2SVinicius Costa Gomes key = old_key; 1308c9839a11SVinicius Costa Gomes else { 1309c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 131075d262c2SVinicius Costa Gomes if (!key) 131175d262c2SVinicius Costa Gomes return -ENOMEM; 1312c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 131375d262c2SVinicius Costa Gomes } 131475d262c2SVinicius Costa Gomes 131575d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 1316c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 1317c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 1318c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 1319c9839a11SVinicius Costa Gomes key->ediv = ediv; 1320c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 1321c9839a11SVinicius Costa Gomes key->type = type; 1322c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 132375d262c2SVinicius Costa Gomes 1324c9839a11SVinicius Costa Gomes if (!new_key) 1325c9839a11SVinicius Costa Gomes return 0; 132675d262c2SVinicius Costa Gomes 1327261cc5aaSVinicius Costa Gomes if (type & HCI_SMP_LTK) 1328261cc5aaSVinicius Costa Gomes mgmt_new_ltk(hdev, key, 1); 1329261cc5aaSVinicius Costa Gomes 133075d262c2SVinicius Costa Gomes return 0; 133175d262c2SVinicius Costa Gomes } 133275d262c2SVinicius Costa Gomes 133355ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 133455ed8ca1SJohan Hedberg { 133555ed8ca1SJohan Hedberg struct link_key *key; 133655ed8ca1SJohan Hedberg 133755ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 133855ed8ca1SJohan Hedberg if (!key) 133955ed8ca1SJohan Hedberg return -ENOENT; 134055ed8ca1SJohan Hedberg 134155ed8ca1SJohan Hedberg BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 134255ed8ca1SJohan Hedberg 134355ed8ca1SJohan Hedberg list_del(&key->list); 134455ed8ca1SJohan Hedberg kfree(key); 134555ed8ca1SJohan Hedberg 134655ed8ca1SJohan Hedberg return 0; 134755ed8ca1SJohan Hedberg } 134855ed8ca1SJohan Hedberg 1349b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 1350b899efafSVinicius Costa Gomes { 1351b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1352b899efafSVinicius Costa Gomes 1353b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1354b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 1355b899efafSVinicius Costa Gomes continue; 1356b899efafSVinicius Costa Gomes 1357b899efafSVinicius Costa Gomes BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 1358b899efafSVinicius Costa Gomes 1359b899efafSVinicius Costa Gomes list_del(&k->list); 1360b899efafSVinicius Costa Gomes kfree(k); 1361b899efafSVinicius Costa Gomes } 1362b899efafSVinicius Costa Gomes 1363b899efafSVinicius Costa Gomes return 0; 1364b899efafSVinicius Costa Gomes } 1365b899efafSVinicius Costa Gomes 13666bd32326SVille Tervo /* HCI command timer function */ 1367bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg) 13686bd32326SVille Tervo { 13696bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 13706bd32326SVille Tervo 1371bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 1372bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 1373bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 1374bda4f23aSAndrei Emeltchenko 1375bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 1376bda4f23aSAndrei Emeltchenko } else { 13776bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 1378bda4f23aSAndrei Emeltchenko } 1379bda4f23aSAndrei Emeltchenko 13806bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 1381c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 13826bd32326SVille Tervo } 13836bd32326SVille Tervo 13842763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 13852763eda6SSzymon Janc bdaddr_t *bdaddr) 13862763eda6SSzymon Janc { 13872763eda6SSzymon Janc struct oob_data *data; 13882763eda6SSzymon Janc 13892763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 13902763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 13912763eda6SSzymon Janc return data; 13922763eda6SSzymon Janc 13932763eda6SSzymon Janc return NULL; 13942763eda6SSzymon Janc } 13952763eda6SSzymon Janc 13962763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 13972763eda6SSzymon Janc { 13982763eda6SSzymon Janc struct oob_data *data; 13992763eda6SSzymon Janc 14002763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14012763eda6SSzymon Janc if (!data) 14022763eda6SSzymon Janc return -ENOENT; 14032763eda6SSzymon Janc 14042763eda6SSzymon Janc BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 14052763eda6SSzymon Janc 14062763eda6SSzymon Janc list_del(&data->list); 14072763eda6SSzymon Janc kfree(data); 14082763eda6SSzymon Janc 14092763eda6SSzymon Janc return 0; 14102763eda6SSzymon Janc } 14112763eda6SSzymon Janc 14122763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 14132763eda6SSzymon Janc { 14142763eda6SSzymon Janc struct oob_data *data, *n; 14152763eda6SSzymon Janc 14162763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 14172763eda6SSzymon Janc list_del(&data->list); 14182763eda6SSzymon Janc kfree(data); 14192763eda6SSzymon Janc } 14202763eda6SSzymon Janc 14212763eda6SSzymon Janc return 0; 14222763eda6SSzymon Janc } 14232763eda6SSzymon Janc 14242763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 14252763eda6SSzymon Janc u8 *randomizer) 14262763eda6SSzymon Janc { 14272763eda6SSzymon Janc struct oob_data *data; 14282763eda6SSzymon Janc 14292763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14302763eda6SSzymon Janc 14312763eda6SSzymon Janc if (!data) { 14322763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 14332763eda6SSzymon Janc if (!data) 14342763eda6SSzymon Janc return -ENOMEM; 14352763eda6SSzymon Janc 14362763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 14372763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 14382763eda6SSzymon Janc } 14392763eda6SSzymon Janc 14402763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 14412763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 14422763eda6SSzymon Janc 14432763eda6SSzymon Janc BT_DBG("%s for %s", hdev->name, batostr(bdaddr)); 14442763eda6SSzymon Janc 14452763eda6SSzymon Janc return 0; 14462763eda6SSzymon Janc } 14472763eda6SSzymon Janc 144804124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 1449b2a66aadSAntti Julku { 1450b2a66aadSAntti Julku struct bdaddr_list *b; 1451b2a66aadSAntti Julku 14528035ded4SLuiz Augusto von Dentz list_for_each_entry(b, &hdev->blacklist, list) 1453b2a66aadSAntti Julku if (bacmp(bdaddr, &b->bdaddr) == 0) 1454b2a66aadSAntti Julku return b; 1455b2a66aadSAntti Julku 1456b2a66aadSAntti Julku return NULL; 1457b2a66aadSAntti Julku } 1458b2a66aadSAntti Julku 1459b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 1460b2a66aadSAntti Julku { 1461b2a66aadSAntti Julku struct list_head *p, *n; 1462b2a66aadSAntti Julku 1463b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 1464b2a66aadSAntti Julku struct bdaddr_list *b; 1465b2a66aadSAntti Julku 1466b2a66aadSAntti Julku b = list_entry(p, struct bdaddr_list, list); 1467b2a66aadSAntti Julku 1468b2a66aadSAntti Julku list_del(p); 1469b2a66aadSAntti Julku kfree(b); 1470b2a66aadSAntti Julku } 1471b2a66aadSAntti Julku 1472b2a66aadSAntti Julku return 0; 1473b2a66aadSAntti Julku } 1474b2a66aadSAntti Julku 147588c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1476b2a66aadSAntti Julku { 1477b2a66aadSAntti Julku struct bdaddr_list *entry; 1478b2a66aadSAntti Julku 1479b2a66aadSAntti Julku if (bacmp(bdaddr, BDADDR_ANY) == 0) 1480b2a66aadSAntti Julku return -EBADF; 1481b2a66aadSAntti Julku 14825e762444SAntti Julku if (hci_blacklist_lookup(hdev, bdaddr)) 14835e762444SAntti Julku return -EEXIST; 1484b2a66aadSAntti Julku 1485b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 14865e762444SAntti Julku if (!entry) 14875e762444SAntti Julku return -ENOMEM; 1488b2a66aadSAntti Julku 1489b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 1490b2a66aadSAntti Julku 1491b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 1492b2a66aadSAntti Julku 149388c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 1494b2a66aadSAntti Julku } 1495b2a66aadSAntti Julku 149688c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1497b2a66aadSAntti Julku { 1498b2a66aadSAntti Julku struct bdaddr_list *entry; 1499b2a66aadSAntti Julku 15001ec918ceSSzymon Janc if (bacmp(bdaddr, BDADDR_ANY) == 0) 15015e762444SAntti Julku return hci_blacklist_clear(hdev); 1502b2a66aadSAntti Julku 1503b2a66aadSAntti Julku entry = hci_blacklist_lookup(hdev, bdaddr); 15041ec918ceSSzymon Janc if (!entry) 15055e762444SAntti Julku return -ENOENT; 1506b2a66aadSAntti Julku 1507b2a66aadSAntti Julku list_del(&entry->list); 1508b2a66aadSAntti Julku kfree(entry); 1509b2a66aadSAntti Julku 151088c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 1511b2a66aadSAntti Julku } 1512b2a66aadSAntti Julku 15137ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt) 15147ba8b4beSAndre Guedes { 15157ba8b4beSAndre Guedes struct le_scan_params *param = (struct le_scan_params *) opt; 15167ba8b4beSAndre Guedes struct hci_cp_le_set_scan_param cp; 15177ba8b4beSAndre Guedes 15187ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 15197ba8b4beSAndre Guedes cp.type = param->type; 15207ba8b4beSAndre Guedes cp.interval = cpu_to_le16(param->interval); 15217ba8b4beSAndre Guedes cp.window = cpu_to_le16(param->window); 15227ba8b4beSAndre Guedes 15237ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); 15247ba8b4beSAndre Guedes } 15257ba8b4beSAndre Guedes 15267ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt) 15277ba8b4beSAndre Guedes { 15287ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 15297ba8b4beSAndre Guedes 15307ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 15317ba8b4beSAndre Guedes cp.enable = 1; 15320431a43cSAndre Guedes cp.filter_dup = 1; 15337ba8b4beSAndre Guedes 15347ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 15357ba8b4beSAndre Guedes } 15367ba8b4beSAndre Guedes 15377ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, 15387ba8b4beSAndre Guedes u16 window, int timeout) 15397ba8b4beSAndre Guedes { 15407ba8b4beSAndre Guedes long timeo = msecs_to_jiffies(3000); 15417ba8b4beSAndre Guedes struct le_scan_params param; 15427ba8b4beSAndre Guedes int err; 15437ba8b4beSAndre Guedes 15447ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 15457ba8b4beSAndre Guedes 15467ba8b4beSAndre Guedes if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 15477ba8b4beSAndre Guedes return -EINPROGRESS; 15487ba8b4beSAndre Guedes 15497ba8b4beSAndre Guedes param.type = type; 15507ba8b4beSAndre Guedes param.interval = interval; 15517ba8b4beSAndre Guedes param.window = window; 15527ba8b4beSAndre Guedes 15537ba8b4beSAndre Guedes hci_req_lock(hdev); 15547ba8b4beSAndre Guedes 15557ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_param_req, (unsigned long) ¶m, 15567ba8b4beSAndre Guedes timeo); 15577ba8b4beSAndre Guedes if (!err) 15587ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_enable_req, 0, timeo); 15597ba8b4beSAndre Guedes 15607ba8b4beSAndre Guedes hci_req_unlock(hdev); 15617ba8b4beSAndre Guedes 15627ba8b4beSAndre Guedes if (err < 0) 15637ba8b4beSAndre Guedes return err; 15647ba8b4beSAndre Guedes 15657ba8b4beSAndre Guedes schedule_delayed_work(&hdev->le_scan_disable, 15667ba8b4beSAndre Guedes msecs_to_jiffies(timeout)); 15677ba8b4beSAndre Guedes 15687ba8b4beSAndre Guedes return 0; 15697ba8b4beSAndre Guedes } 15707ba8b4beSAndre Guedes 15717dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev) 15727dbfac1dSAndre Guedes { 15737dbfac1dSAndre Guedes BT_DBG("%s", hdev->name); 15747dbfac1dSAndre Guedes 15757dbfac1dSAndre Guedes if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 15767dbfac1dSAndre Guedes return -EALREADY; 15777dbfac1dSAndre Guedes 15787dbfac1dSAndre Guedes if (cancel_delayed_work(&hdev->le_scan_disable)) { 15797dbfac1dSAndre Guedes struct hci_cp_le_set_scan_enable cp; 15807dbfac1dSAndre Guedes 15817dbfac1dSAndre Guedes /* Send HCI command to disable LE Scan */ 15827dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 15837dbfac1dSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 15847dbfac1dSAndre Guedes } 15857dbfac1dSAndre Guedes 15867dbfac1dSAndre Guedes return 0; 15877dbfac1dSAndre Guedes } 15887dbfac1dSAndre Guedes 15897ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 15907ba8b4beSAndre Guedes { 15917ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 15927ba8b4beSAndre Guedes le_scan_disable.work); 15937ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 15947ba8b4beSAndre Guedes 15957ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 15967ba8b4beSAndre Guedes 15977ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 15987ba8b4beSAndre Guedes 15997ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 16007ba8b4beSAndre Guedes } 16017ba8b4beSAndre Guedes 160228b75a89SAndre Guedes static void le_scan_work(struct work_struct *work) 160328b75a89SAndre Guedes { 160428b75a89SAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan); 160528b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 160628b75a89SAndre Guedes 160728b75a89SAndre Guedes BT_DBG("%s", hdev->name); 160828b75a89SAndre Guedes 160904124681SGustavo F. Padovan hci_do_le_scan(hdev, param->type, param->interval, param->window, 161004124681SGustavo F. Padovan param->timeout); 161128b75a89SAndre Guedes } 161228b75a89SAndre Guedes 161328b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, 161428b75a89SAndre Guedes int timeout) 161528b75a89SAndre Guedes { 161628b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 161728b75a89SAndre Guedes 161828b75a89SAndre Guedes BT_DBG("%s", hdev->name); 161928b75a89SAndre Guedes 162028b75a89SAndre Guedes if (work_busy(&hdev->le_scan)) 162128b75a89SAndre Guedes return -EINPROGRESS; 162228b75a89SAndre Guedes 162328b75a89SAndre Guedes param->type = type; 162428b75a89SAndre Guedes param->interval = interval; 162528b75a89SAndre Guedes param->window = window; 162628b75a89SAndre Guedes param->timeout = timeout; 162728b75a89SAndre Guedes 162828b75a89SAndre Guedes queue_work(system_long_wq, &hdev->le_scan); 162928b75a89SAndre Guedes 163028b75a89SAndre Guedes return 0; 163128b75a89SAndre Guedes } 163228b75a89SAndre Guedes 16339be0dab7SDavid Herrmann /* Alloc HCI device */ 16349be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 16359be0dab7SDavid Herrmann { 16369be0dab7SDavid Herrmann struct hci_dev *hdev; 16379be0dab7SDavid Herrmann 16389be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 16399be0dab7SDavid Herrmann if (!hdev) 16409be0dab7SDavid Herrmann return NULL; 16419be0dab7SDavid Herrmann 1642b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 1643b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 1644b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 1645b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 1646b1b813d4SDavid Herrmann 1647b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 1648b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 1649b1b813d4SDavid Herrmann 1650b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 1651b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 1652b1b813d4SDavid Herrmann 1653b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 1654b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 1655b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 1656b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 1657b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 1658b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 16596b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 1660b1b813d4SDavid Herrmann 1661b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 1662b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 1663b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 1664b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 1665b1b813d4SDavid Herrmann INIT_WORK(&hdev->le_scan, le_scan_work); 1666b1b813d4SDavid Herrmann 1667b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 1668b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 1669b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 1670b1b813d4SDavid Herrmann 16719be0dab7SDavid Herrmann skb_queue_head_init(&hdev->driver_init); 1672b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 1673b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 1674b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 1675b1b813d4SDavid Herrmann 1676b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 1677b1b813d4SDavid Herrmann 1678bda4f23aSAndrei Emeltchenko setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); 1679b1b813d4SDavid Herrmann 1680b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 1681b1b813d4SDavid Herrmann discovery_init(hdev); 16829be0dab7SDavid Herrmann 16839be0dab7SDavid Herrmann return hdev; 16849be0dab7SDavid Herrmann } 16859be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 16869be0dab7SDavid Herrmann 16879be0dab7SDavid Herrmann /* Free HCI device */ 16889be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 16899be0dab7SDavid Herrmann { 16909be0dab7SDavid Herrmann skb_queue_purge(&hdev->driver_init); 16919be0dab7SDavid Herrmann 16929be0dab7SDavid Herrmann /* will free via device release */ 16939be0dab7SDavid Herrmann put_device(&hdev->dev); 16949be0dab7SDavid Herrmann } 16959be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 16969be0dab7SDavid Herrmann 16971da177e4SLinus Torvalds /* Register HCI device */ 16981da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 16991da177e4SLinus Torvalds { 1700b1b813d4SDavid Herrmann int id, error; 17011da177e4SLinus Torvalds 1702010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 17031da177e4SLinus Torvalds return -EINVAL; 17041da177e4SLinus Torvalds 170508add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 170608add513SMat Martineau * so the index can be used as the AMP controller ID. 170708add513SMat Martineau */ 17083df92b31SSasha Levin switch (hdev->dev_type) { 17093df92b31SSasha Levin case HCI_BREDR: 17103df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 17111da177e4SLinus Torvalds break; 17123df92b31SSasha Levin case HCI_AMP: 17133df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 17143df92b31SSasha Levin break; 17153df92b31SSasha Levin default: 17163df92b31SSasha Levin return -EINVAL; 17171da177e4SLinus Torvalds } 17181da177e4SLinus Torvalds 17193df92b31SSasha Levin if (id < 0) 17203df92b31SSasha Levin return id; 17213df92b31SSasha Levin 17221da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 17231da177e4SLinus Torvalds hdev->id = id; 17242d8b3a11SAndrei Emeltchenko 17252d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 17262d8b3a11SAndrei Emeltchenko 17273df92b31SSasha Levin write_lock(&hci_dev_list_lock); 17283df92b31SSasha Levin list_add(&hdev->list, &hci_dev_list); 1729f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 17301da177e4SLinus Torvalds 173132845eb1SGustavo F. Padovan hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | 173232845eb1SGustavo F. Padovan WQ_MEM_RECLAIM, 1); 173333ca954dSDavid Herrmann if (!hdev->workqueue) { 173433ca954dSDavid Herrmann error = -ENOMEM; 173533ca954dSDavid Herrmann goto err; 173633ca954dSDavid Herrmann } 1737f48fd9c8SMarcel Holtmann 173833ca954dSDavid Herrmann error = hci_add_sysfs(hdev); 173933ca954dSDavid Herrmann if (error < 0) 174033ca954dSDavid Herrmann goto err_wqueue; 17411da177e4SLinus Torvalds 1742611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 1743a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 1744a8c5fb1aSGustavo Padovan hdev); 1745611b30f7SMarcel Holtmann if (hdev->rfkill) { 1746611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 1747611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1748611b30f7SMarcel Holtmann hdev->rfkill = NULL; 1749611b30f7SMarcel Holtmann } 1750611b30f7SMarcel Holtmann } 1751611b30f7SMarcel Holtmann 1752a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 1753ce2be9acSAndrei Emeltchenko 1754ce2be9acSAndrei Emeltchenko if (hdev->dev_type != HCI_AMP) 1755ce2be9acSAndrei Emeltchenko set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 1756ce2be9acSAndrei Emeltchenko 17577f971041SGustavo F. Padovan schedule_work(&hdev->power_on); 1758ab81cbf9SJohan Hedberg 17591da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 1760dc946bd8SDavid Herrmann hci_dev_hold(hdev); 17611da177e4SLinus Torvalds 17621da177e4SLinus Torvalds return id; 1763f48fd9c8SMarcel Holtmann 176433ca954dSDavid Herrmann err_wqueue: 176533ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 176633ca954dSDavid Herrmann err: 17673df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 1768f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 1769f48fd9c8SMarcel Holtmann list_del(&hdev->list); 1770f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 1771f48fd9c8SMarcel Holtmann 177233ca954dSDavid Herrmann return error; 17731da177e4SLinus Torvalds } 17741da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 17751da177e4SLinus Torvalds 17761da177e4SLinus Torvalds /* Unregister HCI device */ 177759735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 17781da177e4SLinus Torvalds { 17793df92b31SSasha Levin int i, id; 1780ef222013SMarcel Holtmann 1781c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 17821da177e4SLinus Torvalds 178394324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 178494324962SJohan Hovold 17853df92b31SSasha Levin id = hdev->id; 17863df92b31SSasha Levin 1787f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 17881da177e4SLinus Torvalds list_del(&hdev->list); 1789f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 17901da177e4SLinus Torvalds 17911da177e4SLinus Torvalds hci_dev_do_close(hdev); 17921da177e4SLinus Torvalds 1793cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1794ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 1795ef222013SMarcel Holtmann 1796ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 1797a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 179809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1799744cf19eSJohan Hedberg mgmt_index_removed(hdev); 180009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 180156e5cb86SJohan Hedberg } 1802ab81cbf9SJohan Hedberg 18032e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 18042e58ef3eSJohan Hedberg * pending list */ 18052e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 18062e58ef3eSJohan Hedberg 18071da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 18081da177e4SLinus Torvalds 1809611b30f7SMarcel Holtmann if (hdev->rfkill) { 1810611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 1811611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1812611b30f7SMarcel Holtmann } 1813611b30f7SMarcel Holtmann 1814ce242970SDavid Herrmann hci_del_sysfs(hdev); 1815147e2d59SDave Young 1816f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 1817f48fd9c8SMarcel Holtmann 181809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1819e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 18202aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 182155ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 1822b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 18232763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 182409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 1825e2e0cacbSJohan Hedberg 1826dc946bd8SDavid Herrmann hci_dev_put(hdev); 18273df92b31SSasha Levin 18283df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 18291da177e4SLinus Torvalds } 18301da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 18311da177e4SLinus Torvalds 18321da177e4SLinus Torvalds /* Suspend HCI device */ 18331da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 18341da177e4SLinus Torvalds { 18351da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 18361da177e4SLinus Torvalds return 0; 18371da177e4SLinus Torvalds } 18381da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 18391da177e4SLinus Torvalds 18401da177e4SLinus Torvalds /* Resume HCI device */ 18411da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 18421da177e4SLinus Torvalds { 18431da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 18441da177e4SLinus Torvalds return 0; 18451da177e4SLinus Torvalds } 18461da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 18471da177e4SLinus Torvalds 184876bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 184976bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb) 185076bca880SMarcel Holtmann { 185176bca880SMarcel Holtmann struct hci_dev *hdev = (struct hci_dev *) skb->dev; 185276bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 185376bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 185476bca880SMarcel Holtmann kfree_skb(skb); 185576bca880SMarcel Holtmann return -ENXIO; 185676bca880SMarcel Holtmann } 185776bca880SMarcel Holtmann 1858*d82603c6SJorrit Schippers /* Incoming skb */ 185976bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 186076bca880SMarcel Holtmann 186176bca880SMarcel Holtmann /* Time stamp */ 186276bca880SMarcel Holtmann __net_timestamp(skb); 186376bca880SMarcel Holtmann 186476bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 1865b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 1866c78ae283SMarcel Holtmann 186776bca880SMarcel Holtmann return 0; 186876bca880SMarcel Holtmann } 186976bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 187076bca880SMarcel Holtmann 187133e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 18721e429f38SGustavo F. Padovan int count, __u8 index) 187333e882a5SSuraj Sumangala { 187433e882a5SSuraj Sumangala int len = 0; 187533e882a5SSuraj Sumangala int hlen = 0; 187633e882a5SSuraj Sumangala int remain = count; 187733e882a5SSuraj Sumangala struct sk_buff *skb; 187833e882a5SSuraj Sumangala struct bt_skb_cb *scb; 187933e882a5SSuraj Sumangala 188033e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 188133e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 188233e882a5SSuraj Sumangala return -EILSEQ; 188333e882a5SSuraj Sumangala 188433e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 188533e882a5SSuraj Sumangala 188633e882a5SSuraj Sumangala if (!skb) { 188733e882a5SSuraj Sumangala switch (type) { 188833e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 188933e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 189033e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 189133e882a5SSuraj Sumangala break; 189233e882a5SSuraj Sumangala case HCI_EVENT_PKT: 189333e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 189433e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 189533e882a5SSuraj Sumangala break; 189633e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 189733e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 189833e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 189933e882a5SSuraj Sumangala break; 190033e882a5SSuraj Sumangala } 190133e882a5SSuraj Sumangala 19021e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 190333e882a5SSuraj Sumangala if (!skb) 190433e882a5SSuraj Sumangala return -ENOMEM; 190533e882a5SSuraj Sumangala 190633e882a5SSuraj Sumangala scb = (void *) skb->cb; 190733e882a5SSuraj Sumangala scb->expect = hlen; 190833e882a5SSuraj Sumangala scb->pkt_type = type; 190933e882a5SSuraj Sumangala 191033e882a5SSuraj Sumangala skb->dev = (void *) hdev; 191133e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 191233e882a5SSuraj Sumangala } 191333e882a5SSuraj Sumangala 191433e882a5SSuraj Sumangala while (count) { 191533e882a5SSuraj Sumangala scb = (void *) skb->cb; 191689bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 191733e882a5SSuraj Sumangala 191833e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 191933e882a5SSuraj Sumangala 192033e882a5SSuraj Sumangala count -= len; 192133e882a5SSuraj Sumangala data += len; 192233e882a5SSuraj Sumangala scb->expect -= len; 192333e882a5SSuraj Sumangala remain = count; 192433e882a5SSuraj Sumangala 192533e882a5SSuraj Sumangala switch (type) { 192633e882a5SSuraj Sumangala case HCI_EVENT_PKT: 192733e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 192833e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 192933e882a5SSuraj Sumangala scb->expect = h->plen; 193033e882a5SSuraj Sumangala 193133e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 193233e882a5SSuraj Sumangala kfree_skb(skb); 193333e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 193433e882a5SSuraj Sumangala return -ENOMEM; 193533e882a5SSuraj Sumangala } 193633e882a5SSuraj Sumangala } 193733e882a5SSuraj Sumangala break; 193833e882a5SSuraj Sumangala 193933e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 194033e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 194133e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 194233e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 194333e882a5SSuraj Sumangala 194433e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 194533e882a5SSuraj Sumangala kfree_skb(skb); 194633e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 194733e882a5SSuraj Sumangala return -ENOMEM; 194833e882a5SSuraj Sumangala } 194933e882a5SSuraj Sumangala } 195033e882a5SSuraj Sumangala break; 195133e882a5SSuraj Sumangala 195233e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 195333e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 195433e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 195533e882a5SSuraj Sumangala scb->expect = h->dlen; 195633e882a5SSuraj Sumangala 195733e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 195833e882a5SSuraj Sumangala kfree_skb(skb); 195933e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 196033e882a5SSuraj Sumangala return -ENOMEM; 196133e882a5SSuraj Sumangala } 196233e882a5SSuraj Sumangala } 196333e882a5SSuraj Sumangala break; 196433e882a5SSuraj Sumangala } 196533e882a5SSuraj Sumangala 196633e882a5SSuraj Sumangala if (scb->expect == 0) { 196733e882a5SSuraj Sumangala /* Complete frame */ 196833e882a5SSuraj Sumangala 196933e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 197033e882a5SSuraj Sumangala hci_recv_frame(skb); 197133e882a5SSuraj Sumangala 197233e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 197333e882a5SSuraj Sumangala return remain; 197433e882a5SSuraj Sumangala } 197533e882a5SSuraj Sumangala } 197633e882a5SSuraj Sumangala 197733e882a5SSuraj Sumangala return remain; 197833e882a5SSuraj Sumangala } 197933e882a5SSuraj Sumangala 1980ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 1981ef222013SMarcel Holtmann { 1982f39a3c06SSuraj Sumangala int rem = 0; 1983f39a3c06SSuraj Sumangala 1984ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 1985ef222013SMarcel Holtmann return -EILSEQ; 1986ef222013SMarcel Holtmann 1987da5f6c37SGustavo F. Padovan while (count) { 19881e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 1989f39a3c06SSuraj Sumangala if (rem < 0) 1990f39a3c06SSuraj Sumangala return rem; 1991ef222013SMarcel Holtmann 1992f39a3c06SSuraj Sumangala data += (count - rem); 1993f39a3c06SSuraj Sumangala count = rem; 1994f81c6224SJoe Perches } 1995ef222013SMarcel Holtmann 1996f39a3c06SSuraj Sumangala return rem; 1997ef222013SMarcel Holtmann } 1998ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 1999ef222013SMarcel Holtmann 200099811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 200199811510SSuraj Sumangala 200299811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 200399811510SSuraj Sumangala { 200499811510SSuraj Sumangala int type; 200599811510SSuraj Sumangala int rem = 0; 200699811510SSuraj Sumangala 2007da5f6c37SGustavo F. Padovan while (count) { 200899811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 200999811510SSuraj Sumangala 201099811510SSuraj Sumangala if (!skb) { 201199811510SSuraj Sumangala struct { char type; } *pkt; 201299811510SSuraj Sumangala 201399811510SSuraj Sumangala /* Start of the frame */ 201499811510SSuraj Sumangala pkt = data; 201599811510SSuraj Sumangala type = pkt->type; 201699811510SSuraj Sumangala 201799811510SSuraj Sumangala data++; 201899811510SSuraj Sumangala count--; 201999811510SSuraj Sumangala } else 202099811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 202199811510SSuraj Sumangala 20221e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 20231e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 202499811510SSuraj Sumangala if (rem < 0) 202599811510SSuraj Sumangala return rem; 202699811510SSuraj Sumangala 202799811510SSuraj Sumangala data += (count - rem); 202899811510SSuraj Sumangala count = rem; 2029f81c6224SJoe Perches } 203099811510SSuraj Sumangala 203199811510SSuraj Sumangala return rem; 203299811510SSuraj Sumangala } 203399811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 203499811510SSuraj Sumangala 20351da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 20361da177e4SLinus Torvalds 20371da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 20381da177e4SLinus Torvalds { 20391da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 20401da177e4SLinus Torvalds 2041f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 20421da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 2043f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 20441da177e4SLinus Torvalds 20451da177e4SLinus Torvalds return 0; 20461da177e4SLinus Torvalds } 20471da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 20481da177e4SLinus Torvalds 20491da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 20501da177e4SLinus Torvalds { 20511da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 20521da177e4SLinus Torvalds 2053f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 20541da177e4SLinus Torvalds list_del(&cb->list); 2055f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 20561da177e4SLinus Torvalds 20571da177e4SLinus Torvalds return 0; 20581da177e4SLinus Torvalds } 20591da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 20601da177e4SLinus Torvalds 20611da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb) 20621da177e4SLinus Torvalds { 20631da177e4SLinus Torvalds struct hci_dev *hdev = (struct hci_dev *) skb->dev; 20641da177e4SLinus Torvalds 20651da177e4SLinus Torvalds if (!hdev) { 20661da177e4SLinus Torvalds kfree_skb(skb); 20671da177e4SLinus Torvalds return -ENODEV; 20681da177e4SLinus Torvalds } 20691da177e4SLinus Torvalds 20700d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 20711da177e4SLinus Torvalds 20721da177e4SLinus Torvalds /* Time stamp */ 2073a61bbcf2SPatrick McHardy __net_timestamp(skb); 20741da177e4SLinus Torvalds 2075cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2076cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2077cd82e61cSMarcel Holtmann 2078cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 2079cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 2080470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 20811da177e4SLinus Torvalds } 20821da177e4SLinus Torvalds 20831da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 20841da177e4SLinus Torvalds skb_orphan(skb); 20851da177e4SLinus Torvalds 20861da177e4SLinus Torvalds return hdev->send(skb); 20871da177e4SLinus Torvalds } 20881da177e4SLinus Torvalds 20891da177e4SLinus Torvalds /* Send HCI command */ 2090a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) 20911da177e4SLinus Torvalds { 20921da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 20931da177e4SLinus Torvalds struct hci_command_hdr *hdr; 20941da177e4SLinus Torvalds struct sk_buff *skb; 20951da177e4SLinus Torvalds 2096f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 20971da177e4SLinus Torvalds 20981da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 20991da177e4SLinus Torvalds if (!skb) { 2100ef222013SMarcel Holtmann BT_ERR("%s no memory for command", hdev->name); 21011da177e4SLinus Torvalds return -ENOMEM; 21021da177e4SLinus Torvalds } 21031da177e4SLinus Torvalds 21041da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 2105a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 21061da177e4SLinus Torvalds hdr->plen = plen; 21071da177e4SLinus Torvalds 21081da177e4SLinus Torvalds if (plen) 21091da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 21101da177e4SLinus Torvalds 21111da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 21121da177e4SLinus Torvalds 21130d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 21141da177e4SLinus Torvalds skb->dev = (void *) hdev; 2115c78ae283SMarcel Holtmann 2116a5040efaSJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags)) 2117a5040efaSJohan Hedberg hdev->init_last_cmd = opcode; 2118a5040efaSJohan Hedberg 21191da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 2120c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 21211da177e4SLinus Torvalds 21221da177e4SLinus Torvalds return 0; 21231da177e4SLinus Torvalds } 21241da177e4SLinus Torvalds 21251da177e4SLinus Torvalds /* Get data from the previously sent command */ 2126a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 21271da177e4SLinus Torvalds { 21281da177e4SLinus Torvalds struct hci_command_hdr *hdr; 21291da177e4SLinus Torvalds 21301da177e4SLinus Torvalds if (!hdev->sent_cmd) 21311da177e4SLinus Torvalds return NULL; 21321da177e4SLinus Torvalds 21331da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 21341da177e4SLinus Torvalds 2135a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 21361da177e4SLinus Torvalds return NULL; 21371da177e4SLinus Torvalds 2138f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 21391da177e4SLinus Torvalds 21401da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 21411da177e4SLinus Torvalds } 21421da177e4SLinus Torvalds 21431da177e4SLinus Torvalds /* Send ACL data */ 21441da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 21451da177e4SLinus Torvalds { 21461da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 21471da177e4SLinus Torvalds int len = skb->len; 21481da177e4SLinus Torvalds 2149badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 2150badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 21519c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 2152aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 2153aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 21541da177e4SLinus Torvalds } 21551da177e4SLinus Torvalds 215673d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, 215773d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 21581da177e4SLinus Torvalds { 21591da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 21601da177e4SLinus Torvalds struct sk_buff *list; 21611da177e4SLinus Torvalds 2162087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 2163087bfd99SGustavo Padovan skb->data_len = 0; 2164087bfd99SGustavo Padovan 2165087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2166087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 2167087bfd99SGustavo Padovan 216870f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 216970f23020SAndrei Emeltchenko if (!list) { 21701da177e4SLinus Torvalds /* Non fragmented */ 21711da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 21721da177e4SLinus Torvalds 217373d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 21741da177e4SLinus Torvalds } else { 21751da177e4SLinus Torvalds /* Fragmented */ 21761da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 21771da177e4SLinus Torvalds 21781da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 21791da177e4SLinus Torvalds 21801da177e4SLinus Torvalds /* Queue all fragments atomically */ 2181af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 21821da177e4SLinus Torvalds 218373d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 2184e702112fSAndrei Emeltchenko 2185e702112fSAndrei Emeltchenko flags &= ~ACL_START; 2186e702112fSAndrei Emeltchenko flags |= ACL_CONT; 21871da177e4SLinus Torvalds do { 21881da177e4SLinus Torvalds skb = list; list = list->next; 21891da177e4SLinus Torvalds 21901da177e4SLinus Torvalds skb->dev = (void *) hdev; 21910d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2192e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 21931da177e4SLinus Torvalds 21941da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 21951da177e4SLinus Torvalds 219673d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 21971da177e4SLinus Torvalds } while (list); 21981da177e4SLinus Torvalds 2199af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 22001da177e4SLinus Torvalds } 220173d80debSLuiz Augusto von Dentz } 220273d80debSLuiz Augusto von Dentz 220373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 220473d80debSLuiz Augusto von Dentz { 220573d80debSLuiz Augusto von Dentz struct hci_conn *conn = chan->conn; 220673d80debSLuiz Augusto von Dentz struct hci_dev *hdev = conn->hdev; 220773d80debSLuiz Augusto von Dentz 2208f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 220973d80debSLuiz Augusto von Dentz 221073d80debSLuiz Augusto von Dentz skb->dev = (void *) hdev; 221173d80debSLuiz Augusto von Dentz 221273d80debSLuiz Augusto von Dentz hci_queue_acl(conn, &chan->data_q, skb, flags); 22131da177e4SLinus Torvalds 22143eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 22151da177e4SLinus Torvalds } 22161da177e4SLinus Torvalds 22171da177e4SLinus Torvalds /* Send SCO data */ 22180d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 22191da177e4SLinus Torvalds { 22201da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 22211da177e4SLinus Torvalds struct hci_sco_hdr hdr; 22221da177e4SLinus Torvalds 22231da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 22241da177e4SLinus Torvalds 2225aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 22261da177e4SLinus Torvalds hdr.dlen = skb->len; 22271da177e4SLinus Torvalds 2228badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 2229badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 22309c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 22311da177e4SLinus Torvalds 22321da177e4SLinus Torvalds skb->dev = (void *) hdev; 22330d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 2234c78ae283SMarcel Holtmann 22351da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 22363eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 22371da177e4SLinus Torvalds } 22381da177e4SLinus Torvalds 22391da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 22401da177e4SLinus Torvalds 22411da177e4SLinus Torvalds /* HCI Connection scheduler */ 22426039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 2243a8c5fb1aSGustavo Padovan int *quote) 22441da177e4SLinus Torvalds { 22451da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 22468035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 2247abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 22481da177e4SLinus Torvalds 22491da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 22501da177e4SLinus Torvalds * added and removed with TX task disabled. */ 2251bf4c6325SGustavo F. Padovan 2252bf4c6325SGustavo F. Padovan rcu_read_lock(); 2253bf4c6325SGustavo F. Padovan 2254bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2255769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 22561da177e4SLinus Torvalds continue; 2257769be974SMarcel Holtmann 2258769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 2259769be974SMarcel Holtmann continue; 2260769be974SMarcel Holtmann 22611da177e4SLinus Torvalds num++; 22621da177e4SLinus Torvalds 22631da177e4SLinus Torvalds if (c->sent < min) { 22641da177e4SLinus Torvalds min = c->sent; 22651da177e4SLinus Torvalds conn = c; 22661da177e4SLinus Torvalds } 226752087a79SLuiz Augusto von Dentz 226852087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 226952087a79SLuiz Augusto von Dentz break; 22701da177e4SLinus Torvalds } 22711da177e4SLinus Torvalds 2272bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2273bf4c6325SGustavo F. Padovan 22741da177e4SLinus Torvalds if (conn) { 22756ed58ec5SVille Tervo int cnt, q; 22766ed58ec5SVille Tervo 22776ed58ec5SVille Tervo switch (conn->type) { 22786ed58ec5SVille Tervo case ACL_LINK: 22796ed58ec5SVille Tervo cnt = hdev->acl_cnt; 22806ed58ec5SVille Tervo break; 22816ed58ec5SVille Tervo case SCO_LINK: 22826ed58ec5SVille Tervo case ESCO_LINK: 22836ed58ec5SVille Tervo cnt = hdev->sco_cnt; 22846ed58ec5SVille Tervo break; 22856ed58ec5SVille Tervo case LE_LINK: 22866ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 22876ed58ec5SVille Tervo break; 22886ed58ec5SVille Tervo default: 22896ed58ec5SVille Tervo cnt = 0; 22906ed58ec5SVille Tervo BT_ERR("Unknown link type"); 22916ed58ec5SVille Tervo } 22926ed58ec5SVille Tervo 22936ed58ec5SVille Tervo q = cnt / num; 22941da177e4SLinus Torvalds *quote = q ? q : 1; 22951da177e4SLinus Torvalds } else 22961da177e4SLinus Torvalds *quote = 0; 22971da177e4SLinus Torvalds 22981da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 22991da177e4SLinus Torvalds return conn; 23001da177e4SLinus Torvalds } 23011da177e4SLinus Torvalds 23026039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 23031da177e4SLinus Torvalds { 23041da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 23051da177e4SLinus Torvalds struct hci_conn *c; 23061da177e4SLinus Torvalds 2307bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 23081da177e4SLinus Torvalds 2309bf4c6325SGustavo F. Padovan rcu_read_lock(); 2310bf4c6325SGustavo F. Padovan 23111da177e4SLinus Torvalds /* Kill stalled connections */ 2312bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2313bae1f5d9SVille Tervo if (c->type == type && c->sent) { 2314bae1f5d9SVille Tervo BT_ERR("%s killing stalled connection %s", 23151da177e4SLinus Torvalds hdev->name, batostr(&c->dst)); 23167490c6c2SAndrei Emeltchenko hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM); 23171da177e4SLinus Torvalds } 23181da177e4SLinus Torvalds } 2319bf4c6325SGustavo F. Padovan 2320bf4c6325SGustavo F. Padovan rcu_read_unlock(); 23211da177e4SLinus Torvalds } 23221da177e4SLinus Torvalds 23236039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 232473d80debSLuiz Augusto von Dentz int *quote) 232573d80debSLuiz Augusto von Dentz { 232673d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 232773d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 2328abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 232973d80debSLuiz Augusto von Dentz struct hci_conn *conn; 233073d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 233173d80debSLuiz Augusto von Dentz 233273d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 233373d80debSLuiz Augusto von Dentz 2334bf4c6325SGustavo F. Padovan rcu_read_lock(); 2335bf4c6325SGustavo F. Padovan 2336bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 233773d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 233873d80debSLuiz Augusto von Dentz 233973d80debSLuiz Augusto von Dentz if (conn->type != type) 234073d80debSLuiz Augusto von Dentz continue; 234173d80debSLuiz Augusto von Dentz 234273d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 234373d80debSLuiz Augusto von Dentz continue; 234473d80debSLuiz Augusto von Dentz 234573d80debSLuiz Augusto von Dentz conn_num++; 234673d80debSLuiz Augusto von Dentz 23478192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 234873d80debSLuiz Augusto von Dentz struct sk_buff *skb; 234973d80debSLuiz Augusto von Dentz 235073d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 235173d80debSLuiz Augusto von Dentz continue; 235273d80debSLuiz Augusto von Dentz 235373d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 235473d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 235573d80debSLuiz Augusto von Dentz continue; 235673d80debSLuiz Augusto von Dentz 235773d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 235873d80debSLuiz Augusto von Dentz num = 0; 235973d80debSLuiz Augusto von Dentz min = ~0; 236073d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 236173d80debSLuiz Augusto von Dentz } 236273d80debSLuiz Augusto von Dentz 236373d80debSLuiz Augusto von Dentz num++; 236473d80debSLuiz Augusto von Dentz 236573d80debSLuiz Augusto von Dentz if (conn->sent < min) { 236673d80debSLuiz Augusto von Dentz min = conn->sent; 236773d80debSLuiz Augusto von Dentz chan = tmp; 236873d80debSLuiz Augusto von Dentz } 236973d80debSLuiz Augusto von Dentz } 237073d80debSLuiz Augusto von Dentz 237173d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 237273d80debSLuiz Augusto von Dentz break; 237373d80debSLuiz Augusto von Dentz } 237473d80debSLuiz Augusto von Dentz 2375bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2376bf4c6325SGustavo F. Padovan 237773d80debSLuiz Augusto von Dentz if (!chan) 237873d80debSLuiz Augusto von Dentz return NULL; 237973d80debSLuiz Augusto von Dentz 238073d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 238173d80debSLuiz Augusto von Dentz case ACL_LINK: 238273d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 238373d80debSLuiz Augusto von Dentz break; 238473d80debSLuiz Augusto von Dentz case SCO_LINK: 238573d80debSLuiz Augusto von Dentz case ESCO_LINK: 238673d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 238773d80debSLuiz Augusto von Dentz break; 238873d80debSLuiz Augusto von Dentz case LE_LINK: 238973d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 239073d80debSLuiz Augusto von Dentz break; 239173d80debSLuiz Augusto von Dentz default: 239273d80debSLuiz Augusto von Dentz cnt = 0; 239373d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 239473d80debSLuiz Augusto von Dentz } 239573d80debSLuiz Augusto von Dentz 239673d80debSLuiz Augusto von Dentz q = cnt / num; 239773d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 239873d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 239973d80debSLuiz Augusto von Dentz return chan; 240073d80debSLuiz Augusto von Dentz } 240173d80debSLuiz Augusto von Dentz 240202b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 240302b20f0bSLuiz Augusto von Dentz { 240402b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 240502b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 240602b20f0bSLuiz Augusto von Dentz int num = 0; 240702b20f0bSLuiz Augusto von Dentz 240802b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 240902b20f0bSLuiz Augusto von Dentz 2410bf4c6325SGustavo F. Padovan rcu_read_lock(); 2411bf4c6325SGustavo F. Padovan 2412bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 241302b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 241402b20f0bSLuiz Augusto von Dentz 241502b20f0bSLuiz Augusto von Dentz if (conn->type != type) 241602b20f0bSLuiz Augusto von Dentz continue; 241702b20f0bSLuiz Augusto von Dentz 241802b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 241902b20f0bSLuiz Augusto von Dentz continue; 242002b20f0bSLuiz Augusto von Dentz 242102b20f0bSLuiz Augusto von Dentz num++; 242202b20f0bSLuiz Augusto von Dentz 24238192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 242402b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 242502b20f0bSLuiz Augusto von Dentz 242602b20f0bSLuiz Augusto von Dentz if (chan->sent) { 242702b20f0bSLuiz Augusto von Dentz chan->sent = 0; 242802b20f0bSLuiz Augusto von Dentz continue; 242902b20f0bSLuiz Augusto von Dentz } 243002b20f0bSLuiz Augusto von Dentz 243102b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 243202b20f0bSLuiz Augusto von Dentz continue; 243302b20f0bSLuiz Augusto von Dentz 243402b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 243502b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 243602b20f0bSLuiz Augusto von Dentz continue; 243702b20f0bSLuiz Augusto von Dentz 243802b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 243902b20f0bSLuiz Augusto von Dentz 244002b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 244102b20f0bSLuiz Augusto von Dentz skb->priority); 244202b20f0bSLuiz Augusto von Dentz } 244302b20f0bSLuiz Augusto von Dentz 244402b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 244502b20f0bSLuiz Augusto von Dentz break; 244602b20f0bSLuiz Augusto von Dentz } 2447bf4c6325SGustavo F. Padovan 2448bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2449bf4c6325SGustavo F. Padovan 245002b20f0bSLuiz Augusto von Dentz } 245102b20f0bSLuiz Augusto von Dentz 2452b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 2453b71d385aSAndrei Emeltchenko { 2454b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 2455b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 2456b71d385aSAndrei Emeltchenko } 2457b71d385aSAndrei Emeltchenko 24586039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 24591da177e4SLinus Torvalds { 24601da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 24611da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 24621da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 246363d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 24645f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 2465bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 24661da177e4SLinus Torvalds } 246763d2bc1bSAndrei Emeltchenko } 24681da177e4SLinus Torvalds 24696039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 247063d2bc1bSAndrei Emeltchenko { 247163d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 247263d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 247363d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 247463d2bc1bSAndrei Emeltchenko int quote; 247563d2bc1bSAndrei Emeltchenko 247663d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 247704837f64SMarcel Holtmann 247873d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 247973d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2480ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2481ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 248273d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 248373d80debSLuiz Augusto von Dentz skb->len, skb->priority); 248473d80debSLuiz Augusto von Dentz 2485ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2486ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2487ec1cce24SLuiz Augusto von Dentz break; 2488ec1cce24SLuiz Augusto von Dentz 2489ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2490ec1cce24SLuiz Augusto von Dentz 249173d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 249273d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 249304837f64SMarcel Holtmann 24941da177e4SLinus Torvalds hci_send_frame(skb); 24951da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 24961da177e4SLinus Torvalds 24971da177e4SLinus Torvalds hdev->acl_cnt--; 249873d80debSLuiz Augusto von Dentz chan->sent++; 249973d80debSLuiz Augusto von Dentz chan->conn->sent++; 25001da177e4SLinus Torvalds } 25011da177e4SLinus Torvalds } 250202b20f0bSLuiz Augusto von Dentz 250302b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 250402b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 25051da177e4SLinus Torvalds } 25061da177e4SLinus Torvalds 25076039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 2508b71d385aSAndrei Emeltchenko { 250963d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 2510b71d385aSAndrei Emeltchenko struct hci_chan *chan; 2511b71d385aSAndrei Emeltchenko struct sk_buff *skb; 2512b71d385aSAndrei Emeltchenko int quote; 2513b71d385aSAndrei Emeltchenko 251463d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 2515b71d385aSAndrei Emeltchenko 2516b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 2517b71d385aSAndrei Emeltchenko (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2518b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 2519b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 2520b71d385aSAndrei Emeltchenko int blocks; 2521b71d385aSAndrei Emeltchenko 2522b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 2523b71d385aSAndrei Emeltchenko skb->len, skb->priority); 2524b71d385aSAndrei Emeltchenko 2525b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 2526b71d385aSAndrei Emeltchenko if (skb->priority < priority) 2527b71d385aSAndrei Emeltchenko break; 2528b71d385aSAndrei Emeltchenko 2529b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 2530b71d385aSAndrei Emeltchenko 2531b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 2532b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 2533b71d385aSAndrei Emeltchenko return; 2534b71d385aSAndrei Emeltchenko 2535b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 2536b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 2537b71d385aSAndrei Emeltchenko 2538b71d385aSAndrei Emeltchenko hci_send_frame(skb); 2539b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 2540b71d385aSAndrei Emeltchenko 2541b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 2542b71d385aSAndrei Emeltchenko quote -= blocks; 2543b71d385aSAndrei Emeltchenko 2544b71d385aSAndrei Emeltchenko chan->sent += blocks; 2545b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 2546b71d385aSAndrei Emeltchenko } 2547b71d385aSAndrei Emeltchenko } 2548b71d385aSAndrei Emeltchenko 2549b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 2550b71d385aSAndrei Emeltchenko hci_prio_recalculate(hdev, ACL_LINK); 2551b71d385aSAndrei Emeltchenko } 2552b71d385aSAndrei Emeltchenko 25536039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 2554b71d385aSAndrei Emeltchenko { 2555b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 2556b71d385aSAndrei Emeltchenko 2557b71d385aSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK)) 2558b71d385aSAndrei Emeltchenko return; 2559b71d385aSAndrei Emeltchenko 2560b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 2561b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 2562b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 2563b71d385aSAndrei Emeltchenko break; 2564b71d385aSAndrei Emeltchenko 2565b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 2566b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 2567b71d385aSAndrei Emeltchenko break; 2568b71d385aSAndrei Emeltchenko } 2569b71d385aSAndrei Emeltchenko } 2570b71d385aSAndrei Emeltchenko 25711da177e4SLinus Torvalds /* Schedule SCO */ 25726039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 25731da177e4SLinus Torvalds { 25741da177e4SLinus Torvalds struct hci_conn *conn; 25751da177e4SLinus Torvalds struct sk_buff *skb; 25761da177e4SLinus Torvalds int quote; 25771da177e4SLinus Torvalds 25781da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 25791da177e4SLinus Torvalds 258052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 258152087a79SLuiz Augusto von Dentz return; 258252087a79SLuiz Augusto von Dentz 25831da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 25841da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 25851da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 25861da177e4SLinus Torvalds hci_send_frame(skb); 25871da177e4SLinus Torvalds 25881da177e4SLinus Torvalds conn->sent++; 25891da177e4SLinus Torvalds if (conn->sent == ~0) 25901da177e4SLinus Torvalds conn->sent = 0; 25911da177e4SLinus Torvalds } 25921da177e4SLinus Torvalds } 25931da177e4SLinus Torvalds } 25941da177e4SLinus Torvalds 25956039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 2596b6a0dc82SMarcel Holtmann { 2597b6a0dc82SMarcel Holtmann struct hci_conn *conn; 2598b6a0dc82SMarcel Holtmann struct sk_buff *skb; 2599b6a0dc82SMarcel Holtmann int quote; 2600b6a0dc82SMarcel Holtmann 2601b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 2602b6a0dc82SMarcel Holtmann 260352087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 260452087a79SLuiz Augusto von Dentz return; 260552087a79SLuiz Augusto von Dentz 26068fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 26078fc9ced3SGustavo Padovan "e))) { 2608b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 2609b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 2610b6a0dc82SMarcel Holtmann hci_send_frame(skb); 2611b6a0dc82SMarcel Holtmann 2612b6a0dc82SMarcel Holtmann conn->sent++; 2613b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 2614b6a0dc82SMarcel Holtmann conn->sent = 0; 2615b6a0dc82SMarcel Holtmann } 2616b6a0dc82SMarcel Holtmann } 2617b6a0dc82SMarcel Holtmann } 2618b6a0dc82SMarcel Holtmann 26196039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 26206ed58ec5SVille Tervo { 262173d80debSLuiz Augusto von Dentz struct hci_chan *chan; 26226ed58ec5SVille Tervo struct sk_buff *skb; 262302b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 26246ed58ec5SVille Tervo 26256ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 26266ed58ec5SVille Tervo 262752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 262852087a79SLuiz Augusto von Dentz return; 262952087a79SLuiz Augusto von Dentz 26306ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 26316ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 26326ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 2633bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 26346ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 2635bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 26366ed58ec5SVille Tervo } 26376ed58ec5SVille Tervo 26386ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 263902b20f0bSLuiz Augusto von Dentz tmp = cnt; 264073d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 2641ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2642ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 264373d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 264473d80debSLuiz Augusto von Dentz skb->len, skb->priority); 26456ed58ec5SVille Tervo 2646ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2647ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2648ec1cce24SLuiz Augusto von Dentz break; 2649ec1cce24SLuiz Augusto von Dentz 2650ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2651ec1cce24SLuiz Augusto von Dentz 26526ed58ec5SVille Tervo hci_send_frame(skb); 26536ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 26546ed58ec5SVille Tervo 26556ed58ec5SVille Tervo cnt--; 265673d80debSLuiz Augusto von Dentz chan->sent++; 265773d80debSLuiz Augusto von Dentz chan->conn->sent++; 26586ed58ec5SVille Tervo } 26596ed58ec5SVille Tervo } 266073d80debSLuiz Augusto von Dentz 26616ed58ec5SVille Tervo if (hdev->le_pkts) 26626ed58ec5SVille Tervo hdev->le_cnt = cnt; 26636ed58ec5SVille Tervo else 26646ed58ec5SVille Tervo hdev->acl_cnt = cnt; 266502b20f0bSLuiz Augusto von Dentz 266602b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 266702b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 26686ed58ec5SVille Tervo } 26696ed58ec5SVille Tervo 26703eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 26711da177e4SLinus Torvalds { 26723eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 26731da177e4SLinus Torvalds struct sk_buff *skb; 26741da177e4SLinus Torvalds 26756ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 26766ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 26771da177e4SLinus Torvalds 26781da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 26791da177e4SLinus Torvalds 26801da177e4SLinus Torvalds hci_sched_acl(hdev); 26811da177e4SLinus Torvalds 26821da177e4SLinus Torvalds hci_sched_sco(hdev); 26831da177e4SLinus Torvalds 2684b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 2685b6a0dc82SMarcel Holtmann 26866ed58ec5SVille Tervo hci_sched_le(hdev); 26876ed58ec5SVille Tervo 26881da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 26891da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 26901da177e4SLinus Torvalds hci_send_frame(skb); 26911da177e4SLinus Torvalds } 26921da177e4SLinus Torvalds 269325985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 26941da177e4SLinus Torvalds 26951da177e4SLinus Torvalds /* ACL data packet */ 26966039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 26971da177e4SLinus Torvalds { 26981da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 26991da177e4SLinus Torvalds struct hci_conn *conn; 27001da177e4SLinus Torvalds __u16 handle, flags; 27011da177e4SLinus Torvalds 27021da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 27031da177e4SLinus Torvalds 27041da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 27051da177e4SLinus Torvalds flags = hci_flags(handle); 27061da177e4SLinus Torvalds handle = hci_handle(handle); 27071da177e4SLinus Torvalds 2708f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 2709a8c5fb1aSGustavo Padovan handle, flags); 27101da177e4SLinus Torvalds 27111da177e4SLinus Torvalds hdev->stat.acl_rx++; 27121da177e4SLinus Torvalds 27131da177e4SLinus Torvalds hci_dev_lock(hdev); 27141da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 27151da177e4SLinus Torvalds hci_dev_unlock(hdev); 27161da177e4SLinus Torvalds 27171da177e4SLinus Torvalds if (conn) { 271865983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 271904837f64SMarcel Holtmann 2720671267bfSJohan Hedberg hci_dev_lock(hdev); 2721671267bfSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags) && 2722671267bfSJohan Hedberg !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 2723671267bfSJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 2724671267bfSJohan Hedberg conn->dst_type, 0, NULL, 0, 2725671267bfSJohan Hedberg conn->dev_class); 2726671267bfSJohan Hedberg hci_dev_unlock(hdev); 2727671267bfSJohan Hedberg 27281da177e4SLinus Torvalds /* Send to upper protocol */ 2729686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 27301da177e4SLinus Torvalds return; 27311da177e4SLinus Torvalds } else { 27321da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 27331da177e4SLinus Torvalds hdev->name, handle); 27341da177e4SLinus Torvalds } 27351da177e4SLinus Torvalds 27361da177e4SLinus Torvalds kfree_skb(skb); 27371da177e4SLinus Torvalds } 27381da177e4SLinus Torvalds 27391da177e4SLinus Torvalds /* SCO data packet */ 27406039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 27411da177e4SLinus Torvalds { 27421da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 27431da177e4SLinus Torvalds struct hci_conn *conn; 27441da177e4SLinus Torvalds __u16 handle; 27451da177e4SLinus Torvalds 27461da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 27471da177e4SLinus Torvalds 27481da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 27491da177e4SLinus Torvalds 2750f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 27511da177e4SLinus Torvalds 27521da177e4SLinus Torvalds hdev->stat.sco_rx++; 27531da177e4SLinus Torvalds 27541da177e4SLinus Torvalds hci_dev_lock(hdev); 27551da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 27561da177e4SLinus Torvalds hci_dev_unlock(hdev); 27571da177e4SLinus Torvalds 27581da177e4SLinus Torvalds if (conn) { 27591da177e4SLinus Torvalds /* Send to upper protocol */ 2760686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 27611da177e4SLinus Torvalds return; 27621da177e4SLinus Torvalds } else { 27631da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 27641da177e4SLinus Torvalds hdev->name, handle); 27651da177e4SLinus Torvalds } 27661da177e4SLinus Torvalds 27671da177e4SLinus Torvalds kfree_skb(skb); 27681da177e4SLinus Torvalds } 27691da177e4SLinus Torvalds 2770b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 27711da177e4SLinus Torvalds { 2772b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 27731da177e4SLinus Torvalds struct sk_buff *skb; 27741da177e4SLinus Torvalds 27751da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 27761da177e4SLinus Torvalds 27771da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 2778cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2779cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2780cd82e61cSMarcel Holtmann 27811da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 27821da177e4SLinus Torvalds /* Send copy to the sockets */ 2783470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 27841da177e4SLinus Torvalds } 27851da177e4SLinus Torvalds 27861da177e4SLinus Torvalds if (test_bit(HCI_RAW, &hdev->flags)) { 27871da177e4SLinus Torvalds kfree_skb(skb); 27881da177e4SLinus Torvalds continue; 27891da177e4SLinus Torvalds } 27901da177e4SLinus Torvalds 27911da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 27921da177e4SLinus Torvalds /* Don't process data packets in this states. */ 27930d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 27941da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 27951da177e4SLinus Torvalds case HCI_SCODATA_PKT: 27961da177e4SLinus Torvalds kfree_skb(skb); 27971da177e4SLinus Torvalds continue; 27983ff50b79SStephen Hemminger } 27991da177e4SLinus Torvalds } 28001da177e4SLinus Torvalds 28011da177e4SLinus Torvalds /* Process frame */ 28020d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 28031da177e4SLinus Torvalds case HCI_EVENT_PKT: 2804b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 28051da177e4SLinus Torvalds hci_event_packet(hdev, skb); 28061da177e4SLinus Torvalds break; 28071da177e4SLinus Torvalds 28081da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 28091da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 28101da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 28111da177e4SLinus Torvalds break; 28121da177e4SLinus Torvalds 28131da177e4SLinus Torvalds case HCI_SCODATA_PKT: 28141da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 28151da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 28161da177e4SLinus Torvalds break; 28171da177e4SLinus Torvalds 28181da177e4SLinus Torvalds default: 28191da177e4SLinus Torvalds kfree_skb(skb); 28201da177e4SLinus Torvalds break; 28211da177e4SLinus Torvalds } 28221da177e4SLinus Torvalds } 28231da177e4SLinus Torvalds } 28241da177e4SLinus Torvalds 2825c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 28261da177e4SLinus Torvalds { 2827c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 28281da177e4SLinus Torvalds struct sk_buff *skb; 28291da177e4SLinus Torvalds 28302104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 28312104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 28321da177e4SLinus Torvalds 28331da177e4SLinus Torvalds /* Send queued commands */ 28345a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 28355a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 28365a08ecceSAndrei Emeltchenko if (!skb) 28375a08ecceSAndrei Emeltchenko return; 28385a08ecceSAndrei Emeltchenko 28391da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 28401da177e4SLinus Torvalds 284170f23020SAndrei Emeltchenko hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC); 284270f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 28431da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 28441da177e4SLinus Torvalds hci_send_frame(skb); 28457bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 28467bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 28477bdb8a5cSSzymon Janc else 28486bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 28495f246e89SAndrei Emeltchenko jiffies + HCI_CMD_TIMEOUT); 28501da177e4SLinus Torvalds } else { 28511da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 2852c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 28531da177e4SLinus Torvalds } 28541da177e4SLinus Torvalds } 28551da177e4SLinus Torvalds } 28562519a1fcSAndre Guedes 28572519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length) 28582519a1fcSAndre Guedes { 28592519a1fcSAndre Guedes /* General inquiry access code (GIAC) */ 28602519a1fcSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 28612519a1fcSAndre Guedes struct hci_cp_inquiry cp; 28622519a1fcSAndre Guedes 28632519a1fcSAndre Guedes BT_DBG("%s", hdev->name); 28642519a1fcSAndre Guedes 28652519a1fcSAndre Guedes if (test_bit(HCI_INQUIRY, &hdev->flags)) 28662519a1fcSAndre Guedes return -EINPROGRESS; 28672519a1fcSAndre Guedes 28684663262cSJohan Hedberg inquiry_cache_flush(hdev); 28694663262cSJohan Hedberg 28702519a1fcSAndre Guedes memset(&cp, 0, sizeof(cp)); 28712519a1fcSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 28722519a1fcSAndre Guedes cp.length = length; 28732519a1fcSAndre Guedes 28742519a1fcSAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 28752519a1fcSAndre Guedes } 2876023d5049SAndre Guedes 2877023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev) 2878023d5049SAndre Guedes { 2879023d5049SAndre Guedes BT_DBG("%s", hdev->name); 2880023d5049SAndre Guedes 2881023d5049SAndre Guedes if (!test_bit(HCI_INQUIRY, &hdev->flags)) 28827537e5c3SAndre Guedes return -EALREADY; 2883023d5049SAndre Guedes 2884023d5049SAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); 2885023d5049SAndre Guedes } 288631f7956cSAndre Guedes 288731f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type) 288831f7956cSAndre Guedes { 288931f7956cSAndre Guedes switch (bdaddr_type) { 289031f7956cSAndre Guedes case BDADDR_LE_PUBLIC: 289131f7956cSAndre Guedes return ADDR_LE_DEV_PUBLIC; 289231f7956cSAndre Guedes 289331f7956cSAndre Guedes default: 289431f7956cSAndre Guedes /* Fallback to LE Random address type */ 289531f7956cSAndre Guedes return ADDR_LE_DEV_RANDOM; 289631f7956cSAndre Guedes } 289731f7956cSAndre Guedes } 2898