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 36ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000 37ab81cbf9SJohan Hedberg 38b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 39c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 403eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 411da177e4SLinus Torvalds 421da177e4SLinus Torvalds /* HCI device list */ 431da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 441da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds /* HCI callback list */ 471da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 481da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 491da177e4SLinus Torvalds 503df92b31SSasha Levin /* HCI ID Numbering */ 513df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 523df92b31SSasha Levin 531da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 541da177e4SLinus Torvalds 556516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 561da177e4SLinus Torvalds { 57040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 581da177e4SLinus Torvalds } 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds /* ---- HCI requests ---- */ 611da177e4SLinus Torvalds 6223bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) 631da177e4SLinus Torvalds { 6423bb5763SJohan Hedberg BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result); 6523bb5763SJohan Hedberg 66a5040efaSJohan Hedberg /* If this is the init phase check if the completed command matches 67a5040efaSJohan Hedberg * the last init command, and if not just return. 68a5040efaSJohan Hedberg */ 6975fb0e32SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) { 7075fb0e32SJohan Hedberg struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 711036b890SAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 7275fb0e32SJohan Hedberg struct sk_buff *skb; 7375fb0e32SJohan Hedberg 7475fb0e32SJohan Hedberg /* Some CSR based controllers generate a spontaneous 7575fb0e32SJohan Hedberg * reset complete event during init and any pending 7675fb0e32SJohan Hedberg * command will never be completed. In such a case we 7775fb0e32SJohan Hedberg * need to resend whatever was the last sent 7875fb0e32SJohan Hedberg * command. 7975fb0e32SJohan Hedberg */ 8075fb0e32SJohan Hedberg 811036b890SAndrei Emeltchenko if (cmd != HCI_OP_RESET || opcode == HCI_OP_RESET) 8223bb5763SJohan Hedberg return; 831da177e4SLinus Torvalds 8475fb0e32SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC); 8575fb0e32SJohan Hedberg if (skb) { 8675fb0e32SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 8775fb0e32SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 8875fb0e32SJohan Hedberg } 8975fb0e32SJohan Hedberg 9075fb0e32SJohan Hedberg return; 9175fb0e32SJohan Hedberg } 9275fb0e32SJohan Hedberg 931da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 941da177e4SLinus Torvalds hdev->req_result = result; 951da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 961da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 971da177e4SLinus Torvalds } 981da177e4SLinus Torvalds } 991da177e4SLinus Torvalds 1001da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 1011da177e4SLinus Torvalds { 1021da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 1031da177e4SLinus Torvalds 1041da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 1051da177e4SLinus Torvalds hdev->req_result = err; 1061da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 1071da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 1081da177e4SLinus Torvalds } 1091da177e4SLinus Torvalds } 1101da177e4SLinus Torvalds 1111da177e4SLinus Torvalds /* Execute request and wait for completion. */ 112a8c5fb1aSGustavo Padovan static int __hci_request(struct hci_dev *hdev, 113a8c5fb1aSGustavo Padovan void (*req)(struct hci_dev *hdev, unsigned long opt), 1141da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 1151da177e4SLinus Torvalds { 1161da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 1171da177e4SLinus Torvalds int err = 0; 1181da177e4SLinus Torvalds 1191da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 1201da177e4SLinus Torvalds 1211da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 1221da177e4SLinus Torvalds 1231da177e4SLinus Torvalds add_wait_queue(&hdev->req_wait_q, &wait); 1241da177e4SLinus Torvalds set_current_state(TASK_INTERRUPTIBLE); 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds req(hdev, opt); 1271da177e4SLinus Torvalds schedule_timeout(timeout); 1281da177e4SLinus Torvalds 1291da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 1301da177e4SLinus Torvalds 1311da177e4SLinus Torvalds if (signal_pending(current)) 1321da177e4SLinus Torvalds return -EINTR; 1331da177e4SLinus Torvalds 1341da177e4SLinus Torvalds switch (hdev->req_status) { 1351da177e4SLinus Torvalds case HCI_REQ_DONE: 136e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 1371da177e4SLinus Torvalds break; 1381da177e4SLinus Torvalds 1391da177e4SLinus Torvalds case HCI_REQ_CANCELED: 1401da177e4SLinus Torvalds err = -hdev->req_result; 1411da177e4SLinus Torvalds break; 1421da177e4SLinus Torvalds 1431da177e4SLinus Torvalds default: 1441da177e4SLinus Torvalds err = -ETIMEDOUT; 1451da177e4SLinus Torvalds break; 1463ff50b79SStephen Hemminger } 1471da177e4SLinus Torvalds 148a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 1491da177e4SLinus Torvalds 1501da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 1511da177e4SLinus Torvalds 1521da177e4SLinus Torvalds return err; 1531da177e4SLinus Torvalds } 1541da177e4SLinus Torvalds 1556039aa73SGustavo Padovan static int hci_request(struct hci_dev *hdev, 1566039aa73SGustavo Padovan void (*req)(struct hci_dev *hdev, unsigned long opt), 1571da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 1581da177e4SLinus Torvalds { 1591da177e4SLinus Torvalds int ret; 1601da177e4SLinus Torvalds 1617c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 1627c6a329eSMarcel Holtmann return -ENETDOWN; 1637c6a329eSMarcel Holtmann 1641da177e4SLinus Torvalds /* Serialize all requests */ 1651da177e4SLinus Torvalds hci_req_lock(hdev); 1661da177e4SLinus Torvalds ret = __hci_request(hdev, req, opt, timeout); 1671da177e4SLinus Torvalds hci_req_unlock(hdev); 1681da177e4SLinus Torvalds 1691da177e4SLinus Torvalds return ret; 1701da177e4SLinus Torvalds } 1711da177e4SLinus Torvalds 1721da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) 1731da177e4SLinus Torvalds { 1741da177e4SLinus Torvalds BT_DBG("%s %ld", hdev->name, opt); 1751da177e4SLinus Torvalds 1761da177e4SLinus Torvalds /* Reset device */ 177f630cf0dSGustavo F. Padovan set_bit(HCI_RESET, &hdev->flags); 178a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 1791da177e4SLinus Torvalds } 1801da177e4SLinus Torvalds 181e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev) 1821da177e4SLinus Torvalds { 183b0916ea0SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 1841ebb9252SMarcel Holtmann __le16 param; 18589f2783dSMarcel Holtmann __u8 flt_type; 1861da177e4SLinus Torvalds 1872455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 1882455a3eaSAndrei Emeltchenko 1891da177e4SLinus Torvalds /* Mandatory initialization */ 1901da177e4SLinus Torvalds 1911da177e4SLinus Torvalds /* Reset */ 192a6c511c6SSzymon Janc if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 193f630cf0dSGustavo F. Padovan set_bit(HCI_RESET, &hdev->flags); 194a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 195f630cf0dSGustavo F. Padovan } 1961da177e4SLinus Torvalds 1971da177e4SLinus Torvalds /* Read Local Supported Features */ 198a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 1991da177e4SLinus Torvalds 2001143e5a6SMarcel Holtmann /* Read Local Version */ 201a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2021143e5a6SMarcel Holtmann 2031da177e4SLinus Torvalds /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 204a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 2051da177e4SLinus Torvalds 2061da177e4SLinus Torvalds /* Read BD Address */ 207a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); 208a9de9248SMarcel Holtmann 209a9de9248SMarcel Holtmann /* Read Class of Device */ 210a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 211a9de9248SMarcel Holtmann 212a9de9248SMarcel Holtmann /* Read Local Name */ 213a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); 2141da177e4SLinus Torvalds 2151da177e4SLinus Torvalds /* Read Voice Setting */ 216a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); 2171da177e4SLinus Torvalds 2181da177e4SLinus Torvalds /* Optional initialization */ 2191da177e4SLinus Torvalds 2201da177e4SLinus Torvalds /* Clear Event Filters */ 22189f2783dSMarcel Holtmann flt_type = HCI_FLT_CLEAR_ALL; 222a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 2231da177e4SLinus Torvalds 2241da177e4SLinus Torvalds /* Connection accept timeout ~20 secs */ 22582781e63SAndrei Emeltchenko param = __constant_cpu_to_le16(0x7d00); 226a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 227b0916ea0SJohan Hedberg 228b0916ea0SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 229b0916ea0SJohan Hedberg cp.delete_all = 1; 230b0916ea0SJohan Hedberg hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); 2311da177e4SLinus Torvalds } 2321da177e4SLinus Torvalds 233e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev) 234e61ef499SAndrei Emeltchenko { 2352455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 2362455a3eaSAndrei Emeltchenko 237e61ef499SAndrei Emeltchenko /* Reset */ 238e61ef499SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 239e61ef499SAndrei Emeltchenko 240e61ef499SAndrei Emeltchenko /* Read Local Version */ 241e61ef499SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2426bcbc489SAndrei Emeltchenko 2436bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 2446bcbc489SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 245e61ef499SAndrei Emeltchenko } 246e61ef499SAndrei Emeltchenko 247e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt) 248e61ef499SAndrei Emeltchenko { 249e61ef499SAndrei Emeltchenko struct sk_buff *skb; 250e61ef499SAndrei Emeltchenko 251e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 252e61ef499SAndrei Emeltchenko 253e61ef499SAndrei Emeltchenko /* Driver initialization */ 254e61ef499SAndrei Emeltchenko 255e61ef499SAndrei Emeltchenko /* Special commands */ 256e61ef499SAndrei Emeltchenko while ((skb = skb_dequeue(&hdev->driver_init))) { 257e61ef499SAndrei Emeltchenko bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 258e61ef499SAndrei Emeltchenko skb->dev = (void *) hdev; 259e61ef499SAndrei Emeltchenko 260e61ef499SAndrei Emeltchenko skb_queue_tail(&hdev->cmd_q, skb); 261e61ef499SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->cmd_work); 262e61ef499SAndrei Emeltchenko } 263e61ef499SAndrei Emeltchenko skb_queue_purge(&hdev->driver_init); 264e61ef499SAndrei Emeltchenko 265e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 266e61ef499SAndrei Emeltchenko case HCI_BREDR: 267e61ef499SAndrei Emeltchenko bredr_init(hdev); 268e61ef499SAndrei Emeltchenko break; 269e61ef499SAndrei Emeltchenko 270e61ef499SAndrei Emeltchenko case HCI_AMP: 271e61ef499SAndrei Emeltchenko amp_init(hdev); 272e61ef499SAndrei Emeltchenko break; 273e61ef499SAndrei Emeltchenko 274e61ef499SAndrei Emeltchenko default: 275e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 276e61ef499SAndrei Emeltchenko break; 277e61ef499SAndrei Emeltchenko } 278e61ef499SAndrei Emeltchenko 279e61ef499SAndrei Emeltchenko } 280e61ef499SAndrei Emeltchenko 2816ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) 2826ed58ec5SVille Tervo { 2836ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 2846ed58ec5SVille Tervo 2856ed58ec5SVille Tervo /* Read LE buffer size */ 2866ed58ec5SVille Tervo hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 2876ed58ec5SVille Tervo } 2886ed58ec5SVille Tervo 2891da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) 2901da177e4SLinus Torvalds { 2911da177e4SLinus Torvalds __u8 scan = opt; 2921da177e4SLinus Torvalds 2931da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, scan); 2941da177e4SLinus Torvalds 2951da177e4SLinus Torvalds /* Inquiry and Page scans */ 296a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 2971da177e4SLinus Torvalds } 2981da177e4SLinus Torvalds 2991da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt) 3001da177e4SLinus Torvalds { 3011da177e4SLinus Torvalds __u8 auth = opt; 3021da177e4SLinus Torvalds 3031da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, auth); 3041da177e4SLinus Torvalds 3051da177e4SLinus Torvalds /* Authentication */ 306a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 3071da177e4SLinus Torvalds } 3081da177e4SLinus Torvalds 3091da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt) 3101da177e4SLinus Torvalds { 3111da177e4SLinus Torvalds __u8 encrypt = opt; 3121da177e4SLinus Torvalds 3131da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, encrypt); 3141da177e4SLinus Torvalds 315e4e8e37cSMarcel Holtmann /* Encryption */ 316a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 3171da177e4SLinus Torvalds } 3181da177e4SLinus Torvalds 319e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt) 320e4e8e37cSMarcel Holtmann { 321e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 322e4e8e37cSMarcel Holtmann 323a418b893SMarcel Holtmann BT_DBG("%s %x", hdev->name, policy); 324e4e8e37cSMarcel Holtmann 325e4e8e37cSMarcel Holtmann /* Default link policy */ 326e4e8e37cSMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 327e4e8e37cSMarcel Holtmann } 328e4e8e37cSMarcel Holtmann 3291da177e4SLinus Torvalds /* Get HCI device by index. 3301da177e4SLinus Torvalds * Device is held on return. */ 3311da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 3321da177e4SLinus Torvalds { 3338035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 3341da177e4SLinus Torvalds 3351da177e4SLinus Torvalds BT_DBG("%d", index); 3361da177e4SLinus Torvalds 3371da177e4SLinus Torvalds if (index < 0) 3381da177e4SLinus Torvalds return NULL; 3391da177e4SLinus Torvalds 3401da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 3418035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 3421da177e4SLinus Torvalds if (d->id == index) { 3431da177e4SLinus Torvalds hdev = hci_dev_hold(d); 3441da177e4SLinus Torvalds break; 3451da177e4SLinus Torvalds } 3461da177e4SLinus Torvalds } 3471da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 3481da177e4SLinus Torvalds return hdev; 3491da177e4SLinus Torvalds } 3501da177e4SLinus Torvalds 3511da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 352ff9ef578SJohan Hedberg 35330dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 35430dc78e1SJohan Hedberg { 35530dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 35630dc78e1SJohan Hedberg 3576fbe195dSAndre Guedes switch (discov->state) { 358343f935bSAndre Guedes case DISCOVERY_FINDING: 3596fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 36030dc78e1SJohan Hedberg return true; 36130dc78e1SJohan Hedberg 3626fbe195dSAndre Guedes default: 36330dc78e1SJohan Hedberg return false; 36430dc78e1SJohan Hedberg } 3656fbe195dSAndre Guedes } 36630dc78e1SJohan Hedberg 367ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 368ff9ef578SJohan Hedberg { 369ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 370ff9ef578SJohan Hedberg 371ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 372ff9ef578SJohan Hedberg return; 373ff9ef578SJohan Hedberg 374ff9ef578SJohan Hedberg switch (state) { 375ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 3767b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 377ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 378ff9ef578SJohan Hedberg break; 379ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 380ff9ef578SJohan Hedberg break; 381343f935bSAndre Guedes case DISCOVERY_FINDING: 382ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 383ff9ef578SJohan Hedberg break; 38430dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 38530dc78e1SJohan Hedberg break; 386ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 387ff9ef578SJohan Hedberg break; 388ff9ef578SJohan Hedberg } 389ff9ef578SJohan Hedberg 390ff9ef578SJohan Hedberg hdev->discovery.state = state; 391ff9ef578SJohan Hedberg } 392ff9ef578SJohan Hedberg 3931da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev) 3941da177e4SLinus Torvalds { 39530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 396b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 3971da177e4SLinus Torvalds 398561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 399561aafbcSJohan Hedberg list_del(&p->all); 400b57c1a56SJohan Hedberg kfree(p); 4011da177e4SLinus Torvalds } 402561aafbcSJohan Hedberg 403561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 404561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 4051da177e4SLinus Torvalds } 4061da177e4SLinus Torvalds 407a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 408a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 4091da177e4SLinus Torvalds { 41030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 4111da177e4SLinus Torvalds struct inquiry_entry *e; 4121da177e4SLinus Torvalds 4131da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 4141da177e4SLinus Torvalds 415561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 4161da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 4171da177e4SLinus Torvalds return e; 4181da177e4SLinus Torvalds } 4191da177e4SLinus Torvalds 420b57c1a56SJohan Hedberg return NULL; 421b57c1a56SJohan Hedberg } 422b57c1a56SJohan Hedberg 423561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 424561aafbcSJohan Hedberg bdaddr_t *bdaddr) 425561aafbcSJohan Hedberg { 42630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 427561aafbcSJohan Hedberg struct inquiry_entry *e; 428561aafbcSJohan Hedberg 429561aafbcSJohan Hedberg BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 430561aafbcSJohan Hedberg 431561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 432561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 433561aafbcSJohan Hedberg return e; 434561aafbcSJohan Hedberg } 435561aafbcSJohan Hedberg 436561aafbcSJohan Hedberg return NULL; 437561aafbcSJohan Hedberg } 438561aafbcSJohan Hedberg 43930dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 44030dc78e1SJohan Hedberg bdaddr_t *bdaddr, 44130dc78e1SJohan Hedberg int state) 44230dc78e1SJohan Hedberg { 44330dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 44430dc78e1SJohan Hedberg struct inquiry_entry *e; 44530dc78e1SJohan Hedberg 44630dc78e1SJohan Hedberg BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state); 44730dc78e1SJohan Hedberg 44830dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 44930dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 45030dc78e1SJohan Hedberg return e; 45130dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 45230dc78e1SJohan Hedberg return e; 45330dc78e1SJohan Hedberg } 45430dc78e1SJohan Hedberg 45530dc78e1SJohan Hedberg return NULL; 45630dc78e1SJohan Hedberg } 45730dc78e1SJohan Hedberg 458a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 459a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 460a3d4e20aSJohan Hedberg { 461a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 462a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 463a3d4e20aSJohan Hedberg struct inquiry_entry *p; 464a3d4e20aSJohan Hedberg 465a3d4e20aSJohan Hedberg list_del(&ie->list); 466a3d4e20aSJohan Hedberg 467a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 468a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 469a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 470a3d4e20aSJohan Hedberg break; 471a3d4e20aSJohan Hedberg pos = &p->list; 472a3d4e20aSJohan Hedberg } 473a3d4e20aSJohan Hedberg 474a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 475a3d4e20aSJohan Hedberg } 476a3d4e20aSJohan Hedberg 4773175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 478388fc8faSJohan Hedberg bool name_known, bool *ssp) 4791da177e4SLinus Torvalds { 48030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 48170f23020SAndrei Emeltchenko struct inquiry_entry *ie; 4821da177e4SLinus Torvalds 4831da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr)); 4841da177e4SLinus Torvalds 485388fc8faSJohan Hedberg if (ssp) 486388fc8faSJohan Hedberg *ssp = data->ssp_mode; 487388fc8faSJohan Hedberg 48870f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 489a3d4e20aSJohan Hedberg if (ie) { 490388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 491388fc8faSJohan Hedberg *ssp = true; 492388fc8faSJohan Hedberg 493a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 494a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 495a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 496a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 497a3d4e20aSJohan Hedberg } 498a3d4e20aSJohan Hedberg 499561aafbcSJohan Hedberg goto update; 500a3d4e20aSJohan Hedberg } 501561aafbcSJohan Hedberg 5021da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 50370f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 50470f23020SAndrei Emeltchenko if (!ie) 5053175405bSJohan Hedberg return false; 50670f23020SAndrei Emeltchenko 507561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 508561aafbcSJohan Hedberg 509561aafbcSJohan Hedberg if (name_known) { 510561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 511561aafbcSJohan Hedberg } else { 512561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 513561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 514561aafbcSJohan Hedberg } 515561aafbcSJohan Hedberg 516561aafbcSJohan Hedberg update: 517561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 518561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 519561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 520561aafbcSJohan Hedberg list_del(&ie->list); 5211da177e4SLinus Torvalds } 5221da177e4SLinus Torvalds 52370f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 52470f23020SAndrei Emeltchenko ie->timestamp = jiffies; 5251da177e4SLinus Torvalds cache->timestamp = jiffies; 5263175405bSJohan Hedberg 5273175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 5283175405bSJohan Hedberg return false; 5293175405bSJohan Hedberg 5303175405bSJohan Hedberg return true; 5311da177e4SLinus Torvalds } 5321da177e4SLinus Torvalds 5331da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 5341da177e4SLinus Torvalds { 53530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 5361da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 5371da177e4SLinus Torvalds struct inquiry_entry *e; 5381da177e4SLinus Torvalds int copied = 0; 5391da177e4SLinus Torvalds 540561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 5411da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 542b57c1a56SJohan Hedberg 543b57c1a56SJohan Hedberg if (copied >= num) 544b57c1a56SJohan Hedberg break; 545b57c1a56SJohan Hedberg 5461da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 5471da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 5481da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 5491da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 5501da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 5511da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 552b57c1a56SJohan Hedberg 5531da177e4SLinus Torvalds info++; 554b57c1a56SJohan Hedberg copied++; 5551da177e4SLinus Torvalds } 5561da177e4SLinus Torvalds 5571da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 5581da177e4SLinus Torvalds return copied; 5591da177e4SLinus Torvalds } 5601da177e4SLinus Torvalds 5611da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt) 5621da177e4SLinus Torvalds { 5631da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 5641da177e4SLinus Torvalds struct hci_cp_inquiry cp; 5651da177e4SLinus Torvalds 5661da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 5671da177e4SLinus Torvalds 5681da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 5691da177e4SLinus Torvalds return; 5701da177e4SLinus Torvalds 5711da177e4SLinus Torvalds /* Start Inquiry */ 5721da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 5731da177e4SLinus Torvalds cp.length = ir->length; 5741da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 575a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 5761da177e4SLinus Torvalds } 5771da177e4SLinus Torvalds 5781da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 5791da177e4SLinus Torvalds { 5801da177e4SLinus Torvalds __u8 __user *ptr = arg; 5811da177e4SLinus Torvalds struct hci_inquiry_req ir; 5821da177e4SLinus Torvalds struct hci_dev *hdev; 5831da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 5841da177e4SLinus Torvalds long timeo; 5851da177e4SLinus Torvalds __u8 *buf; 5861da177e4SLinus Torvalds 5871da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 5881da177e4SLinus Torvalds return -EFAULT; 5891da177e4SLinus Torvalds 5905a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 5915a08ecceSAndrei Emeltchenko if (!hdev) 5921da177e4SLinus Torvalds return -ENODEV; 5931da177e4SLinus Torvalds 59409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 5951da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 596a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 5971da177e4SLinus Torvalds inquiry_cache_flush(hdev); 5981da177e4SLinus Torvalds do_inquiry = 1; 5991da177e4SLinus Torvalds } 60009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 6011da177e4SLinus Torvalds 60204837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 60370f23020SAndrei Emeltchenko 60470f23020SAndrei Emeltchenko if (do_inquiry) { 60570f23020SAndrei Emeltchenko err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo); 60670f23020SAndrei Emeltchenko if (err < 0) 6071da177e4SLinus Torvalds goto done; 60870f23020SAndrei Emeltchenko } 6091da177e4SLinus Torvalds 6108fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 6118fc9ced3SGustavo Padovan * 255 entries 6128fc9ced3SGustavo Padovan */ 6131da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 6141da177e4SLinus Torvalds 6151da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 6161da177e4SLinus Torvalds * copy it to the user space. 6171da177e4SLinus Torvalds */ 61870f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 61970f23020SAndrei Emeltchenko if (!buf) { 6201da177e4SLinus Torvalds err = -ENOMEM; 6211da177e4SLinus Torvalds goto done; 6221da177e4SLinus Torvalds } 6231da177e4SLinus Torvalds 62409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 6251da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 62609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 6271da177e4SLinus Torvalds 6281da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 6291da177e4SLinus Torvalds 6301da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 6311da177e4SLinus Torvalds ptr += sizeof(ir); 6321da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 6331da177e4SLinus Torvalds ir.num_rsp)) 6341da177e4SLinus Torvalds err = -EFAULT; 6351da177e4SLinus Torvalds } else 6361da177e4SLinus Torvalds err = -EFAULT; 6371da177e4SLinus Torvalds 6381da177e4SLinus Torvalds kfree(buf); 6391da177e4SLinus Torvalds 6401da177e4SLinus Torvalds done: 6411da177e4SLinus Torvalds hci_dev_put(hdev); 6421da177e4SLinus Torvalds return err; 6431da177e4SLinus Torvalds } 6441da177e4SLinus Torvalds 6451da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */ 6461da177e4SLinus Torvalds 6471da177e4SLinus Torvalds int hci_dev_open(__u16 dev) 6481da177e4SLinus Torvalds { 6491da177e4SLinus Torvalds struct hci_dev *hdev; 6501da177e4SLinus Torvalds int ret = 0; 6511da177e4SLinus Torvalds 6525a08ecceSAndrei Emeltchenko hdev = hci_dev_get(dev); 6535a08ecceSAndrei Emeltchenko if (!hdev) 6541da177e4SLinus Torvalds return -ENODEV; 6551da177e4SLinus Torvalds 6561da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 6571da177e4SLinus Torvalds 6581da177e4SLinus Torvalds hci_req_lock(hdev); 6591da177e4SLinus Torvalds 66094324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 66194324962SJohan Hovold ret = -ENODEV; 66294324962SJohan Hovold goto done; 66394324962SJohan Hovold } 66494324962SJohan Hovold 665611b30f7SMarcel Holtmann if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { 666611b30f7SMarcel Holtmann ret = -ERFKILL; 667611b30f7SMarcel Holtmann goto done; 668611b30f7SMarcel Holtmann } 669611b30f7SMarcel Holtmann 6701da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 6711da177e4SLinus Torvalds ret = -EALREADY; 6721da177e4SLinus Torvalds goto done; 6731da177e4SLinus Torvalds } 6741da177e4SLinus Torvalds 6751da177e4SLinus Torvalds if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 6761da177e4SLinus Torvalds set_bit(HCI_RAW, &hdev->flags); 6771da177e4SLinus Torvalds 67807e3b94aSAndrei Emeltchenko /* Treat all non BR/EDR controllers as raw devices if 67907e3b94aSAndrei Emeltchenko enable_hs is not set */ 68007e3b94aSAndrei Emeltchenko if (hdev->dev_type != HCI_BREDR && !enable_hs) 681943da25dSMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 682943da25dSMarcel Holtmann 6831da177e4SLinus Torvalds if (hdev->open(hdev)) { 6841da177e4SLinus Torvalds ret = -EIO; 6851da177e4SLinus Torvalds goto done; 6861da177e4SLinus Torvalds } 6871da177e4SLinus Torvalds 6881da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 6891da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 6901da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 691a5040efaSJohan Hedberg hdev->init_last_cmd = 0; 6921da177e4SLinus Torvalds 69304837f64SMarcel Holtmann ret = __hci_request(hdev, hci_init_req, 0, 69404837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 6951da177e4SLinus Torvalds 696eead27daSAndre Guedes if (lmp_host_le_capable(hdev)) 6976ed58ec5SVille Tervo ret = __hci_request(hdev, hci_le_init_req, 0, 6986ed58ec5SVille Tervo msecs_to_jiffies(HCI_INIT_TIMEOUT)); 6996ed58ec5SVille Tervo 7001da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7011da177e4SLinus Torvalds } 7021da177e4SLinus Torvalds 7031da177e4SLinus Torvalds if (!ret) { 7041da177e4SLinus Torvalds hci_dev_hold(hdev); 7051da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 7061da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 707a8b2d5c2SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 70809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 709744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 71009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 71156e5cb86SJohan Hedberg } 7121da177e4SLinus Torvalds } else { 7131da177e4SLinus Torvalds /* Init failed, cleanup */ 7143eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 715c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 716b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7171da177e4SLinus Torvalds 7181da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7191da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7201da177e4SLinus Torvalds 7211da177e4SLinus Torvalds if (hdev->flush) 7221da177e4SLinus Torvalds hdev->flush(hdev); 7231da177e4SLinus Torvalds 7241da177e4SLinus Torvalds if (hdev->sent_cmd) { 7251da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 7261da177e4SLinus Torvalds hdev->sent_cmd = NULL; 7271da177e4SLinus Torvalds } 7281da177e4SLinus Torvalds 7291da177e4SLinus Torvalds hdev->close(hdev); 7301da177e4SLinus Torvalds hdev->flags = 0; 7311da177e4SLinus Torvalds } 7321da177e4SLinus Torvalds 7331da177e4SLinus Torvalds done: 7341da177e4SLinus Torvalds hci_req_unlock(hdev); 7351da177e4SLinus Torvalds hci_dev_put(hdev); 7361da177e4SLinus Torvalds return ret; 7371da177e4SLinus Torvalds } 7381da177e4SLinus Torvalds 7391da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 7401da177e4SLinus Torvalds { 7411da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 7421da177e4SLinus Torvalds 74328b75a89SAndre Guedes cancel_work_sync(&hdev->le_scan); 74428b75a89SAndre Guedes 7451da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 7461da177e4SLinus Torvalds hci_req_lock(hdev); 7471da177e4SLinus Torvalds 7481da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 749b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 7501da177e4SLinus Torvalds hci_req_unlock(hdev); 7511da177e4SLinus Torvalds return 0; 7521da177e4SLinus Torvalds } 7531da177e4SLinus Torvalds 7543eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 7553eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 756b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7571da177e4SLinus Torvalds 75816ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 759e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 76016ab91abSJohan Hedberg hdev->discov_timeout = 0; 7615e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 76216ab91abSJohan Hedberg } 76316ab91abSJohan Hedberg 764a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 7657d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 7667d78525dSJohan Hedberg 7677ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 7687ba8b4beSAndre Guedes 76909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 7701da177e4SLinus Torvalds inquiry_cache_flush(hdev); 7711da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 77209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 7731da177e4SLinus Torvalds 7741da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 7751da177e4SLinus Torvalds 7761da177e4SLinus Torvalds if (hdev->flush) 7771da177e4SLinus Torvalds hdev->flush(hdev); 7781da177e4SLinus Torvalds 7791da177e4SLinus Torvalds /* Reset device */ 7801da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7811da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 7828af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 783a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 7841da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 78504837f64SMarcel Holtmann __hci_request(hdev, hci_reset_req, 0, 786cad44c2bSGustavo F. Padovan msecs_to_jiffies(250)); 7871da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7881da177e4SLinus Torvalds } 7891da177e4SLinus Torvalds 790c347b765SGustavo F. Padovan /* flush cmd work */ 791c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 7921da177e4SLinus Torvalds 7931da177e4SLinus Torvalds /* Drop queues */ 7941da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7951da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7961da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 7971da177e4SLinus Torvalds 7981da177e4SLinus Torvalds /* Drop last sent command */ 7991da177e4SLinus Torvalds if (hdev->sent_cmd) { 800b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 8011da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 8021da177e4SLinus Torvalds hdev->sent_cmd = NULL; 8031da177e4SLinus Torvalds } 8041da177e4SLinus Torvalds 8051da177e4SLinus Torvalds /* After this point our queues are empty 8061da177e4SLinus Torvalds * and no tasks are scheduled. */ 8071da177e4SLinus Torvalds hdev->close(hdev); 8081da177e4SLinus Torvalds 8098ee56540SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 81009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 811744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 81209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8138ee56540SMarcel Holtmann } 8145add6af8SJohan Hedberg 8151da177e4SLinus Torvalds /* Clear flags */ 8161da177e4SLinus Torvalds hdev->flags = 0; 8171da177e4SLinus Torvalds 818e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 81909b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 820e59fda8dSJohan Hedberg 8211da177e4SLinus Torvalds hci_req_unlock(hdev); 8221da177e4SLinus Torvalds 8231da177e4SLinus Torvalds hci_dev_put(hdev); 8241da177e4SLinus Torvalds return 0; 8251da177e4SLinus Torvalds } 8261da177e4SLinus Torvalds 8271da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 8281da177e4SLinus Torvalds { 8291da177e4SLinus Torvalds struct hci_dev *hdev; 8301da177e4SLinus Torvalds int err; 8311da177e4SLinus Torvalds 83270f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 83370f23020SAndrei Emeltchenko if (!hdev) 8341da177e4SLinus Torvalds return -ENODEV; 8358ee56540SMarcel Holtmann 8368ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 8378ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 8388ee56540SMarcel Holtmann 8391da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 8408ee56540SMarcel Holtmann 8411da177e4SLinus Torvalds hci_dev_put(hdev); 8421da177e4SLinus Torvalds return err; 8431da177e4SLinus Torvalds } 8441da177e4SLinus Torvalds 8451da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 8461da177e4SLinus Torvalds { 8471da177e4SLinus Torvalds struct hci_dev *hdev; 8481da177e4SLinus Torvalds int ret = 0; 8491da177e4SLinus Torvalds 85070f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 85170f23020SAndrei Emeltchenko if (!hdev) 8521da177e4SLinus Torvalds return -ENODEV; 8531da177e4SLinus Torvalds 8541da177e4SLinus Torvalds hci_req_lock(hdev); 8551da177e4SLinus Torvalds 8561da177e4SLinus Torvalds if (!test_bit(HCI_UP, &hdev->flags)) 8571da177e4SLinus Torvalds goto done; 8581da177e4SLinus Torvalds 8591da177e4SLinus Torvalds /* Drop queues */ 8601da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 8611da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8621da177e4SLinus Torvalds 86309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 8641da177e4SLinus Torvalds inquiry_cache_flush(hdev); 8651da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 86609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8671da177e4SLinus Torvalds 8681da177e4SLinus Torvalds if (hdev->flush) 8691da177e4SLinus Torvalds hdev->flush(hdev); 8701da177e4SLinus Torvalds 8711da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 8726ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 8731da177e4SLinus Torvalds 8741da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 87504837f64SMarcel Holtmann ret = __hci_request(hdev, hci_reset_req, 0, 87604837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 8771da177e4SLinus Torvalds 8781da177e4SLinus Torvalds done: 8791da177e4SLinus Torvalds hci_req_unlock(hdev); 8801da177e4SLinus Torvalds hci_dev_put(hdev); 8811da177e4SLinus Torvalds return ret; 8821da177e4SLinus Torvalds } 8831da177e4SLinus Torvalds 8841da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 8851da177e4SLinus Torvalds { 8861da177e4SLinus Torvalds struct hci_dev *hdev; 8871da177e4SLinus Torvalds int ret = 0; 8881da177e4SLinus Torvalds 88970f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 89070f23020SAndrei Emeltchenko if (!hdev) 8911da177e4SLinus Torvalds return -ENODEV; 8921da177e4SLinus Torvalds 8931da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 8941da177e4SLinus Torvalds 8951da177e4SLinus Torvalds hci_dev_put(hdev); 8961da177e4SLinus Torvalds 8971da177e4SLinus Torvalds return ret; 8981da177e4SLinus Torvalds } 8991da177e4SLinus Torvalds 9001da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 9011da177e4SLinus Torvalds { 9021da177e4SLinus Torvalds struct hci_dev *hdev; 9031da177e4SLinus Torvalds struct hci_dev_req dr; 9041da177e4SLinus Torvalds int err = 0; 9051da177e4SLinus Torvalds 9061da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 9071da177e4SLinus Torvalds return -EFAULT; 9081da177e4SLinus Torvalds 90970f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 91070f23020SAndrei Emeltchenko if (!hdev) 9111da177e4SLinus Torvalds return -ENODEV; 9121da177e4SLinus Torvalds 9131da177e4SLinus Torvalds switch (cmd) { 9141da177e4SLinus Torvalds case HCISETAUTH: 91504837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 91604837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9171da177e4SLinus Torvalds break; 9181da177e4SLinus Torvalds 9191da177e4SLinus Torvalds case HCISETENCRYPT: 9201da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 9211da177e4SLinus Torvalds err = -EOPNOTSUPP; 9221da177e4SLinus Torvalds break; 9231da177e4SLinus Torvalds } 9241da177e4SLinus Torvalds 9251da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 9261da177e4SLinus Torvalds /* Auth must be enabled first */ 92704837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 92804837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9291da177e4SLinus Torvalds if (err) 9301da177e4SLinus Torvalds break; 9311da177e4SLinus Torvalds } 9321da177e4SLinus Torvalds 93304837f64SMarcel Holtmann err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, 93404837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9351da177e4SLinus Torvalds break; 9361da177e4SLinus Torvalds 9371da177e4SLinus Torvalds case HCISETSCAN: 93804837f64SMarcel Holtmann err = hci_request(hdev, hci_scan_req, dr.dev_opt, 93904837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9401da177e4SLinus Torvalds break; 9411da177e4SLinus Torvalds 9421da177e4SLinus Torvalds case HCISETLINKPOL: 943e4e8e37cSMarcel Holtmann err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, 944e4e8e37cSMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9451da177e4SLinus Torvalds break; 9461da177e4SLinus Torvalds 9471da177e4SLinus Torvalds case HCISETLINKMODE: 948e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 949e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 950e4e8e37cSMarcel Holtmann break; 951e4e8e37cSMarcel Holtmann 952e4e8e37cSMarcel Holtmann case HCISETPTYPE: 953e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 9541da177e4SLinus Torvalds break; 9551da177e4SLinus Torvalds 9561da177e4SLinus Torvalds case HCISETACLMTU: 9571da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 9581da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 9591da177e4SLinus Torvalds break; 9601da177e4SLinus Torvalds 9611da177e4SLinus Torvalds case HCISETSCOMTU: 9621da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 9631da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 9641da177e4SLinus Torvalds break; 9651da177e4SLinus Torvalds 9661da177e4SLinus Torvalds default: 9671da177e4SLinus Torvalds err = -EINVAL; 9681da177e4SLinus Torvalds break; 9691da177e4SLinus Torvalds } 970e4e8e37cSMarcel Holtmann 9711da177e4SLinus Torvalds hci_dev_put(hdev); 9721da177e4SLinus Torvalds return err; 9731da177e4SLinus Torvalds } 9741da177e4SLinus Torvalds 9751da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 9761da177e4SLinus Torvalds { 9778035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 9781da177e4SLinus Torvalds struct hci_dev_list_req *dl; 9791da177e4SLinus Torvalds struct hci_dev_req *dr; 9801da177e4SLinus Torvalds int n = 0, size, err; 9811da177e4SLinus Torvalds __u16 dev_num; 9821da177e4SLinus Torvalds 9831da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 9841da177e4SLinus Torvalds return -EFAULT; 9851da177e4SLinus Torvalds 9861da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 9871da177e4SLinus Torvalds return -EINVAL; 9881da177e4SLinus Torvalds 9891da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 9901da177e4SLinus Torvalds 99170f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 99270f23020SAndrei Emeltchenko if (!dl) 9931da177e4SLinus Torvalds return -ENOMEM; 9941da177e4SLinus Torvalds 9951da177e4SLinus Torvalds dr = dl->dev_req; 9961da177e4SLinus Torvalds 997f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 9988035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 999a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1000e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 1001c542a06cSJohan Hedberg 1002a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1003a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1004c542a06cSJohan Hedberg 10051da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 10061da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 1007c542a06cSJohan Hedberg 10081da177e4SLinus Torvalds if (++n >= dev_num) 10091da177e4SLinus Torvalds break; 10101da177e4SLinus Torvalds } 1011f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 10121da177e4SLinus Torvalds 10131da177e4SLinus Torvalds dl->dev_num = n; 10141da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 10151da177e4SLinus Torvalds 10161da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 10171da177e4SLinus Torvalds kfree(dl); 10181da177e4SLinus Torvalds 10191da177e4SLinus Torvalds return err ? -EFAULT : 0; 10201da177e4SLinus Torvalds } 10211da177e4SLinus Torvalds 10221da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 10231da177e4SLinus Torvalds { 10241da177e4SLinus Torvalds struct hci_dev *hdev; 10251da177e4SLinus Torvalds struct hci_dev_info di; 10261da177e4SLinus Torvalds int err = 0; 10271da177e4SLinus Torvalds 10281da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 10291da177e4SLinus Torvalds return -EFAULT; 10301da177e4SLinus Torvalds 103170f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 103270f23020SAndrei Emeltchenko if (!hdev) 10331da177e4SLinus Torvalds return -ENODEV; 10341da177e4SLinus Torvalds 1035a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 10363243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 1037ab81cbf9SJohan Hedberg 1038a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1039a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1040c542a06cSJohan Hedberg 10411da177e4SLinus Torvalds strcpy(di.name, hdev->name); 10421da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 1043943da25dSMarcel Holtmann di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); 10441da177e4SLinus Torvalds di.flags = hdev->flags; 10451da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 10461da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 10471da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 10481da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 10491da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 10501da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 10511da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 10521da177e4SLinus Torvalds 10531da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 10541da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 10551da177e4SLinus Torvalds 10561da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 10571da177e4SLinus Torvalds err = -EFAULT; 10581da177e4SLinus Torvalds 10591da177e4SLinus Torvalds hci_dev_put(hdev); 10601da177e4SLinus Torvalds 10611da177e4SLinus Torvalds return err; 10621da177e4SLinus Torvalds } 10631da177e4SLinus Torvalds 10641da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 10651da177e4SLinus Torvalds 1066611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 1067611b30f7SMarcel Holtmann { 1068611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 1069611b30f7SMarcel Holtmann 1070611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 1071611b30f7SMarcel Holtmann 1072611b30f7SMarcel Holtmann if (!blocked) 1073611b30f7SMarcel Holtmann return 0; 1074611b30f7SMarcel Holtmann 1075611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 1076611b30f7SMarcel Holtmann 1077611b30f7SMarcel Holtmann return 0; 1078611b30f7SMarcel Holtmann } 1079611b30f7SMarcel Holtmann 1080611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 1081611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 1082611b30f7SMarcel Holtmann }; 1083611b30f7SMarcel Holtmann 1084ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 1085ab81cbf9SJohan Hedberg { 1086ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 1087ab81cbf9SJohan Hedberg 1088ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1089ab81cbf9SJohan Hedberg 1090ab81cbf9SJohan Hedberg if (hci_dev_open(hdev->id) < 0) 1091ab81cbf9SJohan Hedberg return; 1092ab81cbf9SJohan Hedberg 1093a8b2d5c2SJohan Hedberg if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 109480b7ab33SGustavo F. Padovan schedule_delayed_work(&hdev->power_off, 10953243553fSJohan Hedberg msecs_to_jiffies(AUTO_OFF_TIMEOUT)); 1096ab81cbf9SJohan Hedberg 1097a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 1098744cf19eSJohan Hedberg mgmt_index_added(hdev); 1099ab81cbf9SJohan Hedberg } 1100ab81cbf9SJohan Hedberg 1101ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1102ab81cbf9SJohan Hedberg { 11033243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 11043243553fSJohan Hedberg power_off.work); 1105ab81cbf9SJohan Hedberg 1106ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1107ab81cbf9SJohan Hedberg 11088ee56540SMarcel Holtmann hci_dev_do_close(hdev); 1109ab81cbf9SJohan Hedberg } 1110ab81cbf9SJohan Hedberg 111116ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 111216ab91abSJohan Hedberg { 111316ab91abSJohan Hedberg struct hci_dev *hdev; 111416ab91abSJohan Hedberg u8 scan = SCAN_PAGE; 111516ab91abSJohan Hedberg 111616ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 111716ab91abSJohan Hedberg 111816ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 111916ab91abSJohan Hedberg 112009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 112116ab91abSJohan Hedberg 112216ab91abSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); 112316ab91abSJohan Hedberg 112416ab91abSJohan Hedberg hdev->discov_timeout = 0; 112516ab91abSJohan Hedberg 112609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 112716ab91abSJohan Hedberg } 112816ab91abSJohan Hedberg 11292aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 11302aeb9a1aSJohan Hedberg { 11312aeb9a1aSJohan Hedberg struct list_head *p, *n; 11322aeb9a1aSJohan Hedberg 11332aeb9a1aSJohan Hedberg list_for_each_safe(p, n, &hdev->uuids) { 11342aeb9a1aSJohan Hedberg struct bt_uuid *uuid; 11352aeb9a1aSJohan Hedberg 11362aeb9a1aSJohan Hedberg uuid = list_entry(p, struct bt_uuid, list); 11372aeb9a1aSJohan Hedberg 11382aeb9a1aSJohan Hedberg list_del(p); 11392aeb9a1aSJohan Hedberg kfree(uuid); 11402aeb9a1aSJohan Hedberg } 11412aeb9a1aSJohan Hedberg 11422aeb9a1aSJohan Hedberg return 0; 11432aeb9a1aSJohan Hedberg } 11442aeb9a1aSJohan Hedberg 114555ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 114655ed8ca1SJohan Hedberg { 114755ed8ca1SJohan Hedberg struct list_head *p, *n; 114855ed8ca1SJohan Hedberg 114955ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 115055ed8ca1SJohan Hedberg struct link_key *key; 115155ed8ca1SJohan Hedberg 115255ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 115355ed8ca1SJohan Hedberg 115455ed8ca1SJohan Hedberg list_del(p); 115555ed8ca1SJohan Hedberg kfree(key); 115655ed8ca1SJohan Hedberg } 115755ed8ca1SJohan Hedberg 115855ed8ca1SJohan Hedberg return 0; 115955ed8ca1SJohan Hedberg } 116055ed8ca1SJohan Hedberg 1161b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 1162b899efafSVinicius Costa Gomes { 1163b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1164b899efafSVinicius Costa Gomes 1165b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1166b899efafSVinicius Costa Gomes list_del(&k->list); 1167b899efafSVinicius Costa Gomes kfree(k); 1168b899efafSVinicius Costa Gomes } 1169b899efafSVinicius Costa Gomes 1170b899efafSVinicius Costa Gomes return 0; 1171b899efafSVinicius Costa Gomes } 1172b899efafSVinicius Costa Gomes 117355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 117455ed8ca1SJohan Hedberg { 117555ed8ca1SJohan Hedberg struct link_key *k; 117655ed8ca1SJohan Hedberg 11778035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 117855ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 117955ed8ca1SJohan Hedberg return k; 118055ed8ca1SJohan Hedberg 118155ed8ca1SJohan Hedberg return NULL; 118255ed8ca1SJohan Hedberg } 118355ed8ca1SJohan Hedberg 1184745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 1185d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 1186d25e28abSJohan Hedberg { 1187d25e28abSJohan Hedberg /* Legacy key */ 1188d25e28abSJohan Hedberg if (key_type < 0x03) 1189745c0ce3SVishal Agarwal return true; 1190d25e28abSJohan Hedberg 1191d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 1192d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 1193745c0ce3SVishal Agarwal return false; 1194d25e28abSJohan Hedberg 1195d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 1196d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 1197745c0ce3SVishal Agarwal return false; 1198d25e28abSJohan Hedberg 1199d25e28abSJohan Hedberg /* Security mode 3 case */ 1200d25e28abSJohan Hedberg if (!conn) 1201745c0ce3SVishal Agarwal return true; 1202d25e28abSJohan Hedberg 1203d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 1204d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 1205745c0ce3SVishal Agarwal return true; 1206d25e28abSJohan Hedberg 1207d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 1208d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 1209745c0ce3SVishal Agarwal return true; 1210d25e28abSJohan Hedberg 1211d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 1212d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 1213745c0ce3SVishal Agarwal return true; 1214d25e28abSJohan Hedberg 1215d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 1216d25e28abSJohan Hedberg * persistently */ 1217745c0ce3SVishal Agarwal return false; 1218d25e28abSJohan Hedberg } 1219d25e28abSJohan Hedberg 1220c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 122175d262c2SVinicius Costa Gomes { 1222c9839a11SVinicius Costa Gomes struct smp_ltk *k; 122375d262c2SVinicius Costa Gomes 1224c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 1225c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 1226c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 122775d262c2SVinicius Costa Gomes continue; 122875d262c2SVinicius Costa Gomes 122975d262c2SVinicius Costa Gomes return k; 123075d262c2SVinicius Costa Gomes } 123175d262c2SVinicius Costa Gomes 123275d262c2SVinicius Costa Gomes return NULL; 123375d262c2SVinicius Costa Gomes } 123475d262c2SVinicius Costa Gomes 1235c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1236c9839a11SVinicius Costa Gomes u8 addr_type) 123775d262c2SVinicius Costa Gomes { 1238c9839a11SVinicius Costa Gomes struct smp_ltk *k; 123975d262c2SVinicius Costa Gomes 1240c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 1241c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 1242c9839a11SVinicius Costa Gomes bacmp(bdaddr, &k->bdaddr) == 0) 124375d262c2SVinicius Costa Gomes return k; 124475d262c2SVinicius Costa Gomes 124575d262c2SVinicius Costa Gomes return NULL; 124675d262c2SVinicius Costa Gomes } 124775d262c2SVinicius Costa Gomes 1248d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 1249d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 125055ed8ca1SJohan Hedberg { 125155ed8ca1SJohan Hedberg struct link_key *key, *old_key; 1252745c0ce3SVishal Agarwal u8 old_key_type; 1253745c0ce3SVishal Agarwal bool persistent; 125455ed8ca1SJohan Hedberg 125555ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 125655ed8ca1SJohan Hedberg if (old_key) { 125755ed8ca1SJohan Hedberg old_key_type = old_key->type; 125855ed8ca1SJohan Hedberg key = old_key; 125955ed8ca1SJohan Hedberg } else { 126012adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 126155ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 126255ed8ca1SJohan Hedberg if (!key) 126355ed8ca1SJohan Hedberg return -ENOMEM; 126455ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 126555ed8ca1SJohan Hedberg } 126655ed8ca1SJohan Hedberg 126755ed8ca1SJohan Hedberg BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); 126855ed8ca1SJohan Hedberg 1269d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1270d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1271d25e28abSJohan Hedberg * previous key */ 1272d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1273a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 1274d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1275655fe6ecSJohan Hedberg if (conn) 1276655fe6ecSJohan Hedberg conn->key_type = type; 1277655fe6ecSJohan Hedberg } 1278d25e28abSJohan Hedberg 127955ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 12809b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 128155ed8ca1SJohan Hedberg key->pin_len = pin_len; 128255ed8ca1SJohan Hedberg 1283b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 128455ed8ca1SJohan Hedberg key->type = old_key_type; 12854748fed2SJohan Hedberg else 12864748fed2SJohan Hedberg key->type = type; 12874748fed2SJohan Hedberg 12884df378a1SJohan Hedberg if (!new_key) 12894df378a1SJohan Hedberg return 0; 12904df378a1SJohan Hedberg 12914df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 12924df378a1SJohan Hedberg 1293744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 12944df378a1SJohan Hedberg 12956ec5bcadSVishal Agarwal if (conn) 12966ec5bcadSVishal Agarwal conn->flush_key = !persistent; 129755ed8ca1SJohan Hedberg 129855ed8ca1SJohan Hedberg return 0; 129955ed8ca1SJohan Hedberg } 130055ed8ca1SJohan Hedberg 1301c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 13029a006657SAndrei Emeltchenko int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 130304124681SGustavo F. Padovan ediv, u8 rand[8]) 130475d262c2SVinicius Costa Gomes { 1305c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 130675d262c2SVinicius Costa Gomes 1307c9839a11SVinicius Costa Gomes if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 1308c9839a11SVinicius Costa Gomes return 0; 130975d262c2SVinicius Costa Gomes 1310c9839a11SVinicius Costa Gomes old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 1311c9839a11SVinicius Costa Gomes if (old_key) 131275d262c2SVinicius Costa Gomes key = old_key; 1313c9839a11SVinicius Costa Gomes else { 1314c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 131575d262c2SVinicius Costa Gomes if (!key) 131675d262c2SVinicius Costa Gomes return -ENOMEM; 1317c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 131875d262c2SVinicius Costa Gomes } 131975d262c2SVinicius Costa Gomes 132075d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 1321c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 1322c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 1323c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 1324c9839a11SVinicius Costa Gomes key->ediv = ediv; 1325c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 1326c9839a11SVinicius Costa Gomes key->type = type; 1327c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 132875d262c2SVinicius Costa Gomes 1329c9839a11SVinicius Costa Gomes if (!new_key) 1330c9839a11SVinicius Costa Gomes return 0; 133175d262c2SVinicius Costa Gomes 1332261cc5aaSVinicius Costa Gomes if (type & HCI_SMP_LTK) 1333261cc5aaSVinicius Costa Gomes mgmt_new_ltk(hdev, key, 1); 1334261cc5aaSVinicius Costa Gomes 133575d262c2SVinicius Costa Gomes return 0; 133675d262c2SVinicius Costa Gomes } 133775d262c2SVinicius Costa Gomes 133855ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 133955ed8ca1SJohan Hedberg { 134055ed8ca1SJohan Hedberg struct link_key *key; 134155ed8ca1SJohan Hedberg 134255ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 134355ed8ca1SJohan Hedberg if (!key) 134455ed8ca1SJohan Hedberg return -ENOENT; 134555ed8ca1SJohan Hedberg 134655ed8ca1SJohan Hedberg BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 134755ed8ca1SJohan Hedberg 134855ed8ca1SJohan Hedberg list_del(&key->list); 134955ed8ca1SJohan Hedberg kfree(key); 135055ed8ca1SJohan Hedberg 135155ed8ca1SJohan Hedberg return 0; 135255ed8ca1SJohan Hedberg } 135355ed8ca1SJohan Hedberg 1354b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 1355b899efafSVinicius Costa Gomes { 1356b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1357b899efafSVinicius Costa Gomes 1358b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1359b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 1360b899efafSVinicius Costa Gomes continue; 1361b899efafSVinicius Costa Gomes 1362b899efafSVinicius Costa Gomes BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 1363b899efafSVinicius Costa Gomes 1364b899efafSVinicius Costa Gomes list_del(&k->list); 1365b899efafSVinicius Costa Gomes kfree(k); 1366b899efafSVinicius Costa Gomes } 1367b899efafSVinicius Costa Gomes 1368b899efafSVinicius Costa Gomes return 0; 1369b899efafSVinicius Costa Gomes } 1370b899efafSVinicius Costa Gomes 13716bd32326SVille Tervo /* HCI command timer function */ 13726bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg) 13736bd32326SVille Tervo { 13746bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 13756bd32326SVille Tervo 13766bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 13776bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 1378c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 13796bd32326SVille Tervo } 13806bd32326SVille Tervo 13812763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 13822763eda6SSzymon Janc bdaddr_t *bdaddr) 13832763eda6SSzymon Janc { 13842763eda6SSzymon Janc struct oob_data *data; 13852763eda6SSzymon Janc 13862763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 13872763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 13882763eda6SSzymon Janc return data; 13892763eda6SSzymon Janc 13902763eda6SSzymon Janc return NULL; 13912763eda6SSzymon Janc } 13922763eda6SSzymon Janc 13932763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 13942763eda6SSzymon Janc { 13952763eda6SSzymon Janc struct oob_data *data; 13962763eda6SSzymon Janc 13972763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 13982763eda6SSzymon Janc if (!data) 13992763eda6SSzymon Janc return -ENOENT; 14002763eda6SSzymon Janc 14012763eda6SSzymon Janc BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 14022763eda6SSzymon Janc 14032763eda6SSzymon Janc list_del(&data->list); 14042763eda6SSzymon Janc kfree(data); 14052763eda6SSzymon Janc 14062763eda6SSzymon Janc return 0; 14072763eda6SSzymon Janc } 14082763eda6SSzymon Janc 14092763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 14102763eda6SSzymon Janc { 14112763eda6SSzymon Janc struct oob_data *data, *n; 14122763eda6SSzymon Janc 14132763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 14142763eda6SSzymon Janc list_del(&data->list); 14152763eda6SSzymon Janc kfree(data); 14162763eda6SSzymon Janc } 14172763eda6SSzymon Janc 14182763eda6SSzymon Janc return 0; 14192763eda6SSzymon Janc } 14202763eda6SSzymon Janc 14212763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 14222763eda6SSzymon Janc u8 *randomizer) 14232763eda6SSzymon Janc { 14242763eda6SSzymon Janc struct oob_data *data; 14252763eda6SSzymon Janc 14262763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14272763eda6SSzymon Janc 14282763eda6SSzymon Janc if (!data) { 14292763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 14302763eda6SSzymon Janc if (!data) 14312763eda6SSzymon Janc return -ENOMEM; 14322763eda6SSzymon Janc 14332763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 14342763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 14352763eda6SSzymon Janc } 14362763eda6SSzymon Janc 14372763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 14382763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 14392763eda6SSzymon Janc 14402763eda6SSzymon Janc BT_DBG("%s for %s", hdev->name, batostr(bdaddr)); 14412763eda6SSzymon Janc 14422763eda6SSzymon Janc return 0; 14432763eda6SSzymon Janc } 14442763eda6SSzymon Janc 144504124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 1446b2a66aadSAntti Julku { 1447b2a66aadSAntti Julku struct bdaddr_list *b; 1448b2a66aadSAntti Julku 14498035ded4SLuiz Augusto von Dentz list_for_each_entry(b, &hdev->blacklist, list) 1450b2a66aadSAntti Julku if (bacmp(bdaddr, &b->bdaddr) == 0) 1451b2a66aadSAntti Julku return b; 1452b2a66aadSAntti Julku 1453b2a66aadSAntti Julku return NULL; 1454b2a66aadSAntti Julku } 1455b2a66aadSAntti Julku 1456b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 1457b2a66aadSAntti Julku { 1458b2a66aadSAntti Julku struct list_head *p, *n; 1459b2a66aadSAntti Julku 1460b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 1461b2a66aadSAntti Julku struct bdaddr_list *b; 1462b2a66aadSAntti Julku 1463b2a66aadSAntti Julku b = list_entry(p, struct bdaddr_list, list); 1464b2a66aadSAntti Julku 1465b2a66aadSAntti Julku list_del(p); 1466b2a66aadSAntti Julku kfree(b); 1467b2a66aadSAntti Julku } 1468b2a66aadSAntti Julku 1469b2a66aadSAntti Julku return 0; 1470b2a66aadSAntti Julku } 1471b2a66aadSAntti Julku 147288c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1473b2a66aadSAntti Julku { 1474b2a66aadSAntti Julku struct bdaddr_list *entry; 1475b2a66aadSAntti Julku 1476b2a66aadSAntti Julku if (bacmp(bdaddr, BDADDR_ANY) == 0) 1477b2a66aadSAntti Julku return -EBADF; 1478b2a66aadSAntti Julku 14795e762444SAntti Julku if (hci_blacklist_lookup(hdev, bdaddr)) 14805e762444SAntti Julku return -EEXIST; 1481b2a66aadSAntti Julku 1482b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 14835e762444SAntti Julku if (!entry) 14845e762444SAntti Julku return -ENOMEM; 1485b2a66aadSAntti Julku 1486b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 1487b2a66aadSAntti Julku 1488b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 1489b2a66aadSAntti Julku 149088c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 1491b2a66aadSAntti Julku } 1492b2a66aadSAntti Julku 149388c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1494b2a66aadSAntti Julku { 1495b2a66aadSAntti Julku struct bdaddr_list *entry; 1496b2a66aadSAntti Julku 14971ec918ceSSzymon Janc if (bacmp(bdaddr, BDADDR_ANY) == 0) 14985e762444SAntti Julku return hci_blacklist_clear(hdev); 1499b2a66aadSAntti Julku 1500b2a66aadSAntti Julku entry = hci_blacklist_lookup(hdev, bdaddr); 15011ec918ceSSzymon Janc if (!entry) 15025e762444SAntti Julku return -ENOENT; 1503b2a66aadSAntti Julku 1504b2a66aadSAntti Julku list_del(&entry->list); 1505b2a66aadSAntti Julku kfree(entry); 1506b2a66aadSAntti Julku 150788c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 1508b2a66aadSAntti Julku } 1509b2a66aadSAntti Julku 15107ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt) 15117ba8b4beSAndre Guedes { 15127ba8b4beSAndre Guedes struct le_scan_params *param = (struct le_scan_params *) opt; 15137ba8b4beSAndre Guedes struct hci_cp_le_set_scan_param cp; 15147ba8b4beSAndre Guedes 15157ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 15167ba8b4beSAndre Guedes cp.type = param->type; 15177ba8b4beSAndre Guedes cp.interval = cpu_to_le16(param->interval); 15187ba8b4beSAndre Guedes cp.window = cpu_to_le16(param->window); 15197ba8b4beSAndre Guedes 15207ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); 15217ba8b4beSAndre Guedes } 15227ba8b4beSAndre Guedes 15237ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt) 15247ba8b4beSAndre Guedes { 15257ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 15267ba8b4beSAndre Guedes 15277ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 15287ba8b4beSAndre Guedes cp.enable = 1; 15290431a43cSAndre Guedes cp.filter_dup = 1; 15307ba8b4beSAndre Guedes 15317ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 15327ba8b4beSAndre Guedes } 15337ba8b4beSAndre Guedes 15347ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, 15357ba8b4beSAndre Guedes u16 window, int timeout) 15367ba8b4beSAndre Guedes { 15377ba8b4beSAndre Guedes long timeo = msecs_to_jiffies(3000); 15387ba8b4beSAndre Guedes struct le_scan_params param; 15397ba8b4beSAndre Guedes int err; 15407ba8b4beSAndre Guedes 15417ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 15427ba8b4beSAndre Guedes 15437ba8b4beSAndre Guedes if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 15447ba8b4beSAndre Guedes return -EINPROGRESS; 15457ba8b4beSAndre Guedes 15467ba8b4beSAndre Guedes param.type = type; 15477ba8b4beSAndre Guedes param.interval = interval; 15487ba8b4beSAndre Guedes param.window = window; 15497ba8b4beSAndre Guedes 15507ba8b4beSAndre Guedes hci_req_lock(hdev); 15517ba8b4beSAndre Guedes 15527ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_param_req, (unsigned long) ¶m, 15537ba8b4beSAndre Guedes timeo); 15547ba8b4beSAndre Guedes if (!err) 15557ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_enable_req, 0, timeo); 15567ba8b4beSAndre Guedes 15577ba8b4beSAndre Guedes hci_req_unlock(hdev); 15587ba8b4beSAndre Guedes 15597ba8b4beSAndre Guedes if (err < 0) 15607ba8b4beSAndre Guedes return err; 15617ba8b4beSAndre Guedes 15627ba8b4beSAndre Guedes schedule_delayed_work(&hdev->le_scan_disable, 15637ba8b4beSAndre Guedes msecs_to_jiffies(timeout)); 15647ba8b4beSAndre Guedes 15657ba8b4beSAndre Guedes return 0; 15667ba8b4beSAndre Guedes } 15677ba8b4beSAndre Guedes 15687dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev) 15697dbfac1dSAndre Guedes { 15707dbfac1dSAndre Guedes BT_DBG("%s", hdev->name); 15717dbfac1dSAndre Guedes 15727dbfac1dSAndre Guedes if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 15737dbfac1dSAndre Guedes return -EALREADY; 15747dbfac1dSAndre Guedes 15757dbfac1dSAndre Guedes if (cancel_delayed_work(&hdev->le_scan_disable)) { 15767dbfac1dSAndre Guedes struct hci_cp_le_set_scan_enable cp; 15777dbfac1dSAndre Guedes 15787dbfac1dSAndre Guedes /* Send HCI command to disable LE Scan */ 15797dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 15807dbfac1dSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 15817dbfac1dSAndre Guedes } 15827dbfac1dSAndre Guedes 15837dbfac1dSAndre Guedes return 0; 15847dbfac1dSAndre Guedes } 15857dbfac1dSAndre Guedes 15867ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 15877ba8b4beSAndre Guedes { 15887ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 15897ba8b4beSAndre Guedes le_scan_disable.work); 15907ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 15917ba8b4beSAndre Guedes 15927ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 15937ba8b4beSAndre Guedes 15947ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 15957ba8b4beSAndre Guedes 15967ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 15977ba8b4beSAndre Guedes } 15987ba8b4beSAndre Guedes 159928b75a89SAndre Guedes static void le_scan_work(struct work_struct *work) 160028b75a89SAndre Guedes { 160128b75a89SAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan); 160228b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 160328b75a89SAndre Guedes 160428b75a89SAndre Guedes BT_DBG("%s", hdev->name); 160528b75a89SAndre Guedes 160604124681SGustavo F. Padovan hci_do_le_scan(hdev, param->type, param->interval, param->window, 160704124681SGustavo F. Padovan param->timeout); 160828b75a89SAndre Guedes } 160928b75a89SAndre Guedes 161028b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, 161128b75a89SAndre Guedes int timeout) 161228b75a89SAndre Guedes { 161328b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 161428b75a89SAndre Guedes 161528b75a89SAndre Guedes BT_DBG("%s", hdev->name); 161628b75a89SAndre Guedes 161728b75a89SAndre Guedes if (work_busy(&hdev->le_scan)) 161828b75a89SAndre Guedes return -EINPROGRESS; 161928b75a89SAndre Guedes 162028b75a89SAndre Guedes param->type = type; 162128b75a89SAndre Guedes param->interval = interval; 162228b75a89SAndre Guedes param->window = window; 162328b75a89SAndre Guedes param->timeout = timeout; 162428b75a89SAndre Guedes 162528b75a89SAndre Guedes queue_work(system_long_wq, &hdev->le_scan); 162628b75a89SAndre Guedes 162728b75a89SAndre Guedes return 0; 162828b75a89SAndre Guedes } 162928b75a89SAndre Guedes 16309be0dab7SDavid Herrmann /* Alloc HCI device */ 16319be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 16329be0dab7SDavid Herrmann { 16339be0dab7SDavid Herrmann struct hci_dev *hdev; 16349be0dab7SDavid Herrmann 16359be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 16369be0dab7SDavid Herrmann if (!hdev) 16379be0dab7SDavid Herrmann return NULL; 16389be0dab7SDavid Herrmann 1639b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 1640b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 1641b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 1642b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 1643b1b813d4SDavid Herrmann 1644b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 1645b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 1646b1b813d4SDavid Herrmann 1647b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 1648b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 1649b1b813d4SDavid Herrmann 1650b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 1651b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 1652b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 1653b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 1654b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 1655b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 1656b1b813d4SDavid Herrmann 1657b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 1658b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 1659b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 1660b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 1661b1b813d4SDavid Herrmann INIT_WORK(&hdev->le_scan, le_scan_work); 1662b1b813d4SDavid Herrmann 1663b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 1664b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 1665b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 1666b1b813d4SDavid Herrmann 16679be0dab7SDavid Herrmann skb_queue_head_init(&hdev->driver_init); 1668b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 1669b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 1670b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 1671b1b813d4SDavid Herrmann 1672b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 1673b1b813d4SDavid Herrmann 1674b1b813d4SDavid Herrmann setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); 1675b1b813d4SDavid Herrmann 1676b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 1677b1b813d4SDavid Herrmann discovery_init(hdev); 1678b1b813d4SDavid Herrmann hci_conn_hash_init(hdev); 16799be0dab7SDavid Herrmann 16809be0dab7SDavid Herrmann return hdev; 16819be0dab7SDavid Herrmann } 16829be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 16839be0dab7SDavid Herrmann 16849be0dab7SDavid Herrmann /* Free HCI device */ 16859be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 16869be0dab7SDavid Herrmann { 16879be0dab7SDavid Herrmann skb_queue_purge(&hdev->driver_init); 16889be0dab7SDavid Herrmann 16899be0dab7SDavid Herrmann /* will free via device release */ 16909be0dab7SDavid Herrmann put_device(&hdev->dev); 16919be0dab7SDavid Herrmann } 16929be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 16939be0dab7SDavid Herrmann 16941da177e4SLinus Torvalds /* Register HCI device */ 16951da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 16961da177e4SLinus Torvalds { 1697b1b813d4SDavid Herrmann int id, error; 16981da177e4SLinus Torvalds 1699010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 17001da177e4SLinus Torvalds return -EINVAL; 17011da177e4SLinus Torvalds 170208add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 170308add513SMat Martineau * so the index can be used as the AMP controller ID. 170408add513SMat Martineau */ 17053df92b31SSasha Levin switch (hdev->dev_type) { 17063df92b31SSasha Levin case HCI_BREDR: 17073df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 17081da177e4SLinus Torvalds break; 17093df92b31SSasha Levin case HCI_AMP: 17103df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 17113df92b31SSasha Levin break; 17123df92b31SSasha Levin default: 17133df92b31SSasha Levin return -EINVAL; 17141da177e4SLinus Torvalds } 17151da177e4SLinus Torvalds 17163df92b31SSasha Levin if (id < 0) 17173df92b31SSasha Levin return id; 17183df92b31SSasha Levin 17191da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 17201da177e4SLinus Torvalds hdev->id = id; 17212d8b3a11SAndrei Emeltchenko 17222d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 17232d8b3a11SAndrei Emeltchenko 17243df92b31SSasha Levin write_lock(&hci_dev_list_lock); 17253df92b31SSasha Levin list_add(&hdev->list, &hci_dev_list); 1726f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 17271da177e4SLinus Torvalds 172832845eb1SGustavo F. Padovan hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | 172932845eb1SGustavo F. Padovan WQ_MEM_RECLAIM, 1); 173033ca954dSDavid Herrmann if (!hdev->workqueue) { 173133ca954dSDavid Herrmann error = -ENOMEM; 173233ca954dSDavid Herrmann goto err; 173333ca954dSDavid Herrmann } 1734f48fd9c8SMarcel Holtmann 173533ca954dSDavid Herrmann error = hci_add_sysfs(hdev); 173633ca954dSDavid Herrmann if (error < 0) 173733ca954dSDavid Herrmann goto err_wqueue; 17381da177e4SLinus Torvalds 1739611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 1740a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 1741a8c5fb1aSGustavo Padovan hdev); 1742611b30f7SMarcel Holtmann if (hdev->rfkill) { 1743611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 1744611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1745611b30f7SMarcel Holtmann hdev->rfkill = NULL; 1746611b30f7SMarcel Holtmann } 1747611b30f7SMarcel Holtmann } 1748611b30f7SMarcel Holtmann 1749a8b2d5c2SJohan Hedberg set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 1750a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 17517f971041SGustavo F. Padovan schedule_work(&hdev->power_on); 1752ab81cbf9SJohan Hedberg 17531da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 1754dc946bd8SDavid Herrmann hci_dev_hold(hdev); 17551da177e4SLinus Torvalds 17561da177e4SLinus Torvalds return id; 1757f48fd9c8SMarcel Holtmann 175833ca954dSDavid Herrmann err_wqueue: 175933ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 176033ca954dSDavid Herrmann err: 17613df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 1762f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 1763f48fd9c8SMarcel Holtmann list_del(&hdev->list); 1764f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 1765f48fd9c8SMarcel Holtmann 176633ca954dSDavid Herrmann return error; 17671da177e4SLinus Torvalds } 17681da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 17691da177e4SLinus Torvalds 17701da177e4SLinus Torvalds /* Unregister HCI device */ 177159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 17721da177e4SLinus Torvalds { 17733df92b31SSasha Levin int i, id; 1774ef222013SMarcel Holtmann 1775c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 17761da177e4SLinus Torvalds 177794324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 177894324962SJohan Hovold 17793df92b31SSasha Levin id = hdev->id; 17803df92b31SSasha Levin 1781f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 17821da177e4SLinus Torvalds list_del(&hdev->list); 1783f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 17841da177e4SLinus Torvalds 17851da177e4SLinus Torvalds hci_dev_do_close(hdev); 17861da177e4SLinus Torvalds 1787cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1788ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 1789ef222013SMarcel Holtmann 1790ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 1791a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 179209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1793744cf19eSJohan Hedberg mgmt_index_removed(hdev); 179409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 179556e5cb86SJohan Hedberg } 1796ab81cbf9SJohan Hedberg 17972e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 17982e58ef3eSJohan Hedberg * pending list */ 17992e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 18002e58ef3eSJohan Hedberg 18011da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 18021da177e4SLinus Torvalds 1803611b30f7SMarcel Holtmann if (hdev->rfkill) { 1804611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 1805611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1806611b30f7SMarcel Holtmann } 1807611b30f7SMarcel Holtmann 1808ce242970SDavid Herrmann hci_del_sysfs(hdev); 1809147e2d59SDave Young 1810f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 1811f48fd9c8SMarcel Holtmann 181209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1813e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 18142aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 181555ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 1816b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 18172763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 181809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 1819e2e0cacbSJohan Hedberg 1820dc946bd8SDavid Herrmann hci_dev_put(hdev); 18213df92b31SSasha Levin 18223df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 18231da177e4SLinus Torvalds } 18241da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 18251da177e4SLinus Torvalds 18261da177e4SLinus Torvalds /* Suspend HCI device */ 18271da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 18281da177e4SLinus Torvalds { 18291da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 18301da177e4SLinus Torvalds return 0; 18311da177e4SLinus Torvalds } 18321da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 18331da177e4SLinus Torvalds 18341da177e4SLinus Torvalds /* Resume HCI device */ 18351da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 18361da177e4SLinus Torvalds { 18371da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 18381da177e4SLinus Torvalds return 0; 18391da177e4SLinus Torvalds } 18401da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 18411da177e4SLinus Torvalds 184276bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 184376bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb) 184476bca880SMarcel Holtmann { 184576bca880SMarcel Holtmann struct hci_dev *hdev = (struct hci_dev *) skb->dev; 184676bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 184776bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 184876bca880SMarcel Holtmann kfree_skb(skb); 184976bca880SMarcel Holtmann return -ENXIO; 185076bca880SMarcel Holtmann } 185176bca880SMarcel Holtmann 185276bca880SMarcel Holtmann /* Incomming skb */ 185376bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 185476bca880SMarcel Holtmann 185576bca880SMarcel Holtmann /* Time stamp */ 185676bca880SMarcel Holtmann __net_timestamp(skb); 185776bca880SMarcel Holtmann 185876bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 1859b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 1860c78ae283SMarcel Holtmann 186176bca880SMarcel Holtmann return 0; 186276bca880SMarcel Holtmann } 186376bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 186476bca880SMarcel Holtmann 186533e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 18661e429f38SGustavo F. Padovan int count, __u8 index) 186733e882a5SSuraj Sumangala { 186833e882a5SSuraj Sumangala int len = 0; 186933e882a5SSuraj Sumangala int hlen = 0; 187033e882a5SSuraj Sumangala int remain = count; 187133e882a5SSuraj Sumangala struct sk_buff *skb; 187233e882a5SSuraj Sumangala struct bt_skb_cb *scb; 187333e882a5SSuraj Sumangala 187433e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 187533e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 187633e882a5SSuraj Sumangala return -EILSEQ; 187733e882a5SSuraj Sumangala 187833e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 187933e882a5SSuraj Sumangala 188033e882a5SSuraj Sumangala if (!skb) { 188133e882a5SSuraj Sumangala switch (type) { 188233e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 188333e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 188433e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 188533e882a5SSuraj Sumangala break; 188633e882a5SSuraj Sumangala case HCI_EVENT_PKT: 188733e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 188833e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 188933e882a5SSuraj Sumangala break; 189033e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 189133e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 189233e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 189333e882a5SSuraj Sumangala break; 189433e882a5SSuraj Sumangala } 189533e882a5SSuraj Sumangala 18961e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 189733e882a5SSuraj Sumangala if (!skb) 189833e882a5SSuraj Sumangala return -ENOMEM; 189933e882a5SSuraj Sumangala 190033e882a5SSuraj Sumangala scb = (void *) skb->cb; 190133e882a5SSuraj Sumangala scb->expect = hlen; 190233e882a5SSuraj Sumangala scb->pkt_type = type; 190333e882a5SSuraj Sumangala 190433e882a5SSuraj Sumangala skb->dev = (void *) hdev; 190533e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 190633e882a5SSuraj Sumangala } 190733e882a5SSuraj Sumangala 190833e882a5SSuraj Sumangala while (count) { 190933e882a5SSuraj Sumangala scb = (void *) skb->cb; 191089bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 191133e882a5SSuraj Sumangala 191233e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 191333e882a5SSuraj Sumangala 191433e882a5SSuraj Sumangala count -= len; 191533e882a5SSuraj Sumangala data += len; 191633e882a5SSuraj Sumangala scb->expect -= len; 191733e882a5SSuraj Sumangala remain = count; 191833e882a5SSuraj Sumangala 191933e882a5SSuraj Sumangala switch (type) { 192033e882a5SSuraj Sumangala case HCI_EVENT_PKT: 192133e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 192233e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 192333e882a5SSuraj Sumangala scb->expect = h->plen; 192433e882a5SSuraj Sumangala 192533e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 192633e882a5SSuraj Sumangala kfree_skb(skb); 192733e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 192833e882a5SSuraj Sumangala return -ENOMEM; 192933e882a5SSuraj Sumangala } 193033e882a5SSuraj Sumangala } 193133e882a5SSuraj Sumangala break; 193233e882a5SSuraj Sumangala 193333e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 193433e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 193533e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 193633e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 193733e882a5SSuraj Sumangala 193833e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 193933e882a5SSuraj Sumangala kfree_skb(skb); 194033e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 194133e882a5SSuraj Sumangala return -ENOMEM; 194233e882a5SSuraj Sumangala } 194333e882a5SSuraj Sumangala } 194433e882a5SSuraj Sumangala break; 194533e882a5SSuraj Sumangala 194633e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 194733e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 194833e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 194933e882a5SSuraj Sumangala scb->expect = h->dlen; 195033e882a5SSuraj Sumangala 195133e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 195233e882a5SSuraj Sumangala kfree_skb(skb); 195333e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 195433e882a5SSuraj Sumangala return -ENOMEM; 195533e882a5SSuraj Sumangala } 195633e882a5SSuraj Sumangala } 195733e882a5SSuraj Sumangala break; 195833e882a5SSuraj Sumangala } 195933e882a5SSuraj Sumangala 196033e882a5SSuraj Sumangala if (scb->expect == 0) { 196133e882a5SSuraj Sumangala /* Complete frame */ 196233e882a5SSuraj Sumangala 196333e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 196433e882a5SSuraj Sumangala hci_recv_frame(skb); 196533e882a5SSuraj Sumangala 196633e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 196733e882a5SSuraj Sumangala return remain; 196833e882a5SSuraj Sumangala } 196933e882a5SSuraj Sumangala } 197033e882a5SSuraj Sumangala 197133e882a5SSuraj Sumangala return remain; 197233e882a5SSuraj Sumangala } 197333e882a5SSuraj Sumangala 1974ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 1975ef222013SMarcel Holtmann { 1976f39a3c06SSuraj Sumangala int rem = 0; 1977f39a3c06SSuraj Sumangala 1978ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 1979ef222013SMarcel Holtmann return -EILSEQ; 1980ef222013SMarcel Holtmann 1981da5f6c37SGustavo F. Padovan while (count) { 19821e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 1983f39a3c06SSuraj Sumangala if (rem < 0) 1984f39a3c06SSuraj Sumangala return rem; 1985ef222013SMarcel Holtmann 1986f39a3c06SSuraj Sumangala data += (count - rem); 1987f39a3c06SSuraj Sumangala count = rem; 1988f81c6224SJoe Perches } 1989ef222013SMarcel Holtmann 1990f39a3c06SSuraj Sumangala return rem; 1991ef222013SMarcel Holtmann } 1992ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 1993ef222013SMarcel Holtmann 199499811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 199599811510SSuraj Sumangala 199699811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 199799811510SSuraj Sumangala { 199899811510SSuraj Sumangala int type; 199999811510SSuraj Sumangala int rem = 0; 200099811510SSuraj Sumangala 2001da5f6c37SGustavo F. Padovan while (count) { 200299811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 200399811510SSuraj Sumangala 200499811510SSuraj Sumangala if (!skb) { 200599811510SSuraj Sumangala struct { char type; } *pkt; 200699811510SSuraj Sumangala 200799811510SSuraj Sumangala /* Start of the frame */ 200899811510SSuraj Sumangala pkt = data; 200999811510SSuraj Sumangala type = pkt->type; 201099811510SSuraj Sumangala 201199811510SSuraj Sumangala data++; 201299811510SSuraj Sumangala count--; 201399811510SSuraj Sumangala } else 201499811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 201599811510SSuraj Sumangala 20161e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 20171e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 201899811510SSuraj Sumangala if (rem < 0) 201999811510SSuraj Sumangala return rem; 202099811510SSuraj Sumangala 202199811510SSuraj Sumangala data += (count - rem); 202299811510SSuraj Sumangala count = rem; 2023f81c6224SJoe Perches } 202499811510SSuraj Sumangala 202599811510SSuraj Sumangala return rem; 202699811510SSuraj Sumangala } 202799811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 202899811510SSuraj Sumangala 20291da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 20301da177e4SLinus Torvalds 20311da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 20321da177e4SLinus Torvalds { 20331da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 20341da177e4SLinus Torvalds 2035f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 20361da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 2037f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 20381da177e4SLinus Torvalds 20391da177e4SLinus Torvalds return 0; 20401da177e4SLinus Torvalds } 20411da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 20421da177e4SLinus Torvalds 20431da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 20441da177e4SLinus Torvalds { 20451da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 20461da177e4SLinus Torvalds 2047f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 20481da177e4SLinus Torvalds list_del(&cb->list); 2049f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 20501da177e4SLinus Torvalds 20511da177e4SLinus Torvalds return 0; 20521da177e4SLinus Torvalds } 20531da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 20541da177e4SLinus Torvalds 20551da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb) 20561da177e4SLinus Torvalds { 20571da177e4SLinus Torvalds struct hci_dev *hdev = (struct hci_dev *) skb->dev; 20581da177e4SLinus Torvalds 20591da177e4SLinus Torvalds if (!hdev) { 20601da177e4SLinus Torvalds kfree_skb(skb); 20611da177e4SLinus Torvalds return -ENODEV; 20621da177e4SLinus Torvalds } 20631da177e4SLinus Torvalds 20640d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 20651da177e4SLinus Torvalds 20661da177e4SLinus Torvalds /* Time stamp */ 2067a61bbcf2SPatrick McHardy __net_timestamp(skb); 20681da177e4SLinus Torvalds 2069cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2070cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2071cd82e61cSMarcel Holtmann 2072cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 2073cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 2074470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 20751da177e4SLinus Torvalds } 20761da177e4SLinus Torvalds 20771da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 20781da177e4SLinus Torvalds skb_orphan(skb); 20791da177e4SLinus Torvalds 20801da177e4SLinus Torvalds return hdev->send(skb); 20811da177e4SLinus Torvalds } 20821da177e4SLinus Torvalds 20831da177e4SLinus Torvalds /* Send HCI command */ 2084a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) 20851da177e4SLinus Torvalds { 20861da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 20871da177e4SLinus Torvalds struct hci_command_hdr *hdr; 20881da177e4SLinus Torvalds struct sk_buff *skb; 20891da177e4SLinus Torvalds 2090a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen); 20911da177e4SLinus Torvalds 20921da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 20931da177e4SLinus Torvalds if (!skb) { 2094ef222013SMarcel Holtmann BT_ERR("%s no memory for command", hdev->name); 20951da177e4SLinus Torvalds return -ENOMEM; 20961da177e4SLinus Torvalds } 20971da177e4SLinus Torvalds 20981da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 2099a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 21001da177e4SLinus Torvalds hdr->plen = plen; 21011da177e4SLinus Torvalds 21021da177e4SLinus Torvalds if (plen) 21031da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 21041da177e4SLinus Torvalds 21051da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 21061da177e4SLinus Torvalds 21070d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 21081da177e4SLinus Torvalds skb->dev = (void *) hdev; 2109c78ae283SMarcel Holtmann 2110a5040efaSJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags)) 2111a5040efaSJohan Hedberg hdev->init_last_cmd = opcode; 2112a5040efaSJohan Hedberg 21131da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 2114c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 21151da177e4SLinus Torvalds 21161da177e4SLinus Torvalds return 0; 21171da177e4SLinus Torvalds } 21181da177e4SLinus Torvalds 21191da177e4SLinus Torvalds /* Get data from the previously sent command */ 2120a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 21211da177e4SLinus Torvalds { 21221da177e4SLinus Torvalds struct hci_command_hdr *hdr; 21231da177e4SLinus Torvalds 21241da177e4SLinus Torvalds if (!hdev->sent_cmd) 21251da177e4SLinus Torvalds return NULL; 21261da177e4SLinus Torvalds 21271da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 21281da177e4SLinus Torvalds 2129a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 21301da177e4SLinus Torvalds return NULL; 21311da177e4SLinus Torvalds 2132a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 21331da177e4SLinus Torvalds 21341da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 21351da177e4SLinus Torvalds } 21361da177e4SLinus Torvalds 21371da177e4SLinus Torvalds /* Send ACL data */ 21381da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 21391da177e4SLinus Torvalds { 21401da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 21411da177e4SLinus Torvalds int len = skb->len; 21421da177e4SLinus Torvalds 2143badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 2144badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 21459c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 2146aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 2147aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 21481da177e4SLinus Torvalds } 21491da177e4SLinus Torvalds 215073d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, 215173d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 21521da177e4SLinus Torvalds { 21531da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 21541da177e4SLinus Torvalds struct sk_buff *list; 21551da177e4SLinus Torvalds 2156087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 2157087bfd99SGustavo Padovan skb->data_len = 0; 2158087bfd99SGustavo Padovan 2159087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2160087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 2161087bfd99SGustavo Padovan 216270f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 216370f23020SAndrei Emeltchenko if (!list) { 21641da177e4SLinus Torvalds /* Non fragmented */ 21651da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 21661da177e4SLinus Torvalds 216773d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 21681da177e4SLinus Torvalds } else { 21691da177e4SLinus Torvalds /* Fragmented */ 21701da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 21711da177e4SLinus Torvalds 21721da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 21731da177e4SLinus Torvalds 21741da177e4SLinus Torvalds /* Queue all fragments atomically */ 2175af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 21761da177e4SLinus Torvalds 217773d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 2178e702112fSAndrei Emeltchenko 2179e702112fSAndrei Emeltchenko flags &= ~ACL_START; 2180e702112fSAndrei Emeltchenko flags |= ACL_CONT; 21811da177e4SLinus Torvalds do { 21821da177e4SLinus Torvalds skb = list; list = list->next; 21831da177e4SLinus Torvalds 21841da177e4SLinus Torvalds skb->dev = (void *) hdev; 21850d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2186e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 21871da177e4SLinus Torvalds 21881da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 21891da177e4SLinus Torvalds 219073d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 21911da177e4SLinus Torvalds } while (list); 21921da177e4SLinus Torvalds 2193af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 21941da177e4SLinus Torvalds } 219573d80debSLuiz Augusto von Dentz } 219673d80debSLuiz Augusto von Dentz 219773d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 219873d80debSLuiz Augusto von Dentz { 219973d80debSLuiz Augusto von Dentz struct hci_conn *conn = chan->conn; 220073d80debSLuiz Augusto von Dentz struct hci_dev *hdev = conn->hdev; 220173d80debSLuiz Augusto von Dentz 220273d80debSLuiz Augusto von Dentz BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags); 220373d80debSLuiz Augusto von Dentz 220473d80debSLuiz Augusto von Dentz skb->dev = (void *) hdev; 220573d80debSLuiz Augusto von Dentz 220673d80debSLuiz Augusto von Dentz hci_queue_acl(conn, &chan->data_q, skb, flags); 22071da177e4SLinus Torvalds 22083eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 22091da177e4SLinus Torvalds } 22101da177e4SLinus Torvalds 22111da177e4SLinus Torvalds /* Send SCO data */ 22120d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 22131da177e4SLinus Torvalds { 22141da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 22151da177e4SLinus Torvalds struct hci_sco_hdr hdr; 22161da177e4SLinus Torvalds 22171da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 22181da177e4SLinus Torvalds 2219aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 22201da177e4SLinus Torvalds hdr.dlen = skb->len; 22211da177e4SLinus Torvalds 2222badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 2223badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 22249c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 22251da177e4SLinus Torvalds 22261da177e4SLinus Torvalds skb->dev = (void *) hdev; 22270d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 2228c78ae283SMarcel Holtmann 22291da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 22303eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 22311da177e4SLinus Torvalds } 22321da177e4SLinus Torvalds 22331da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 22341da177e4SLinus Torvalds 22351da177e4SLinus Torvalds /* HCI Connection scheduler */ 22366039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 2237a8c5fb1aSGustavo Padovan int *quote) 22381da177e4SLinus Torvalds { 22391da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 22408035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 2241abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 22421da177e4SLinus Torvalds 22431da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 22441da177e4SLinus Torvalds * added and removed with TX task disabled. */ 2245bf4c6325SGustavo F. Padovan 2246bf4c6325SGustavo F. Padovan rcu_read_lock(); 2247bf4c6325SGustavo F. Padovan 2248bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2249769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 22501da177e4SLinus Torvalds continue; 2251769be974SMarcel Holtmann 2252769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 2253769be974SMarcel Holtmann continue; 2254769be974SMarcel Holtmann 22551da177e4SLinus Torvalds num++; 22561da177e4SLinus Torvalds 22571da177e4SLinus Torvalds if (c->sent < min) { 22581da177e4SLinus Torvalds min = c->sent; 22591da177e4SLinus Torvalds conn = c; 22601da177e4SLinus Torvalds } 226152087a79SLuiz Augusto von Dentz 226252087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 226352087a79SLuiz Augusto von Dentz break; 22641da177e4SLinus Torvalds } 22651da177e4SLinus Torvalds 2266bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2267bf4c6325SGustavo F. Padovan 22681da177e4SLinus Torvalds if (conn) { 22696ed58ec5SVille Tervo int cnt, q; 22706ed58ec5SVille Tervo 22716ed58ec5SVille Tervo switch (conn->type) { 22726ed58ec5SVille Tervo case ACL_LINK: 22736ed58ec5SVille Tervo cnt = hdev->acl_cnt; 22746ed58ec5SVille Tervo break; 22756ed58ec5SVille Tervo case SCO_LINK: 22766ed58ec5SVille Tervo case ESCO_LINK: 22776ed58ec5SVille Tervo cnt = hdev->sco_cnt; 22786ed58ec5SVille Tervo break; 22796ed58ec5SVille Tervo case LE_LINK: 22806ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 22816ed58ec5SVille Tervo break; 22826ed58ec5SVille Tervo default: 22836ed58ec5SVille Tervo cnt = 0; 22846ed58ec5SVille Tervo BT_ERR("Unknown link type"); 22856ed58ec5SVille Tervo } 22866ed58ec5SVille Tervo 22876ed58ec5SVille Tervo q = cnt / num; 22881da177e4SLinus Torvalds *quote = q ? q : 1; 22891da177e4SLinus Torvalds } else 22901da177e4SLinus Torvalds *quote = 0; 22911da177e4SLinus Torvalds 22921da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 22931da177e4SLinus Torvalds return conn; 22941da177e4SLinus Torvalds } 22951da177e4SLinus Torvalds 22966039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 22971da177e4SLinus Torvalds { 22981da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 22991da177e4SLinus Torvalds struct hci_conn *c; 23001da177e4SLinus Torvalds 2301bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 23021da177e4SLinus Torvalds 2303bf4c6325SGustavo F. Padovan rcu_read_lock(); 2304bf4c6325SGustavo F. Padovan 23051da177e4SLinus Torvalds /* Kill stalled connections */ 2306bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2307bae1f5d9SVille Tervo if (c->type == type && c->sent) { 2308bae1f5d9SVille Tervo BT_ERR("%s killing stalled connection %s", 23091da177e4SLinus Torvalds hdev->name, batostr(&c->dst)); 23107490c6c2SAndrei Emeltchenko hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM); 23111da177e4SLinus Torvalds } 23121da177e4SLinus Torvalds } 2313bf4c6325SGustavo F. Padovan 2314bf4c6325SGustavo F. Padovan rcu_read_unlock(); 23151da177e4SLinus Torvalds } 23161da177e4SLinus Torvalds 23176039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 231873d80debSLuiz Augusto von Dentz int *quote) 231973d80debSLuiz Augusto von Dentz { 232073d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 232173d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 2322abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 232373d80debSLuiz Augusto von Dentz struct hci_conn *conn; 232473d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 232573d80debSLuiz Augusto von Dentz 232673d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 232773d80debSLuiz Augusto von Dentz 2328bf4c6325SGustavo F. Padovan rcu_read_lock(); 2329bf4c6325SGustavo F. Padovan 2330bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 233173d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 233273d80debSLuiz Augusto von Dentz 233373d80debSLuiz Augusto von Dentz if (conn->type != type) 233473d80debSLuiz Augusto von Dentz continue; 233573d80debSLuiz Augusto von Dentz 233673d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 233773d80debSLuiz Augusto von Dentz continue; 233873d80debSLuiz Augusto von Dentz 233973d80debSLuiz Augusto von Dentz conn_num++; 234073d80debSLuiz Augusto von Dentz 23418192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 234273d80debSLuiz Augusto von Dentz struct sk_buff *skb; 234373d80debSLuiz Augusto von Dentz 234473d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 234573d80debSLuiz Augusto von Dentz continue; 234673d80debSLuiz Augusto von Dentz 234773d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 234873d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 234973d80debSLuiz Augusto von Dentz continue; 235073d80debSLuiz Augusto von Dentz 235173d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 235273d80debSLuiz Augusto von Dentz num = 0; 235373d80debSLuiz Augusto von Dentz min = ~0; 235473d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 235573d80debSLuiz Augusto von Dentz } 235673d80debSLuiz Augusto von Dentz 235773d80debSLuiz Augusto von Dentz num++; 235873d80debSLuiz Augusto von Dentz 235973d80debSLuiz Augusto von Dentz if (conn->sent < min) { 236073d80debSLuiz Augusto von Dentz min = conn->sent; 236173d80debSLuiz Augusto von Dentz chan = tmp; 236273d80debSLuiz Augusto von Dentz } 236373d80debSLuiz Augusto von Dentz } 236473d80debSLuiz Augusto von Dentz 236573d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 236673d80debSLuiz Augusto von Dentz break; 236773d80debSLuiz Augusto von Dentz } 236873d80debSLuiz Augusto von Dentz 2369bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2370bf4c6325SGustavo F. Padovan 237173d80debSLuiz Augusto von Dentz if (!chan) 237273d80debSLuiz Augusto von Dentz return NULL; 237373d80debSLuiz Augusto von Dentz 237473d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 237573d80debSLuiz Augusto von Dentz case ACL_LINK: 237673d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 237773d80debSLuiz Augusto von Dentz break; 237873d80debSLuiz Augusto von Dentz case SCO_LINK: 237973d80debSLuiz Augusto von Dentz case ESCO_LINK: 238073d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 238173d80debSLuiz Augusto von Dentz break; 238273d80debSLuiz Augusto von Dentz case LE_LINK: 238373d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 238473d80debSLuiz Augusto von Dentz break; 238573d80debSLuiz Augusto von Dentz default: 238673d80debSLuiz Augusto von Dentz cnt = 0; 238773d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 238873d80debSLuiz Augusto von Dentz } 238973d80debSLuiz Augusto von Dentz 239073d80debSLuiz Augusto von Dentz q = cnt / num; 239173d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 239273d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 239373d80debSLuiz Augusto von Dentz return chan; 239473d80debSLuiz Augusto von Dentz } 239573d80debSLuiz Augusto von Dentz 239602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 239702b20f0bSLuiz Augusto von Dentz { 239802b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 239902b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 240002b20f0bSLuiz Augusto von Dentz int num = 0; 240102b20f0bSLuiz Augusto von Dentz 240202b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 240302b20f0bSLuiz Augusto von Dentz 2404bf4c6325SGustavo F. Padovan rcu_read_lock(); 2405bf4c6325SGustavo F. Padovan 2406bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 240702b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 240802b20f0bSLuiz Augusto von Dentz 240902b20f0bSLuiz Augusto von Dentz if (conn->type != type) 241002b20f0bSLuiz Augusto von Dentz continue; 241102b20f0bSLuiz Augusto von Dentz 241202b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 241302b20f0bSLuiz Augusto von Dentz continue; 241402b20f0bSLuiz Augusto von Dentz 241502b20f0bSLuiz Augusto von Dentz num++; 241602b20f0bSLuiz Augusto von Dentz 24178192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 241802b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 241902b20f0bSLuiz Augusto von Dentz 242002b20f0bSLuiz Augusto von Dentz if (chan->sent) { 242102b20f0bSLuiz Augusto von Dentz chan->sent = 0; 242202b20f0bSLuiz Augusto von Dentz continue; 242302b20f0bSLuiz Augusto von Dentz } 242402b20f0bSLuiz Augusto von Dentz 242502b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 242602b20f0bSLuiz Augusto von Dentz continue; 242702b20f0bSLuiz Augusto von Dentz 242802b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 242902b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 243002b20f0bSLuiz Augusto von Dentz continue; 243102b20f0bSLuiz Augusto von Dentz 243202b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 243302b20f0bSLuiz Augusto von Dentz 243402b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 243502b20f0bSLuiz Augusto von Dentz skb->priority); 243602b20f0bSLuiz Augusto von Dentz } 243702b20f0bSLuiz Augusto von Dentz 243802b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 243902b20f0bSLuiz Augusto von Dentz break; 244002b20f0bSLuiz Augusto von Dentz } 2441bf4c6325SGustavo F. Padovan 2442bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2443bf4c6325SGustavo F. Padovan 244402b20f0bSLuiz Augusto von Dentz } 244502b20f0bSLuiz Augusto von Dentz 2446b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 2447b71d385aSAndrei Emeltchenko { 2448b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 2449b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 2450b71d385aSAndrei Emeltchenko } 2451b71d385aSAndrei Emeltchenko 24526039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 24531da177e4SLinus Torvalds { 24541da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 24551da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 24561da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 245763d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 2458cc48dc0aSAndrei Emeltchenko msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) 2459bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 24601da177e4SLinus Torvalds } 246163d2bc1bSAndrei Emeltchenko } 24621da177e4SLinus Torvalds 24636039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 246463d2bc1bSAndrei Emeltchenko { 246563d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 246663d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 246763d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 246863d2bc1bSAndrei Emeltchenko int quote; 246963d2bc1bSAndrei Emeltchenko 247063d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 247104837f64SMarcel Holtmann 247273d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 247373d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2474ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2475ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 247673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 247773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 247873d80debSLuiz Augusto von Dentz 2479ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2480ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2481ec1cce24SLuiz Augusto von Dentz break; 2482ec1cce24SLuiz Augusto von Dentz 2483ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2484ec1cce24SLuiz Augusto von Dentz 248573d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 248673d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 248704837f64SMarcel Holtmann 24881da177e4SLinus Torvalds hci_send_frame(skb); 24891da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 24901da177e4SLinus Torvalds 24911da177e4SLinus Torvalds hdev->acl_cnt--; 249273d80debSLuiz Augusto von Dentz chan->sent++; 249373d80debSLuiz Augusto von Dentz chan->conn->sent++; 24941da177e4SLinus Torvalds } 24951da177e4SLinus Torvalds } 249602b20f0bSLuiz Augusto von Dentz 249702b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 249802b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 24991da177e4SLinus Torvalds } 25001da177e4SLinus Torvalds 25016039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 2502b71d385aSAndrei Emeltchenko { 250363d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 2504b71d385aSAndrei Emeltchenko struct hci_chan *chan; 2505b71d385aSAndrei Emeltchenko struct sk_buff *skb; 2506b71d385aSAndrei Emeltchenko int quote; 2507b71d385aSAndrei Emeltchenko 250863d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 2509b71d385aSAndrei Emeltchenko 2510b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 2511b71d385aSAndrei Emeltchenko (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2512b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 2513b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 2514b71d385aSAndrei Emeltchenko int blocks; 2515b71d385aSAndrei Emeltchenko 2516b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 2517b71d385aSAndrei Emeltchenko skb->len, skb->priority); 2518b71d385aSAndrei Emeltchenko 2519b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 2520b71d385aSAndrei Emeltchenko if (skb->priority < priority) 2521b71d385aSAndrei Emeltchenko break; 2522b71d385aSAndrei Emeltchenko 2523b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 2524b71d385aSAndrei Emeltchenko 2525b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 2526b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 2527b71d385aSAndrei Emeltchenko return; 2528b71d385aSAndrei Emeltchenko 2529b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 2530b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 2531b71d385aSAndrei Emeltchenko 2532b71d385aSAndrei Emeltchenko hci_send_frame(skb); 2533b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 2534b71d385aSAndrei Emeltchenko 2535b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 2536b71d385aSAndrei Emeltchenko quote -= blocks; 2537b71d385aSAndrei Emeltchenko 2538b71d385aSAndrei Emeltchenko chan->sent += blocks; 2539b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 2540b71d385aSAndrei Emeltchenko } 2541b71d385aSAndrei Emeltchenko } 2542b71d385aSAndrei Emeltchenko 2543b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 2544b71d385aSAndrei Emeltchenko hci_prio_recalculate(hdev, ACL_LINK); 2545b71d385aSAndrei Emeltchenko } 2546b71d385aSAndrei Emeltchenko 25476039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 2548b71d385aSAndrei Emeltchenko { 2549b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 2550b71d385aSAndrei Emeltchenko 2551b71d385aSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK)) 2552b71d385aSAndrei Emeltchenko return; 2553b71d385aSAndrei Emeltchenko 2554b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 2555b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 2556b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 2557b71d385aSAndrei Emeltchenko break; 2558b71d385aSAndrei Emeltchenko 2559b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 2560b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 2561b71d385aSAndrei Emeltchenko break; 2562b71d385aSAndrei Emeltchenko } 2563b71d385aSAndrei Emeltchenko } 2564b71d385aSAndrei Emeltchenko 25651da177e4SLinus Torvalds /* Schedule SCO */ 25666039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 25671da177e4SLinus Torvalds { 25681da177e4SLinus Torvalds struct hci_conn *conn; 25691da177e4SLinus Torvalds struct sk_buff *skb; 25701da177e4SLinus Torvalds int quote; 25711da177e4SLinus Torvalds 25721da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 25731da177e4SLinus Torvalds 257452087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 257552087a79SLuiz Augusto von Dentz return; 257652087a79SLuiz Augusto von Dentz 25771da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 25781da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 25791da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 25801da177e4SLinus Torvalds hci_send_frame(skb); 25811da177e4SLinus Torvalds 25821da177e4SLinus Torvalds conn->sent++; 25831da177e4SLinus Torvalds if (conn->sent == ~0) 25841da177e4SLinus Torvalds conn->sent = 0; 25851da177e4SLinus Torvalds } 25861da177e4SLinus Torvalds } 25871da177e4SLinus Torvalds } 25881da177e4SLinus Torvalds 25896039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 2590b6a0dc82SMarcel Holtmann { 2591b6a0dc82SMarcel Holtmann struct hci_conn *conn; 2592b6a0dc82SMarcel Holtmann struct sk_buff *skb; 2593b6a0dc82SMarcel Holtmann int quote; 2594b6a0dc82SMarcel Holtmann 2595b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 2596b6a0dc82SMarcel Holtmann 259752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 259852087a79SLuiz Augusto von Dentz return; 259952087a79SLuiz Augusto von Dentz 26008fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 26018fc9ced3SGustavo Padovan "e))) { 2602b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 2603b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 2604b6a0dc82SMarcel Holtmann hci_send_frame(skb); 2605b6a0dc82SMarcel Holtmann 2606b6a0dc82SMarcel Holtmann conn->sent++; 2607b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 2608b6a0dc82SMarcel Holtmann conn->sent = 0; 2609b6a0dc82SMarcel Holtmann } 2610b6a0dc82SMarcel Holtmann } 2611b6a0dc82SMarcel Holtmann } 2612b6a0dc82SMarcel Holtmann 26136039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 26146ed58ec5SVille Tervo { 261573d80debSLuiz Augusto von Dentz struct hci_chan *chan; 26166ed58ec5SVille Tervo struct sk_buff *skb; 261702b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 26186ed58ec5SVille Tervo 26196ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 26206ed58ec5SVille Tervo 262152087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 262252087a79SLuiz Augusto von Dentz return; 262352087a79SLuiz Augusto von Dentz 26246ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 26256ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 26266ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 2627bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 26286ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 2629bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 26306ed58ec5SVille Tervo } 26316ed58ec5SVille Tervo 26326ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 263302b20f0bSLuiz Augusto von Dentz tmp = cnt; 263473d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 2635ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2636ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 263773d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 263873d80debSLuiz Augusto von Dentz skb->len, skb->priority); 26396ed58ec5SVille Tervo 2640ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2641ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2642ec1cce24SLuiz Augusto von Dentz break; 2643ec1cce24SLuiz Augusto von Dentz 2644ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2645ec1cce24SLuiz Augusto von Dentz 26466ed58ec5SVille Tervo hci_send_frame(skb); 26476ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 26486ed58ec5SVille Tervo 26496ed58ec5SVille Tervo cnt--; 265073d80debSLuiz Augusto von Dentz chan->sent++; 265173d80debSLuiz Augusto von Dentz chan->conn->sent++; 26526ed58ec5SVille Tervo } 26536ed58ec5SVille Tervo } 265473d80debSLuiz Augusto von Dentz 26556ed58ec5SVille Tervo if (hdev->le_pkts) 26566ed58ec5SVille Tervo hdev->le_cnt = cnt; 26576ed58ec5SVille Tervo else 26586ed58ec5SVille Tervo hdev->acl_cnt = cnt; 265902b20f0bSLuiz Augusto von Dentz 266002b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 266102b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 26626ed58ec5SVille Tervo } 26636ed58ec5SVille Tervo 26643eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 26651da177e4SLinus Torvalds { 26663eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 26671da177e4SLinus Torvalds struct sk_buff *skb; 26681da177e4SLinus Torvalds 26696ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 26706ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 26711da177e4SLinus Torvalds 26721da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 26731da177e4SLinus Torvalds 26741da177e4SLinus Torvalds hci_sched_acl(hdev); 26751da177e4SLinus Torvalds 26761da177e4SLinus Torvalds hci_sched_sco(hdev); 26771da177e4SLinus Torvalds 2678b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 2679b6a0dc82SMarcel Holtmann 26806ed58ec5SVille Tervo hci_sched_le(hdev); 26816ed58ec5SVille Tervo 26821da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 26831da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 26841da177e4SLinus Torvalds hci_send_frame(skb); 26851da177e4SLinus Torvalds } 26861da177e4SLinus Torvalds 268725985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 26881da177e4SLinus Torvalds 26891da177e4SLinus Torvalds /* ACL data packet */ 26906039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 26911da177e4SLinus Torvalds { 26921da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 26931da177e4SLinus Torvalds struct hci_conn *conn; 26941da177e4SLinus Torvalds __u16 handle, flags; 26951da177e4SLinus Torvalds 26961da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 26971da177e4SLinus Torvalds 26981da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 26991da177e4SLinus Torvalds flags = hci_flags(handle); 27001da177e4SLinus Torvalds handle = hci_handle(handle); 27011da177e4SLinus Torvalds 2702a8c5fb1aSGustavo Padovan BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, 2703a8c5fb1aSGustavo Padovan handle, flags); 27041da177e4SLinus Torvalds 27051da177e4SLinus Torvalds hdev->stat.acl_rx++; 27061da177e4SLinus Torvalds 27071da177e4SLinus Torvalds hci_dev_lock(hdev); 27081da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 27091da177e4SLinus Torvalds hci_dev_unlock(hdev); 27101da177e4SLinus Torvalds 27111da177e4SLinus Torvalds if (conn) { 271265983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 271304837f64SMarcel Holtmann 2714671267bfSJohan Hedberg hci_dev_lock(hdev); 2715671267bfSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags) && 2716671267bfSJohan Hedberg !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 2717671267bfSJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 2718671267bfSJohan Hedberg conn->dst_type, 0, NULL, 0, 2719671267bfSJohan Hedberg conn->dev_class); 2720671267bfSJohan Hedberg hci_dev_unlock(hdev); 2721671267bfSJohan Hedberg 27221da177e4SLinus Torvalds /* Send to upper protocol */ 2723686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 27241da177e4SLinus Torvalds return; 27251da177e4SLinus Torvalds } else { 27261da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 27271da177e4SLinus Torvalds hdev->name, handle); 27281da177e4SLinus Torvalds } 27291da177e4SLinus Torvalds 27301da177e4SLinus Torvalds kfree_skb(skb); 27311da177e4SLinus Torvalds } 27321da177e4SLinus Torvalds 27331da177e4SLinus Torvalds /* SCO data packet */ 27346039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 27351da177e4SLinus Torvalds { 27361da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 27371da177e4SLinus Torvalds struct hci_conn *conn; 27381da177e4SLinus Torvalds __u16 handle; 27391da177e4SLinus Torvalds 27401da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 27411da177e4SLinus Torvalds 27421da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 27431da177e4SLinus Torvalds 27441da177e4SLinus Torvalds BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle); 27451da177e4SLinus Torvalds 27461da177e4SLinus Torvalds hdev->stat.sco_rx++; 27471da177e4SLinus Torvalds 27481da177e4SLinus Torvalds hci_dev_lock(hdev); 27491da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 27501da177e4SLinus Torvalds hci_dev_unlock(hdev); 27511da177e4SLinus Torvalds 27521da177e4SLinus Torvalds if (conn) { 27531da177e4SLinus Torvalds /* Send to upper protocol */ 2754686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 27551da177e4SLinus Torvalds return; 27561da177e4SLinus Torvalds } else { 27571da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 27581da177e4SLinus Torvalds hdev->name, handle); 27591da177e4SLinus Torvalds } 27601da177e4SLinus Torvalds 27611da177e4SLinus Torvalds kfree_skb(skb); 27621da177e4SLinus Torvalds } 27631da177e4SLinus Torvalds 2764b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 27651da177e4SLinus Torvalds { 2766b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 27671da177e4SLinus Torvalds struct sk_buff *skb; 27681da177e4SLinus Torvalds 27691da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 27701da177e4SLinus Torvalds 27711da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 2772cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2773cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2774cd82e61cSMarcel Holtmann 27751da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 27761da177e4SLinus Torvalds /* Send copy to the sockets */ 2777470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 27781da177e4SLinus Torvalds } 27791da177e4SLinus Torvalds 27801da177e4SLinus Torvalds if (test_bit(HCI_RAW, &hdev->flags)) { 27811da177e4SLinus Torvalds kfree_skb(skb); 27821da177e4SLinus Torvalds continue; 27831da177e4SLinus Torvalds } 27841da177e4SLinus Torvalds 27851da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 27861da177e4SLinus Torvalds /* Don't process data packets in this states. */ 27870d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 27881da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 27891da177e4SLinus Torvalds case HCI_SCODATA_PKT: 27901da177e4SLinus Torvalds kfree_skb(skb); 27911da177e4SLinus Torvalds continue; 27923ff50b79SStephen Hemminger } 27931da177e4SLinus Torvalds } 27941da177e4SLinus Torvalds 27951da177e4SLinus Torvalds /* Process frame */ 27960d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 27971da177e4SLinus Torvalds case HCI_EVENT_PKT: 2798b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 27991da177e4SLinus Torvalds hci_event_packet(hdev, skb); 28001da177e4SLinus Torvalds break; 28011da177e4SLinus Torvalds 28021da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 28031da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 28041da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 28051da177e4SLinus Torvalds break; 28061da177e4SLinus Torvalds 28071da177e4SLinus Torvalds case HCI_SCODATA_PKT: 28081da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 28091da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 28101da177e4SLinus Torvalds break; 28111da177e4SLinus Torvalds 28121da177e4SLinus Torvalds default: 28131da177e4SLinus Torvalds kfree_skb(skb); 28141da177e4SLinus Torvalds break; 28151da177e4SLinus Torvalds } 28161da177e4SLinus Torvalds } 28171da177e4SLinus Torvalds } 28181da177e4SLinus Torvalds 2819c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 28201da177e4SLinus Torvalds { 2821c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 28221da177e4SLinus Torvalds struct sk_buff *skb; 28231da177e4SLinus Torvalds 28241da177e4SLinus Torvalds BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); 28251da177e4SLinus Torvalds 28261da177e4SLinus Torvalds /* Send queued commands */ 28275a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 28285a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 28295a08ecceSAndrei Emeltchenko if (!skb) 28305a08ecceSAndrei Emeltchenko return; 28315a08ecceSAndrei Emeltchenko 28321da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 28331da177e4SLinus Torvalds 283470f23020SAndrei Emeltchenko hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC); 283570f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 28361da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 28371da177e4SLinus Torvalds hci_send_frame(skb); 28387bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 28397bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 28407bdb8a5cSSzymon Janc else 28416bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 28426bd32326SVille Tervo jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); 28431da177e4SLinus Torvalds } else { 28441da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 2845c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 28461da177e4SLinus Torvalds } 28471da177e4SLinus Torvalds } 28481da177e4SLinus Torvalds } 28492519a1fcSAndre Guedes 28502519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length) 28512519a1fcSAndre Guedes { 28522519a1fcSAndre Guedes /* General inquiry access code (GIAC) */ 28532519a1fcSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 28542519a1fcSAndre Guedes struct hci_cp_inquiry cp; 28552519a1fcSAndre Guedes 28562519a1fcSAndre Guedes BT_DBG("%s", hdev->name); 28572519a1fcSAndre Guedes 28582519a1fcSAndre Guedes if (test_bit(HCI_INQUIRY, &hdev->flags)) 28592519a1fcSAndre Guedes return -EINPROGRESS; 28602519a1fcSAndre Guedes 28614663262cSJohan Hedberg inquiry_cache_flush(hdev); 28624663262cSJohan Hedberg 28632519a1fcSAndre Guedes memset(&cp, 0, sizeof(cp)); 28642519a1fcSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 28652519a1fcSAndre Guedes cp.length = length; 28662519a1fcSAndre Guedes 28672519a1fcSAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 28682519a1fcSAndre Guedes } 2869023d5049SAndre Guedes 2870023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev) 2871023d5049SAndre Guedes { 2872023d5049SAndre Guedes BT_DBG("%s", hdev->name); 2873023d5049SAndre Guedes 2874023d5049SAndre Guedes if (!test_bit(HCI_INQUIRY, &hdev->flags)) 28757537e5c3SAndre Guedes return -EALREADY; 2876023d5049SAndre Guedes 2877023d5049SAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); 2878023d5049SAndre Guedes } 287931f7956cSAndre Guedes 288031f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type) 288131f7956cSAndre Guedes { 288231f7956cSAndre Guedes switch (bdaddr_type) { 288331f7956cSAndre Guedes case BDADDR_LE_PUBLIC: 288431f7956cSAndre Guedes return ADDR_LE_DEV_PUBLIC; 288531f7956cSAndre Guedes 288631f7956cSAndre Guedes default: 288731f7956cSAndre Guedes /* Fallback to LE Random address type */ 288831f7956cSAndre Guedes return ADDR_LE_DEV_RANDOM; 288931f7956cSAndre Guedes } 289031f7956cSAndre Guedes } 2891