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 2882453021SS.Çağlar Onur #include <linux/jiffies.h> 291da177e4SLinus Torvalds #include <linux/module.h> 301da177e4SLinus Torvalds #include <linux/kmod.h> 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds #include <linux/types.h> 331da177e4SLinus Torvalds #include <linux/errno.h> 341da177e4SLinus Torvalds #include <linux/kernel.h> 351da177e4SLinus Torvalds #include <linux/sched.h> 361da177e4SLinus Torvalds #include <linux/slab.h> 371da177e4SLinus Torvalds #include <linux/poll.h> 381da177e4SLinus Torvalds #include <linux/fcntl.h> 391da177e4SLinus Torvalds #include <linux/init.h> 401da177e4SLinus Torvalds #include <linux/skbuff.h> 41f48fd9c8SMarcel Holtmann #include <linux/workqueue.h> 421da177e4SLinus Torvalds #include <linux/interrupt.h> 43611b30f7SMarcel Holtmann #include <linux/rfkill.h> 446bd32326SVille Tervo #include <linux/timer.h> 453a0259bbSVinicius Costa Gomes #include <linux/crypto.h> 461da177e4SLinus Torvalds #include <net/sock.h> 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds #include <asm/system.h> 4970f23020SAndrei Emeltchenko #include <linux/uaccess.h> 501da177e4SLinus Torvalds #include <asm/unaligned.h> 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 531da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 541da177e4SLinus Torvalds 55ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000 56ab81cbf9SJohan Hedberg 57b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 58c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 593eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds /* HCI device list */ 621da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 631da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds /* HCI callback list */ 661da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 671da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 701da177e4SLinus Torvalds 716516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 721da177e4SLinus Torvalds { 73040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 741da177e4SLinus Torvalds } 751da177e4SLinus Torvalds 761da177e4SLinus Torvalds /* ---- HCI requests ---- */ 771da177e4SLinus Torvalds 7823bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) 791da177e4SLinus Torvalds { 8023bb5763SJohan Hedberg BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result); 8123bb5763SJohan Hedberg 82a5040efaSJohan Hedberg /* If this is the init phase check if the completed command matches 83a5040efaSJohan Hedberg * the last init command, and if not just return. 84a5040efaSJohan Hedberg */ 8575fb0e32SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) { 8675fb0e32SJohan Hedberg struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 8775fb0e32SJohan Hedberg struct sk_buff *skb; 8875fb0e32SJohan Hedberg 8975fb0e32SJohan Hedberg /* Some CSR based controllers generate a spontaneous 9075fb0e32SJohan Hedberg * reset complete event during init and any pending 9175fb0e32SJohan Hedberg * command will never be completed. In such a case we 9275fb0e32SJohan Hedberg * need to resend whatever was the last sent 9375fb0e32SJohan Hedberg * command. 9475fb0e32SJohan Hedberg */ 9575fb0e32SJohan Hedberg 9675fb0e32SJohan Hedberg if (cmd != HCI_OP_RESET || sent->opcode == HCI_OP_RESET) 9723bb5763SJohan Hedberg return; 981da177e4SLinus Torvalds 9975fb0e32SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC); 10075fb0e32SJohan Hedberg if (skb) { 10175fb0e32SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 10275fb0e32SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 10375fb0e32SJohan Hedberg } 10475fb0e32SJohan Hedberg 10575fb0e32SJohan Hedberg return; 10675fb0e32SJohan Hedberg } 10775fb0e32SJohan Hedberg 1081da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 1091da177e4SLinus Torvalds hdev->req_result = result; 1101da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 1111da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 1121da177e4SLinus Torvalds } 1131da177e4SLinus Torvalds } 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 1161da177e4SLinus Torvalds { 1171da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 1181da177e4SLinus Torvalds 1191da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 1201da177e4SLinus Torvalds hdev->req_result = err; 1211da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 1221da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 1231da177e4SLinus Torvalds } 1241da177e4SLinus Torvalds } 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds /* Execute request and wait for completion. */ 1271da177e4SLinus Torvalds static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), 1281da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 1291da177e4SLinus Torvalds { 1301da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 1311da177e4SLinus Torvalds int err = 0; 1321da177e4SLinus Torvalds 1331da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 1341da177e4SLinus Torvalds 1351da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 1361da177e4SLinus Torvalds 1371da177e4SLinus Torvalds add_wait_queue(&hdev->req_wait_q, &wait); 1381da177e4SLinus Torvalds set_current_state(TASK_INTERRUPTIBLE); 1391da177e4SLinus Torvalds 1401da177e4SLinus Torvalds req(hdev, opt); 1411da177e4SLinus Torvalds schedule_timeout(timeout); 1421da177e4SLinus Torvalds 1431da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 1441da177e4SLinus Torvalds 1451da177e4SLinus Torvalds if (signal_pending(current)) 1461da177e4SLinus Torvalds return -EINTR; 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds switch (hdev->req_status) { 1491da177e4SLinus Torvalds case HCI_REQ_DONE: 150e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 1511da177e4SLinus Torvalds break; 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds case HCI_REQ_CANCELED: 1541da177e4SLinus Torvalds err = -hdev->req_result; 1551da177e4SLinus Torvalds break; 1561da177e4SLinus Torvalds 1571da177e4SLinus Torvalds default: 1581da177e4SLinus Torvalds err = -ETIMEDOUT; 1591da177e4SLinus Torvalds break; 1603ff50b79SStephen Hemminger } 1611da177e4SLinus Torvalds 162a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 1631da177e4SLinus Torvalds 1641da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 1651da177e4SLinus Torvalds 1661da177e4SLinus Torvalds return err; 1671da177e4SLinus Torvalds } 1681da177e4SLinus Torvalds 1691da177e4SLinus Torvalds static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), 1701da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 1711da177e4SLinus Torvalds { 1721da177e4SLinus Torvalds int ret; 1731da177e4SLinus Torvalds 1747c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 1757c6a329eSMarcel Holtmann return -ENETDOWN; 1767c6a329eSMarcel Holtmann 1771da177e4SLinus Torvalds /* Serialize all requests */ 1781da177e4SLinus Torvalds hci_req_lock(hdev); 1791da177e4SLinus Torvalds ret = __hci_request(hdev, req, opt, timeout); 1801da177e4SLinus Torvalds hci_req_unlock(hdev); 1811da177e4SLinus Torvalds 1821da177e4SLinus Torvalds return ret; 1831da177e4SLinus Torvalds } 1841da177e4SLinus Torvalds 1851da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) 1861da177e4SLinus Torvalds { 1871da177e4SLinus Torvalds BT_DBG("%s %ld", hdev->name, opt); 1881da177e4SLinus Torvalds 1891da177e4SLinus Torvalds /* Reset device */ 190f630cf0dSGustavo F. Padovan set_bit(HCI_RESET, &hdev->flags); 191a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 1921da177e4SLinus Torvalds } 1931da177e4SLinus Torvalds 194e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev) 1951da177e4SLinus Torvalds { 196b0916ea0SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 1971ebb9252SMarcel Holtmann __le16 param; 19889f2783dSMarcel Holtmann __u8 flt_type; 1991da177e4SLinus Torvalds 2002455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 2012455a3eaSAndrei Emeltchenko 2021da177e4SLinus Torvalds /* Mandatory initialization */ 2031da177e4SLinus Torvalds 2041da177e4SLinus Torvalds /* Reset */ 205f630cf0dSGustavo F. Padovan if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { 206f630cf0dSGustavo F. Padovan set_bit(HCI_RESET, &hdev->flags); 207a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 208f630cf0dSGustavo F. Padovan } 2091da177e4SLinus Torvalds 2101da177e4SLinus Torvalds /* Read Local Supported Features */ 211a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 2121da177e4SLinus Torvalds 2131143e5a6SMarcel Holtmann /* Read Local Version */ 214a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2151143e5a6SMarcel Holtmann 2161da177e4SLinus Torvalds /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 217a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 2181da177e4SLinus Torvalds 2191da177e4SLinus Torvalds /* Read BD Address */ 220a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); 221a9de9248SMarcel Holtmann 222a9de9248SMarcel Holtmann /* Read Class of Device */ 223a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 224a9de9248SMarcel Holtmann 225a9de9248SMarcel Holtmann /* Read Local Name */ 226a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); 2271da177e4SLinus Torvalds 2281da177e4SLinus Torvalds /* Read Voice Setting */ 229a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); 2301da177e4SLinus Torvalds 2311da177e4SLinus Torvalds /* Optional initialization */ 2321da177e4SLinus Torvalds 2331da177e4SLinus Torvalds /* Clear Event Filters */ 23489f2783dSMarcel Holtmann flt_type = HCI_FLT_CLEAR_ALL; 235a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 2361da177e4SLinus Torvalds 2371da177e4SLinus Torvalds /* Connection accept timeout ~20 secs */ 238aca3192cSYOSHIFUJI Hideaki param = cpu_to_le16(0x7d00); 239a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 240b0916ea0SJohan Hedberg 241b0916ea0SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 242b0916ea0SJohan Hedberg cp.delete_all = 1; 243b0916ea0SJohan Hedberg hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); 2441da177e4SLinus Torvalds } 2451da177e4SLinus Torvalds 246e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev) 247e61ef499SAndrei Emeltchenko { 2482455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 2492455a3eaSAndrei Emeltchenko 250e61ef499SAndrei Emeltchenko /* Reset */ 251e61ef499SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 252e61ef499SAndrei Emeltchenko 253e61ef499SAndrei Emeltchenko /* Read Local Version */ 254e61ef499SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 255e61ef499SAndrei Emeltchenko } 256e61ef499SAndrei Emeltchenko 257e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt) 258e61ef499SAndrei Emeltchenko { 259e61ef499SAndrei Emeltchenko struct sk_buff *skb; 260e61ef499SAndrei Emeltchenko 261e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 262e61ef499SAndrei Emeltchenko 263e61ef499SAndrei Emeltchenko /* Driver initialization */ 264e61ef499SAndrei Emeltchenko 265e61ef499SAndrei Emeltchenko /* Special commands */ 266e61ef499SAndrei Emeltchenko while ((skb = skb_dequeue(&hdev->driver_init))) { 267e61ef499SAndrei Emeltchenko bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 268e61ef499SAndrei Emeltchenko skb->dev = (void *) hdev; 269e61ef499SAndrei Emeltchenko 270e61ef499SAndrei Emeltchenko skb_queue_tail(&hdev->cmd_q, skb); 271e61ef499SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->cmd_work); 272e61ef499SAndrei Emeltchenko } 273e61ef499SAndrei Emeltchenko skb_queue_purge(&hdev->driver_init); 274e61ef499SAndrei Emeltchenko 275e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 276e61ef499SAndrei Emeltchenko case HCI_BREDR: 277e61ef499SAndrei Emeltchenko bredr_init(hdev); 278e61ef499SAndrei Emeltchenko break; 279e61ef499SAndrei Emeltchenko 280e61ef499SAndrei Emeltchenko case HCI_AMP: 281e61ef499SAndrei Emeltchenko amp_init(hdev); 282e61ef499SAndrei Emeltchenko break; 283e61ef499SAndrei Emeltchenko 284e61ef499SAndrei Emeltchenko default: 285e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 286e61ef499SAndrei Emeltchenko break; 287e61ef499SAndrei Emeltchenko } 288e61ef499SAndrei Emeltchenko 289e61ef499SAndrei Emeltchenko } 290e61ef499SAndrei Emeltchenko 2916ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) 2926ed58ec5SVille Tervo { 2936ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 2946ed58ec5SVille Tervo 2956ed58ec5SVille Tervo /* Read LE buffer size */ 2966ed58ec5SVille Tervo hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 2976ed58ec5SVille Tervo } 2986ed58ec5SVille Tervo 2991da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) 3001da177e4SLinus Torvalds { 3011da177e4SLinus Torvalds __u8 scan = opt; 3021da177e4SLinus Torvalds 3031da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, scan); 3041da177e4SLinus Torvalds 3051da177e4SLinus Torvalds /* Inquiry and Page scans */ 306a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 3071da177e4SLinus Torvalds } 3081da177e4SLinus Torvalds 3091da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt) 3101da177e4SLinus Torvalds { 3111da177e4SLinus Torvalds __u8 auth = opt; 3121da177e4SLinus Torvalds 3131da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, auth); 3141da177e4SLinus Torvalds 3151da177e4SLinus Torvalds /* Authentication */ 316a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 3171da177e4SLinus Torvalds } 3181da177e4SLinus Torvalds 3191da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt) 3201da177e4SLinus Torvalds { 3211da177e4SLinus Torvalds __u8 encrypt = opt; 3221da177e4SLinus Torvalds 3231da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, encrypt); 3241da177e4SLinus Torvalds 325e4e8e37cSMarcel Holtmann /* Encryption */ 326a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 3271da177e4SLinus Torvalds } 3281da177e4SLinus Torvalds 329e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt) 330e4e8e37cSMarcel Holtmann { 331e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 332e4e8e37cSMarcel Holtmann 333a418b893SMarcel Holtmann BT_DBG("%s %x", hdev->name, policy); 334e4e8e37cSMarcel Holtmann 335e4e8e37cSMarcel Holtmann /* Default link policy */ 336e4e8e37cSMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 337e4e8e37cSMarcel Holtmann } 338e4e8e37cSMarcel Holtmann 3391da177e4SLinus Torvalds /* Get HCI device by index. 3401da177e4SLinus Torvalds * Device is held on return. */ 3411da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 3421da177e4SLinus Torvalds { 3438035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 3441da177e4SLinus Torvalds 3451da177e4SLinus Torvalds BT_DBG("%d", index); 3461da177e4SLinus Torvalds 3471da177e4SLinus Torvalds if (index < 0) 3481da177e4SLinus Torvalds return NULL; 3491da177e4SLinus Torvalds 3501da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 3518035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 3521da177e4SLinus Torvalds if (d->id == index) { 3531da177e4SLinus Torvalds hdev = hci_dev_hold(d); 3541da177e4SLinus Torvalds break; 3551da177e4SLinus Torvalds } 3561da177e4SLinus Torvalds } 3571da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 3581da177e4SLinus Torvalds return hdev; 3591da177e4SLinus Torvalds } 3601da177e4SLinus Torvalds 3611da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 362ff9ef578SJohan Hedberg 36330dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 36430dc78e1SJohan Hedberg { 36530dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 36630dc78e1SJohan Hedberg 3676fbe195dSAndre Guedes switch (discov->state) { 368343f935bSAndre Guedes case DISCOVERY_FINDING: 3696fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 37030dc78e1SJohan Hedberg return true; 37130dc78e1SJohan Hedberg 3726fbe195dSAndre Guedes default: 37330dc78e1SJohan Hedberg return false; 37430dc78e1SJohan Hedberg } 3756fbe195dSAndre Guedes } 37630dc78e1SJohan Hedberg 377ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 378ff9ef578SJohan Hedberg { 379ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 380ff9ef578SJohan Hedberg 381ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 382ff9ef578SJohan Hedberg return; 383ff9ef578SJohan Hedberg 384ff9ef578SJohan Hedberg switch (state) { 385ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 3867b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 387ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 388f963e8e9SJohan Hedberg hdev->discovery.type = 0; 389ff9ef578SJohan Hedberg break; 390ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 391ff9ef578SJohan Hedberg break; 392343f935bSAndre Guedes case DISCOVERY_FINDING: 393ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 394ff9ef578SJohan Hedberg break; 39530dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 39630dc78e1SJohan Hedberg break; 397ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 398ff9ef578SJohan Hedberg break; 399ff9ef578SJohan Hedberg } 400ff9ef578SJohan Hedberg 401ff9ef578SJohan Hedberg hdev->discovery.state = state; 402ff9ef578SJohan Hedberg } 403ff9ef578SJohan Hedberg 4041da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev) 4051da177e4SLinus Torvalds { 40630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 407b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 4081da177e4SLinus Torvalds 409561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 410561aafbcSJohan Hedberg list_del(&p->all); 411b57c1a56SJohan Hedberg kfree(p); 4121da177e4SLinus Torvalds } 413561aafbcSJohan Hedberg 414561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 415561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 4161da177e4SLinus Torvalds } 4171da177e4SLinus Torvalds 4181da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 4191da177e4SLinus Torvalds { 42030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 4211da177e4SLinus Torvalds struct inquiry_entry *e; 4221da177e4SLinus Torvalds 4231da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 4241da177e4SLinus Torvalds 425561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 4261da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 4271da177e4SLinus Torvalds return e; 4281da177e4SLinus Torvalds } 4291da177e4SLinus Torvalds 430b57c1a56SJohan Hedberg return NULL; 431b57c1a56SJohan Hedberg } 432b57c1a56SJohan Hedberg 433561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 434561aafbcSJohan Hedberg bdaddr_t *bdaddr) 435561aafbcSJohan Hedberg { 43630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 437561aafbcSJohan Hedberg struct inquiry_entry *e; 438561aafbcSJohan Hedberg 439561aafbcSJohan Hedberg BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 440561aafbcSJohan Hedberg 441561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 442561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 443561aafbcSJohan Hedberg return e; 444561aafbcSJohan Hedberg } 445561aafbcSJohan Hedberg 446561aafbcSJohan Hedberg return NULL; 447561aafbcSJohan Hedberg } 448561aafbcSJohan Hedberg 44930dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 45030dc78e1SJohan Hedberg bdaddr_t *bdaddr, 45130dc78e1SJohan Hedberg int state) 45230dc78e1SJohan Hedberg { 45330dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 45430dc78e1SJohan Hedberg struct inquiry_entry *e; 45530dc78e1SJohan Hedberg 45630dc78e1SJohan Hedberg BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state); 45730dc78e1SJohan Hedberg 45830dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 45930dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 46030dc78e1SJohan Hedberg return e; 46130dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 46230dc78e1SJohan Hedberg return e; 46330dc78e1SJohan Hedberg } 46430dc78e1SJohan Hedberg 46530dc78e1SJohan Hedberg return NULL; 46630dc78e1SJohan Hedberg } 46730dc78e1SJohan Hedberg 468a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 469a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 470a3d4e20aSJohan Hedberg { 471a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 472a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 473a3d4e20aSJohan Hedberg struct inquiry_entry *p; 474a3d4e20aSJohan Hedberg 475a3d4e20aSJohan Hedberg list_del(&ie->list); 476a3d4e20aSJohan Hedberg 477a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 478a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 479a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 480a3d4e20aSJohan Hedberg break; 481a3d4e20aSJohan Hedberg pos = &p->list; 482a3d4e20aSJohan Hedberg } 483a3d4e20aSJohan Hedberg 484a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 485a3d4e20aSJohan Hedberg } 486a3d4e20aSJohan Hedberg 4873175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 488388fc8faSJohan Hedberg bool name_known, bool *ssp) 4891da177e4SLinus Torvalds { 49030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 49170f23020SAndrei Emeltchenko struct inquiry_entry *ie; 4921da177e4SLinus Torvalds 4931da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr)); 4941da177e4SLinus Torvalds 495388fc8faSJohan Hedberg if (ssp) 496388fc8faSJohan Hedberg *ssp = data->ssp_mode; 497388fc8faSJohan Hedberg 49870f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 499a3d4e20aSJohan Hedberg if (ie) { 500388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 501388fc8faSJohan Hedberg *ssp = true; 502388fc8faSJohan Hedberg 503a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 504a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 505a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 506a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 507a3d4e20aSJohan Hedberg } 508a3d4e20aSJohan Hedberg 509561aafbcSJohan Hedberg goto update; 510a3d4e20aSJohan Hedberg } 511561aafbcSJohan Hedberg 5121da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 51370f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 51470f23020SAndrei Emeltchenko if (!ie) 5153175405bSJohan Hedberg return false; 51670f23020SAndrei Emeltchenko 517561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 518561aafbcSJohan Hedberg 519561aafbcSJohan Hedberg if (name_known) { 520561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 521561aafbcSJohan Hedberg } else { 522561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 523561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 524561aafbcSJohan Hedberg } 525561aafbcSJohan Hedberg 526561aafbcSJohan Hedberg update: 527561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 528561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 529561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 530561aafbcSJohan Hedberg list_del(&ie->list); 5311da177e4SLinus Torvalds } 5321da177e4SLinus Torvalds 53370f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 53470f23020SAndrei Emeltchenko ie->timestamp = jiffies; 5351da177e4SLinus Torvalds cache->timestamp = jiffies; 5363175405bSJohan Hedberg 5373175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 5383175405bSJohan Hedberg return false; 5393175405bSJohan Hedberg 5403175405bSJohan Hedberg return true; 5411da177e4SLinus Torvalds } 5421da177e4SLinus Torvalds 5431da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 5441da177e4SLinus Torvalds { 54530883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 5461da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 5471da177e4SLinus Torvalds struct inquiry_entry *e; 5481da177e4SLinus Torvalds int copied = 0; 5491da177e4SLinus Torvalds 550561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 5511da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 552b57c1a56SJohan Hedberg 553b57c1a56SJohan Hedberg if (copied >= num) 554b57c1a56SJohan Hedberg break; 555b57c1a56SJohan Hedberg 5561da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 5571da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 5581da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 5591da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 5601da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 5611da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 562b57c1a56SJohan Hedberg 5631da177e4SLinus Torvalds info++; 564b57c1a56SJohan Hedberg copied++; 5651da177e4SLinus Torvalds } 5661da177e4SLinus Torvalds 5671da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 5681da177e4SLinus Torvalds return copied; 5691da177e4SLinus Torvalds } 5701da177e4SLinus Torvalds 5711da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt) 5721da177e4SLinus Torvalds { 5731da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 5741da177e4SLinus Torvalds struct hci_cp_inquiry cp; 5751da177e4SLinus Torvalds 5761da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 5771da177e4SLinus Torvalds 5781da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 5791da177e4SLinus Torvalds return; 5801da177e4SLinus Torvalds 5811da177e4SLinus Torvalds /* Start Inquiry */ 5821da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 5831da177e4SLinus Torvalds cp.length = ir->length; 5841da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 585a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 5861da177e4SLinus Torvalds } 5871da177e4SLinus Torvalds 5881da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 5891da177e4SLinus Torvalds { 5901da177e4SLinus Torvalds __u8 __user *ptr = arg; 5911da177e4SLinus Torvalds struct hci_inquiry_req ir; 5921da177e4SLinus Torvalds struct hci_dev *hdev; 5931da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 5941da177e4SLinus Torvalds long timeo; 5951da177e4SLinus Torvalds __u8 *buf; 5961da177e4SLinus Torvalds 5971da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 5981da177e4SLinus Torvalds return -EFAULT; 5991da177e4SLinus Torvalds 6005a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 6015a08ecceSAndrei Emeltchenko if (!hdev) 6021da177e4SLinus Torvalds return -ENODEV; 6031da177e4SLinus Torvalds 60409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 6051da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 6061da177e4SLinus Torvalds inquiry_cache_empty(hdev) || 6071da177e4SLinus Torvalds ir.flags & IREQ_CACHE_FLUSH) { 6081da177e4SLinus Torvalds inquiry_cache_flush(hdev); 6091da177e4SLinus Torvalds do_inquiry = 1; 6101da177e4SLinus Torvalds } 61109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 6121da177e4SLinus Torvalds 61304837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 61470f23020SAndrei Emeltchenko 61570f23020SAndrei Emeltchenko if (do_inquiry) { 61670f23020SAndrei Emeltchenko err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo); 61770f23020SAndrei Emeltchenko if (err < 0) 6181da177e4SLinus Torvalds goto done; 61970f23020SAndrei Emeltchenko } 6201da177e4SLinus Torvalds 6211da177e4SLinus Torvalds /* for unlimited number of responses we will use buffer with 255 entries */ 6221da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 6231da177e4SLinus Torvalds 6241da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 6251da177e4SLinus Torvalds * copy it to the user space. 6261da177e4SLinus Torvalds */ 62770f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 62870f23020SAndrei Emeltchenko if (!buf) { 6291da177e4SLinus Torvalds err = -ENOMEM; 6301da177e4SLinus Torvalds goto done; 6311da177e4SLinus Torvalds } 6321da177e4SLinus Torvalds 63309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 6341da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 63509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 6361da177e4SLinus Torvalds 6371da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 6381da177e4SLinus Torvalds 6391da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 6401da177e4SLinus Torvalds ptr += sizeof(ir); 6411da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 6421da177e4SLinus Torvalds ir.num_rsp)) 6431da177e4SLinus Torvalds err = -EFAULT; 6441da177e4SLinus Torvalds } else 6451da177e4SLinus Torvalds err = -EFAULT; 6461da177e4SLinus Torvalds 6471da177e4SLinus Torvalds kfree(buf); 6481da177e4SLinus Torvalds 6491da177e4SLinus Torvalds done: 6501da177e4SLinus Torvalds hci_dev_put(hdev); 6511da177e4SLinus Torvalds return err; 6521da177e4SLinus Torvalds } 6531da177e4SLinus Torvalds 6541da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */ 6551da177e4SLinus Torvalds 6561da177e4SLinus Torvalds int hci_dev_open(__u16 dev) 6571da177e4SLinus Torvalds { 6581da177e4SLinus Torvalds struct hci_dev *hdev; 6591da177e4SLinus Torvalds int ret = 0; 6601da177e4SLinus Torvalds 6615a08ecceSAndrei Emeltchenko hdev = hci_dev_get(dev); 6625a08ecceSAndrei Emeltchenko if (!hdev) 6631da177e4SLinus Torvalds return -ENODEV; 6641da177e4SLinus Torvalds 6651da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 6661da177e4SLinus Torvalds 6671da177e4SLinus Torvalds hci_req_lock(hdev); 6681da177e4SLinus Torvalds 66994324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 67094324962SJohan Hovold ret = -ENODEV; 67194324962SJohan Hovold goto done; 67294324962SJohan Hovold } 67394324962SJohan Hovold 674611b30f7SMarcel Holtmann if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { 675611b30f7SMarcel Holtmann ret = -ERFKILL; 676611b30f7SMarcel Holtmann goto done; 677611b30f7SMarcel Holtmann } 678611b30f7SMarcel Holtmann 6791da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 6801da177e4SLinus Torvalds ret = -EALREADY; 6811da177e4SLinus Torvalds goto done; 6821da177e4SLinus Torvalds } 6831da177e4SLinus Torvalds 6841da177e4SLinus Torvalds if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 6851da177e4SLinus Torvalds set_bit(HCI_RAW, &hdev->flags); 6861da177e4SLinus Torvalds 68707e3b94aSAndrei Emeltchenko /* Treat all non BR/EDR controllers as raw devices if 68807e3b94aSAndrei Emeltchenko enable_hs is not set */ 68907e3b94aSAndrei Emeltchenko if (hdev->dev_type != HCI_BREDR && !enable_hs) 690943da25dSMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 691943da25dSMarcel Holtmann 6921da177e4SLinus Torvalds if (hdev->open(hdev)) { 6931da177e4SLinus Torvalds ret = -EIO; 6941da177e4SLinus Torvalds goto done; 6951da177e4SLinus Torvalds } 6961da177e4SLinus Torvalds 6971da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 6981da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 6991da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 700a5040efaSJohan Hedberg hdev->init_last_cmd = 0; 7011da177e4SLinus Torvalds 70204837f64SMarcel Holtmann ret = __hci_request(hdev, hci_init_req, 0, 70304837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 7041da177e4SLinus Torvalds 705eead27daSAndre Guedes if (lmp_host_le_capable(hdev)) 7066ed58ec5SVille Tervo ret = __hci_request(hdev, hci_le_init_req, 0, 7076ed58ec5SVille Tervo msecs_to_jiffies(HCI_INIT_TIMEOUT)); 7086ed58ec5SVille Tervo 7091da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7101da177e4SLinus Torvalds } 7111da177e4SLinus Torvalds 7121da177e4SLinus Torvalds if (!ret) { 7131da177e4SLinus Torvalds hci_dev_hold(hdev); 7141da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 7151da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 716a8b2d5c2SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 71709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 718744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 71909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 72056e5cb86SJohan Hedberg } 7211da177e4SLinus Torvalds } else { 7221da177e4SLinus Torvalds /* Init failed, cleanup */ 7233eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 724c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 725b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7261da177e4SLinus Torvalds 7271da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7281da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7291da177e4SLinus Torvalds 7301da177e4SLinus Torvalds if (hdev->flush) 7311da177e4SLinus Torvalds hdev->flush(hdev); 7321da177e4SLinus Torvalds 7331da177e4SLinus Torvalds if (hdev->sent_cmd) { 7341da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 7351da177e4SLinus Torvalds hdev->sent_cmd = NULL; 7361da177e4SLinus Torvalds } 7371da177e4SLinus Torvalds 7381da177e4SLinus Torvalds hdev->close(hdev); 7391da177e4SLinus Torvalds hdev->flags = 0; 7401da177e4SLinus Torvalds } 7411da177e4SLinus Torvalds 7421da177e4SLinus Torvalds done: 7431da177e4SLinus Torvalds hci_req_unlock(hdev); 7441da177e4SLinus Torvalds hci_dev_put(hdev); 7451da177e4SLinus Torvalds return ret; 7461da177e4SLinus Torvalds } 7471da177e4SLinus Torvalds 7481da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 7491da177e4SLinus Torvalds { 7501da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 7511da177e4SLinus Torvalds 75228b75a89SAndre Guedes cancel_work_sync(&hdev->le_scan); 75328b75a89SAndre Guedes 7541da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 7551da177e4SLinus Torvalds hci_req_lock(hdev); 7561da177e4SLinus Torvalds 7571da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 758b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 7591da177e4SLinus Torvalds hci_req_unlock(hdev); 7601da177e4SLinus Torvalds return 0; 7611da177e4SLinus Torvalds } 7621da177e4SLinus Torvalds 7633eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 7643eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 765b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7661da177e4SLinus Torvalds 76716ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 768e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 76916ab91abSJohan Hedberg hdev->discov_timeout = 0; 7705e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 77116ab91abSJohan Hedberg } 77216ab91abSJohan Hedberg 773a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 7747d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 7757d78525dSJohan Hedberg 7767ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 7777ba8b4beSAndre Guedes 77809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 7791da177e4SLinus Torvalds inquiry_cache_flush(hdev); 7801da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 78109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 7821da177e4SLinus Torvalds 7831da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 7841da177e4SLinus Torvalds 7851da177e4SLinus Torvalds if (hdev->flush) 7861da177e4SLinus Torvalds hdev->flush(hdev); 7871da177e4SLinus Torvalds 7881da177e4SLinus Torvalds /* Reset device */ 7891da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7901da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 7918af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 7928af59467SJohan Hedberg test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { 7931da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 79404837f64SMarcel Holtmann __hci_request(hdev, hci_reset_req, 0, 795cad44c2bSGustavo F. Padovan msecs_to_jiffies(250)); 7961da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7971da177e4SLinus Torvalds } 7981da177e4SLinus Torvalds 799c347b765SGustavo F. Padovan /* flush cmd work */ 800c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 8011da177e4SLinus Torvalds 8021da177e4SLinus Torvalds /* Drop queues */ 8031da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 8041da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8051da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 8061da177e4SLinus Torvalds 8071da177e4SLinus Torvalds /* Drop last sent command */ 8081da177e4SLinus Torvalds if (hdev->sent_cmd) { 809b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 8101da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 8111da177e4SLinus Torvalds hdev->sent_cmd = NULL; 8121da177e4SLinus Torvalds } 8131da177e4SLinus Torvalds 8141da177e4SLinus Torvalds /* After this point our queues are empty 8151da177e4SLinus Torvalds * and no tasks are scheduled. */ 8161da177e4SLinus Torvalds hdev->close(hdev); 8171da177e4SLinus Torvalds 8188ee56540SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 81909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 820744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 82109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8228ee56540SMarcel Holtmann } 8235add6af8SJohan Hedberg 8241da177e4SLinus Torvalds /* Clear flags */ 8251da177e4SLinus Torvalds hdev->flags = 0; 8261da177e4SLinus Torvalds 827e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 82809b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 829e59fda8dSJohan Hedberg 8301da177e4SLinus Torvalds hci_req_unlock(hdev); 8311da177e4SLinus Torvalds 8321da177e4SLinus Torvalds hci_dev_put(hdev); 8331da177e4SLinus Torvalds return 0; 8341da177e4SLinus Torvalds } 8351da177e4SLinus Torvalds 8361da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 8371da177e4SLinus Torvalds { 8381da177e4SLinus Torvalds struct hci_dev *hdev; 8391da177e4SLinus Torvalds int err; 8401da177e4SLinus Torvalds 84170f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 84270f23020SAndrei Emeltchenko if (!hdev) 8431da177e4SLinus Torvalds return -ENODEV; 8448ee56540SMarcel Holtmann 8458ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 8468ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 8478ee56540SMarcel Holtmann 8481da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 8498ee56540SMarcel Holtmann 8501da177e4SLinus Torvalds hci_dev_put(hdev); 8511da177e4SLinus Torvalds return err; 8521da177e4SLinus Torvalds } 8531da177e4SLinus Torvalds 8541da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 8551da177e4SLinus Torvalds { 8561da177e4SLinus Torvalds struct hci_dev *hdev; 8571da177e4SLinus Torvalds int ret = 0; 8581da177e4SLinus Torvalds 85970f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 86070f23020SAndrei Emeltchenko if (!hdev) 8611da177e4SLinus Torvalds return -ENODEV; 8621da177e4SLinus Torvalds 8631da177e4SLinus Torvalds hci_req_lock(hdev); 8641da177e4SLinus Torvalds 8651da177e4SLinus Torvalds if (!test_bit(HCI_UP, &hdev->flags)) 8661da177e4SLinus Torvalds goto done; 8671da177e4SLinus Torvalds 8681da177e4SLinus Torvalds /* Drop queues */ 8691da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 8701da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8711da177e4SLinus Torvalds 87209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 8731da177e4SLinus Torvalds inquiry_cache_flush(hdev); 8741da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 87509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8761da177e4SLinus Torvalds 8771da177e4SLinus Torvalds if (hdev->flush) 8781da177e4SLinus Torvalds hdev->flush(hdev); 8791da177e4SLinus Torvalds 8801da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 8816ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 8821da177e4SLinus Torvalds 8831da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 88404837f64SMarcel Holtmann ret = __hci_request(hdev, hci_reset_req, 0, 88504837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 8861da177e4SLinus Torvalds 8871da177e4SLinus Torvalds done: 8881da177e4SLinus Torvalds hci_req_unlock(hdev); 8891da177e4SLinus Torvalds hci_dev_put(hdev); 8901da177e4SLinus Torvalds return ret; 8911da177e4SLinus Torvalds } 8921da177e4SLinus Torvalds 8931da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 8941da177e4SLinus Torvalds { 8951da177e4SLinus Torvalds struct hci_dev *hdev; 8961da177e4SLinus Torvalds int ret = 0; 8971da177e4SLinus Torvalds 89870f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 89970f23020SAndrei Emeltchenko if (!hdev) 9001da177e4SLinus Torvalds return -ENODEV; 9011da177e4SLinus Torvalds 9021da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 9031da177e4SLinus Torvalds 9041da177e4SLinus Torvalds hci_dev_put(hdev); 9051da177e4SLinus Torvalds 9061da177e4SLinus Torvalds return ret; 9071da177e4SLinus Torvalds } 9081da177e4SLinus Torvalds 9091da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 9101da177e4SLinus Torvalds { 9111da177e4SLinus Torvalds struct hci_dev *hdev; 9121da177e4SLinus Torvalds struct hci_dev_req dr; 9131da177e4SLinus Torvalds int err = 0; 9141da177e4SLinus Torvalds 9151da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 9161da177e4SLinus Torvalds return -EFAULT; 9171da177e4SLinus Torvalds 91870f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 91970f23020SAndrei Emeltchenko if (!hdev) 9201da177e4SLinus Torvalds return -ENODEV; 9211da177e4SLinus Torvalds 9221da177e4SLinus Torvalds switch (cmd) { 9231da177e4SLinus Torvalds case HCISETAUTH: 92404837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 92504837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9261da177e4SLinus Torvalds break; 9271da177e4SLinus Torvalds 9281da177e4SLinus Torvalds case HCISETENCRYPT: 9291da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 9301da177e4SLinus Torvalds err = -EOPNOTSUPP; 9311da177e4SLinus Torvalds break; 9321da177e4SLinus Torvalds } 9331da177e4SLinus Torvalds 9341da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 9351da177e4SLinus Torvalds /* Auth must be enabled first */ 93604837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 93704837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9381da177e4SLinus Torvalds if (err) 9391da177e4SLinus Torvalds break; 9401da177e4SLinus Torvalds } 9411da177e4SLinus Torvalds 94204837f64SMarcel Holtmann err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, 94304837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9441da177e4SLinus Torvalds break; 9451da177e4SLinus Torvalds 9461da177e4SLinus Torvalds case HCISETSCAN: 94704837f64SMarcel Holtmann err = hci_request(hdev, hci_scan_req, dr.dev_opt, 94804837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9491da177e4SLinus Torvalds break; 9501da177e4SLinus Torvalds 9511da177e4SLinus Torvalds case HCISETLINKPOL: 952e4e8e37cSMarcel Holtmann err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, 953e4e8e37cSMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9541da177e4SLinus Torvalds break; 9551da177e4SLinus Torvalds 9561da177e4SLinus Torvalds case HCISETLINKMODE: 957e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 958e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 959e4e8e37cSMarcel Holtmann break; 960e4e8e37cSMarcel Holtmann 961e4e8e37cSMarcel Holtmann case HCISETPTYPE: 962e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 9631da177e4SLinus Torvalds break; 9641da177e4SLinus Torvalds 9651da177e4SLinus Torvalds case HCISETACLMTU: 9661da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 9671da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 9681da177e4SLinus Torvalds break; 9691da177e4SLinus Torvalds 9701da177e4SLinus Torvalds case HCISETSCOMTU: 9711da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 9721da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 9731da177e4SLinus Torvalds break; 9741da177e4SLinus Torvalds 9751da177e4SLinus Torvalds default: 9761da177e4SLinus Torvalds err = -EINVAL; 9771da177e4SLinus Torvalds break; 9781da177e4SLinus Torvalds } 979e4e8e37cSMarcel Holtmann 9801da177e4SLinus Torvalds hci_dev_put(hdev); 9811da177e4SLinus Torvalds return err; 9821da177e4SLinus Torvalds } 9831da177e4SLinus Torvalds 9841da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 9851da177e4SLinus Torvalds { 9868035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 9871da177e4SLinus Torvalds struct hci_dev_list_req *dl; 9881da177e4SLinus Torvalds struct hci_dev_req *dr; 9891da177e4SLinus Torvalds int n = 0, size, err; 9901da177e4SLinus Torvalds __u16 dev_num; 9911da177e4SLinus Torvalds 9921da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 9931da177e4SLinus Torvalds return -EFAULT; 9941da177e4SLinus Torvalds 9951da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 9961da177e4SLinus Torvalds return -EINVAL; 9971da177e4SLinus Torvalds 9981da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 9991da177e4SLinus Torvalds 100070f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 100170f23020SAndrei Emeltchenko if (!dl) 10021da177e4SLinus Torvalds return -ENOMEM; 10031da177e4SLinus Torvalds 10041da177e4SLinus Torvalds dr = dl->dev_req; 10051da177e4SLinus Torvalds 1006f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 10078035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 1008a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1009e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 1010c542a06cSJohan Hedberg 1011a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1012a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1013c542a06cSJohan Hedberg 10141da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 10151da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 1016c542a06cSJohan Hedberg 10171da177e4SLinus Torvalds if (++n >= dev_num) 10181da177e4SLinus Torvalds break; 10191da177e4SLinus Torvalds } 1020f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 10211da177e4SLinus Torvalds 10221da177e4SLinus Torvalds dl->dev_num = n; 10231da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 10241da177e4SLinus Torvalds 10251da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 10261da177e4SLinus Torvalds kfree(dl); 10271da177e4SLinus Torvalds 10281da177e4SLinus Torvalds return err ? -EFAULT : 0; 10291da177e4SLinus Torvalds } 10301da177e4SLinus Torvalds 10311da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 10321da177e4SLinus Torvalds { 10331da177e4SLinus Torvalds struct hci_dev *hdev; 10341da177e4SLinus Torvalds struct hci_dev_info di; 10351da177e4SLinus Torvalds int err = 0; 10361da177e4SLinus Torvalds 10371da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 10381da177e4SLinus Torvalds return -EFAULT; 10391da177e4SLinus Torvalds 104070f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 104170f23020SAndrei Emeltchenko if (!hdev) 10421da177e4SLinus Torvalds return -ENODEV; 10431da177e4SLinus Torvalds 1044a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 10453243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 1046ab81cbf9SJohan Hedberg 1047a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1048a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1049c542a06cSJohan Hedberg 10501da177e4SLinus Torvalds strcpy(di.name, hdev->name); 10511da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 1052943da25dSMarcel Holtmann di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); 10531da177e4SLinus Torvalds di.flags = hdev->flags; 10541da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 10551da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 10561da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 10571da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 10581da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 10591da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 10601da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 10611da177e4SLinus Torvalds 10621da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 10631da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 10641da177e4SLinus Torvalds 10651da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 10661da177e4SLinus Torvalds err = -EFAULT; 10671da177e4SLinus Torvalds 10681da177e4SLinus Torvalds hci_dev_put(hdev); 10691da177e4SLinus Torvalds 10701da177e4SLinus Torvalds return err; 10711da177e4SLinus Torvalds } 10721da177e4SLinus Torvalds 10731da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 10741da177e4SLinus Torvalds 1075611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 1076611b30f7SMarcel Holtmann { 1077611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 1078611b30f7SMarcel Holtmann 1079611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 1080611b30f7SMarcel Holtmann 1081611b30f7SMarcel Holtmann if (!blocked) 1082611b30f7SMarcel Holtmann return 0; 1083611b30f7SMarcel Holtmann 1084611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 1085611b30f7SMarcel Holtmann 1086611b30f7SMarcel Holtmann return 0; 1087611b30f7SMarcel Holtmann } 1088611b30f7SMarcel Holtmann 1089611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 1090611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 1091611b30f7SMarcel Holtmann }; 1092611b30f7SMarcel Holtmann 10931da177e4SLinus Torvalds /* Alloc HCI device */ 10941da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void) 10951da177e4SLinus Torvalds { 10961da177e4SLinus Torvalds struct hci_dev *hdev; 10971da177e4SLinus Torvalds 109825ea6db0SMarcel Holtmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 10991da177e4SLinus Torvalds if (!hdev) 11001da177e4SLinus Torvalds return NULL; 11011da177e4SLinus Torvalds 11020ac7e700SDavid Herrmann hci_init_sysfs(hdev); 11031da177e4SLinus Torvalds skb_queue_head_init(&hdev->driver_init); 11041da177e4SLinus Torvalds 11051da177e4SLinus Torvalds return hdev; 11061da177e4SLinus Torvalds } 11071da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev); 11081da177e4SLinus Torvalds 11091da177e4SLinus Torvalds /* Free HCI device */ 11101da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev) 11111da177e4SLinus Torvalds { 11121da177e4SLinus Torvalds skb_queue_purge(&hdev->driver_init); 11131da177e4SLinus Torvalds 1114a91f2e39SMarcel Holtmann /* will free via device release */ 1115a91f2e39SMarcel Holtmann put_device(&hdev->dev); 11161da177e4SLinus Torvalds } 11171da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev); 11181da177e4SLinus Torvalds 1119ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 1120ab81cbf9SJohan Hedberg { 1121ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 1122ab81cbf9SJohan Hedberg 1123ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1124ab81cbf9SJohan Hedberg 1125ab81cbf9SJohan Hedberg if (hci_dev_open(hdev->id) < 0) 1126ab81cbf9SJohan Hedberg return; 1127ab81cbf9SJohan Hedberg 1128a8b2d5c2SJohan Hedberg if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 112980b7ab33SGustavo F. Padovan schedule_delayed_work(&hdev->power_off, 11303243553fSJohan Hedberg msecs_to_jiffies(AUTO_OFF_TIMEOUT)); 1131ab81cbf9SJohan Hedberg 1132a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 1133744cf19eSJohan Hedberg mgmt_index_added(hdev); 1134ab81cbf9SJohan Hedberg } 1135ab81cbf9SJohan Hedberg 1136ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1137ab81cbf9SJohan Hedberg { 11383243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 11393243553fSJohan Hedberg power_off.work); 1140ab81cbf9SJohan Hedberg 1141ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1142ab81cbf9SJohan Hedberg 11438ee56540SMarcel Holtmann hci_dev_do_close(hdev); 1144ab81cbf9SJohan Hedberg } 1145ab81cbf9SJohan Hedberg 114616ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 114716ab91abSJohan Hedberg { 114816ab91abSJohan Hedberg struct hci_dev *hdev; 114916ab91abSJohan Hedberg u8 scan = SCAN_PAGE; 115016ab91abSJohan Hedberg 115116ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 115216ab91abSJohan Hedberg 115316ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 115416ab91abSJohan Hedberg 115509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 115616ab91abSJohan Hedberg 115716ab91abSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); 115816ab91abSJohan Hedberg 115916ab91abSJohan Hedberg hdev->discov_timeout = 0; 116016ab91abSJohan Hedberg 116109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 116216ab91abSJohan Hedberg } 116316ab91abSJohan Hedberg 11642aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 11652aeb9a1aSJohan Hedberg { 11662aeb9a1aSJohan Hedberg struct list_head *p, *n; 11672aeb9a1aSJohan Hedberg 11682aeb9a1aSJohan Hedberg list_for_each_safe(p, n, &hdev->uuids) { 11692aeb9a1aSJohan Hedberg struct bt_uuid *uuid; 11702aeb9a1aSJohan Hedberg 11712aeb9a1aSJohan Hedberg uuid = list_entry(p, struct bt_uuid, list); 11722aeb9a1aSJohan Hedberg 11732aeb9a1aSJohan Hedberg list_del(p); 11742aeb9a1aSJohan Hedberg kfree(uuid); 11752aeb9a1aSJohan Hedberg } 11762aeb9a1aSJohan Hedberg 11772aeb9a1aSJohan Hedberg return 0; 11782aeb9a1aSJohan Hedberg } 11792aeb9a1aSJohan Hedberg 118055ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 118155ed8ca1SJohan Hedberg { 118255ed8ca1SJohan Hedberg struct list_head *p, *n; 118355ed8ca1SJohan Hedberg 118455ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 118555ed8ca1SJohan Hedberg struct link_key *key; 118655ed8ca1SJohan Hedberg 118755ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 118855ed8ca1SJohan Hedberg 118955ed8ca1SJohan Hedberg list_del(p); 119055ed8ca1SJohan Hedberg kfree(key); 119155ed8ca1SJohan Hedberg } 119255ed8ca1SJohan Hedberg 119355ed8ca1SJohan Hedberg return 0; 119455ed8ca1SJohan Hedberg } 119555ed8ca1SJohan Hedberg 1196b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 1197b899efafSVinicius Costa Gomes { 1198b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1199b899efafSVinicius Costa Gomes 1200b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1201b899efafSVinicius Costa Gomes list_del(&k->list); 1202b899efafSVinicius Costa Gomes kfree(k); 1203b899efafSVinicius Costa Gomes } 1204b899efafSVinicius Costa Gomes 1205b899efafSVinicius Costa Gomes return 0; 1206b899efafSVinicius Costa Gomes } 1207b899efafSVinicius Costa Gomes 120855ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 120955ed8ca1SJohan Hedberg { 121055ed8ca1SJohan Hedberg struct link_key *k; 121155ed8ca1SJohan Hedberg 12128035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 121355ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 121455ed8ca1SJohan Hedberg return k; 121555ed8ca1SJohan Hedberg 121655ed8ca1SJohan Hedberg return NULL; 121755ed8ca1SJohan Hedberg } 121855ed8ca1SJohan Hedberg 1219745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 1220d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 1221d25e28abSJohan Hedberg { 1222d25e28abSJohan Hedberg /* Legacy key */ 1223d25e28abSJohan Hedberg if (key_type < 0x03) 1224745c0ce3SVishal Agarwal return true; 1225d25e28abSJohan Hedberg 1226d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 1227d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 1228745c0ce3SVishal Agarwal return false; 1229d25e28abSJohan Hedberg 1230d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 1231d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 1232745c0ce3SVishal Agarwal return false; 1233d25e28abSJohan Hedberg 1234d25e28abSJohan Hedberg /* Security mode 3 case */ 1235d25e28abSJohan Hedberg if (!conn) 1236745c0ce3SVishal Agarwal return true; 1237d25e28abSJohan Hedberg 1238d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 1239d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 1240745c0ce3SVishal Agarwal return true; 1241d25e28abSJohan Hedberg 1242d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 1243d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 1244745c0ce3SVishal Agarwal return true; 1245d25e28abSJohan Hedberg 1246d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 1247d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 1248745c0ce3SVishal Agarwal return true; 1249d25e28abSJohan Hedberg 1250d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 1251d25e28abSJohan Hedberg * persistently */ 1252745c0ce3SVishal Agarwal return false; 1253d25e28abSJohan Hedberg } 1254d25e28abSJohan Hedberg 1255c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 125675d262c2SVinicius Costa Gomes { 1257c9839a11SVinicius Costa Gomes struct smp_ltk *k; 125875d262c2SVinicius Costa Gomes 1259c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 1260c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 1261c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 126275d262c2SVinicius Costa Gomes continue; 126375d262c2SVinicius Costa Gomes 126475d262c2SVinicius Costa Gomes return k; 126575d262c2SVinicius Costa Gomes } 126675d262c2SVinicius Costa Gomes 126775d262c2SVinicius Costa Gomes return NULL; 126875d262c2SVinicius Costa Gomes } 126975d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk); 127075d262c2SVinicius Costa Gomes 1271c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1272c9839a11SVinicius Costa Gomes u8 addr_type) 127375d262c2SVinicius Costa Gomes { 1274c9839a11SVinicius Costa Gomes struct smp_ltk *k; 127575d262c2SVinicius Costa Gomes 1276c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 1277c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 1278c9839a11SVinicius Costa Gomes bacmp(bdaddr, &k->bdaddr) == 0) 127975d262c2SVinicius Costa Gomes return k; 128075d262c2SVinicius Costa Gomes 128175d262c2SVinicius Costa Gomes return NULL; 128275d262c2SVinicius Costa Gomes } 1283c9839a11SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk_by_addr); 128475d262c2SVinicius Costa Gomes 1285d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 1286d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 128755ed8ca1SJohan Hedberg { 128855ed8ca1SJohan Hedberg struct link_key *key, *old_key; 1289745c0ce3SVishal Agarwal u8 old_key_type; 1290745c0ce3SVishal Agarwal bool persistent; 129155ed8ca1SJohan Hedberg 129255ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 129355ed8ca1SJohan Hedberg if (old_key) { 129455ed8ca1SJohan Hedberg old_key_type = old_key->type; 129555ed8ca1SJohan Hedberg key = old_key; 129655ed8ca1SJohan Hedberg } else { 129712adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 129855ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 129955ed8ca1SJohan Hedberg if (!key) 130055ed8ca1SJohan Hedberg return -ENOMEM; 130155ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 130255ed8ca1SJohan Hedberg } 130355ed8ca1SJohan Hedberg 130455ed8ca1SJohan Hedberg BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); 130555ed8ca1SJohan Hedberg 1306d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1307d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1308d25e28abSJohan Hedberg * previous key */ 1309d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1310d25e28abSJohan Hedberg (!conn || conn->remote_auth == 0xff) && 1311655fe6ecSJohan Hedberg old_key_type == 0xff) { 1312d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1313655fe6ecSJohan Hedberg if (conn) 1314655fe6ecSJohan Hedberg conn->key_type = type; 1315655fe6ecSJohan Hedberg } 1316d25e28abSJohan Hedberg 131755ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 131855ed8ca1SJohan Hedberg memcpy(key->val, val, 16); 131955ed8ca1SJohan Hedberg key->pin_len = pin_len; 132055ed8ca1SJohan Hedberg 1321b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 132255ed8ca1SJohan Hedberg key->type = old_key_type; 13234748fed2SJohan Hedberg else 13244748fed2SJohan Hedberg key->type = type; 13254748fed2SJohan Hedberg 13264df378a1SJohan Hedberg if (!new_key) 13274df378a1SJohan Hedberg return 0; 13284df378a1SJohan Hedberg 13294df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 13304df378a1SJohan Hedberg 1331744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 13324df378a1SJohan Hedberg 13336ec5bcadSVishal Agarwal if (conn) 13346ec5bcadSVishal Agarwal conn->flush_key = !persistent; 133555ed8ca1SJohan Hedberg 133655ed8ca1SJohan Hedberg return 0; 133755ed8ca1SJohan Hedberg } 133855ed8ca1SJohan Hedberg 1339c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 134004124681SGustavo F. Padovan int new_key, u8 authenticated, u8 tk[16], u8 enc_size, u16 134104124681SGustavo F. Padovan ediv, u8 rand[8]) 134275d262c2SVinicius Costa Gomes { 1343c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 134475d262c2SVinicius Costa Gomes 1345c9839a11SVinicius Costa Gomes if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 1346c9839a11SVinicius Costa Gomes return 0; 134775d262c2SVinicius Costa Gomes 1348c9839a11SVinicius Costa Gomes old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 1349c9839a11SVinicius Costa Gomes if (old_key) 135075d262c2SVinicius Costa Gomes key = old_key; 1351c9839a11SVinicius Costa Gomes else { 1352c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 135375d262c2SVinicius Costa Gomes if (!key) 135475d262c2SVinicius Costa Gomes return -ENOMEM; 1355c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 135675d262c2SVinicius Costa Gomes } 135775d262c2SVinicius Costa Gomes 135875d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 1359c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 1360c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 1361c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 1362c9839a11SVinicius Costa Gomes key->ediv = ediv; 1363c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 1364c9839a11SVinicius Costa Gomes key->type = type; 1365c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 136675d262c2SVinicius Costa Gomes 1367c9839a11SVinicius Costa Gomes if (!new_key) 1368c9839a11SVinicius Costa Gomes return 0; 136975d262c2SVinicius Costa Gomes 1370261cc5aaSVinicius Costa Gomes if (type & HCI_SMP_LTK) 1371261cc5aaSVinicius Costa Gomes mgmt_new_ltk(hdev, key, 1); 1372261cc5aaSVinicius Costa Gomes 137375d262c2SVinicius Costa Gomes return 0; 137475d262c2SVinicius Costa Gomes } 137575d262c2SVinicius Costa Gomes 137655ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 137755ed8ca1SJohan Hedberg { 137855ed8ca1SJohan Hedberg struct link_key *key; 137955ed8ca1SJohan Hedberg 138055ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 138155ed8ca1SJohan Hedberg if (!key) 138255ed8ca1SJohan Hedberg return -ENOENT; 138355ed8ca1SJohan Hedberg 138455ed8ca1SJohan Hedberg BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 138555ed8ca1SJohan Hedberg 138655ed8ca1SJohan Hedberg list_del(&key->list); 138755ed8ca1SJohan Hedberg kfree(key); 138855ed8ca1SJohan Hedberg 138955ed8ca1SJohan Hedberg return 0; 139055ed8ca1SJohan Hedberg } 139155ed8ca1SJohan Hedberg 1392b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 1393b899efafSVinicius Costa Gomes { 1394b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1395b899efafSVinicius Costa Gomes 1396b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1397b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 1398b899efafSVinicius Costa Gomes continue; 1399b899efafSVinicius Costa Gomes 1400b899efafSVinicius Costa Gomes BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 1401b899efafSVinicius Costa Gomes 1402b899efafSVinicius Costa Gomes list_del(&k->list); 1403b899efafSVinicius Costa Gomes kfree(k); 1404b899efafSVinicius Costa Gomes } 1405b899efafSVinicius Costa Gomes 1406b899efafSVinicius Costa Gomes return 0; 1407b899efafSVinicius Costa Gomes } 1408b899efafSVinicius Costa Gomes 14096bd32326SVille Tervo /* HCI command timer function */ 14106bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg) 14116bd32326SVille Tervo { 14126bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 14136bd32326SVille Tervo 14146bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 14156bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 1416c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 14176bd32326SVille Tervo } 14186bd32326SVille Tervo 14192763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 14202763eda6SSzymon Janc bdaddr_t *bdaddr) 14212763eda6SSzymon Janc { 14222763eda6SSzymon Janc struct oob_data *data; 14232763eda6SSzymon Janc 14242763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 14252763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 14262763eda6SSzymon Janc return data; 14272763eda6SSzymon Janc 14282763eda6SSzymon Janc return NULL; 14292763eda6SSzymon Janc } 14302763eda6SSzymon Janc 14312763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 14322763eda6SSzymon Janc { 14332763eda6SSzymon Janc struct oob_data *data; 14342763eda6SSzymon Janc 14352763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14362763eda6SSzymon Janc if (!data) 14372763eda6SSzymon Janc return -ENOENT; 14382763eda6SSzymon Janc 14392763eda6SSzymon Janc BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 14402763eda6SSzymon Janc 14412763eda6SSzymon Janc list_del(&data->list); 14422763eda6SSzymon Janc kfree(data); 14432763eda6SSzymon Janc 14442763eda6SSzymon Janc return 0; 14452763eda6SSzymon Janc } 14462763eda6SSzymon Janc 14472763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 14482763eda6SSzymon Janc { 14492763eda6SSzymon Janc struct oob_data *data, *n; 14502763eda6SSzymon Janc 14512763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 14522763eda6SSzymon Janc list_del(&data->list); 14532763eda6SSzymon Janc kfree(data); 14542763eda6SSzymon Janc } 14552763eda6SSzymon Janc 14562763eda6SSzymon Janc return 0; 14572763eda6SSzymon Janc } 14582763eda6SSzymon Janc 14592763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 14602763eda6SSzymon Janc u8 *randomizer) 14612763eda6SSzymon Janc { 14622763eda6SSzymon Janc struct oob_data *data; 14632763eda6SSzymon Janc 14642763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14652763eda6SSzymon Janc 14662763eda6SSzymon Janc if (!data) { 14672763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 14682763eda6SSzymon Janc if (!data) 14692763eda6SSzymon Janc return -ENOMEM; 14702763eda6SSzymon Janc 14712763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 14722763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 14732763eda6SSzymon Janc } 14742763eda6SSzymon Janc 14752763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 14762763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 14772763eda6SSzymon Janc 14782763eda6SSzymon Janc BT_DBG("%s for %s", hdev->name, batostr(bdaddr)); 14792763eda6SSzymon Janc 14802763eda6SSzymon Janc return 0; 14812763eda6SSzymon Janc } 14822763eda6SSzymon Janc 148304124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 1484b2a66aadSAntti Julku { 1485b2a66aadSAntti Julku struct bdaddr_list *b; 1486b2a66aadSAntti Julku 14878035ded4SLuiz Augusto von Dentz list_for_each_entry(b, &hdev->blacklist, list) 1488b2a66aadSAntti Julku if (bacmp(bdaddr, &b->bdaddr) == 0) 1489b2a66aadSAntti Julku return b; 1490b2a66aadSAntti Julku 1491b2a66aadSAntti Julku return NULL; 1492b2a66aadSAntti Julku } 1493b2a66aadSAntti Julku 1494b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 1495b2a66aadSAntti Julku { 1496b2a66aadSAntti Julku struct list_head *p, *n; 1497b2a66aadSAntti Julku 1498b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 1499b2a66aadSAntti Julku struct bdaddr_list *b; 1500b2a66aadSAntti Julku 1501b2a66aadSAntti Julku b = list_entry(p, struct bdaddr_list, list); 1502b2a66aadSAntti Julku 1503b2a66aadSAntti Julku list_del(p); 1504b2a66aadSAntti Julku kfree(b); 1505b2a66aadSAntti Julku } 1506b2a66aadSAntti Julku 1507b2a66aadSAntti Julku return 0; 1508b2a66aadSAntti Julku } 1509b2a66aadSAntti Julku 151088c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1511b2a66aadSAntti Julku { 1512b2a66aadSAntti Julku struct bdaddr_list *entry; 1513b2a66aadSAntti Julku 1514b2a66aadSAntti Julku if (bacmp(bdaddr, BDADDR_ANY) == 0) 1515b2a66aadSAntti Julku return -EBADF; 1516b2a66aadSAntti Julku 15175e762444SAntti Julku if (hci_blacklist_lookup(hdev, bdaddr)) 15185e762444SAntti Julku return -EEXIST; 1519b2a66aadSAntti Julku 1520b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 15215e762444SAntti Julku if (!entry) 15225e762444SAntti Julku return -ENOMEM; 1523b2a66aadSAntti Julku 1524b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 1525b2a66aadSAntti Julku 1526b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 1527b2a66aadSAntti Julku 152888c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 1529b2a66aadSAntti Julku } 1530b2a66aadSAntti Julku 153188c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1532b2a66aadSAntti Julku { 1533b2a66aadSAntti Julku struct bdaddr_list *entry; 1534b2a66aadSAntti Julku 15351ec918ceSSzymon Janc if (bacmp(bdaddr, BDADDR_ANY) == 0) 15365e762444SAntti Julku return hci_blacklist_clear(hdev); 1537b2a66aadSAntti Julku 1538b2a66aadSAntti Julku entry = hci_blacklist_lookup(hdev, bdaddr); 15391ec918ceSSzymon Janc if (!entry) 15405e762444SAntti Julku return -ENOENT; 1541b2a66aadSAntti Julku 1542b2a66aadSAntti Julku list_del(&entry->list); 1543b2a66aadSAntti Julku kfree(entry); 1544b2a66aadSAntti Julku 154588c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 1546b2a66aadSAntti Julku } 1547b2a66aadSAntti Julku 1548db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work) 154935815085SAndre Guedes { 1550db323f2fSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, 1551db323f2fSGustavo F. Padovan adv_work.work); 155235815085SAndre Guedes 155335815085SAndre Guedes hci_dev_lock(hdev); 155435815085SAndre Guedes 155535815085SAndre Guedes hci_adv_entries_clear(hdev); 155635815085SAndre Guedes 155735815085SAndre Guedes hci_dev_unlock(hdev); 155835815085SAndre Guedes } 155935815085SAndre Guedes 156076c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev) 156176c8686fSAndre Guedes { 156276c8686fSAndre Guedes struct adv_entry *entry, *tmp; 156376c8686fSAndre Guedes 156476c8686fSAndre Guedes list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) { 156576c8686fSAndre Guedes list_del(&entry->list); 156676c8686fSAndre Guedes kfree(entry); 156776c8686fSAndre Guedes } 156876c8686fSAndre Guedes 156976c8686fSAndre Guedes BT_DBG("%s adv cache cleared", hdev->name); 157076c8686fSAndre Guedes 157176c8686fSAndre Guedes return 0; 157276c8686fSAndre Guedes } 157376c8686fSAndre Guedes 157476c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr) 157576c8686fSAndre Guedes { 157676c8686fSAndre Guedes struct adv_entry *entry; 157776c8686fSAndre Guedes 157876c8686fSAndre Guedes list_for_each_entry(entry, &hdev->adv_entries, list) 157976c8686fSAndre Guedes if (bacmp(bdaddr, &entry->bdaddr) == 0) 158076c8686fSAndre Guedes return entry; 158176c8686fSAndre Guedes 158276c8686fSAndre Guedes return NULL; 158376c8686fSAndre Guedes } 158476c8686fSAndre Guedes 158576c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type) 158676c8686fSAndre Guedes { 158776c8686fSAndre Guedes if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND) 158876c8686fSAndre Guedes return 1; 158976c8686fSAndre Guedes 159076c8686fSAndre Guedes return 0; 159176c8686fSAndre Guedes } 159276c8686fSAndre Guedes 159376c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev, 159404124681SGustavo F. Padovan struct hci_ev_le_advertising_info *ev) { struct adv_entry *entry; if (!is_connectable_adv(ev->evt_type)) 159576c8686fSAndre Guedes return -EINVAL; 159676c8686fSAndre Guedes 159776c8686fSAndre Guedes /* Only new entries should be added to adv_entries. So, if 159876c8686fSAndre Guedes * bdaddr was found, don't add it. */ 159976c8686fSAndre Guedes if (hci_find_adv_entry(hdev, &ev->bdaddr)) 160076c8686fSAndre Guedes return 0; 160176c8686fSAndre Guedes 16024777bfdeSAndre Guedes entry = kzalloc(sizeof(*entry), GFP_KERNEL); 160376c8686fSAndre Guedes if (!entry) 160476c8686fSAndre Guedes return -ENOMEM; 160576c8686fSAndre Guedes 160676c8686fSAndre Guedes bacpy(&entry->bdaddr, &ev->bdaddr); 160776c8686fSAndre Guedes entry->bdaddr_type = ev->bdaddr_type; 160876c8686fSAndre Guedes 160976c8686fSAndre Guedes list_add(&entry->list, &hdev->adv_entries); 161076c8686fSAndre Guedes 161176c8686fSAndre Guedes BT_DBG("%s adv entry added: address %s type %u", hdev->name, 161276c8686fSAndre Guedes batostr(&entry->bdaddr), entry->bdaddr_type); 161376c8686fSAndre Guedes 161476c8686fSAndre Guedes return 0; 161576c8686fSAndre Guedes } 161676c8686fSAndre Guedes 16177ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt) 16187ba8b4beSAndre Guedes { 16197ba8b4beSAndre Guedes struct le_scan_params *param = (struct le_scan_params *) opt; 16207ba8b4beSAndre Guedes struct hci_cp_le_set_scan_param cp; 16217ba8b4beSAndre Guedes 16227ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 16237ba8b4beSAndre Guedes cp.type = param->type; 16247ba8b4beSAndre Guedes cp.interval = cpu_to_le16(param->interval); 16257ba8b4beSAndre Guedes cp.window = cpu_to_le16(param->window); 16267ba8b4beSAndre Guedes 16277ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); 16287ba8b4beSAndre Guedes } 16297ba8b4beSAndre Guedes 16307ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt) 16317ba8b4beSAndre Guedes { 16327ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 16337ba8b4beSAndre Guedes 16347ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 16357ba8b4beSAndre Guedes cp.enable = 1; 16367ba8b4beSAndre Guedes 16377ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 16387ba8b4beSAndre Guedes } 16397ba8b4beSAndre Guedes 16407ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, 16417ba8b4beSAndre Guedes u16 window, int timeout) 16427ba8b4beSAndre Guedes { 16437ba8b4beSAndre Guedes long timeo = msecs_to_jiffies(3000); 16447ba8b4beSAndre Guedes struct le_scan_params param; 16457ba8b4beSAndre Guedes int err; 16467ba8b4beSAndre Guedes 16477ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 16487ba8b4beSAndre Guedes 16497ba8b4beSAndre Guedes if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 16507ba8b4beSAndre Guedes return -EINPROGRESS; 16517ba8b4beSAndre Guedes 16527ba8b4beSAndre Guedes param.type = type; 16537ba8b4beSAndre Guedes param.interval = interval; 16547ba8b4beSAndre Guedes param.window = window; 16557ba8b4beSAndre Guedes 16567ba8b4beSAndre Guedes hci_req_lock(hdev); 16577ba8b4beSAndre Guedes 16587ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_param_req, (unsigned long) ¶m, 16597ba8b4beSAndre Guedes timeo); 16607ba8b4beSAndre Guedes if (!err) 16617ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_enable_req, 0, timeo); 16627ba8b4beSAndre Guedes 16637ba8b4beSAndre Guedes hci_req_unlock(hdev); 16647ba8b4beSAndre Guedes 16657ba8b4beSAndre Guedes if (err < 0) 16667ba8b4beSAndre Guedes return err; 16677ba8b4beSAndre Guedes 16687ba8b4beSAndre Guedes schedule_delayed_work(&hdev->le_scan_disable, 16697ba8b4beSAndre Guedes msecs_to_jiffies(timeout)); 16707ba8b4beSAndre Guedes 16717ba8b4beSAndre Guedes return 0; 16727ba8b4beSAndre Guedes } 16737ba8b4beSAndre Guedes 16747ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 16757ba8b4beSAndre Guedes { 16767ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 16777ba8b4beSAndre Guedes le_scan_disable.work); 16787ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 16797ba8b4beSAndre Guedes 16807ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 16817ba8b4beSAndre Guedes 16827ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 16837ba8b4beSAndre Guedes 16847ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 16857ba8b4beSAndre Guedes } 16867ba8b4beSAndre Guedes 168728b75a89SAndre Guedes static void le_scan_work(struct work_struct *work) 168828b75a89SAndre Guedes { 168928b75a89SAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan); 169028b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 169128b75a89SAndre Guedes 169228b75a89SAndre Guedes BT_DBG("%s", hdev->name); 169328b75a89SAndre Guedes 169404124681SGustavo F. Padovan hci_do_le_scan(hdev, param->type, param->interval, param->window, 169504124681SGustavo F. Padovan param->timeout); 169628b75a89SAndre Guedes } 169728b75a89SAndre Guedes 169828b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, 169928b75a89SAndre Guedes int timeout) 170028b75a89SAndre Guedes { 170128b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 170228b75a89SAndre Guedes 170328b75a89SAndre Guedes BT_DBG("%s", hdev->name); 170428b75a89SAndre Guedes 170528b75a89SAndre Guedes if (work_busy(&hdev->le_scan)) 170628b75a89SAndre Guedes return -EINPROGRESS; 170728b75a89SAndre Guedes 170828b75a89SAndre Guedes param->type = type; 170928b75a89SAndre Guedes param->interval = interval; 171028b75a89SAndre Guedes param->window = window; 171128b75a89SAndre Guedes param->timeout = timeout; 171228b75a89SAndre Guedes 171328b75a89SAndre Guedes queue_work(system_long_wq, &hdev->le_scan); 171428b75a89SAndre Guedes 171528b75a89SAndre Guedes return 0; 171628b75a89SAndre Guedes } 171728b75a89SAndre Guedes 17181da177e4SLinus Torvalds /* Register HCI device */ 17191da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 17201da177e4SLinus Torvalds { 17211da177e4SLinus Torvalds struct list_head *head = &hci_dev_list, *p; 172208add513SMat Martineau int i, id, error; 17231da177e4SLinus Torvalds 1724e9b9cfa1SDavid Herrmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 17251da177e4SLinus Torvalds 1726010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 17271da177e4SLinus Torvalds return -EINVAL; 17281da177e4SLinus Torvalds 172908add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 173008add513SMat Martineau * so the index can be used as the AMP controller ID. 173108add513SMat Martineau */ 173208add513SMat Martineau id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; 173308add513SMat Martineau 1734f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 17351da177e4SLinus Torvalds 17361da177e4SLinus Torvalds /* Find first available device id */ 17371da177e4SLinus Torvalds list_for_each(p, &hci_dev_list) { 17381da177e4SLinus Torvalds if (list_entry(p, struct hci_dev, list)->id != id) 17391da177e4SLinus Torvalds break; 17401da177e4SLinus Torvalds head = p; id++; 17411da177e4SLinus Torvalds } 17421da177e4SLinus Torvalds 17431da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 17441da177e4SLinus Torvalds hdev->id = id; 1745c6feeb28SAndrei Emeltchenko list_add_tail(&hdev->list, head); 17461da177e4SLinus Torvalds 174709fd0de5SGustavo F. Padovan mutex_init(&hdev->lock); 17481da177e4SLinus Torvalds 17491da177e4SLinus Torvalds hdev->flags = 0; 1750d23264a8SAndre Guedes hdev->dev_flags = 0; 17511da177e4SLinus Torvalds hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 17525b7f9909SMarcel Holtmann hdev->esco_type = (ESCO_HV1); 17531da177e4SLinus Torvalds hdev->link_mode = (HCI_LM_ACCEPT); 175417fa4b9dSJohan Hedberg hdev->io_capability = 0x03; /* No Input No Output */ 17551da177e4SLinus Torvalds 175604837f64SMarcel Holtmann hdev->idle_timeout = 0; 175704837f64SMarcel Holtmann hdev->sniff_max_interval = 800; 175804837f64SMarcel Holtmann hdev->sniff_min_interval = 80; 175904837f64SMarcel Holtmann 1760b78752ccSMarcel Holtmann INIT_WORK(&hdev->rx_work, hci_rx_work); 1761c347b765SGustavo F. Padovan INIT_WORK(&hdev->cmd_work, hci_cmd_work); 17623eff45eaSGustavo F. Padovan INIT_WORK(&hdev->tx_work, hci_tx_work); 1763b78752ccSMarcel Holtmann 17641da177e4SLinus Torvalds 17651da177e4SLinus Torvalds skb_queue_head_init(&hdev->rx_q); 17661da177e4SLinus Torvalds skb_queue_head_init(&hdev->cmd_q); 17671da177e4SLinus Torvalds skb_queue_head_init(&hdev->raw_q); 17681da177e4SLinus Torvalds 17696bd32326SVille Tervo setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); 17706bd32326SVille Tervo 1771cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1772ef222013SMarcel Holtmann hdev->reassembly[i] = NULL; 1773ef222013SMarcel Holtmann 17741da177e4SLinus Torvalds init_waitqueue_head(&hdev->req_wait_q); 1775a6a67efdSThomas Gleixner mutex_init(&hdev->req_lock); 17761da177e4SLinus Torvalds 177730883512SJohan Hedberg discovery_init(hdev); 17781da177e4SLinus Torvalds 17791da177e4SLinus Torvalds hci_conn_hash_init(hdev); 17801da177e4SLinus Torvalds 17812e58ef3eSJohan Hedberg INIT_LIST_HEAD(&hdev->mgmt_pending); 17822e58ef3eSJohan Hedberg 1783ea4bd8baSDavid Miller INIT_LIST_HEAD(&hdev->blacklist); 1784f0358568SJohan Hedberg 17852aeb9a1aSJohan Hedberg INIT_LIST_HEAD(&hdev->uuids); 17862aeb9a1aSJohan Hedberg 178755ed8ca1SJohan Hedberg INIT_LIST_HEAD(&hdev->link_keys); 1788b899efafSVinicius Costa Gomes INIT_LIST_HEAD(&hdev->long_term_keys); 178955ed8ca1SJohan Hedberg 17902763eda6SSzymon Janc INIT_LIST_HEAD(&hdev->remote_oob_data); 17912763eda6SSzymon Janc 179276c8686fSAndre Guedes INIT_LIST_HEAD(&hdev->adv_entries); 179376c8686fSAndre Guedes 1794db323f2fSGustavo F. Padovan INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache); 1795ab81cbf9SJohan Hedberg INIT_WORK(&hdev->power_on, hci_power_on); 17963243553fSJohan Hedberg INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 1797ab81cbf9SJohan Hedberg 179816ab91abSJohan Hedberg INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 179916ab91abSJohan Hedberg 18001da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 18011da177e4SLinus Torvalds 18021da177e4SLinus Torvalds atomic_set(&hdev->promisc, 0); 18031da177e4SLinus Torvalds 180428b75a89SAndre Guedes INIT_WORK(&hdev->le_scan, le_scan_work); 180528b75a89SAndre Guedes 18067ba8b4beSAndre Guedes INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 18077ba8b4beSAndre Guedes 1808f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 18091da177e4SLinus Torvalds 181032845eb1SGustavo F. Padovan hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | 181132845eb1SGustavo F. Padovan WQ_MEM_RECLAIM, 1); 181233ca954dSDavid Herrmann if (!hdev->workqueue) { 181333ca954dSDavid Herrmann error = -ENOMEM; 181433ca954dSDavid Herrmann goto err; 181533ca954dSDavid Herrmann } 1816f48fd9c8SMarcel Holtmann 181733ca954dSDavid Herrmann error = hci_add_sysfs(hdev); 181833ca954dSDavid Herrmann if (error < 0) 181933ca954dSDavid Herrmann goto err_wqueue; 18201da177e4SLinus Torvalds 1821611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 1822611b30f7SMarcel Holtmann RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); 1823611b30f7SMarcel Holtmann if (hdev->rfkill) { 1824611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 1825611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1826611b30f7SMarcel Holtmann hdev->rfkill = NULL; 1827611b30f7SMarcel Holtmann } 1828611b30f7SMarcel Holtmann } 1829611b30f7SMarcel Holtmann 1830a8b2d5c2SJohan Hedberg set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 1831a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 18327f971041SGustavo F. Padovan schedule_work(&hdev->power_on); 1833ab81cbf9SJohan Hedberg 18341da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 1835dc946bd8SDavid Herrmann hci_dev_hold(hdev); 18361da177e4SLinus Torvalds 18371da177e4SLinus Torvalds return id; 1838f48fd9c8SMarcel Holtmann 183933ca954dSDavid Herrmann err_wqueue: 184033ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 184133ca954dSDavid Herrmann err: 1842f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 1843f48fd9c8SMarcel Holtmann list_del(&hdev->list); 1844f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 1845f48fd9c8SMarcel Holtmann 184633ca954dSDavid Herrmann return error; 18471da177e4SLinus Torvalds } 18481da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 18491da177e4SLinus Torvalds 18501da177e4SLinus Torvalds /* Unregister HCI device */ 185159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 18521da177e4SLinus Torvalds { 1853ef222013SMarcel Holtmann int i; 1854ef222013SMarcel Holtmann 1855c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 18561da177e4SLinus Torvalds 185794324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 185894324962SJohan Hovold 1859f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 18601da177e4SLinus Torvalds list_del(&hdev->list); 1861f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 18621da177e4SLinus Torvalds 18631da177e4SLinus Torvalds hci_dev_do_close(hdev); 18641da177e4SLinus Torvalds 1865cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1866ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 1867ef222013SMarcel Holtmann 1868ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 1869a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 187009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1871744cf19eSJohan Hedberg mgmt_index_removed(hdev); 187209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 187356e5cb86SJohan Hedberg } 1874ab81cbf9SJohan Hedberg 18752e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 18762e58ef3eSJohan Hedberg * pending list */ 18772e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 18782e58ef3eSJohan Hedberg 18791da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 18801da177e4SLinus Torvalds 1881611b30f7SMarcel Holtmann if (hdev->rfkill) { 1882611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 1883611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1884611b30f7SMarcel Holtmann } 1885611b30f7SMarcel Holtmann 1886ce242970SDavid Herrmann hci_del_sysfs(hdev); 1887147e2d59SDave Young 1888db323f2fSGustavo F. Padovan cancel_delayed_work_sync(&hdev->adv_work); 1889c6f3c5f7SGustavo F. Padovan 1890f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 1891f48fd9c8SMarcel Holtmann 189209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1893e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 18942aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 189555ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 1896b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 18972763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 189876c8686fSAndre Guedes hci_adv_entries_clear(hdev); 189909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 1900e2e0cacbSJohan Hedberg 1901dc946bd8SDavid Herrmann hci_dev_put(hdev); 19021da177e4SLinus Torvalds } 19031da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 19041da177e4SLinus Torvalds 19051da177e4SLinus Torvalds /* Suspend HCI device */ 19061da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 19071da177e4SLinus Torvalds { 19081da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 19091da177e4SLinus Torvalds return 0; 19101da177e4SLinus Torvalds } 19111da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 19121da177e4SLinus Torvalds 19131da177e4SLinus Torvalds /* Resume HCI device */ 19141da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 19151da177e4SLinus Torvalds { 19161da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 19171da177e4SLinus Torvalds return 0; 19181da177e4SLinus Torvalds } 19191da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 19201da177e4SLinus Torvalds 192176bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 192276bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb) 192376bca880SMarcel Holtmann { 192476bca880SMarcel Holtmann struct hci_dev *hdev = (struct hci_dev *) skb->dev; 192576bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 192676bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 192776bca880SMarcel Holtmann kfree_skb(skb); 192876bca880SMarcel Holtmann return -ENXIO; 192976bca880SMarcel Holtmann } 193076bca880SMarcel Holtmann 193176bca880SMarcel Holtmann /* Incomming skb */ 193276bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 193376bca880SMarcel Holtmann 193476bca880SMarcel Holtmann /* Time stamp */ 193576bca880SMarcel Holtmann __net_timestamp(skb); 193676bca880SMarcel Holtmann 193776bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 1938b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 1939c78ae283SMarcel Holtmann 194076bca880SMarcel Holtmann return 0; 194176bca880SMarcel Holtmann } 194276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 194376bca880SMarcel Holtmann 194433e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 19451e429f38SGustavo F. Padovan int count, __u8 index) 194633e882a5SSuraj Sumangala { 194733e882a5SSuraj Sumangala int len = 0; 194833e882a5SSuraj Sumangala int hlen = 0; 194933e882a5SSuraj Sumangala int remain = count; 195033e882a5SSuraj Sumangala struct sk_buff *skb; 195133e882a5SSuraj Sumangala struct bt_skb_cb *scb; 195233e882a5SSuraj Sumangala 195333e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 195433e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 195533e882a5SSuraj Sumangala return -EILSEQ; 195633e882a5SSuraj Sumangala 195733e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 195833e882a5SSuraj Sumangala 195933e882a5SSuraj Sumangala if (!skb) { 196033e882a5SSuraj Sumangala switch (type) { 196133e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 196233e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 196333e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 196433e882a5SSuraj Sumangala break; 196533e882a5SSuraj Sumangala case HCI_EVENT_PKT: 196633e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 196733e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 196833e882a5SSuraj Sumangala break; 196933e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 197033e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 197133e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 197233e882a5SSuraj Sumangala break; 197333e882a5SSuraj Sumangala } 197433e882a5SSuraj Sumangala 19751e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 197633e882a5SSuraj Sumangala if (!skb) 197733e882a5SSuraj Sumangala return -ENOMEM; 197833e882a5SSuraj Sumangala 197933e882a5SSuraj Sumangala scb = (void *) skb->cb; 198033e882a5SSuraj Sumangala scb->expect = hlen; 198133e882a5SSuraj Sumangala scb->pkt_type = type; 198233e882a5SSuraj Sumangala 198333e882a5SSuraj Sumangala skb->dev = (void *) hdev; 198433e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 198533e882a5SSuraj Sumangala } 198633e882a5SSuraj Sumangala 198733e882a5SSuraj Sumangala while (count) { 198833e882a5SSuraj Sumangala scb = (void *) skb->cb; 198989bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 199033e882a5SSuraj Sumangala 199133e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 199233e882a5SSuraj Sumangala 199333e882a5SSuraj Sumangala count -= len; 199433e882a5SSuraj Sumangala data += len; 199533e882a5SSuraj Sumangala scb->expect -= len; 199633e882a5SSuraj Sumangala remain = count; 199733e882a5SSuraj Sumangala 199833e882a5SSuraj Sumangala switch (type) { 199933e882a5SSuraj Sumangala case HCI_EVENT_PKT: 200033e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 200133e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 200233e882a5SSuraj Sumangala scb->expect = h->plen; 200333e882a5SSuraj Sumangala 200433e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 200533e882a5SSuraj Sumangala kfree_skb(skb); 200633e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 200733e882a5SSuraj Sumangala return -ENOMEM; 200833e882a5SSuraj Sumangala } 200933e882a5SSuraj Sumangala } 201033e882a5SSuraj Sumangala break; 201133e882a5SSuraj Sumangala 201233e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 201333e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 201433e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 201533e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 201633e882a5SSuraj Sumangala 201733e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 201833e882a5SSuraj Sumangala kfree_skb(skb); 201933e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 202033e882a5SSuraj Sumangala return -ENOMEM; 202133e882a5SSuraj Sumangala } 202233e882a5SSuraj Sumangala } 202333e882a5SSuraj Sumangala break; 202433e882a5SSuraj Sumangala 202533e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 202633e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 202733e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 202833e882a5SSuraj Sumangala scb->expect = h->dlen; 202933e882a5SSuraj Sumangala 203033e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 203133e882a5SSuraj Sumangala kfree_skb(skb); 203233e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 203333e882a5SSuraj Sumangala return -ENOMEM; 203433e882a5SSuraj Sumangala } 203533e882a5SSuraj Sumangala } 203633e882a5SSuraj Sumangala break; 203733e882a5SSuraj Sumangala } 203833e882a5SSuraj Sumangala 203933e882a5SSuraj Sumangala if (scb->expect == 0) { 204033e882a5SSuraj Sumangala /* Complete frame */ 204133e882a5SSuraj Sumangala 204233e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 204333e882a5SSuraj Sumangala hci_recv_frame(skb); 204433e882a5SSuraj Sumangala 204533e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 204633e882a5SSuraj Sumangala return remain; 204733e882a5SSuraj Sumangala } 204833e882a5SSuraj Sumangala } 204933e882a5SSuraj Sumangala 205033e882a5SSuraj Sumangala return remain; 205133e882a5SSuraj Sumangala } 205233e882a5SSuraj Sumangala 2053ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 2054ef222013SMarcel Holtmann { 2055f39a3c06SSuraj Sumangala int rem = 0; 2056f39a3c06SSuraj Sumangala 2057ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 2058ef222013SMarcel Holtmann return -EILSEQ; 2059ef222013SMarcel Holtmann 2060da5f6c37SGustavo F. Padovan while (count) { 20611e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 2062f39a3c06SSuraj Sumangala if (rem < 0) 2063f39a3c06SSuraj Sumangala return rem; 2064ef222013SMarcel Holtmann 2065f39a3c06SSuraj Sumangala data += (count - rem); 2066f39a3c06SSuraj Sumangala count = rem; 2067f81c6224SJoe Perches } 2068ef222013SMarcel Holtmann 2069f39a3c06SSuraj Sumangala return rem; 2070ef222013SMarcel Holtmann } 2071ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 2072ef222013SMarcel Holtmann 207399811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 207499811510SSuraj Sumangala 207599811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 207699811510SSuraj Sumangala { 207799811510SSuraj Sumangala int type; 207899811510SSuraj Sumangala int rem = 0; 207999811510SSuraj Sumangala 2080da5f6c37SGustavo F. Padovan while (count) { 208199811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 208299811510SSuraj Sumangala 208399811510SSuraj Sumangala if (!skb) { 208499811510SSuraj Sumangala struct { char type; } *pkt; 208599811510SSuraj Sumangala 208699811510SSuraj Sumangala /* Start of the frame */ 208799811510SSuraj Sumangala pkt = data; 208899811510SSuraj Sumangala type = pkt->type; 208999811510SSuraj Sumangala 209099811510SSuraj Sumangala data++; 209199811510SSuraj Sumangala count--; 209299811510SSuraj Sumangala } else 209399811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 209499811510SSuraj Sumangala 20951e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 20961e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 209799811510SSuraj Sumangala if (rem < 0) 209899811510SSuraj Sumangala return rem; 209999811510SSuraj Sumangala 210099811510SSuraj Sumangala data += (count - rem); 210199811510SSuraj Sumangala count = rem; 2102f81c6224SJoe Perches } 210399811510SSuraj Sumangala 210499811510SSuraj Sumangala return rem; 210599811510SSuraj Sumangala } 210699811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 210799811510SSuraj Sumangala 21081da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 21091da177e4SLinus Torvalds 21101da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 21111da177e4SLinus Torvalds { 21121da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 21131da177e4SLinus Torvalds 2114f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 21151da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 2116f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 21171da177e4SLinus Torvalds 21181da177e4SLinus Torvalds return 0; 21191da177e4SLinus Torvalds } 21201da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 21211da177e4SLinus Torvalds 21221da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 21231da177e4SLinus Torvalds { 21241da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 21251da177e4SLinus Torvalds 2126f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 21271da177e4SLinus Torvalds list_del(&cb->list); 2128f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 21291da177e4SLinus Torvalds 21301da177e4SLinus Torvalds return 0; 21311da177e4SLinus Torvalds } 21321da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 21331da177e4SLinus Torvalds 21341da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb) 21351da177e4SLinus Torvalds { 21361da177e4SLinus Torvalds struct hci_dev *hdev = (struct hci_dev *) skb->dev; 21371da177e4SLinus Torvalds 21381da177e4SLinus Torvalds if (!hdev) { 21391da177e4SLinus Torvalds kfree_skb(skb); 21401da177e4SLinus Torvalds return -ENODEV; 21411da177e4SLinus Torvalds } 21421da177e4SLinus Torvalds 21430d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 21441da177e4SLinus Torvalds 21451da177e4SLinus Torvalds /* Time stamp */ 2146a61bbcf2SPatrick McHardy __net_timestamp(skb); 21471da177e4SLinus Torvalds 2148cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2149cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2150cd82e61cSMarcel Holtmann 2151cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 2152cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 2153470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 21541da177e4SLinus Torvalds } 21551da177e4SLinus Torvalds 21561da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 21571da177e4SLinus Torvalds skb_orphan(skb); 21581da177e4SLinus Torvalds 21591da177e4SLinus Torvalds return hdev->send(skb); 21601da177e4SLinus Torvalds } 21611da177e4SLinus Torvalds 21621da177e4SLinus Torvalds /* Send HCI command */ 2163a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) 21641da177e4SLinus Torvalds { 21651da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 21661da177e4SLinus Torvalds struct hci_command_hdr *hdr; 21671da177e4SLinus Torvalds struct sk_buff *skb; 21681da177e4SLinus Torvalds 2169a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen); 21701da177e4SLinus Torvalds 21711da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 21721da177e4SLinus Torvalds if (!skb) { 2173ef222013SMarcel Holtmann BT_ERR("%s no memory for command", hdev->name); 21741da177e4SLinus Torvalds return -ENOMEM; 21751da177e4SLinus Torvalds } 21761da177e4SLinus Torvalds 21771da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 2178a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 21791da177e4SLinus Torvalds hdr->plen = plen; 21801da177e4SLinus Torvalds 21811da177e4SLinus Torvalds if (plen) 21821da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 21831da177e4SLinus Torvalds 21841da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 21851da177e4SLinus Torvalds 21860d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 21871da177e4SLinus Torvalds skb->dev = (void *) hdev; 2188c78ae283SMarcel Holtmann 2189a5040efaSJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags)) 2190a5040efaSJohan Hedberg hdev->init_last_cmd = opcode; 2191a5040efaSJohan Hedberg 21921da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 2193c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 21941da177e4SLinus Torvalds 21951da177e4SLinus Torvalds return 0; 21961da177e4SLinus Torvalds } 21971da177e4SLinus Torvalds 21981da177e4SLinus Torvalds /* Get data from the previously sent command */ 2199a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 22001da177e4SLinus Torvalds { 22011da177e4SLinus Torvalds struct hci_command_hdr *hdr; 22021da177e4SLinus Torvalds 22031da177e4SLinus Torvalds if (!hdev->sent_cmd) 22041da177e4SLinus Torvalds return NULL; 22051da177e4SLinus Torvalds 22061da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 22071da177e4SLinus Torvalds 2208a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 22091da177e4SLinus Torvalds return NULL; 22101da177e4SLinus Torvalds 2211a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 22121da177e4SLinus Torvalds 22131da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 22141da177e4SLinus Torvalds } 22151da177e4SLinus Torvalds 22161da177e4SLinus Torvalds /* Send ACL data */ 22171da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 22181da177e4SLinus Torvalds { 22191da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 22201da177e4SLinus Torvalds int len = skb->len; 22211da177e4SLinus Torvalds 2222badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 2223badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 22249c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 2225aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 2226aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 22271da177e4SLinus Torvalds } 22281da177e4SLinus Torvalds 222973d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, 223073d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 22311da177e4SLinus Torvalds { 22321da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 22331da177e4SLinus Torvalds struct sk_buff *list; 22341da177e4SLinus Torvalds 223570f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 223670f23020SAndrei Emeltchenko if (!list) { 22371da177e4SLinus Torvalds /* Non fragmented */ 22381da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 22391da177e4SLinus Torvalds 224073d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 22411da177e4SLinus Torvalds } else { 22421da177e4SLinus Torvalds /* Fragmented */ 22431da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 22441da177e4SLinus Torvalds 22451da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 22461da177e4SLinus Torvalds 22471da177e4SLinus Torvalds /* Queue all fragments atomically */ 2248af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 22491da177e4SLinus Torvalds 225073d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 2251e702112fSAndrei Emeltchenko 2252e702112fSAndrei Emeltchenko flags &= ~ACL_START; 2253e702112fSAndrei Emeltchenko flags |= ACL_CONT; 22541da177e4SLinus Torvalds do { 22551da177e4SLinus Torvalds skb = list; list = list->next; 22561da177e4SLinus Torvalds 22571da177e4SLinus Torvalds skb->dev = (void *) hdev; 22580d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2259e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 22601da177e4SLinus Torvalds 22611da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 22621da177e4SLinus Torvalds 226373d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 22641da177e4SLinus Torvalds } while (list); 22651da177e4SLinus Torvalds 2266af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 22671da177e4SLinus Torvalds } 226873d80debSLuiz Augusto von Dentz } 226973d80debSLuiz Augusto von Dentz 227073d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 227173d80debSLuiz Augusto von Dentz { 227273d80debSLuiz Augusto von Dentz struct hci_conn *conn = chan->conn; 227373d80debSLuiz Augusto von Dentz struct hci_dev *hdev = conn->hdev; 227473d80debSLuiz Augusto von Dentz 227573d80debSLuiz Augusto von Dentz BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags); 227673d80debSLuiz Augusto von Dentz 227773d80debSLuiz Augusto von Dentz skb->dev = (void *) hdev; 227873d80debSLuiz Augusto von Dentz bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 227973d80debSLuiz Augusto von Dentz hci_add_acl_hdr(skb, conn->handle, flags); 228073d80debSLuiz Augusto von Dentz 228173d80debSLuiz Augusto von Dentz hci_queue_acl(conn, &chan->data_q, skb, flags); 22821da177e4SLinus Torvalds 22833eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 22841da177e4SLinus Torvalds } 22851da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl); 22861da177e4SLinus Torvalds 22871da177e4SLinus Torvalds /* Send SCO data */ 22880d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 22891da177e4SLinus Torvalds { 22901da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 22911da177e4SLinus Torvalds struct hci_sco_hdr hdr; 22921da177e4SLinus Torvalds 22931da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 22941da177e4SLinus Torvalds 2295aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 22961da177e4SLinus Torvalds hdr.dlen = skb->len; 22971da177e4SLinus Torvalds 2298badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 2299badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 23009c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 23011da177e4SLinus Torvalds 23021da177e4SLinus Torvalds skb->dev = (void *) hdev; 23030d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 2304c78ae283SMarcel Holtmann 23051da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 23063eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 23071da177e4SLinus Torvalds } 23081da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco); 23091da177e4SLinus Torvalds 23101da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 23111da177e4SLinus Torvalds 23121da177e4SLinus Torvalds /* HCI Connection scheduler */ 23131da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) 23141da177e4SLinus Torvalds { 23151da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 23168035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 23171da177e4SLinus Torvalds int num = 0, min = ~0; 23181da177e4SLinus Torvalds 23191da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 23201da177e4SLinus Torvalds * added and removed with TX task disabled. */ 2321bf4c6325SGustavo F. Padovan 2322bf4c6325SGustavo F. Padovan rcu_read_lock(); 2323bf4c6325SGustavo F. Padovan 2324bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2325769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 23261da177e4SLinus Torvalds continue; 2327769be974SMarcel Holtmann 2328769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 2329769be974SMarcel Holtmann continue; 2330769be974SMarcel Holtmann 23311da177e4SLinus Torvalds num++; 23321da177e4SLinus Torvalds 23331da177e4SLinus Torvalds if (c->sent < min) { 23341da177e4SLinus Torvalds min = c->sent; 23351da177e4SLinus Torvalds conn = c; 23361da177e4SLinus Torvalds } 233752087a79SLuiz Augusto von Dentz 233852087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 233952087a79SLuiz Augusto von Dentz break; 23401da177e4SLinus Torvalds } 23411da177e4SLinus Torvalds 2342bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2343bf4c6325SGustavo F. Padovan 23441da177e4SLinus Torvalds if (conn) { 23456ed58ec5SVille Tervo int cnt, q; 23466ed58ec5SVille Tervo 23476ed58ec5SVille Tervo switch (conn->type) { 23486ed58ec5SVille Tervo case ACL_LINK: 23496ed58ec5SVille Tervo cnt = hdev->acl_cnt; 23506ed58ec5SVille Tervo break; 23516ed58ec5SVille Tervo case SCO_LINK: 23526ed58ec5SVille Tervo case ESCO_LINK: 23536ed58ec5SVille Tervo cnt = hdev->sco_cnt; 23546ed58ec5SVille Tervo break; 23556ed58ec5SVille Tervo case LE_LINK: 23566ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 23576ed58ec5SVille Tervo break; 23586ed58ec5SVille Tervo default: 23596ed58ec5SVille Tervo cnt = 0; 23606ed58ec5SVille Tervo BT_ERR("Unknown link type"); 23616ed58ec5SVille Tervo } 23626ed58ec5SVille Tervo 23636ed58ec5SVille Tervo q = cnt / num; 23641da177e4SLinus Torvalds *quote = q ? q : 1; 23651da177e4SLinus Torvalds } else 23661da177e4SLinus Torvalds *quote = 0; 23671da177e4SLinus Torvalds 23681da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 23691da177e4SLinus Torvalds return conn; 23701da177e4SLinus Torvalds } 23711da177e4SLinus Torvalds 2372bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 23731da177e4SLinus Torvalds { 23741da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 23751da177e4SLinus Torvalds struct hci_conn *c; 23761da177e4SLinus Torvalds 2377bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 23781da177e4SLinus Torvalds 2379bf4c6325SGustavo F. Padovan rcu_read_lock(); 2380bf4c6325SGustavo F. Padovan 23811da177e4SLinus Torvalds /* Kill stalled connections */ 2382bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2383bae1f5d9SVille Tervo if (c->type == type && c->sent) { 2384bae1f5d9SVille Tervo BT_ERR("%s killing stalled connection %s", 23851da177e4SLinus Torvalds hdev->name, batostr(&c->dst)); 23861da177e4SLinus Torvalds hci_acl_disconn(c, 0x13); 23871da177e4SLinus Torvalds } 23881da177e4SLinus Torvalds } 2389bf4c6325SGustavo F. Padovan 2390bf4c6325SGustavo F. Padovan rcu_read_unlock(); 23911da177e4SLinus Torvalds } 23921da177e4SLinus Torvalds 239373d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 239473d80debSLuiz Augusto von Dentz int *quote) 239573d80debSLuiz Augusto von Dentz { 239673d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 239773d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 239873d80debSLuiz Augusto von Dentz int num = 0, min = ~0, cur_prio = 0; 239973d80debSLuiz Augusto von Dentz struct hci_conn *conn; 240073d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 240173d80debSLuiz Augusto von Dentz 240273d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 240373d80debSLuiz Augusto von Dentz 2404bf4c6325SGustavo F. Padovan rcu_read_lock(); 2405bf4c6325SGustavo F. Padovan 2406bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 240773d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 240873d80debSLuiz Augusto von Dentz 240973d80debSLuiz Augusto von Dentz if (conn->type != type) 241073d80debSLuiz Augusto von Dentz continue; 241173d80debSLuiz Augusto von Dentz 241273d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 241373d80debSLuiz Augusto von Dentz continue; 241473d80debSLuiz Augusto von Dentz 241573d80debSLuiz Augusto von Dentz conn_num++; 241673d80debSLuiz Augusto von Dentz 24178192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 241873d80debSLuiz Augusto von Dentz struct sk_buff *skb; 241973d80debSLuiz Augusto von Dentz 242073d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 242173d80debSLuiz Augusto von Dentz continue; 242273d80debSLuiz Augusto von Dentz 242373d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 242473d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 242573d80debSLuiz Augusto von Dentz continue; 242673d80debSLuiz Augusto von Dentz 242773d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 242873d80debSLuiz Augusto von Dentz num = 0; 242973d80debSLuiz Augusto von Dentz min = ~0; 243073d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 243173d80debSLuiz Augusto von Dentz } 243273d80debSLuiz Augusto von Dentz 243373d80debSLuiz Augusto von Dentz num++; 243473d80debSLuiz Augusto von Dentz 243573d80debSLuiz Augusto von Dentz if (conn->sent < min) { 243673d80debSLuiz Augusto von Dentz min = conn->sent; 243773d80debSLuiz Augusto von Dentz chan = tmp; 243873d80debSLuiz Augusto von Dentz } 243973d80debSLuiz Augusto von Dentz } 244073d80debSLuiz Augusto von Dentz 244173d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 244273d80debSLuiz Augusto von Dentz break; 244373d80debSLuiz Augusto von Dentz } 244473d80debSLuiz Augusto von Dentz 2445bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2446bf4c6325SGustavo F. Padovan 244773d80debSLuiz Augusto von Dentz if (!chan) 244873d80debSLuiz Augusto von Dentz return NULL; 244973d80debSLuiz Augusto von Dentz 245073d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 245173d80debSLuiz Augusto von Dentz case ACL_LINK: 245273d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 245373d80debSLuiz Augusto von Dentz break; 245473d80debSLuiz Augusto von Dentz case SCO_LINK: 245573d80debSLuiz Augusto von Dentz case ESCO_LINK: 245673d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 245773d80debSLuiz Augusto von Dentz break; 245873d80debSLuiz Augusto von Dentz case LE_LINK: 245973d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 246073d80debSLuiz Augusto von Dentz break; 246173d80debSLuiz Augusto von Dentz default: 246273d80debSLuiz Augusto von Dentz cnt = 0; 246373d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 246473d80debSLuiz Augusto von Dentz } 246573d80debSLuiz Augusto von Dentz 246673d80debSLuiz Augusto von Dentz q = cnt / num; 246773d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 246873d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 246973d80debSLuiz Augusto von Dentz return chan; 247073d80debSLuiz Augusto von Dentz } 247173d80debSLuiz Augusto von Dentz 247202b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 247302b20f0bSLuiz Augusto von Dentz { 247402b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 247502b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 247602b20f0bSLuiz Augusto von Dentz int num = 0; 247702b20f0bSLuiz Augusto von Dentz 247802b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 247902b20f0bSLuiz Augusto von Dentz 2480bf4c6325SGustavo F. Padovan rcu_read_lock(); 2481bf4c6325SGustavo F. Padovan 2482bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 248302b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 248402b20f0bSLuiz Augusto von Dentz 248502b20f0bSLuiz Augusto von Dentz if (conn->type != type) 248602b20f0bSLuiz Augusto von Dentz continue; 248702b20f0bSLuiz Augusto von Dentz 248802b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 248902b20f0bSLuiz Augusto von Dentz continue; 249002b20f0bSLuiz Augusto von Dentz 249102b20f0bSLuiz Augusto von Dentz num++; 249202b20f0bSLuiz Augusto von Dentz 24938192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 249402b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 249502b20f0bSLuiz Augusto von Dentz 249602b20f0bSLuiz Augusto von Dentz if (chan->sent) { 249702b20f0bSLuiz Augusto von Dentz chan->sent = 0; 249802b20f0bSLuiz Augusto von Dentz continue; 249902b20f0bSLuiz Augusto von Dentz } 250002b20f0bSLuiz Augusto von Dentz 250102b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 250202b20f0bSLuiz Augusto von Dentz continue; 250302b20f0bSLuiz Augusto von Dentz 250402b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 250502b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 250602b20f0bSLuiz Augusto von Dentz continue; 250702b20f0bSLuiz Augusto von Dentz 250802b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 250902b20f0bSLuiz Augusto von Dentz 251002b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 251102b20f0bSLuiz Augusto von Dentz skb->priority); 251202b20f0bSLuiz Augusto von Dentz } 251302b20f0bSLuiz Augusto von Dentz 251402b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 251502b20f0bSLuiz Augusto von Dentz break; 251602b20f0bSLuiz Augusto von Dentz } 2517bf4c6325SGustavo F. Padovan 2518bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2519bf4c6325SGustavo F. Padovan 252002b20f0bSLuiz Augusto von Dentz } 252102b20f0bSLuiz Augusto von Dentz 2522b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 2523b71d385aSAndrei Emeltchenko { 2524b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 2525b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 2526b71d385aSAndrei Emeltchenko } 2527b71d385aSAndrei Emeltchenko 252863d2bc1bSAndrei Emeltchenko static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 25291da177e4SLinus Torvalds { 25301da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 25311da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 25321da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 253363d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 2534cc48dc0aSAndrei Emeltchenko msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) 2535bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 25361da177e4SLinus Torvalds } 253763d2bc1bSAndrei Emeltchenko } 25381da177e4SLinus Torvalds 253963d2bc1bSAndrei Emeltchenko static inline void hci_sched_acl_pkt(struct hci_dev *hdev) 254063d2bc1bSAndrei Emeltchenko { 254163d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 254263d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 254363d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 254463d2bc1bSAndrei Emeltchenko int quote; 254563d2bc1bSAndrei Emeltchenko 254663d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 254704837f64SMarcel Holtmann 254873d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 254973d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2550ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2551ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 255273d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 255373d80debSLuiz Augusto von Dentz skb->len, skb->priority); 255473d80debSLuiz Augusto von Dentz 2555ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2556ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2557ec1cce24SLuiz Augusto von Dentz break; 2558ec1cce24SLuiz Augusto von Dentz 2559ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2560ec1cce24SLuiz Augusto von Dentz 256173d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 256273d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 256304837f64SMarcel Holtmann 25641da177e4SLinus Torvalds hci_send_frame(skb); 25651da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 25661da177e4SLinus Torvalds 25671da177e4SLinus Torvalds hdev->acl_cnt--; 256873d80debSLuiz Augusto von Dentz chan->sent++; 256973d80debSLuiz Augusto von Dentz chan->conn->sent++; 25701da177e4SLinus Torvalds } 25711da177e4SLinus Torvalds } 257202b20f0bSLuiz Augusto von Dentz 257302b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 257402b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 25751da177e4SLinus Torvalds } 25761da177e4SLinus Torvalds 2577b71d385aSAndrei Emeltchenko static inline void hci_sched_acl_blk(struct hci_dev *hdev) 2578b71d385aSAndrei Emeltchenko { 257963d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 2580b71d385aSAndrei Emeltchenko struct hci_chan *chan; 2581b71d385aSAndrei Emeltchenko struct sk_buff *skb; 2582b71d385aSAndrei Emeltchenko int quote; 2583b71d385aSAndrei Emeltchenko 258463d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 2585b71d385aSAndrei Emeltchenko 2586b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 2587b71d385aSAndrei Emeltchenko (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2588b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 2589b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 2590b71d385aSAndrei Emeltchenko int blocks; 2591b71d385aSAndrei Emeltchenko 2592b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 2593b71d385aSAndrei Emeltchenko skb->len, skb->priority); 2594b71d385aSAndrei Emeltchenko 2595b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 2596b71d385aSAndrei Emeltchenko if (skb->priority < priority) 2597b71d385aSAndrei Emeltchenko break; 2598b71d385aSAndrei Emeltchenko 2599b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 2600b71d385aSAndrei Emeltchenko 2601b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 2602b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 2603b71d385aSAndrei Emeltchenko return; 2604b71d385aSAndrei Emeltchenko 2605b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 2606b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 2607b71d385aSAndrei Emeltchenko 2608b71d385aSAndrei Emeltchenko hci_send_frame(skb); 2609b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 2610b71d385aSAndrei Emeltchenko 2611b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 2612b71d385aSAndrei Emeltchenko quote -= blocks; 2613b71d385aSAndrei Emeltchenko 2614b71d385aSAndrei Emeltchenko chan->sent += blocks; 2615b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 2616b71d385aSAndrei Emeltchenko } 2617b71d385aSAndrei Emeltchenko } 2618b71d385aSAndrei Emeltchenko 2619b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 2620b71d385aSAndrei Emeltchenko hci_prio_recalculate(hdev, ACL_LINK); 2621b71d385aSAndrei Emeltchenko } 2622b71d385aSAndrei Emeltchenko 2623b71d385aSAndrei Emeltchenko static inline void hci_sched_acl(struct hci_dev *hdev) 2624b71d385aSAndrei Emeltchenko { 2625b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 2626b71d385aSAndrei Emeltchenko 2627b71d385aSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK)) 2628b71d385aSAndrei Emeltchenko return; 2629b71d385aSAndrei Emeltchenko 2630b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 2631b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 2632b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 2633b71d385aSAndrei Emeltchenko break; 2634b71d385aSAndrei Emeltchenko 2635b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 2636b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 2637b71d385aSAndrei Emeltchenko break; 2638b71d385aSAndrei Emeltchenko } 2639b71d385aSAndrei Emeltchenko } 2640b71d385aSAndrei Emeltchenko 26411da177e4SLinus Torvalds /* Schedule SCO */ 26421da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev) 26431da177e4SLinus Torvalds { 26441da177e4SLinus Torvalds struct hci_conn *conn; 26451da177e4SLinus Torvalds struct sk_buff *skb; 26461da177e4SLinus Torvalds int quote; 26471da177e4SLinus Torvalds 26481da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 26491da177e4SLinus Torvalds 265052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 265152087a79SLuiz Augusto von Dentz return; 265252087a79SLuiz Augusto von Dentz 26531da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 26541da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 26551da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 26561da177e4SLinus Torvalds hci_send_frame(skb); 26571da177e4SLinus Torvalds 26581da177e4SLinus Torvalds conn->sent++; 26591da177e4SLinus Torvalds if (conn->sent == ~0) 26601da177e4SLinus Torvalds conn->sent = 0; 26611da177e4SLinus Torvalds } 26621da177e4SLinus Torvalds } 26631da177e4SLinus Torvalds } 26641da177e4SLinus Torvalds 2665b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev) 2666b6a0dc82SMarcel Holtmann { 2667b6a0dc82SMarcel Holtmann struct hci_conn *conn; 2668b6a0dc82SMarcel Holtmann struct sk_buff *skb; 2669b6a0dc82SMarcel Holtmann int quote; 2670b6a0dc82SMarcel Holtmann 2671b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 2672b6a0dc82SMarcel Holtmann 267352087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 267452087a79SLuiz Augusto von Dentz return; 267552087a79SLuiz Augusto von Dentz 2676b6a0dc82SMarcel Holtmann while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, "e))) { 2677b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 2678b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 2679b6a0dc82SMarcel Holtmann hci_send_frame(skb); 2680b6a0dc82SMarcel Holtmann 2681b6a0dc82SMarcel Holtmann conn->sent++; 2682b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 2683b6a0dc82SMarcel Holtmann conn->sent = 0; 2684b6a0dc82SMarcel Holtmann } 2685b6a0dc82SMarcel Holtmann } 2686b6a0dc82SMarcel Holtmann } 2687b6a0dc82SMarcel Holtmann 26886ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev) 26896ed58ec5SVille Tervo { 269073d80debSLuiz Augusto von Dentz struct hci_chan *chan; 26916ed58ec5SVille Tervo struct sk_buff *skb; 269202b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 26936ed58ec5SVille Tervo 26946ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 26956ed58ec5SVille Tervo 269652087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 269752087a79SLuiz Augusto von Dentz return; 269852087a79SLuiz Augusto von Dentz 26996ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 27006ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 27016ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 2702bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 27036ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 2704bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 27056ed58ec5SVille Tervo } 27066ed58ec5SVille Tervo 27076ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 270802b20f0bSLuiz Augusto von Dentz tmp = cnt; 270973d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 2710ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2711ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 271273d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 271373d80debSLuiz Augusto von Dentz skb->len, skb->priority); 27146ed58ec5SVille Tervo 2715ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2716ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2717ec1cce24SLuiz Augusto von Dentz break; 2718ec1cce24SLuiz Augusto von Dentz 2719ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2720ec1cce24SLuiz Augusto von Dentz 27216ed58ec5SVille Tervo hci_send_frame(skb); 27226ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 27236ed58ec5SVille Tervo 27246ed58ec5SVille Tervo cnt--; 272573d80debSLuiz Augusto von Dentz chan->sent++; 272673d80debSLuiz Augusto von Dentz chan->conn->sent++; 27276ed58ec5SVille Tervo } 27286ed58ec5SVille Tervo } 272973d80debSLuiz Augusto von Dentz 27306ed58ec5SVille Tervo if (hdev->le_pkts) 27316ed58ec5SVille Tervo hdev->le_cnt = cnt; 27326ed58ec5SVille Tervo else 27336ed58ec5SVille Tervo hdev->acl_cnt = cnt; 273402b20f0bSLuiz Augusto von Dentz 273502b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 273602b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 27376ed58ec5SVille Tervo } 27386ed58ec5SVille Tervo 27393eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 27401da177e4SLinus Torvalds { 27413eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 27421da177e4SLinus Torvalds struct sk_buff *skb; 27431da177e4SLinus Torvalds 27446ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 27456ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 27461da177e4SLinus Torvalds 27471da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 27481da177e4SLinus Torvalds 27491da177e4SLinus Torvalds hci_sched_acl(hdev); 27501da177e4SLinus Torvalds 27511da177e4SLinus Torvalds hci_sched_sco(hdev); 27521da177e4SLinus Torvalds 2753b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 2754b6a0dc82SMarcel Holtmann 27556ed58ec5SVille Tervo hci_sched_le(hdev); 27566ed58ec5SVille Tervo 27571da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 27581da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 27591da177e4SLinus Torvalds hci_send_frame(skb); 27601da177e4SLinus Torvalds } 27611da177e4SLinus Torvalds 276225985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 27631da177e4SLinus Torvalds 27641da177e4SLinus Torvalds /* ACL data packet */ 27651da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 27661da177e4SLinus Torvalds { 27671da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 27681da177e4SLinus Torvalds struct hci_conn *conn; 27691da177e4SLinus Torvalds __u16 handle, flags; 27701da177e4SLinus Torvalds 27711da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 27721da177e4SLinus Torvalds 27731da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 27741da177e4SLinus Torvalds flags = hci_flags(handle); 27751da177e4SLinus Torvalds handle = hci_handle(handle); 27761da177e4SLinus Torvalds 27771da177e4SLinus Torvalds BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags); 27781da177e4SLinus Torvalds 27791da177e4SLinus Torvalds hdev->stat.acl_rx++; 27801da177e4SLinus Torvalds 27811da177e4SLinus Torvalds hci_dev_lock(hdev); 27821da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 27831da177e4SLinus Torvalds hci_dev_unlock(hdev); 27841da177e4SLinus Torvalds 27851da177e4SLinus Torvalds if (conn) { 278665983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 278704837f64SMarcel Holtmann 27881da177e4SLinus Torvalds /* Send to upper protocol */ 2789686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 27901da177e4SLinus Torvalds return; 27911da177e4SLinus Torvalds } else { 27921da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 27931da177e4SLinus Torvalds hdev->name, handle); 27941da177e4SLinus Torvalds } 27951da177e4SLinus Torvalds 27961da177e4SLinus Torvalds kfree_skb(skb); 27971da177e4SLinus Torvalds } 27981da177e4SLinus Torvalds 27991da177e4SLinus Torvalds /* SCO data packet */ 28001da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 28011da177e4SLinus Torvalds { 28021da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 28031da177e4SLinus Torvalds struct hci_conn *conn; 28041da177e4SLinus Torvalds __u16 handle; 28051da177e4SLinus Torvalds 28061da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 28071da177e4SLinus Torvalds 28081da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 28091da177e4SLinus Torvalds 28101da177e4SLinus Torvalds BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle); 28111da177e4SLinus Torvalds 28121da177e4SLinus Torvalds hdev->stat.sco_rx++; 28131da177e4SLinus Torvalds 28141da177e4SLinus Torvalds hci_dev_lock(hdev); 28151da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 28161da177e4SLinus Torvalds hci_dev_unlock(hdev); 28171da177e4SLinus Torvalds 28181da177e4SLinus Torvalds if (conn) { 28191da177e4SLinus Torvalds /* Send to upper protocol */ 2820686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 28211da177e4SLinus Torvalds return; 28221da177e4SLinus Torvalds } else { 28231da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 28241da177e4SLinus Torvalds hdev->name, handle); 28251da177e4SLinus Torvalds } 28261da177e4SLinus Torvalds 28271da177e4SLinus Torvalds kfree_skb(skb); 28281da177e4SLinus Torvalds } 28291da177e4SLinus Torvalds 2830b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 28311da177e4SLinus Torvalds { 2832b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 28331da177e4SLinus Torvalds struct sk_buff *skb; 28341da177e4SLinus Torvalds 28351da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 28361da177e4SLinus Torvalds 28371da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 2838cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2839cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2840cd82e61cSMarcel Holtmann 28411da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 28421da177e4SLinus Torvalds /* Send copy to the sockets */ 2843470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 28441da177e4SLinus Torvalds } 28451da177e4SLinus Torvalds 28461da177e4SLinus Torvalds if (test_bit(HCI_RAW, &hdev->flags)) { 28471da177e4SLinus Torvalds kfree_skb(skb); 28481da177e4SLinus Torvalds continue; 28491da177e4SLinus Torvalds } 28501da177e4SLinus Torvalds 28511da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 28521da177e4SLinus Torvalds /* Don't process data packets in this states. */ 28530d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 28541da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 28551da177e4SLinus Torvalds case HCI_SCODATA_PKT: 28561da177e4SLinus Torvalds kfree_skb(skb); 28571da177e4SLinus Torvalds continue; 28583ff50b79SStephen Hemminger } 28591da177e4SLinus Torvalds } 28601da177e4SLinus Torvalds 28611da177e4SLinus Torvalds /* Process frame */ 28620d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 28631da177e4SLinus Torvalds case HCI_EVENT_PKT: 2864b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 28651da177e4SLinus Torvalds hci_event_packet(hdev, skb); 28661da177e4SLinus Torvalds break; 28671da177e4SLinus Torvalds 28681da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 28691da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 28701da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 28711da177e4SLinus Torvalds break; 28721da177e4SLinus Torvalds 28731da177e4SLinus Torvalds case HCI_SCODATA_PKT: 28741da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 28751da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 28761da177e4SLinus Torvalds break; 28771da177e4SLinus Torvalds 28781da177e4SLinus Torvalds default: 28791da177e4SLinus Torvalds kfree_skb(skb); 28801da177e4SLinus Torvalds break; 28811da177e4SLinus Torvalds } 28821da177e4SLinus Torvalds } 28831da177e4SLinus Torvalds } 28841da177e4SLinus Torvalds 2885c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 28861da177e4SLinus Torvalds { 2887c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 28881da177e4SLinus Torvalds struct sk_buff *skb; 28891da177e4SLinus Torvalds 28901da177e4SLinus Torvalds BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); 28911da177e4SLinus Torvalds 28921da177e4SLinus Torvalds /* Send queued commands */ 28935a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 28945a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 28955a08ecceSAndrei Emeltchenko if (!skb) 28965a08ecceSAndrei Emeltchenko return; 28975a08ecceSAndrei Emeltchenko 28981da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 28991da177e4SLinus Torvalds 290070f23020SAndrei Emeltchenko hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC); 290170f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 29021da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 29031da177e4SLinus Torvalds hci_send_frame(skb); 29047bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 29057bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 29067bdb8a5cSSzymon Janc else 29076bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 29086bd32326SVille Tervo jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); 29091da177e4SLinus Torvalds } else { 29101da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 2911c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 29121da177e4SLinus Torvalds } 29131da177e4SLinus Torvalds } 29141da177e4SLinus Torvalds } 29152519a1fcSAndre Guedes 29162519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length) 29172519a1fcSAndre Guedes { 29182519a1fcSAndre Guedes /* General inquiry access code (GIAC) */ 29192519a1fcSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 29202519a1fcSAndre Guedes struct hci_cp_inquiry cp; 29212519a1fcSAndre Guedes 29222519a1fcSAndre Guedes BT_DBG("%s", hdev->name); 29232519a1fcSAndre Guedes 29242519a1fcSAndre Guedes if (test_bit(HCI_INQUIRY, &hdev->flags)) 29252519a1fcSAndre Guedes return -EINPROGRESS; 29262519a1fcSAndre Guedes 29274663262cSJohan Hedberg inquiry_cache_flush(hdev); 29284663262cSJohan Hedberg 29292519a1fcSAndre Guedes memset(&cp, 0, sizeof(cp)); 29302519a1fcSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 29312519a1fcSAndre Guedes cp.length = length; 29322519a1fcSAndre Guedes 29332519a1fcSAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 29342519a1fcSAndre Guedes } 2935023d5049SAndre Guedes 2936023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev) 2937023d5049SAndre Guedes { 2938023d5049SAndre Guedes BT_DBG("%s", hdev->name); 2939023d5049SAndre Guedes 2940023d5049SAndre Guedes if (!test_bit(HCI_INQUIRY, &hdev->flags)) 2941023d5049SAndre Guedes return -EPERM; 2942023d5049SAndre Guedes 2943023d5049SAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); 2944023d5049SAndre Guedes } 2945