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 669611b30f7SMarcel Holtmann if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { 670611b30f7SMarcel Holtmann ret = -ERFKILL; 671611b30f7SMarcel Holtmann goto done; 672611b30f7SMarcel Holtmann } 673611b30f7SMarcel Holtmann 6741da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 6751da177e4SLinus Torvalds ret = -EALREADY; 6761da177e4SLinus Torvalds goto done; 6771da177e4SLinus Torvalds } 6781da177e4SLinus Torvalds 6791da177e4SLinus Torvalds if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 6801da177e4SLinus Torvalds set_bit(HCI_RAW, &hdev->flags); 6811da177e4SLinus Torvalds 68207e3b94aSAndrei Emeltchenko /* Treat all non BR/EDR controllers as raw devices if 68307e3b94aSAndrei Emeltchenko enable_hs is not set */ 68407e3b94aSAndrei Emeltchenko if (hdev->dev_type != HCI_BREDR && !enable_hs) 685943da25dSMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 686943da25dSMarcel Holtmann 6871da177e4SLinus Torvalds if (hdev->open(hdev)) { 6881da177e4SLinus Torvalds ret = -EIO; 6891da177e4SLinus Torvalds goto done; 6901da177e4SLinus Torvalds } 6911da177e4SLinus Torvalds 6921da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 6931da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 6941da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 695a5040efaSJohan Hedberg hdev->init_last_cmd = 0; 6961da177e4SLinus Torvalds 69704837f64SMarcel Holtmann ret = __hci_request(hdev, hci_init_req, 0, 69804837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 6991da177e4SLinus Torvalds 700eead27daSAndre Guedes if (lmp_host_le_capable(hdev)) 7016ed58ec5SVille Tervo ret = __hci_request(hdev, hci_le_init_req, 0, 7026ed58ec5SVille Tervo msecs_to_jiffies(HCI_INIT_TIMEOUT)); 7036ed58ec5SVille Tervo 7041da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7051da177e4SLinus Torvalds } 7061da177e4SLinus Torvalds 7071da177e4SLinus Torvalds if (!ret) { 7081da177e4SLinus Torvalds hci_dev_hold(hdev); 7091da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 7101da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 711a8b2d5c2SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 71209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 713744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 71409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 71556e5cb86SJohan Hedberg } 7161da177e4SLinus Torvalds } else { 7171da177e4SLinus Torvalds /* Init failed, cleanup */ 7183eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 719c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 720b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7211da177e4SLinus Torvalds 7221da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7231da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7241da177e4SLinus Torvalds 7251da177e4SLinus Torvalds if (hdev->flush) 7261da177e4SLinus Torvalds hdev->flush(hdev); 7271da177e4SLinus Torvalds 7281da177e4SLinus Torvalds if (hdev->sent_cmd) { 7291da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 7301da177e4SLinus Torvalds hdev->sent_cmd = NULL; 7311da177e4SLinus Torvalds } 7321da177e4SLinus Torvalds 7331da177e4SLinus Torvalds hdev->close(hdev); 7341da177e4SLinus Torvalds hdev->flags = 0; 7351da177e4SLinus Torvalds } 7361da177e4SLinus Torvalds 7371da177e4SLinus Torvalds done: 7381da177e4SLinus Torvalds hci_req_unlock(hdev); 7391da177e4SLinus Torvalds hci_dev_put(hdev); 7401da177e4SLinus Torvalds return ret; 7411da177e4SLinus Torvalds } 7421da177e4SLinus Torvalds 7431da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 7441da177e4SLinus Torvalds { 7451da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 7461da177e4SLinus Torvalds 74728b75a89SAndre Guedes cancel_work_sync(&hdev->le_scan); 74828b75a89SAndre Guedes 7491da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 7501da177e4SLinus Torvalds hci_req_lock(hdev); 7511da177e4SLinus Torvalds 7521da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 753b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 7541da177e4SLinus Torvalds hci_req_unlock(hdev); 7551da177e4SLinus Torvalds return 0; 7561da177e4SLinus Torvalds } 7571da177e4SLinus Torvalds 7583eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 7593eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 760b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7611da177e4SLinus Torvalds 76216ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 763e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 76416ab91abSJohan Hedberg hdev->discov_timeout = 0; 7655e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 76616ab91abSJohan Hedberg } 76716ab91abSJohan Hedberg 768a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 7697d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 7707d78525dSJohan Hedberg 7717ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 7727ba8b4beSAndre Guedes 77309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 7741da177e4SLinus Torvalds inquiry_cache_flush(hdev); 7751da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 77609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 7771da177e4SLinus Torvalds 7781da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 7791da177e4SLinus Torvalds 7801da177e4SLinus Torvalds if (hdev->flush) 7811da177e4SLinus Torvalds hdev->flush(hdev); 7821da177e4SLinus Torvalds 7831da177e4SLinus Torvalds /* Reset device */ 7841da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7851da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 7868af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 7878af59467SJohan Hedberg test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { 7881da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 78904837f64SMarcel Holtmann __hci_request(hdev, hci_reset_req, 0, 790cad44c2bSGustavo F. Padovan msecs_to_jiffies(250)); 7911da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7921da177e4SLinus Torvalds } 7931da177e4SLinus Torvalds 794c347b765SGustavo F. Padovan /* flush cmd work */ 795c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 7961da177e4SLinus Torvalds 7971da177e4SLinus Torvalds /* Drop queues */ 7981da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7991da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8001da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 8011da177e4SLinus Torvalds 8021da177e4SLinus Torvalds /* Drop last sent command */ 8031da177e4SLinus Torvalds if (hdev->sent_cmd) { 804b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 8051da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 8061da177e4SLinus Torvalds hdev->sent_cmd = NULL; 8071da177e4SLinus Torvalds } 8081da177e4SLinus Torvalds 8091da177e4SLinus Torvalds /* After this point our queues are empty 8101da177e4SLinus Torvalds * and no tasks are scheduled. */ 8111da177e4SLinus Torvalds hdev->close(hdev); 8121da177e4SLinus Torvalds 8138ee56540SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 81409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 815744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 81609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8178ee56540SMarcel Holtmann } 8185add6af8SJohan Hedberg 8191da177e4SLinus Torvalds /* Clear flags */ 8201da177e4SLinus Torvalds hdev->flags = 0; 8211da177e4SLinus Torvalds 822e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 82309b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 824e59fda8dSJohan Hedberg 8251da177e4SLinus Torvalds hci_req_unlock(hdev); 8261da177e4SLinus Torvalds 8271da177e4SLinus Torvalds hci_dev_put(hdev); 8281da177e4SLinus Torvalds return 0; 8291da177e4SLinus Torvalds } 8301da177e4SLinus Torvalds 8311da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 8321da177e4SLinus Torvalds { 8331da177e4SLinus Torvalds struct hci_dev *hdev; 8341da177e4SLinus Torvalds int err; 8351da177e4SLinus Torvalds 83670f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 83770f23020SAndrei Emeltchenko if (!hdev) 8381da177e4SLinus Torvalds return -ENODEV; 8398ee56540SMarcel Holtmann 8408ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 8418ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 8428ee56540SMarcel Holtmann 8431da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 8448ee56540SMarcel Holtmann 8451da177e4SLinus Torvalds hci_dev_put(hdev); 8461da177e4SLinus Torvalds return err; 8471da177e4SLinus Torvalds } 8481da177e4SLinus Torvalds 8491da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 8501da177e4SLinus Torvalds { 8511da177e4SLinus Torvalds struct hci_dev *hdev; 8521da177e4SLinus Torvalds int ret = 0; 8531da177e4SLinus Torvalds 85470f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 85570f23020SAndrei Emeltchenko if (!hdev) 8561da177e4SLinus Torvalds return -ENODEV; 8571da177e4SLinus Torvalds 8581da177e4SLinus Torvalds hci_req_lock(hdev); 8591da177e4SLinus Torvalds 8601da177e4SLinus Torvalds if (!test_bit(HCI_UP, &hdev->flags)) 8611da177e4SLinus Torvalds goto done; 8621da177e4SLinus Torvalds 8631da177e4SLinus Torvalds /* Drop queues */ 8641da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 8651da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8661da177e4SLinus Torvalds 86709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 8681da177e4SLinus Torvalds inquiry_cache_flush(hdev); 8691da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 87009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8711da177e4SLinus Torvalds 8721da177e4SLinus Torvalds if (hdev->flush) 8731da177e4SLinus Torvalds hdev->flush(hdev); 8741da177e4SLinus Torvalds 8751da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 8766ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 8771da177e4SLinus Torvalds 8781da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 87904837f64SMarcel Holtmann ret = __hci_request(hdev, hci_reset_req, 0, 88004837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 8811da177e4SLinus Torvalds 8821da177e4SLinus Torvalds done: 8831da177e4SLinus Torvalds hci_req_unlock(hdev); 8841da177e4SLinus Torvalds hci_dev_put(hdev); 8851da177e4SLinus Torvalds return ret; 8861da177e4SLinus Torvalds } 8871da177e4SLinus Torvalds 8881da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 8891da177e4SLinus Torvalds { 8901da177e4SLinus Torvalds struct hci_dev *hdev; 8911da177e4SLinus Torvalds int ret = 0; 8921da177e4SLinus Torvalds 89370f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 89470f23020SAndrei Emeltchenko if (!hdev) 8951da177e4SLinus Torvalds return -ENODEV; 8961da177e4SLinus Torvalds 8971da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 8981da177e4SLinus Torvalds 8991da177e4SLinus Torvalds hci_dev_put(hdev); 9001da177e4SLinus Torvalds 9011da177e4SLinus Torvalds return ret; 9021da177e4SLinus Torvalds } 9031da177e4SLinus Torvalds 9041da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 9051da177e4SLinus Torvalds { 9061da177e4SLinus Torvalds struct hci_dev *hdev; 9071da177e4SLinus Torvalds struct hci_dev_req dr; 9081da177e4SLinus Torvalds int err = 0; 9091da177e4SLinus Torvalds 9101da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 9111da177e4SLinus Torvalds return -EFAULT; 9121da177e4SLinus Torvalds 91370f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 91470f23020SAndrei Emeltchenko if (!hdev) 9151da177e4SLinus Torvalds return -ENODEV; 9161da177e4SLinus Torvalds 9171da177e4SLinus Torvalds switch (cmd) { 9181da177e4SLinus Torvalds case HCISETAUTH: 91904837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 92004837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9211da177e4SLinus Torvalds break; 9221da177e4SLinus Torvalds 9231da177e4SLinus Torvalds case HCISETENCRYPT: 9241da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 9251da177e4SLinus Torvalds err = -EOPNOTSUPP; 9261da177e4SLinus Torvalds break; 9271da177e4SLinus Torvalds } 9281da177e4SLinus Torvalds 9291da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 9301da177e4SLinus Torvalds /* Auth must be enabled first */ 93104837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 93204837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9331da177e4SLinus Torvalds if (err) 9341da177e4SLinus Torvalds break; 9351da177e4SLinus Torvalds } 9361da177e4SLinus Torvalds 93704837f64SMarcel Holtmann err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, 93804837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9391da177e4SLinus Torvalds break; 9401da177e4SLinus Torvalds 9411da177e4SLinus Torvalds case HCISETSCAN: 94204837f64SMarcel Holtmann err = hci_request(hdev, hci_scan_req, dr.dev_opt, 94304837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9441da177e4SLinus Torvalds break; 9451da177e4SLinus Torvalds 9461da177e4SLinus Torvalds case HCISETLINKPOL: 947e4e8e37cSMarcel Holtmann err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, 948e4e8e37cSMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9491da177e4SLinus Torvalds break; 9501da177e4SLinus Torvalds 9511da177e4SLinus Torvalds case HCISETLINKMODE: 952e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 953e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 954e4e8e37cSMarcel Holtmann break; 955e4e8e37cSMarcel Holtmann 956e4e8e37cSMarcel Holtmann case HCISETPTYPE: 957e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 9581da177e4SLinus Torvalds break; 9591da177e4SLinus Torvalds 9601da177e4SLinus Torvalds case HCISETACLMTU: 9611da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 9621da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 9631da177e4SLinus Torvalds break; 9641da177e4SLinus Torvalds 9651da177e4SLinus Torvalds case HCISETSCOMTU: 9661da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 9671da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 9681da177e4SLinus Torvalds break; 9691da177e4SLinus Torvalds 9701da177e4SLinus Torvalds default: 9711da177e4SLinus Torvalds err = -EINVAL; 9721da177e4SLinus Torvalds break; 9731da177e4SLinus Torvalds } 974e4e8e37cSMarcel Holtmann 9751da177e4SLinus Torvalds hci_dev_put(hdev); 9761da177e4SLinus Torvalds return err; 9771da177e4SLinus Torvalds } 9781da177e4SLinus Torvalds 9791da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 9801da177e4SLinus Torvalds { 9818035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 9821da177e4SLinus Torvalds struct hci_dev_list_req *dl; 9831da177e4SLinus Torvalds struct hci_dev_req *dr; 9841da177e4SLinus Torvalds int n = 0, size, err; 9851da177e4SLinus Torvalds __u16 dev_num; 9861da177e4SLinus Torvalds 9871da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 9881da177e4SLinus Torvalds return -EFAULT; 9891da177e4SLinus Torvalds 9901da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 9911da177e4SLinus Torvalds return -EINVAL; 9921da177e4SLinus Torvalds 9931da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 9941da177e4SLinus Torvalds 99570f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 99670f23020SAndrei Emeltchenko if (!dl) 9971da177e4SLinus Torvalds return -ENOMEM; 9981da177e4SLinus Torvalds 9991da177e4SLinus Torvalds dr = dl->dev_req; 10001da177e4SLinus Torvalds 1001f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 10028035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 1003a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1004e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 1005c542a06cSJohan Hedberg 1006a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1007a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1008c542a06cSJohan Hedberg 10091da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 10101da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 1011c542a06cSJohan Hedberg 10121da177e4SLinus Torvalds if (++n >= dev_num) 10131da177e4SLinus Torvalds break; 10141da177e4SLinus Torvalds } 1015f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 10161da177e4SLinus Torvalds 10171da177e4SLinus Torvalds dl->dev_num = n; 10181da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 10191da177e4SLinus Torvalds 10201da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 10211da177e4SLinus Torvalds kfree(dl); 10221da177e4SLinus Torvalds 10231da177e4SLinus Torvalds return err ? -EFAULT : 0; 10241da177e4SLinus Torvalds } 10251da177e4SLinus Torvalds 10261da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 10271da177e4SLinus Torvalds { 10281da177e4SLinus Torvalds struct hci_dev *hdev; 10291da177e4SLinus Torvalds struct hci_dev_info di; 10301da177e4SLinus Torvalds int err = 0; 10311da177e4SLinus Torvalds 10321da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 10331da177e4SLinus Torvalds return -EFAULT; 10341da177e4SLinus Torvalds 103570f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 103670f23020SAndrei Emeltchenko if (!hdev) 10371da177e4SLinus Torvalds return -ENODEV; 10381da177e4SLinus Torvalds 1039a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 10403243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 1041ab81cbf9SJohan Hedberg 1042a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1043a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1044c542a06cSJohan Hedberg 10451da177e4SLinus Torvalds strcpy(di.name, hdev->name); 10461da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 1047943da25dSMarcel Holtmann di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); 10481da177e4SLinus Torvalds di.flags = hdev->flags; 10491da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 10501da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 10511da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 10521da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 10531da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 10541da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 10551da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 10561da177e4SLinus Torvalds 10571da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 10581da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 10591da177e4SLinus Torvalds 10601da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 10611da177e4SLinus Torvalds err = -EFAULT; 10621da177e4SLinus Torvalds 10631da177e4SLinus Torvalds hci_dev_put(hdev); 10641da177e4SLinus Torvalds 10651da177e4SLinus Torvalds return err; 10661da177e4SLinus Torvalds } 10671da177e4SLinus Torvalds 10681da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 10691da177e4SLinus Torvalds 1070611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 1071611b30f7SMarcel Holtmann { 1072611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 1073611b30f7SMarcel Holtmann 1074611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 1075611b30f7SMarcel Holtmann 1076611b30f7SMarcel Holtmann if (!blocked) 1077611b30f7SMarcel Holtmann return 0; 1078611b30f7SMarcel Holtmann 1079611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 1080611b30f7SMarcel Holtmann 1081611b30f7SMarcel Holtmann return 0; 1082611b30f7SMarcel Holtmann } 1083611b30f7SMarcel Holtmann 1084611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 1085611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 1086611b30f7SMarcel Holtmann }; 1087611b30f7SMarcel Holtmann 10881da177e4SLinus Torvalds /* Alloc HCI device */ 10891da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void) 10901da177e4SLinus Torvalds { 10911da177e4SLinus Torvalds struct hci_dev *hdev; 10921da177e4SLinus Torvalds 109325ea6db0SMarcel Holtmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 10941da177e4SLinus Torvalds if (!hdev) 10951da177e4SLinus Torvalds return NULL; 10961da177e4SLinus Torvalds 10970ac7e700SDavid Herrmann hci_init_sysfs(hdev); 10981da177e4SLinus Torvalds skb_queue_head_init(&hdev->driver_init); 10991da177e4SLinus Torvalds 11001da177e4SLinus Torvalds return hdev; 11011da177e4SLinus Torvalds } 11021da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev); 11031da177e4SLinus Torvalds 11041da177e4SLinus Torvalds /* Free HCI device */ 11051da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev) 11061da177e4SLinus Torvalds { 11071da177e4SLinus Torvalds skb_queue_purge(&hdev->driver_init); 11081da177e4SLinus Torvalds 1109a91f2e39SMarcel Holtmann /* will free via device release */ 1110a91f2e39SMarcel Holtmann put_device(&hdev->dev); 11111da177e4SLinus Torvalds } 11121da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev); 11131da177e4SLinus Torvalds 1114ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 1115ab81cbf9SJohan Hedberg { 1116ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 1117ab81cbf9SJohan Hedberg 1118ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1119ab81cbf9SJohan Hedberg 1120ab81cbf9SJohan Hedberg if (hci_dev_open(hdev->id) < 0) 1121ab81cbf9SJohan Hedberg return; 1122ab81cbf9SJohan Hedberg 1123a8b2d5c2SJohan Hedberg if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 112480b7ab33SGustavo F. Padovan schedule_delayed_work(&hdev->power_off, 11253243553fSJohan Hedberg msecs_to_jiffies(AUTO_OFF_TIMEOUT)); 1126ab81cbf9SJohan Hedberg 1127a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 1128744cf19eSJohan Hedberg mgmt_index_added(hdev); 1129ab81cbf9SJohan Hedberg } 1130ab81cbf9SJohan Hedberg 1131ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1132ab81cbf9SJohan Hedberg { 11333243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 11343243553fSJohan Hedberg power_off.work); 1135ab81cbf9SJohan Hedberg 1136ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1137ab81cbf9SJohan Hedberg 11388ee56540SMarcel Holtmann hci_dev_do_close(hdev); 1139ab81cbf9SJohan Hedberg } 1140ab81cbf9SJohan Hedberg 114116ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 114216ab91abSJohan Hedberg { 114316ab91abSJohan Hedberg struct hci_dev *hdev; 114416ab91abSJohan Hedberg u8 scan = SCAN_PAGE; 114516ab91abSJohan Hedberg 114616ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 114716ab91abSJohan Hedberg 114816ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 114916ab91abSJohan Hedberg 115009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 115116ab91abSJohan Hedberg 115216ab91abSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); 115316ab91abSJohan Hedberg 115416ab91abSJohan Hedberg hdev->discov_timeout = 0; 115516ab91abSJohan Hedberg 115609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 115716ab91abSJohan Hedberg } 115816ab91abSJohan Hedberg 11592aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 11602aeb9a1aSJohan Hedberg { 11612aeb9a1aSJohan Hedberg struct list_head *p, *n; 11622aeb9a1aSJohan Hedberg 11632aeb9a1aSJohan Hedberg list_for_each_safe(p, n, &hdev->uuids) { 11642aeb9a1aSJohan Hedberg struct bt_uuid *uuid; 11652aeb9a1aSJohan Hedberg 11662aeb9a1aSJohan Hedberg uuid = list_entry(p, struct bt_uuid, list); 11672aeb9a1aSJohan Hedberg 11682aeb9a1aSJohan Hedberg list_del(p); 11692aeb9a1aSJohan Hedberg kfree(uuid); 11702aeb9a1aSJohan Hedberg } 11712aeb9a1aSJohan Hedberg 11722aeb9a1aSJohan Hedberg return 0; 11732aeb9a1aSJohan Hedberg } 11742aeb9a1aSJohan Hedberg 117555ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 117655ed8ca1SJohan Hedberg { 117755ed8ca1SJohan Hedberg struct list_head *p, *n; 117855ed8ca1SJohan Hedberg 117955ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 118055ed8ca1SJohan Hedberg struct link_key *key; 118155ed8ca1SJohan Hedberg 118255ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 118355ed8ca1SJohan Hedberg 118455ed8ca1SJohan Hedberg list_del(p); 118555ed8ca1SJohan Hedberg kfree(key); 118655ed8ca1SJohan Hedberg } 118755ed8ca1SJohan Hedberg 118855ed8ca1SJohan Hedberg return 0; 118955ed8ca1SJohan Hedberg } 119055ed8ca1SJohan Hedberg 1191b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 1192b899efafSVinicius Costa Gomes { 1193b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1194b899efafSVinicius Costa Gomes 1195b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1196b899efafSVinicius Costa Gomes list_del(&k->list); 1197b899efafSVinicius Costa Gomes kfree(k); 1198b899efafSVinicius Costa Gomes } 1199b899efafSVinicius Costa Gomes 1200b899efafSVinicius Costa Gomes return 0; 1201b899efafSVinicius Costa Gomes } 1202b899efafSVinicius Costa Gomes 120355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 120455ed8ca1SJohan Hedberg { 120555ed8ca1SJohan Hedberg struct link_key *k; 120655ed8ca1SJohan Hedberg 12078035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 120855ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 120955ed8ca1SJohan Hedberg return k; 121055ed8ca1SJohan Hedberg 121155ed8ca1SJohan Hedberg return NULL; 121255ed8ca1SJohan Hedberg } 121355ed8ca1SJohan Hedberg 1214d25e28abSJohan Hedberg static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 1215d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 1216d25e28abSJohan Hedberg { 1217d25e28abSJohan Hedberg /* Legacy key */ 1218d25e28abSJohan Hedberg if (key_type < 0x03) 1219d25e28abSJohan Hedberg return 1; 1220d25e28abSJohan Hedberg 1221d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 1222d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 1223d25e28abSJohan Hedberg return 0; 1224d25e28abSJohan Hedberg 1225d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 1226d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 1227d25e28abSJohan Hedberg return 0; 1228d25e28abSJohan Hedberg 1229d25e28abSJohan Hedberg /* Security mode 3 case */ 1230d25e28abSJohan Hedberg if (!conn) 1231d25e28abSJohan Hedberg return 1; 1232d25e28abSJohan Hedberg 1233d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 1234d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 1235d25e28abSJohan Hedberg return 1; 1236d25e28abSJohan Hedberg 1237d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 1238d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 1239d25e28abSJohan Hedberg return 1; 1240d25e28abSJohan Hedberg 1241d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 1242d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 1243d25e28abSJohan Hedberg return 1; 1244d25e28abSJohan Hedberg 1245d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 1246d25e28abSJohan Hedberg * persistently */ 1247d25e28abSJohan Hedberg return 0; 1248d25e28abSJohan Hedberg } 1249d25e28abSJohan Hedberg 1250c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 125175d262c2SVinicius Costa Gomes { 1252c9839a11SVinicius Costa Gomes struct smp_ltk *k; 125375d262c2SVinicius Costa Gomes 1254c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 1255c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 1256c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 125775d262c2SVinicius Costa Gomes continue; 125875d262c2SVinicius Costa Gomes 125975d262c2SVinicius Costa Gomes return k; 126075d262c2SVinicius Costa Gomes } 126175d262c2SVinicius Costa Gomes 126275d262c2SVinicius Costa Gomes return NULL; 126375d262c2SVinicius Costa Gomes } 126475d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk); 126575d262c2SVinicius Costa Gomes 1266c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1267c9839a11SVinicius Costa Gomes u8 addr_type) 126875d262c2SVinicius Costa Gomes { 1269c9839a11SVinicius Costa Gomes struct smp_ltk *k; 127075d262c2SVinicius Costa Gomes 1271c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 1272c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 1273c9839a11SVinicius Costa Gomes bacmp(bdaddr, &k->bdaddr) == 0) 127475d262c2SVinicius Costa Gomes return k; 127575d262c2SVinicius Costa Gomes 127675d262c2SVinicius Costa Gomes return NULL; 127775d262c2SVinicius Costa Gomes } 1278c9839a11SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk_by_addr); 127975d262c2SVinicius Costa Gomes 1280d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 1281d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 128255ed8ca1SJohan Hedberg { 128355ed8ca1SJohan Hedberg struct link_key *key, *old_key; 12844df378a1SJohan Hedberg u8 old_key_type, persistent; 128555ed8ca1SJohan Hedberg 128655ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 128755ed8ca1SJohan Hedberg if (old_key) { 128855ed8ca1SJohan Hedberg old_key_type = old_key->type; 128955ed8ca1SJohan Hedberg key = old_key; 129055ed8ca1SJohan Hedberg } else { 129112adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 129255ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 129355ed8ca1SJohan Hedberg if (!key) 129455ed8ca1SJohan Hedberg return -ENOMEM; 129555ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 129655ed8ca1SJohan Hedberg } 129755ed8ca1SJohan Hedberg 129855ed8ca1SJohan Hedberg BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); 129955ed8ca1SJohan Hedberg 1300d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1301d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1302d25e28abSJohan Hedberg * previous key */ 1303d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1304d25e28abSJohan Hedberg (!conn || conn->remote_auth == 0xff) && 1305655fe6ecSJohan Hedberg old_key_type == 0xff) { 1306d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1307655fe6ecSJohan Hedberg if (conn) 1308655fe6ecSJohan Hedberg conn->key_type = type; 1309655fe6ecSJohan Hedberg } 1310d25e28abSJohan Hedberg 131155ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 131255ed8ca1SJohan Hedberg memcpy(key->val, val, 16); 131355ed8ca1SJohan Hedberg key->pin_len = pin_len; 131455ed8ca1SJohan Hedberg 1315b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 131655ed8ca1SJohan Hedberg key->type = old_key_type; 13174748fed2SJohan Hedberg else 13184748fed2SJohan Hedberg key->type = type; 13194748fed2SJohan Hedberg 13204df378a1SJohan Hedberg if (!new_key) 13214df378a1SJohan Hedberg return 0; 13224df378a1SJohan Hedberg 13234df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 13244df378a1SJohan Hedberg 1325744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 13264df378a1SJohan Hedberg 13274df378a1SJohan Hedberg if (!persistent) { 13284df378a1SJohan Hedberg list_del(&key->list); 13294df378a1SJohan Hedberg kfree(key); 13304df378a1SJohan Hedberg } 133155ed8ca1SJohan Hedberg 133255ed8ca1SJohan Hedberg return 0; 133355ed8ca1SJohan Hedberg } 133455ed8ca1SJohan Hedberg 1335c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 133604124681SGustavo F. Padovan int new_key, u8 authenticated, u8 tk[16], u8 enc_size, u16 133704124681SGustavo F. Padovan ediv, u8 rand[8]) 133875d262c2SVinicius Costa Gomes { 1339c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 134075d262c2SVinicius Costa Gomes 1341c9839a11SVinicius Costa Gomes if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 1342c9839a11SVinicius Costa Gomes return 0; 134375d262c2SVinicius Costa Gomes 1344c9839a11SVinicius Costa Gomes old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 1345c9839a11SVinicius Costa Gomes if (old_key) 134675d262c2SVinicius Costa Gomes key = old_key; 1347c9839a11SVinicius Costa Gomes else { 1348c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 134975d262c2SVinicius Costa Gomes if (!key) 135075d262c2SVinicius Costa Gomes return -ENOMEM; 1351c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 135275d262c2SVinicius Costa Gomes } 135375d262c2SVinicius Costa Gomes 135475d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 1355c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 1356c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 1357c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 1358c9839a11SVinicius Costa Gomes key->ediv = ediv; 1359c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 1360c9839a11SVinicius Costa Gomes key->type = type; 1361c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 136275d262c2SVinicius Costa Gomes 1363c9839a11SVinicius Costa Gomes if (!new_key) 1364c9839a11SVinicius Costa Gomes return 0; 136575d262c2SVinicius Costa Gomes 1366261cc5aaSVinicius Costa Gomes if (type & HCI_SMP_LTK) 1367261cc5aaSVinicius Costa Gomes mgmt_new_ltk(hdev, key, 1); 1368261cc5aaSVinicius Costa Gomes 136975d262c2SVinicius Costa Gomes return 0; 137075d262c2SVinicius Costa Gomes } 137175d262c2SVinicius Costa Gomes 137255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 137355ed8ca1SJohan Hedberg { 137455ed8ca1SJohan Hedberg struct link_key *key; 137555ed8ca1SJohan Hedberg 137655ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 137755ed8ca1SJohan Hedberg if (!key) 137855ed8ca1SJohan Hedberg return -ENOENT; 137955ed8ca1SJohan Hedberg 138055ed8ca1SJohan Hedberg BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 138155ed8ca1SJohan Hedberg 138255ed8ca1SJohan Hedberg list_del(&key->list); 138355ed8ca1SJohan Hedberg kfree(key); 138455ed8ca1SJohan Hedberg 138555ed8ca1SJohan Hedberg return 0; 138655ed8ca1SJohan Hedberg } 138755ed8ca1SJohan Hedberg 1388b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 1389b899efafSVinicius Costa Gomes { 1390b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1391b899efafSVinicius Costa Gomes 1392b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1393b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 1394b899efafSVinicius Costa Gomes continue; 1395b899efafSVinicius Costa Gomes 1396b899efafSVinicius Costa Gomes BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 1397b899efafSVinicius Costa Gomes 1398b899efafSVinicius Costa Gomes list_del(&k->list); 1399b899efafSVinicius Costa Gomes kfree(k); 1400b899efafSVinicius Costa Gomes } 1401b899efafSVinicius Costa Gomes 1402b899efafSVinicius Costa Gomes return 0; 1403b899efafSVinicius Costa Gomes } 1404b899efafSVinicius Costa Gomes 14056bd32326SVille Tervo /* HCI command timer function */ 14066bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg) 14076bd32326SVille Tervo { 14086bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 14096bd32326SVille Tervo 14106bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 14116bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 1412c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 14136bd32326SVille Tervo } 14146bd32326SVille Tervo 14152763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 14162763eda6SSzymon Janc bdaddr_t *bdaddr) 14172763eda6SSzymon Janc { 14182763eda6SSzymon Janc struct oob_data *data; 14192763eda6SSzymon Janc 14202763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 14212763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 14222763eda6SSzymon Janc return data; 14232763eda6SSzymon Janc 14242763eda6SSzymon Janc return NULL; 14252763eda6SSzymon Janc } 14262763eda6SSzymon Janc 14272763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 14282763eda6SSzymon Janc { 14292763eda6SSzymon Janc struct oob_data *data; 14302763eda6SSzymon Janc 14312763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14322763eda6SSzymon Janc if (!data) 14332763eda6SSzymon Janc return -ENOENT; 14342763eda6SSzymon Janc 14352763eda6SSzymon Janc BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 14362763eda6SSzymon Janc 14372763eda6SSzymon Janc list_del(&data->list); 14382763eda6SSzymon Janc kfree(data); 14392763eda6SSzymon Janc 14402763eda6SSzymon Janc return 0; 14412763eda6SSzymon Janc } 14422763eda6SSzymon Janc 14432763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 14442763eda6SSzymon Janc { 14452763eda6SSzymon Janc struct oob_data *data, *n; 14462763eda6SSzymon Janc 14472763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 14482763eda6SSzymon Janc list_del(&data->list); 14492763eda6SSzymon Janc kfree(data); 14502763eda6SSzymon Janc } 14512763eda6SSzymon Janc 14522763eda6SSzymon Janc return 0; 14532763eda6SSzymon Janc } 14542763eda6SSzymon Janc 14552763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 14562763eda6SSzymon Janc u8 *randomizer) 14572763eda6SSzymon Janc { 14582763eda6SSzymon Janc struct oob_data *data; 14592763eda6SSzymon Janc 14602763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14612763eda6SSzymon Janc 14622763eda6SSzymon Janc if (!data) { 14632763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 14642763eda6SSzymon Janc if (!data) 14652763eda6SSzymon Janc return -ENOMEM; 14662763eda6SSzymon Janc 14672763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 14682763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 14692763eda6SSzymon Janc } 14702763eda6SSzymon Janc 14712763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 14722763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 14732763eda6SSzymon Janc 14742763eda6SSzymon Janc BT_DBG("%s for %s", hdev->name, batostr(bdaddr)); 14752763eda6SSzymon Janc 14762763eda6SSzymon Janc return 0; 14772763eda6SSzymon Janc } 14782763eda6SSzymon Janc 147904124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 1480b2a66aadSAntti Julku { 1481b2a66aadSAntti Julku struct bdaddr_list *b; 1482b2a66aadSAntti Julku 14838035ded4SLuiz Augusto von Dentz list_for_each_entry(b, &hdev->blacklist, list) 1484b2a66aadSAntti Julku if (bacmp(bdaddr, &b->bdaddr) == 0) 1485b2a66aadSAntti Julku return b; 1486b2a66aadSAntti Julku 1487b2a66aadSAntti Julku return NULL; 1488b2a66aadSAntti Julku } 1489b2a66aadSAntti Julku 1490b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 1491b2a66aadSAntti Julku { 1492b2a66aadSAntti Julku struct list_head *p, *n; 1493b2a66aadSAntti Julku 1494b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 1495b2a66aadSAntti Julku struct bdaddr_list *b; 1496b2a66aadSAntti Julku 1497b2a66aadSAntti Julku b = list_entry(p, struct bdaddr_list, list); 1498b2a66aadSAntti Julku 1499b2a66aadSAntti Julku list_del(p); 1500b2a66aadSAntti Julku kfree(b); 1501b2a66aadSAntti Julku } 1502b2a66aadSAntti Julku 1503b2a66aadSAntti Julku return 0; 1504b2a66aadSAntti Julku } 1505b2a66aadSAntti Julku 150688c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1507b2a66aadSAntti Julku { 1508b2a66aadSAntti Julku struct bdaddr_list *entry; 1509b2a66aadSAntti Julku 1510b2a66aadSAntti Julku if (bacmp(bdaddr, BDADDR_ANY) == 0) 1511b2a66aadSAntti Julku return -EBADF; 1512b2a66aadSAntti Julku 15135e762444SAntti Julku if (hci_blacklist_lookup(hdev, bdaddr)) 15145e762444SAntti Julku return -EEXIST; 1515b2a66aadSAntti Julku 1516b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 15175e762444SAntti Julku if (!entry) 15185e762444SAntti Julku return -ENOMEM; 1519b2a66aadSAntti Julku 1520b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 1521b2a66aadSAntti Julku 1522b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 1523b2a66aadSAntti Julku 152488c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 1525b2a66aadSAntti Julku } 1526b2a66aadSAntti Julku 152788c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1528b2a66aadSAntti Julku { 1529b2a66aadSAntti Julku struct bdaddr_list *entry; 1530b2a66aadSAntti Julku 15311ec918ceSSzymon Janc if (bacmp(bdaddr, BDADDR_ANY) == 0) 15325e762444SAntti Julku return hci_blacklist_clear(hdev); 1533b2a66aadSAntti Julku 1534b2a66aadSAntti Julku entry = hci_blacklist_lookup(hdev, bdaddr); 15351ec918ceSSzymon Janc if (!entry) 15365e762444SAntti Julku return -ENOENT; 1537b2a66aadSAntti Julku 1538b2a66aadSAntti Julku list_del(&entry->list); 1539b2a66aadSAntti Julku kfree(entry); 1540b2a66aadSAntti Julku 154188c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 1542b2a66aadSAntti Julku } 1543b2a66aadSAntti Julku 1544db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work) 154535815085SAndre Guedes { 1546db323f2fSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, 1547db323f2fSGustavo F. Padovan adv_work.work); 154835815085SAndre Guedes 154935815085SAndre Guedes hci_dev_lock(hdev); 155035815085SAndre Guedes 155135815085SAndre Guedes hci_adv_entries_clear(hdev); 155235815085SAndre Guedes 155335815085SAndre Guedes hci_dev_unlock(hdev); 155435815085SAndre Guedes } 155535815085SAndre Guedes 155676c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev) 155776c8686fSAndre Guedes { 155876c8686fSAndre Guedes struct adv_entry *entry, *tmp; 155976c8686fSAndre Guedes 156076c8686fSAndre Guedes list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) { 156176c8686fSAndre Guedes list_del(&entry->list); 156276c8686fSAndre Guedes kfree(entry); 156376c8686fSAndre Guedes } 156476c8686fSAndre Guedes 156576c8686fSAndre Guedes BT_DBG("%s adv cache cleared", hdev->name); 156676c8686fSAndre Guedes 156776c8686fSAndre Guedes return 0; 156876c8686fSAndre Guedes } 156976c8686fSAndre Guedes 157076c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr) 157176c8686fSAndre Guedes { 157276c8686fSAndre Guedes struct adv_entry *entry; 157376c8686fSAndre Guedes 157476c8686fSAndre Guedes list_for_each_entry(entry, &hdev->adv_entries, list) 157576c8686fSAndre Guedes if (bacmp(bdaddr, &entry->bdaddr) == 0) 157676c8686fSAndre Guedes return entry; 157776c8686fSAndre Guedes 157876c8686fSAndre Guedes return NULL; 157976c8686fSAndre Guedes } 158076c8686fSAndre Guedes 158176c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type) 158276c8686fSAndre Guedes { 158376c8686fSAndre Guedes if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND) 158476c8686fSAndre Guedes return 1; 158576c8686fSAndre Guedes 158676c8686fSAndre Guedes return 0; 158776c8686fSAndre Guedes } 158876c8686fSAndre Guedes 158976c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev, 159004124681SGustavo F. Padovan struct hci_ev_le_advertising_info *ev) { struct adv_entry *entry; if (!is_connectable_adv(ev->evt_type)) 159176c8686fSAndre Guedes return -EINVAL; 159276c8686fSAndre Guedes 159376c8686fSAndre Guedes /* Only new entries should be added to adv_entries. So, if 159476c8686fSAndre Guedes * bdaddr was found, don't add it. */ 159576c8686fSAndre Guedes if (hci_find_adv_entry(hdev, &ev->bdaddr)) 159676c8686fSAndre Guedes return 0; 159776c8686fSAndre Guedes 15984777bfdeSAndre Guedes entry = kzalloc(sizeof(*entry), GFP_KERNEL); 159976c8686fSAndre Guedes if (!entry) 160076c8686fSAndre Guedes return -ENOMEM; 160176c8686fSAndre Guedes 160276c8686fSAndre Guedes bacpy(&entry->bdaddr, &ev->bdaddr); 160376c8686fSAndre Guedes entry->bdaddr_type = ev->bdaddr_type; 160476c8686fSAndre Guedes 160576c8686fSAndre Guedes list_add(&entry->list, &hdev->adv_entries); 160676c8686fSAndre Guedes 160776c8686fSAndre Guedes BT_DBG("%s adv entry added: address %s type %u", hdev->name, 160876c8686fSAndre Guedes batostr(&entry->bdaddr), entry->bdaddr_type); 160976c8686fSAndre Guedes 161076c8686fSAndre Guedes return 0; 161176c8686fSAndre Guedes } 161276c8686fSAndre Guedes 16137ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt) 16147ba8b4beSAndre Guedes { 16157ba8b4beSAndre Guedes struct le_scan_params *param = (struct le_scan_params *) opt; 16167ba8b4beSAndre Guedes struct hci_cp_le_set_scan_param cp; 16177ba8b4beSAndre Guedes 16187ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 16197ba8b4beSAndre Guedes cp.type = param->type; 16207ba8b4beSAndre Guedes cp.interval = cpu_to_le16(param->interval); 16217ba8b4beSAndre Guedes cp.window = cpu_to_le16(param->window); 16227ba8b4beSAndre Guedes 16237ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); 16247ba8b4beSAndre Guedes } 16257ba8b4beSAndre Guedes 16267ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt) 16277ba8b4beSAndre Guedes { 16287ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 16297ba8b4beSAndre Guedes 16307ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 16317ba8b4beSAndre Guedes cp.enable = 1; 16327ba8b4beSAndre Guedes 16337ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 16347ba8b4beSAndre Guedes } 16357ba8b4beSAndre Guedes 16367ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, 16377ba8b4beSAndre Guedes u16 window, int timeout) 16387ba8b4beSAndre Guedes { 16397ba8b4beSAndre Guedes long timeo = msecs_to_jiffies(3000); 16407ba8b4beSAndre Guedes struct le_scan_params param; 16417ba8b4beSAndre Guedes int err; 16427ba8b4beSAndre Guedes 16437ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 16447ba8b4beSAndre Guedes 16457ba8b4beSAndre Guedes if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 16467ba8b4beSAndre Guedes return -EINPROGRESS; 16477ba8b4beSAndre Guedes 16487ba8b4beSAndre Guedes param.type = type; 16497ba8b4beSAndre Guedes param.interval = interval; 16507ba8b4beSAndre Guedes param.window = window; 16517ba8b4beSAndre Guedes 16527ba8b4beSAndre Guedes hci_req_lock(hdev); 16537ba8b4beSAndre Guedes 16547ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_param_req, (unsigned long) ¶m, 16557ba8b4beSAndre Guedes timeo); 16567ba8b4beSAndre Guedes if (!err) 16577ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_enable_req, 0, timeo); 16587ba8b4beSAndre Guedes 16597ba8b4beSAndre Guedes hci_req_unlock(hdev); 16607ba8b4beSAndre Guedes 16617ba8b4beSAndre Guedes if (err < 0) 16627ba8b4beSAndre Guedes return err; 16637ba8b4beSAndre Guedes 16647ba8b4beSAndre Guedes schedule_delayed_work(&hdev->le_scan_disable, 16657ba8b4beSAndre Guedes msecs_to_jiffies(timeout)); 16667ba8b4beSAndre Guedes 16677ba8b4beSAndre Guedes return 0; 16687ba8b4beSAndre Guedes } 16697ba8b4beSAndre Guedes 16707ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 16717ba8b4beSAndre Guedes { 16727ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 16737ba8b4beSAndre Guedes le_scan_disable.work); 16747ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 16757ba8b4beSAndre Guedes 16767ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 16777ba8b4beSAndre Guedes 16787ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 16797ba8b4beSAndre Guedes 16807ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 16817ba8b4beSAndre Guedes } 16827ba8b4beSAndre Guedes 168328b75a89SAndre Guedes static void le_scan_work(struct work_struct *work) 168428b75a89SAndre Guedes { 168528b75a89SAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan); 168628b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 168728b75a89SAndre Guedes 168828b75a89SAndre Guedes BT_DBG("%s", hdev->name); 168928b75a89SAndre Guedes 169004124681SGustavo F. Padovan hci_do_le_scan(hdev, param->type, param->interval, param->window, 169104124681SGustavo F. Padovan param->timeout); 169228b75a89SAndre Guedes } 169328b75a89SAndre Guedes 169428b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, 169528b75a89SAndre Guedes int timeout) 169628b75a89SAndre Guedes { 169728b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 169828b75a89SAndre Guedes 169928b75a89SAndre Guedes BT_DBG("%s", hdev->name); 170028b75a89SAndre Guedes 170128b75a89SAndre Guedes if (work_busy(&hdev->le_scan)) 170228b75a89SAndre Guedes return -EINPROGRESS; 170328b75a89SAndre Guedes 170428b75a89SAndre Guedes param->type = type; 170528b75a89SAndre Guedes param->interval = interval; 170628b75a89SAndre Guedes param->window = window; 170728b75a89SAndre Guedes param->timeout = timeout; 170828b75a89SAndre Guedes 170928b75a89SAndre Guedes queue_work(system_long_wq, &hdev->le_scan); 171028b75a89SAndre Guedes 171128b75a89SAndre Guedes return 0; 171228b75a89SAndre Guedes } 171328b75a89SAndre Guedes 17141da177e4SLinus Torvalds /* Register HCI device */ 17151da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 17161da177e4SLinus Torvalds { 17171da177e4SLinus Torvalds struct list_head *head = &hci_dev_list, *p; 171808add513SMat Martineau int i, id, error; 17191da177e4SLinus Torvalds 1720e9b9cfa1SDavid Herrmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 17211da177e4SLinus Torvalds 1722010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 17231da177e4SLinus Torvalds return -EINVAL; 17241da177e4SLinus Torvalds 172508add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 172608add513SMat Martineau * so the index can be used as the AMP controller ID. 172708add513SMat Martineau */ 172808add513SMat Martineau id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; 172908add513SMat Martineau 1730f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 17311da177e4SLinus Torvalds 17321da177e4SLinus Torvalds /* Find first available device id */ 17331da177e4SLinus Torvalds list_for_each(p, &hci_dev_list) { 17341da177e4SLinus Torvalds if (list_entry(p, struct hci_dev, list)->id != id) 17351da177e4SLinus Torvalds break; 17361da177e4SLinus Torvalds head = p; id++; 17371da177e4SLinus Torvalds } 17381da177e4SLinus Torvalds 17391da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 17401da177e4SLinus Torvalds hdev->id = id; 1741c6feeb28SAndrei Emeltchenko list_add_tail(&hdev->list, head); 17421da177e4SLinus Torvalds 174309fd0de5SGustavo F. Padovan mutex_init(&hdev->lock); 17441da177e4SLinus Torvalds 17451da177e4SLinus Torvalds hdev->flags = 0; 1746d23264a8SAndre Guedes hdev->dev_flags = 0; 17471da177e4SLinus Torvalds hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 17485b7f9909SMarcel Holtmann hdev->esco_type = (ESCO_HV1); 17491da177e4SLinus Torvalds hdev->link_mode = (HCI_LM_ACCEPT); 175017fa4b9dSJohan Hedberg hdev->io_capability = 0x03; /* No Input No Output */ 17511da177e4SLinus Torvalds 175204837f64SMarcel Holtmann hdev->idle_timeout = 0; 175304837f64SMarcel Holtmann hdev->sniff_max_interval = 800; 175404837f64SMarcel Holtmann hdev->sniff_min_interval = 80; 175504837f64SMarcel Holtmann 1756b78752ccSMarcel Holtmann INIT_WORK(&hdev->rx_work, hci_rx_work); 1757c347b765SGustavo F. Padovan INIT_WORK(&hdev->cmd_work, hci_cmd_work); 17583eff45eaSGustavo F. Padovan INIT_WORK(&hdev->tx_work, hci_tx_work); 1759b78752ccSMarcel Holtmann 17601da177e4SLinus Torvalds 17611da177e4SLinus Torvalds skb_queue_head_init(&hdev->rx_q); 17621da177e4SLinus Torvalds skb_queue_head_init(&hdev->cmd_q); 17631da177e4SLinus Torvalds skb_queue_head_init(&hdev->raw_q); 17641da177e4SLinus Torvalds 17656bd32326SVille Tervo setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); 17666bd32326SVille Tervo 1767cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1768ef222013SMarcel Holtmann hdev->reassembly[i] = NULL; 1769ef222013SMarcel Holtmann 17701da177e4SLinus Torvalds init_waitqueue_head(&hdev->req_wait_q); 1771a6a67efdSThomas Gleixner mutex_init(&hdev->req_lock); 17721da177e4SLinus Torvalds 177330883512SJohan Hedberg discovery_init(hdev); 17741da177e4SLinus Torvalds 17751da177e4SLinus Torvalds hci_conn_hash_init(hdev); 17761da177e4SLinus Torvalds 17772e58ef3eSJohan Hedberg INIT_LIST_HEAD(&hdev->mgmt_pending); 17782e58ef3eSJohan Hedberg 1779ea4bd8baSDavid Miller INIT_LIST_HEAD(&hdev->blacklist); 1780f0358568SJohan Hedberg 17812aeb9a1aSJohan Hedberg INIT_LIST_HEAD(&hdev->uuids); 17822aeb9a1aSJohan Hedberg 178355ed8ca1SJohan Hedberg INIT_LIST_HEAD(&hdev->link_keys); 1784b899efafSVinicius Costa Gomes INIT_LIST_HEAD(&hdev->long_term_keys); 178555ed8ca1SJohan Hedberg 17862763eda6SSzymon Janc INIT_LIST_HEAD(&hdev->remote_oob_data); 17872763eda6SSzymon Janc 178876c8686fSAndre Guedes INIT_LIST_HEAD(&hdev->adv_entries); 178976c8686fSAndre Guedes 1790db323f2fSGustavo F. Padovan INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache); 1791ab81cbf9SJohan Hedberg INIT_WORK(&hdev->power_on, hci_power_on); 17923243553fSJohan Hedberg INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 1793ab81cbf9SJohan Hedberg 179416ab91abSJohan Hedberg INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 179516ab91abSJohan Hedberg 17961da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 17971da177e4SLinus Torvalds 17981da177e4SLinus Torvalds atomic_set(&hdev->promisc, 0); 17991da177e4SLinus Torvalds 180028b75a89SAndre Guedes INIT_WORK(&hdev->le_scan, le_scan_work); 180128b75a89SAndre Guedes 18027ba8b4beSAndre Guedes INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 18037ba8b4beSAndre Guedes 1804f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 18051da177e4SLinus Torvalds 180632845eb1SGustavo F. Padovan hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | 180732845eb1SGustavo F. Padovan WQ_MEM_RECLAIM, 1); 180833ca954dSDavid Herrmann if (!hdev->workqueue) { 180933ca954dSDavid Herrmann error = -ENOMEM; 181033ca954dSDavid Herrmann goto err; 181133ca954dSDavid Herrmann } 1812f48fd9c8SMarcel Holtmann 181333ca954dSDavid Herrmann error = hci_add_sysfs(hdev); 181433ca954dSDavid Herrmann if (error < 0) 181533ca954dSDavid Herrmann goto err_wqueue; 18161da177e4SLinus Torvalds 1817611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 1818611b30f7SMarcel Holtmann RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); 1819611b30f7SMarcel Holtmann if (hdev->rfkill) { 1820611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 1821611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1822611b30f7SMarcel Holtmann hdev->rfkill = NULL; 1823611b30f7SMarcel Holtmann } 1824611b30f7SMarcel Holtmann } 1825611b30f7SMarcel Holtmann 1826a8b2d5c2SJohan Hedberg set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 1827a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 18287f971041SGustavo F. Padovan schedule_work(&hdev->power_on); 1829ab81cbf9SJohan Hedberg 18301da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 1831dc946bd8SDavid Herrmann hci_dev_hold(hdev); 18321da177e4SLinus Torvalds 18331da177e4SLinus Torvalds return id; 1834f48fd9c8SMarcel Holtmann 183533ca954dSDavid Herrmann err_wqueue: 183633ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 183733ca954dSDavid Herrmann err: 1838f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 1839f48fd9c8SMarcel Holtmann list_del(&hdev->list); 1840f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 1841f48fd9c8SMarcel Holtmann 184233ca954dSDavid Herrmann return error; 18431da177e4SLinus Torvalds } 18441da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 18451da177e4SLinus Torvalds 18461da177e4SLinus Torvalds /* Unregister HCI device */ 184759735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 18481da177e4SLinus Torvalds { 1849ef222013SMarcel Holtmann int i; 1850ef222013SMarcel Holtmann 1851c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 18521da177e4SLinus Torvalds 1853f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 18541da177e4SLinus Torvalds list_del(&hdev->list); 1855f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 18561da177e4SLinus Torvalds 18571da177e4SLinus Torvalds hci_dev_do_close(hdev); 18581da177e4SLinus Torvalds 1859cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1860ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 1861ef222013SMarcel Holtmann 1862ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 1863a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 186409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1865744cf19eSJohan Hedberg mgmt_index_removed(hdev); 186609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 186756e5cb86SJohan Hedberg } 1868ab81cbf9SJohan Hedberg 18692e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 18702e58ef3eSJohan Hedberg * pending list */ 18712e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 18722e58ef3eSJohan Hedberg 18731da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 18741da177e4SLinus Torvalds 1875611b30f7SMarcel Holtmann if (hdev->rfkill) { 1876611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 1877611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1878611b30f7SMarcel Holtmann } 1879611b30f7SMarcel Holtmann 1880ce242970SDavid Herrmann hci_del_sysfs(hdev); 1881147e2d59SDave Young 1882db323f2fSGustavo F. Padovan cancel_delayed_work_sync(&hdev->adv_work); 1883c6f3c5f7SGustavo F. Padovan 1884f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 1885f48fd9c8SMarcel Holtmann 188609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1887e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 18882aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 188955ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 1890b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 18912763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 189276c8686fSAndre Guedes hci_adv_entries_clear(hdev); 189309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 1894e2e0cacbSJohan Hedberg 1895dc946bd8SDavid Herrmann hci_dev_put(hdev); 18961da177e4SLinus Torvalds } 18971da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 18981da177e4SLinus Torvalds 18991da177e4SLinus Torvalds /* Suspend HCI device */ 19001da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 19011da177e4SLinus Torvalds { 19021da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 19031da177e4SLinus Torvalds return 0; 19041da177e4SLinus Torvalds } 19051da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 19061da177e4SLinus Torvalds 19071da177e4SLinus Torvalds /* Resume HCI device */ 19081da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 19091da177e4SLinus Torvalds { 19101da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 19111da177e4SLinus Torvalds return 0; 19121da177e4SLinus Torvalds } 19131da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 19141da177e4SLinus Torvalds 191576bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 191676bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb) 191776bca880SMarcel Holtmann { 191876bca880SMarcel Holtmann struct hci_dev *hdev = (struct hci_dev *) skb->dev; 191976bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 192076bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 192176bca880SMarcel Holtmann kfree_skb(skb); 192276bca880SMarcel Holtmann return -ENXIO; 192376bca880SMarcel Holtmann } 192476bca880SMarcel Holtmann 192576bca880SMarcel Holtmann /* Incomming skb */ 192676bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 192776bca880SMarcel Holtmann 192876bca880SMarcel Holtmann /* Time stamp */ 192976bca880SMarcel Holtmann __net_timestamp(skb); 193076bca880SMarcel Holtmann 193176bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 1932b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 1933c78ae283SMarcel Holtmann 193476bca880SMarcel Holtmann return 0; 193576bca880SMarcel Holtmann } 193676bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 193776bca880SMarcel Holtmann 193833e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 19391e429f38SGustavo F. Padovan int count, __u8 index) 194033e882a5SSuraj Sumangala { 194133e882a5SSuraj Sumangala int len = 0; 194233e882a5SSuraj Sumangala int hlen = 0; 194333e882a5SSuraj Sumangala int remain = count; 194433e882a5SSuraj Sumangala struct sk_buff *skb; 194533e882a5SSuraj Sumangala struct bt_skb_cb *scb; 194633e882a5SSuraj Sumangala 194733e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 194833e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 194933e882a5SSuraj Sumangala return -EILSEQ; 195033e882a5SSuraj Sumangala 195133e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 195233e882a5SSuraj Sumangala 195333e882a5SSuraj Sumangala if (!skb) { 195433e882a5SSuraj Sumangala switch (type) { 195533e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 195633e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 195733e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 195833e882a5SSuraj Sumangala break; 195933e882a5SSuraj Sumangala case HCI_EVENT_PKT: 196033e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 196133e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 196233e882a5SSuraj Sumangala break; 196333e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 196433e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 196533e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 196633e882a5SSuraj Sumangala break; 196733e882a5SSuraj Sumangala } 196833e882a5SSuraj Sumangala 19691e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 197033e882a5SSuraj Sumangala if (!skb) 197133e882a5SSuraj Sumangala return -ENOMEM; 197233e882a5SSuraj Sumangala 197333e882a5SSuraj Sumangala scb = (void *) skb->cb; 197433e882a5SSuraj Sumangala scb->expect = hlen; 197533e882a5SSuraj Sumangala scb->pkt_type = type; 197633e882a5SSuraj Sumangala 197733e882a5SSuraj Sumangala skb->dev = (void *) hdev; 197833e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 197933e882a5SSuraj Sumangala } 198033e882a5SSuraj Sumangala 198133e882a5SSuraj Sumangala while (count) { 198233e882a5SSuraj Sumangala scb = (void *) skb->cb; 198389bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 198433e882a5SSuraj Sumangala 198533e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 198633e882a5SSuraj Sumangala 198733e882a5SSuraj Sumangala count -= len; 198833e882a5SSuraj Sumangala data += len; 198933e882a5SSuraj Sumangala scb->expect -= len; 199033e882a5SSuraj Sumangala remain = count; 199133e882a5SSuraj Sumangala 199233e882a5SSuraj Sumangala switch (type) { 199333e882a5SSuraj Sumangala case HCI_EVENT_PKT: 199433e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 199533e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 199633e882a5SSuraj Sumangala scb->expect = h->plen; 199733e882a5SSuraj Sumangala 199833e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 199933e882a5SSuraj Sumangala kfree_skb(skb); 200033e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 200133e882a5SSuraj Sumangala return -ENOMEM; 200233e882a5SSuraj Sumangala } 200333e882a5SSuraj Sumangala } 200433e882a5SSuraj Sumangala break; 200533e882a5SSuraj Sumangala 200633e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 200733e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 200833e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 200933e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 201033e882a5SSuraj Sumangala 201133e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 201233e882a5SSuraj Sumangala kfree_skb(skb); 201333e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 201433e882a5SSuraj Sumangala return -ENOMEM; 201533e882a5SSuraj Sumangala } 201633e882a5SSuraj Sumangala } 201733e882a5SSuraj Sumangala break; 201833e882a5SSuraj Sumangala 201933e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 202033e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 202133e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 202233e882a5SSuraj Sumangala scb->expect = h->dlen; 202333e882a5SSuraj Sumangala 202433e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 202533e882a5SSuraj Sumangala kfree_skb(skb); 202633e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 202733e882a5SSuraj Sumangala return -ENOMEM; 202833e882a5SSuraj Sumangala } 202933e882a5SSuraj Sumangala } 203033e882a5SSuraj Sumangala break; 203133e882a5SSuraj Sumangala } 203233e882a5SSuraj Sumangala 203333e882a5SSuraj Sumangala if (scb->expect == 0) { 203433e882a5SSuraj Sumangala /* Complete frame */ 203533e882a5SSuraj Sumangala 203633e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 203733e882a5SSuraj Sumangala hci_recv_frame(skb); 203833e882a5SSuraj Sumangala 203933e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 204033e882a5SSuraj Sumangala return remain; 204133e882a5SSuraj Sumangala } 204233e882a5SSuraj Sumangala } 204333e882a5SSuraj Sumangala 204433e882a5SSuraj Sumangala return remain; 204533e882a5SSuraj Sumangala } 204633e882a5SSuraj Sumangala 2047ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 2048ef222013SMarcel Holtmann { 2049f39a3c06SSuraj Sumangala int rem = 0; 2050f39a3c06SSuraj Sumangala 2051ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 2052ef222013SMarcel Holtmann return -EILSEQ; 2053ef222013SMarcel Holtmann 2054da5f6c37SGustavo F. Padovan while (count) { 20551e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 2056f39a3c06SSuraj Sumangala if (rem < 0) 2057f39a3c06SSuraj Sumangala return rem; 2058ef222013SMarcel Holtmann 2059f39a3c06SSuraj Sumangala data += (count - rem); 2060f39a3c06SSuraj Sumangala count = rem; 2061f81c6224SJoe Perches } 2062ef222013SMarcel Holtmann 2063f39a3c06SSuraj Sumangala return rem; 2064ef222013SMarcel Holtmann } 2065ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 2066ef222013SMarcel Holtmann 206799811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 206899811510SSuraj Sumangala 206999811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 207099811510SSuraj Sumangala { 207199811510SSuraj Sumangala int type; 207299811510SSuraj Sumangala int rem = 0; 207399811510SSuraj Sumangala 2074da5f6c37SGustavo F. Padovan while (count) { 207599811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 207699811510SSuraj Sumangala 207799811510SSuraj Sumangala if (!skb) { 207899811510SSuraj Sumangala struct { char type; } *pkt; 207999811510SSuraj Sumangala 208099811510SSuraj Sumangala /* Start of the frame */ 208199811510SSuraj Sumangala pkt = data; 208299811510SSuraj Sumangala type = pkt->type; 208399811510SSuraj Sumangala 208499811510SSuraj Sumangala data++; 208599811510SSuraj Sumangala count--; 208699811510SSuraj Sumangala } else 208799811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 208899811510SSuraj Sumangala 20891e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 20901e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 209199811510SSuraj Sumangala if (rem < 0) 209299811510SSuraj Sumangala return rem; 209399811510SSuraj Sumangala 209499811510SSuraj Sumangala data += (count - rem); 209599811510SSuraj Sumangala count = rem; 2096f81c6224SJoe Perches } 209799811510SSuraj Sumangala 209899811510SSuraj Sumangala return rem; 209999811510SSuraj Sumangala } 210099811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 210199811510SSuraj Sumangala 21021da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 21031da177e4SLinus Torvalds 21041da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 21051da177e4SLinus Torvalds { 21061da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 21071da177e4SLinus Torvalds 2108f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 21091da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 2110f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 21111da177e4SLinus Torvalds 21121da177e4SLinus Torvalds return 0; 21131da177e4SLinus Torvalds } 21141da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 21151da177e4SLinus Torvalds 21161da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 21171da177e4SLinus Torvalds { 21181da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 21191da177e4SLinus Torvalds 2120f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 21211da177e4SLinus Torvalds list_del(&cb->list); 2122f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 21231da177e4SLinus Torvalds 21241da177e4SLinus Torvalds return 0; 21251da177e4SLinus Torvalds } 21261da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 21271da177e4SLinus Torvalds 21281da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb) 21291da177e4SLinus Torvalds { 21301da177e4SLinus Torvalds struct hci_dev *hdev = (struct hci_dev *) skb->dev; 21311da177e4SLinus Torvalds 21321da177e4SLinus Torvalds if (!hdev) { 21331da177e4SLinus Torvalds kfree_skb(skb); 21341da177e4SLinus Torvalds return -ENODEV; 21351da177e4SLinus Torvalds } 21361da177e4SLinus Torvalds 21370d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 21381da177e4SLinus Torvalds 21391da177e4SLinus Torvalds /* Time stamp */ 2140a61bbcf2SPatrick McHardy __net_timestamp(skb); 21411da177e4SLinus Torvalds 2142cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2143cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2144cd82e61cSMarcel Holtmann 2145cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 2146cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 2147470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 21481da177e4SLinus Torvalds } 21491da177e4SLinus Torvalds 21501da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 21511da177e4SLinus Torvalds skb_orphan(skb); 21521da177e4SLinus Torvalds 21531da177e4SLinus Torvalds return hdev->send(skb); 21541da177e4SLinus Torvalds } 21551da177e4SLinus Torvalds 21561da177e4SLinus Torvalds /* Send HCI command */ 2157a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) 21581da177e4SLinus Torvalds { 21591da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 21601da177e4SLinus Torvalds struct hci_command_hdr *hdr; 21611da177e4SLinus Torvalds struct sk_buff *skb; 21621da177e4SLinus Torvalds 2163a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen); 21641da177e4SLinus Torvalds 21651da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 21661da177e4SLinus Torvalds if (!skb) { 2167ef222013SMarcel Holtmann BT_ERR("%s no memory for command", hdev->name); 21681da177e4SLinus Torvalds return -ENOMEM; 21691da177e4SLinus Torvalds } 21701da177e4SLinus Torvalds 21711da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 2172a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 21731da177e4SLinus Torvalds hdr->plen = plen; 21741da177e4SLinus Torvalds 21751da177e4SLinus Torvalds if (plen) 21761da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 21771da177e4SLinus Torvalds 21781da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 21791da177e4SLinus Torvalds 21800d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 21811da177e4SLinus Torvalds skb->dev = (void *) hdev; 2182c78ae283SMarcel Holtmann 2183a5040efaSJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags)) 2184a5040efaSJohan Hedberg hdev->init_last_cmd = opcode; 2185a5040efaSJohan Hedberg 21861da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 2187c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 21881da177e4SLinus Torvalds 21891da177e4SLinus Torvalds return 0; 21901da177e4SLinus Torvalds } 21911da177e4SLinus Torvalds 21921da177e4SLinus Torvalds /* Get data from the previously sent command */ 2193a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 21941da177e4SLinus Torvalds { 21951da177e4SLinus Torvalds struct hci_command_hdr *hdr; 21961da177e4SLinus Torvalds 21971da177e4SLinus Torvalds if (!hdev->sent_cmd) 21981da177e4SLinus Torvalds return NULL; 21991da177e4SLinus Torvalds 22001da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 22011da177e4SLinus Torvalds 2202a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 22031da177e4SLinus Torvalds return NULL; 22041da177e4SLinus Torvalds 2205a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 22061da177e4SLinus Torvalds 22071da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 22081da177e4SLinus Torvalds } 22091da177e4SLinus Torvalds 22101da177e4SLinus Torvalds /* Send ACL data */ 22111da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 22121da177e4SLinus Torvalds { 22131da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 22141da177e4SLinus Torvalds int len = skb->len; 22151da177e4SLinus Torvalds 2216badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 2217badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 22189c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 2219aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 2220aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 22211da177e4SLinus Torvalds } 22221da177e4SLinus Torvalds 222373d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, 222473d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 22251da177e4SLinus Torvalds { 22261da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 22271da177e4SLinus Torvalds struct sk_buff *list; 22281da177e4SLinus Torvalds 222970f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 223070f23020SAndrei Emeltchenko if (!list) { 22311da177e4SLinus Torvalds /* Non fragmented */ 22321da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 22331da177e4SLinus Torvalds 223473d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 22351da177e4SLinus Torvalds } else { 22361da177e4SLinus Torvalds /* Fragmented */ 22371da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 22381da177e4SLinus Torvalds 22391da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 22401da177e4SLinus Torvalds 22411da177e4SLinus Torvalds /* Queue all fragments atomically */ 2242af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 22431da177e4SLinus Torvalds 224473d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 2245e702112fSAndrei Emeltchenko 2246e702112fSAndrei Emeltchenko flags &= ~ACL_START; 2247e702112fSAndrei Emeltchenko flags |= ACL_CONT; 22481da177e4SLinus Torvalds do { 22491da177e4SLinus Torvalds skb = list; list = list->next; 22501da177e4SLinus Torvalds 22511da177e4SLinus Torvalds skb->dev = (void *) hdev; 22520d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2253e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 22541da177e4SLinus Torvalds 22551da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 22561da177e4SLinus Torvalds 225773d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 22581da177e4SLinus Torvalds } while (list); 22591da177e4SLinus Torvalds 2260af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 22611da177e4SLinus Torvalds } 226273d80debSLuiz Augusto von Dentz } 226373d80debSLuiz Augusto von Dentz 226473d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 226573d80debSLuiz Augusto von Dentz { 226673d80debSLuiz Augusto von Dentz struct hci_conn *conn = chan->conn; 226773d80debSLuiz Augusto von Dentz struct hci_dev *hdev = conn->hdev; 226873d80debSLuiz Augusto von Dentz 226973d80debSLuiz Augusto von Dentz BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags); 227073d80debSLuiz Augusto von Dentz 227173d80debSLuiz Augusto von Dentz skb->dev = (void *) hdev; 227273d80debSLuiz Augusto von Dentz bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 227373d80debSLuiz Augusto von Dentz hci_add_acl_hdr(skb, conn->handle, flags); 227473d80debSLuiz Augusto von Dentz 227573d80debSLuiz Augusto von Dentz hci_queue_acl(conn, &chan->data_q, skb, flags); 22761da177e4SLinus Torvalds 22773eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 22781da177e4SLinus Torvalds } 22791da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl); 22801da177e4SLinus Torvalds 22811da177e4SLinus Torvalds /* Send SCO data */ 22820d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 22831da177e4SLinus Torvalds { 22841da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 22851da177e4SLinus Torvalds struct hci_sco_hdr hdr; 22861da177e4SLinus Torvalds 22871da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 22881da177e4SLinus Torvalds 2289aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 22901da177e4SLinus Torvalds hdr.dlen = skb->len; 22911da177e4SLinus Torvalds 2292badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 2293badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 22949c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 22951da177e4SLinus Torvalds 22961da177e4SLinus Torvalds skb->dev = (void *) hdev; 22970d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 2298c78ae283SMarcel Holtmann 22991da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 23003eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 23011da177e4SLinus Torvalds } 23021da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco); 23031da177e4SLinus Torvalds 23041da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 23051da177e4SLinus Torvalds 23061da177e4SLinus Torvalds /* HCI Connection scheduler */ 23071da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) 23081da177e4SLinus Torvalds { 23091da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 23108035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 23111da177e4SLinus Torvalds int num = 0, min = ~0; 23121da177e4SLinus Torvalds 23131da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 23141da177e4SLinus Torvalds * added and removed with TX task disabled. */ 2315bf4c6325SGustavo F. Padovan 2316bf4c6325SGustavo F. Padovan rcu_read_lock(); 2317bf4c6325SGustavo F. Padovan 2318bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2319769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 23201da177e4SLinus Torvalds continue; 2321769be974SMarcel Holtmann 2322769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 2323769be974SMarcel Holtmann continue; 2324769be974SMarcel Holtmann 23251da177e4SLinus Torvalds num++; 23261da177e4SLinus Torvalds 23271da177e4SLinus Torvalds if (c->sent < min) { 23281da177e4SLinus Torvalds min = c->sent; 23291da177e4SLinus Torvalds conn = c; 23301da177e4SLinus Torvalds } 233152087a79SLuiz Augusto von Dentz 233252087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 233352087a79SLuiz Augusto von Dentz break; 23341da177e4SLinus Torvalds } 23351da177e4SLinus Torvalds 2336bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2337bf4c6325SGustavo F. Padovan 23381da177e4SLinus Torvalds if (conn) { 23396ed58ec5SVille Tervo int cnt, q; 23406ed58ec5SVille Tervo 23416ed58ec5SVille Tervo switch (conn->type) { 23426ed58ec5SVille Tervo case ACL_LINK: 23436ed58ec5SVille Tervo cnt = hdev->acl_cnt; 23446ed58ec5SVille Tervo break; 23456ed58ec5SVille Tervo case SCO_LINK: 23466ed58ec5SVille Tervo case ESCO_LINK: 23476ed58ec5SVille Tervo cnt = hdev->sco_cnt; 23486ed58ec5SVille Tervo break; 23496ed58ec5SVille Tervo case LE_LINK: 23506ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 23516ed58ec5SVille Tervo break; 23526ed58ec5SVille Tervo default: 23536ed58ec5SVille Tervo cnt = 0; 23546ed58ec5SVille Tervo BT_ERR("Unknown link type"); 23556ed58ec5SVille Tervo } 23566ed58ec5SVille Tervo 23576ed58ec5SVille Tervo q = cnt / num; 23581da177e4SLinus Torvalds *quote = q ? q : 1; 23591da177e4SLinus Torvalds } else 23601da177e4SLinus Torvalds *quote = 0; 23611da177e4SLinus Torvalds 23621da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 23631da177e4SLinus Torvalds return conn; 23641da177e4SLinus Torvalds } 23651da177e4SLinus Torvalds 2366bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 23671da177e4SLinus Torvalds { 23681da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 23691da177e4SLinus Torvalds struct hci_conn *c; 23701da177e4SLinus Torvalds 2371bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 23721da177e4SLinus Torvalds 2373bf4c6325SGustavo F. Padovan rcu_read_lock(); 2374bf4c6325SGustavo F. Padovan 23751da177e4SLinus Torvalds /* Kill stalled connections */ 2376bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2377bae1f5d9SVille Tervo if (c->type == type && c->sent) { 2378bae1f5d9SVille Tervo BT_ERR("%s killing stalled connection %s", 23791da177e4SLinus Torvalds hdev->name, batostr(&c->dst)); 23801da177e4SLinus Torvalds hci_acl_disconn(c, 0x13); 23811da177e4SLinus Torvalds } 23821da177e4SLinus Torvalds } 2383bf4c6325SGustavo F. Padovan 2384bf4c6325SGustavo F. Padovan rcu_read_unlock(); 23851da177e4SLinus Torvalds } 23861da177e4SLinus Torvalds 238773d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 238873d80debSLuiz Augusto von Dentz int *quote) 238973d80debSLuiz Augusto von Dentz { 239073d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 239173d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 239273d80debSLuiz Augusto von Dentz int num = 0, min = ~0, cur_prio = 0; 239373d80debSLuiz Augusto von Dentz struct hci_conn *conn; 239473d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 239573d80debSLuiz Augusto von Dentz 239673d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 239773d80debSLuiz Augusto von Dentz 2398bf4c6325SGustavo F. Padovan rcu_read_lock(); 2399bf4c6325SGustavo F. Padovan 2400bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 240173d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 240273d80debSLuiz Augusto von Dentz 240373d80debSLuiz Augusto von Dentz if (conn->type != type) 240473d80debSLuiz Augusto von Dentz continue; 240573d80debSLuiz Augusto von Dentz 240673d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 240773d80debSLuiz Augusto von Dentz continue; 240873d80debSLuiz Augusto von Dentz 240973d80debSLuiz Augusto von Dentz conn_num++; 241073d80debSLuiz Augusto von Dentz 24118192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 241273d80debSLuiz Augusto von Dentz struct sk_buff *skb; 241373d80debSLuiz Augusto von Dentz 241473d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 241573d80debSLuiz Augusto von Dentz continue; 241673d80debSLuiz Augusto von Dentz 241773d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 241873d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 241973d80debSLuiz Augusto von Dentz continue; 242073d80debSLuiz Augusto von Dentz 242173d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 242273d80debSLuiz Augusto von Dentz num = 0; 242373d80debSLuiz Augusto von Dentz min = ~0; 242473d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 242573d80debSLuiz Augusto von Dentz } 242673d80debSLuiz Augusto von Dentz 242773d80debSLuiz Augusto von Dentz num++; 242873d80debSLuiz Augusto von Dentz 242973d80debSLuiz Augusto von Dentz if (conn->sent < min) { 243073d80debSLuiz Augusto von Dentz min = conn->sent; 243173d80debSLuiz Augusto von Dentz chan = tmp; 243273d80debSLuiz Augusto von Dentz } 243373d80debSLuiz Augusto von Dentz } 243473d80debSLuiz Augusto von Dentz 243573d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 243673d80debSLuiz Augusto von Dentz break; 243773d80debSLuiz Augusto von Dentz } 243873d80debSLuiz Augusto von Dentz 2439bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2440bf4c6325SGustavo F. Padovan 244173d80debSLuiz Augusto von Dentz if (!chan) 244273d80debSLuiz Augusto von Dentz return NULL; 244373d80debSLuiz Augusto von Dentz 244473d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 244573d80debSLuiz Augusto von Dentz case ACL_LINK: 244673d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 244773d80debSLuiz Augusto von Dentz break; 244873d80debSLuiz Augusto von Dentz case SCO_LINK: 244973d80debSLuiz Augusto von Dentz case ESCO_LINK: 245073d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 245173d80debSLuiz Augusto von Dentz break; 245273d80debSLuiz Augusto von Dentz case LE_LINK: 245373d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 245473d80debSLuiz Augusto von Dentz break; 245573d80debSLuiz Augusto von Dentz default: 245673d80debSLuiz Augusto von Dentz cnt = 0; 245773d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 245873d80debSLuiz Augusto von Dentz } 245973d80debSLuiz Augusto von Dentz 246073d80debSLuiz Augusto von Dentz q = cnt / num; 246173d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 246273d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 246373d80debSLuiz Augusto von Dentz return chan; 246473d80debSLuiz Augusto von Dentz } 246573d80debSLuiz Augusto von Dentz 246602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 246702b20f0bSLuiz Augusto von Dentz { 246802b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 246902b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 247002b20f0bSLuiz Augusto von Dentz int num = 0; 247102b20f0bSLuiz Augusto von Dentz 247202b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 247302b20f0bSLuiz Augusto von Dentz 2474bf4c6325SGustavo F. Padovan rcu_read_lock(); 2475bf4c6325SGustavo F. Padovan 2476bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 247702b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 247802b20f0bSLuiz Augusto von Dentz 247902b20f0bSLuiz Augusto von Dentz if (conn->type != type) 248002b20f0bSLuiz Augusto von Dentz continue; 248102b20f0bSLuiz Augusto von Dentz 248202b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 248302b20f0bSLuiz Augusto von Dentz continue; 248402b20f0bSLuiz Augusto von Dentz 248502b20f0bSLuiz Augusto von Dentz num++; 248602b20f0bSLuiz Augusto von Dentz 24878192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 248802b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 248902b20f0bSLuiz Augusto von Dentz 249002b20f0bSLuiz Augusto von Dentz if (chan->sent) { 249102b20f0bSLuiz Augusto von Dentz chan->sent = 0; 249202b20f0bSLuiz Augusto von Dentz continue; 249302b20f0bSLuiz Augusto von Dentz } 249402b20f0bSLuiz Augusto von Dentz 249502b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 249602b20f0bSLuiz Augusto von Dentz continue; 249702b20f0bSLuiz Augusto von Dentz 249802b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 249902b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 250002b20f0bSLuiz Augusto von Dentz continue; 250102b20f0bSLuiz Augusto von Dentz 250202b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 250302b20f0bSLuiz Augusto von Dentz 250402b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 250502b20f0bSLuiz Augusto von Dentz skb->priority); 250602b20f0bSLuiz Augusto von Dentz } 250702b20f0bSLuiz Augusto von Dentz 250802b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 250902b20f0bSLuiz Augusto von Dentz break; 251002b20f0bSLuiz Augusto von Dentz } 2511bf4c6325SGustavo F. Padovan 2512bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2513bf4c6325SGustavo F. Padovan 251402b20f0bSLuiz Augusto von Dentz } 251502b20f0bSLuiz Augusto von Dentz 2516b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 2517b71d385aSAndrei Emeltchenko { 2518b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 2519b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 2520b71d385aSAndrei Emeltchenko } 2521b71d385aSAndrei Emeltchenko 252263d2bc1bSAndrei Emeltchenko static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 25231da177e4SLinus Torvalds { 25241da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 25251da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 25261da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 252763d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 2528cc48dc0aSAndrei Emeltchenko msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) 2529bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 25301da177e4SLinus Torvalds } 253163d2bc1bSAndrei Emeltchenko } 25321da177e4SLinus Torvalds 253363d2bc1bSAndrei Emeltchenko static inline void hci_sched_acl_pkt(struct hci_dev *hdev) 253463d2bc1bSAndrei Emeltchenko { 253563d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 253663d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 253763d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 253863d2bc1bSAndrei Emeltchenko int quote; 253963d2bc1bSAndrei Emeltchenko 254063d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 254104837f64SMarcel Holtmann 254273d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 254373d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2544ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2545ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 254673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 254773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 254873d80debSLuiz Augusto von Dentz 2549ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2550ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2551ec1cce24SLuiz Augusto von Dentz break; 2552ec1cce24SLuiz Augusto von Dentz 2553ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2554ec1cce24SLuiz Augusto von Dentz 255573d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 255673d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 255704837f64SMarcel Holtmann 25581da177e4SLinus Torvalds hci_send_frame(skb); 25591da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 25601da177e4SLinus Torvalds 25611da177e4SLinus Torvalds hdev->acl_cnt--; 256273d80debSLuiz Augusto von Dentz chan->sent++; 256373d80debSLuiz Augusto von Dentz chan->conn->sent++; 25641da177e4SLinus Torvalds } 25651da177e4SLinus Torvalds } 256602b20f0bSLuiz Augusto von Dentz 256702b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 256802b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 25691da177e4SLinus Torvalds } 25701da177e4SLinus Torvalds 2571b71d385aSAndrei Emeltchenko static inline void hci_sched_acl_blk(struct hci_dev *hdev) 2572b71d385aSAndrei Emeltchenko { 257363d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 2574b71d385aSAndrei Emeltchenko struct hci_chan *chan; 2575b71d385aSAndrei Emeltchenko struct sk_buff *skb; 2576b71d385aSAndrei Emeltchenko int quote; 2577b71d385aSAndrei Emeltchenko 257863d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 2579b71d385aSAndrei Emeltchenko 2580b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 2581b71d385aSAndrei Emeltchenko (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2582b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 2583b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 2584b71d385aSAndrei Emeltchenko int blocks; 2585b71d385aSAndrei Emeltchenko 2586b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 2587b71d385aSAndrei Emeltchenko skb->len, skb->priority); 2588b71d385aSAndrei Emeltchenko 2589b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 2590b71d385aSAndrei Emeltchenko if (skb->priority < priority) 2591b71d385aSAndrei Emeltchenko break; 2592b71d385aSAndrei Emeltchenko 2593b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 2594b71d385aSAndrei Emeltchenko 2595b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 2596b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 2597b71d385aSAndrei Emeltchenko return; 2598b71d385aSAndrei Emeltchenko 2599b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 2600b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 2601b71d385aSAndrei Emeltchenko 2602b71d385aSAndrei Emeltchenko hci_send_frame(skb); 2603b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 2604b71d385aSAndrei Emeltchenko 2605b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 2606b71d385aSAndrei Emeltchenko quote -= blocks; 2607b71d385aSAndrei Emeltchenko 2608b71d385aSAndrei Emeltchenko chan->sent += blocks; 2609b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 2610b71d385aSAndrei Emeltchenko } 2611b71d385aSAndrei Emeltchenko } 2612b71d385aSAndrei Emeltchenko 2613b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 2614b71d385aSAndrei Emeltchenko hci_prio_recalculate(hdev, ACL_LINK); 2615b71d385aSAndrei Emeltchenko } 2616b71d385aSAndrei Emeltchenko 2617b71d385aSAndrei Emeltchenko static inline void hci_sched_acl(struct hci_dev *hdev) 2618b71d385aSAndrei Emeltchenko { 2619b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 2620b71d385aSAndrei Emeltchenko 2621b71d385aSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK)) 2622b71d385aSAndrei Emeltchenko return; 2623b71d385aSAndrei Emeltchenko 2624b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 2625b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 2626b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 2627b71d385aSAndrei Emeltchenko break; 2628b71d385aSAndrei Emeltchenko 2629b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 2630b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 2631b71d385aSAndrei Emeltchenko break; 2632b71d385aSAndrei Emeltchenko } 2633b71d385aSAndrei Emeltchenko } 2634b71d385aSAndrei Emeltchenko 26351da177e4SLinus Torvalds /* Schedule SCO */ 26361da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev) 26371da177e4SLinus Torvalds { 26381da177e4SLinus Torvalds struct hci_conn *conn; 26391da177e4SLinus Torvalds struct sk_buff *skb; 26401da177e4SLinus Torvalds int quote; 26411da177e4SLinus Torvalds 26421da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 26431da177e4SLinus Torvalds 264452087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 264552087a79SLuiz Augusto von Dentz return; 264652087a79SLuiz Augusto von Dentz 26471da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 26481da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 26491da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 26501da177e4SLinus Torvalds hci_send_frame(skb); 26511da177e4SLinus Torvalds 26521da177e4SLinus Torvalds conn->sent++; 26531da177e4SLinus Torvalds if (conn->sent == ~0) 26541da177e4SLinus Torvalds conn->sent = 0; 26551da177e4SLinus Torvalds } 26561da177e4SLinus Torvalds } 26571da177e4SLinus Torvalds } 26581da177e4SLinus Torvalds 2659b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev) 2660b6a0dc82SMarcel Holtmann { 2661b6a0dc82SMarcel Holtmann struct hci_conn *conn; 2662b6a0dc82SMarcel Holtmann struct sk_buff *skb; 2663b6a0dc82SMarcel Holtmann int quote; 2664b6a0dc82SMarcel Holtmann 2665b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 2666b6a0dc82SMarcel Holtmann 266752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 266852087a79SLuiz Augusto von Dentz return; 266952087a79SLuiz Augusto von Dentz 2670b6a0dc82SMarcel Holtmann while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, "e))) { 2671b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 2672b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 2673b6a0dc82SMarcel Holtmann hci_send_frame(skb); 2674b6a0dc82SMarcel Holtmann 2675b6a0dc82SMarcel Holtmann conn->sent++; 2676b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 2677b6a0dc82SMarcel Holtmann conn->sent = 0; 2678b6a0dc82SMarcel Holtmann } 2679b6a0dc82SMarcel Holtmann } 2680b6a0dc82SMarcel Holtmann } 2681b6a0dc82SMarcel Holtmann 26826ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev) 26836ed58ec5SVille Tervo { 268473d80debSLuiz Augusto von Dentz struct hci_chan *chan; 26856ed58ec5SVille Tervo struct sk_buff *skb; 268602b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 26876ed58ec5SVille Tervo 26886ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 26896ed58ec5SVille Tervo 269052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 269152087a79SLuiz Augusto von Dentz return; 269252087a79SLuiz Augusto von Dentz 26936ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 26946ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 26956ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 2696bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 26976ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 2698bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 26996ed58ec5SVille Tervo } 27006ed58ec5SVille Tervo 27016ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 270202b20f0bSLuiz Augusto von Dentz tmp = cnt; 270373d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 2704ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2705ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 270673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 270773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 27086ed58ec5SVille Tervo 2709ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2710ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2711ec1cce24SLuiz Augusto von Dentz break; 2712ec1cce24SLuiz Augusto von Dentz 2713ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2714ec1cce24SLuiz Augusto von Dentz 27156ed58ec5SVille Tervo hci_send_frame(skb); 27166ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 27176ed58ec5SVille Tervo 27186ed58ec5SVille Tervo cnt--; 271973d80debSLuiz Augusto von Dentz chan->sent++; 272073d80debSLuiz Augusto von Dentz chan->conn->sent++; 27216ed58ec5SVille Tervo } 27226ed58ec5SVille Tervo } 272373d80debSLuiz Augusto von Dentz 27246ed58ec5SVille Tervo if (hdev->le_pkts) 27256ed58ec5SVille Tervo hdev->le_cnt = cnt; 27266ed58ec5SVille Tervo else 27276ed58ec5SVille Tervo hdev->acl_cnt = cnt; 272802b20f0bSLuiz Augusto von Dentz 272902b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 273002b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 27316ed58ec5SVille Tervo } 27326ed58ec5SVille Tervo 27333eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 27341da177e4SLinus Torvalds { 27353eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 27361da177e4SLinus Torvalds struct sk_buff *skb; 27371da177e4SLinus Torvalds 27386ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 27396ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 27401da177e4SLinus Torvalds 27411da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 27421da177e4SLinus Torvalds 27431da177e4SLinus Torvalds hci_sched_acl(hdev); 27441da177e4SLinus Torvalds 27451da177e4SLinus Torvalds hci_sched_sco(hdev); 27461da177e4SLinus Torvalds 2747b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 2748b6a0dc82SMarcel Holtmann 27496ed58ec5SVille Tervo hci_sched_le(hdev); 27506ed58ec5SVille Tervo 27511da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 27521da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 27531da177e4SLinus Torvalds hci_send_frame(skb); 27541da177e4SLinus Torvalds } 27551da177e4SLinus Torvalds 275625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 27571da177e4SLinus Torvalds 27581da177e4SLinus Torvalds /* ACL data packet */ 27591da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 27601da177e4SLinus Torvalds { 27611da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 27621da177e4SLinus Torvalds struct hci_conn *conn; 27631da177e4SLinus Torvalds __u16 handle, flags; 27641da177e4SLinus Torvalds 27651da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 27661da177e4SLinus Torvalds 27671da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 27681da177e4SLinus Torvalds flags = hci_flags(handle); 27691da177e4SLinus Torvalds handle = hci_handle(handle); 27701da177e4SLinus Torvalds 27711da177e4SLinus Torvalds BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags); 27721da177e4SLinus Torvalds 27731da177e4SLinus Torvalds hdev->stat.acl_rx++; 27741da177e4SLinus Torvalds 27751da177e4SLinus Torvalds hci_dev_lock(hdev); 27761da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 27771da177e4SLinus Torvalds hci_dev_unlock(hdev); 27781da177e4SLinus Torvalds 27791da177e4SLinus Torvalds if (conn) { 278065983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 278104837f64SMarcel Holtmann 27821da177e4SLinus Torvalds /* Send to upper protocol */ 2783686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 27841da177e4SLinus Torvalds return; 27851da177e4SLinus Torvalds } else { 27861da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 27871da177e4SLinus Torvalds hdev->name, handle); 27881da177e4SLinus Torvalds } 27891da177e4SLinus Torvalds 27901da177e4SLinus Torvalds kfree_skb(skb); 27911da177e4SLinus Torvalds } 27921da177e4SLinus Torvalds 27931da177e4SLinus Torvalds /* SCO data packet */ 27941da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 27951da177e4SLinus Torvalds { 27961da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 27971da177e4SLinus Torvalds struct hci_conn *conn; 27981da177e4SLinus Torvalds __u16 handle; 27991da177e4SLinus Torvalds 28001da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 28011da177e4SLinus Torvalds 28021da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 28031da177e4SLinus Torvalds 28041da177e4SLinus Torvalds BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle); 28051da177e4SLinus Torvalds 28061da177e4SLinus Torvalds hdev->stat.sco_rx++; 28071da177e4SLinus Torvalds 28081da177e4SLinus Torvalds hci_dev_lock(hdev); 28091da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 28101da177e4SLinus Torvalds hci_dev_unlock(hdev); 28111da177e4SLinus Torvalds 28121da177e4SLinus Torvalds if (conn) { 28131da177e4SLinus Torvalds /* Send to upper protocol */ 2814686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 28151da177e4SLinus Torvalds return; 28161da177e4SLinus Torvalds } else { 28171da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 28181da177e4SLinus Torvalds hdev->name, handle); 28191da177e4SLinus Torvalds } 28201da177e4SLinus Torvalds 28211da177e4SLinus Torvalds kfree_skb(skb); 28221da177e4SLinus Torvalds } 28231da177e4SLinus Torvalds 2824b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 28251da177e4SLinus Torvalds { 2826b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 28271da177e4SLinus Torvalds struct sk_buff *skb; 28281da177e4SLinus Torvalds 28291da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 28301da177e4SLinus Torvalds 28311da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 2832cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2833cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2834cd82e61cSMarcel Holtmann 28351da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 28361da177e4SLinus Torvalds /* Send copy to the sockets */ 2837470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 28381da177e4SLinus Torvalds } 28391da177e4SLinus Torvalds 28401da177e4SLinus Torvalds if (test_bit(HCI_RAW, &hdev->flags)) { 28411da177e4SLinus Torvalds kfree_skb(skb); 28421da177e4SLinus Torvalds continue; 28431da177e4SLinus Torvalds } 28441da177e4SLinus Torvalds 28451da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 28461da177e4SLinus Torvalds /* Don't process data packets in this states. */ 28470d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 28481da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 28491da177e4SLinus Torvalds case HCI_SCODATA_PKT: 28501da177e4SLinus Torvalds kfree_skb(skb); 28511da177e4SLinus Torvalds continue; 28523ff50b79SStephen Hemminger } 28531da177e4SLinus Torvalds } 28541da177e4SLinus Torvalds 28551da177e4SLinus Torvalds /* Process frame */ 28560d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 28571da177e4SLinus Torvalds case HCI_EVENT_PKT: 2858b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 28591da177e4SLinus Torvalds hci_event_packet(hdev, skb); 28601da177e4SLinus Torvalds break; 28611da177e4SLinus Torvalds 28621da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 28631da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 28641da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 28651da177e4SLinus Torvalds break; 28661da177e4SLinus Torvalds 28671da177e4SLinus Torvalds case HCI_SCODATA_PKT: 28681da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 28691da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 28701da177e4SLinus Torvalds break; 28711da177e4SLinus Torvalds 28721da177e4SLinus Torvalds default: 28731da177e4SLinus Torvalds kfree_skb(skb); 28741da177e4SLinus Torvalds break; 28751da177e4SLinus Torvalds } 28761da177e4SLinus Torvalds } 28771da177e4SLinus Torvalds } 28781da177e4SLinus Torvalds 2879c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 28801da177e4SLinus Torvalds { 2881c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 28821da177e4SLinus Torvalds struct sk_buff *skb; 28831da177e4SLinus Torvalds 28841da177e4SLinus Torvalds BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); 28851da177e4SLinus Torvalds 28861da177e4SLinus Torvalds /* Send queued commands */ 28875a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 28885a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 28895a08ecceSAndrei Emeltchenko if (!skb) 28905a08ecceSAndrei Emeltchenko return; 28915a08ecceSAndrei Emeltchenko 28921da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 28931da177e4SLinus Torvalds 289470f23020SAndrei Emeltchenko hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC); 289570f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 28961da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 28971da177e4SLinus Torvalds hci_send_frame(skb); 28987bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 28997bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 29007bdb8a5cSSzymon Janc else 29016bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 29026bd32326SVille Tervo jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); 29031da177e4SLinus Torvalds } else { 29041da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 2905c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 29061da177e4SLinus Torvalds } 29071da177e4SLinus Torvalds } 29081da177e4SLinus Torvalds } 29092519a1fcSAndre Guedes 29102519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length) 29112519a1fcSAndre Guedes { 29122519a1fcSAndre Guedes /* General inquiry access code (GIAC) */ 29132519a1fcSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 29142519a1fcSAndre Guedes struct hci_cp_inquiry cp; 29152519a1fcSAndre Guedes 29162519a1fcSAndre Guedes BT_DBG("%s", hdev->name); 29172519a1fcSAndre Guedes 29182519a1fcSAndre Guedes if (test_bit(HCI_INQUIRY, &hdev->flags)) 29192519a1fcSAndre Guedes return -EINPROGRESS; 29202519a1fcSAndre Guedes 29214663262cSJohan Hedberg inquiry_cache_flush(hdev); 29224663262cSJohan Hedberg 29232519a1fcSAndre Guedes memset(&cp, 0, sizeof(cp)); 29242519a1fcSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 29252519a1fcSAndre Guedes cp.length = length; 29262519a1fcSAndre Guedes 29272519a1fcSAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 29282519a1fcSAndre Guedes } 2929023d5049SAndre Guedes 2930023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev) 2931023d5049SAndre Guedes { 2932023d5049SAndre Guedes BT_DBG("%s", hdev->name); 2933023d5049SAndre Guedes 2934023d5049SAndre Guedes if (!test_bit(HCI_INQUIRY, &hdev->flags)) 2935023d5049SAndre Guedes return -EPERM; 2936023d5049SAndre Guedes 2937023d5049SAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); 2938023d5049SAndre Guedes } 2939