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 4870f23020SAndrei Emeltchenko #include <linux/uaccess.h> 491da177e4SLinus Torvalds #include <asm/unaligned.h> 501da177e4SLinus Torvalds 511da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 521da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 531da177e4SLinus Torvalds 54ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000 55ab81cbf9SJohan Hedberg 56b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 57c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 583eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds /* HCI device list */ 611da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 621da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds /* HCI callback list */ 651da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 661da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 671da177e4SLinus Torvalds 681da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 691da177e4SLinus Torvalds 706516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 711da177e4SLinus Torvalds { 72040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 731da177e4SLinus Torvalds } 741da177e4SLinus Torvalds 751da177e4SLinus Torvalds /* ---- HCI requests ---- */ 761da177e4SLinus Torvalds 7723bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) 781da177e4SLinus Torvalds { 7923bb5763SJohan Hedberg BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result); 8023bb5763SJohan Hedberg 81a5040efaSJohan Hedberg /* If this is the init phase check if the completed command matches 82a5040efaSJohan Hedberg * the last init command, and if not just return. 83a5040efaSJohan Hedberg */ 8475fb0e32SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) { 8575fb0e32SJohan Hedberg struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 861036b890SAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 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 961036b890SAndrei Emeltchenko if (cmd != HCI_OP_RESET || 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); 2556bcbc489SAndrei Emeltchenko 2566bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 2576bcbc489SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 258e61ef499SAndrei Emeltchenko } 259e61ef499SAndrei Emeltchenko 260e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt) 261e61ef499SAndrei Emeltchenko { 262e61ef499SAndrei Emeltchenko struct sk_buff *skb; 263e61ef499SAndrei Emeltchenko 264e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 265e61ef499SAndrei Emeltchenko 266e61ef499SAndrei Emeltchenko /* Driver initialization */ 267e61ef499SAndrei Emeltchenko 268e61ef499SAndrei Emeltchenko /* Special commands */ 269e61ef499SAndrei Emeltchenko while ((skb = skb_dequeue(&hdev->driver_init))) { 270e61ef499SAndrei Emeltchenko bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 271e61ef499SAndrei Emeltchenko skb->dev = (void *) hdev; 272e61ef499SAndrei Emeltchenko 273e61ef499SAndrei Emeltchenko skb_queue_tail(&hdev->cmd_q, skb); 274e61ef499SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->cmd_work); 275e61ef499SAndrei Emeltchenko } 276e61ef499SAndrei Emeltchenko skb_queue_purge(&hdev->driver_init); 277e61ef499SAndrei Emeltchenko 278e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 279e61ef499SAndrei Emeltchenko case HCI_BREDR: 280e61ef499SAndrei Emeltchenko bredr_init(hdev); 281e61ef499SAndrei Emeltchenko break; 282e61ef499SAndrei Emeltchenko 283e61ef499SAndrei Emeltchenko case HCI_AMP: 284e61ef499SAndrei Emeltchenko amp_init(hdev); 285e61ef499SAndrei Emeltchenko break; 286e61ef499SAndrei Emeltchenko 287e61ef499SAndrei Emeltchenko default: 288e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 289e61ef499SAndrei Emeltchenko break; 290e61ef499SAndrei Emeltchenko } 291e61ef499SAndrei Emeltchenko 292e61ef499SAndrei Emeltchenko } 293e61ef499SAndrei Emeltchenko 2946ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) 2956ed58ec5SVille Tervo { 2966ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 2976ed58ec5SVille Tervo 2986ed58ec5SVille Tervo /* Read LE buffer size */ 2996ed58ec5SVille Tervo hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 3006ed58ec5SVille Tervo } 3016ed58ec5SVille Tervo 3021da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) 3031da177e4SLinus Torvalds { 3041da177e4SLinus Torvalds __u8 scan = opt; 3051da177e4SLinus Torvalds 3061da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, scan); 3071da177e4SLinus Torvalds 3081da177e4SLinus Torvalds /* Inquiry and Page scans */ 309a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 3101da177e4SLinus Torvalds } 3111da177e4SLinus Torvalds 3121da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt) 3131da177e4SLinus Torvalds { 3141da177e4SLinus Torvalds __u8 auth = opt; 3151da177e4SLinus Torvalds 3161da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, auth); 3171da177e4SLinus Torvalds 3181da177e4SLinus Torvalds /* Authentication */ 319a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 3201da177e4SLinus Torvalds } 3211da177e4SLinus Torvalds 3221da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt) 3231da177e4SLinus Torvalds { 3241da177e4SLinus Torvalds __u8 encrypt = opt; 3251da177e4SLinus Torvalds 3261da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, encrypt); 3271da177e4SLinus Torvalds 328e4e8e37cSMarcel Holtmann /* Encryption */ 329a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 3301da177e4SLinus Torvalds } 3311da177e4SLinus Torvalds 332e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt) 333e4e8e37cSMarcel Holtmann { 334e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 335e4e8e37cSMarcel Holtmann 336a418b893SMarcel Holtmann BT_DBG("%s %x", hdev->name, policy); 337e4e8e37cSMarcel Holtmann 338e4e8e37cSMarcel Holtmann /* Default link policy */ 339e4e8e37cSMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 340e4e8e37cSMarcel Holtmann } 341e4e8e37cSMarcel Holtmann 3421da177e4SLinus Torvalds /* Get HCI device by index. 3431da177e4SLinus Torvalds * Device is held on return. */ 3441da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 3451da177e4SLinus Torvalds { 3468035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 3471da177e4SLinus Torvalds 3481da177e4SLinus Torvalds BT_DBG("%d", index); 3491da177e4SLinus Torvalds 3501da177e4SLinus Torvalds if (index < 0) 3511da177e4SLinus Torvalds return NULL; 3521da177e4SLinus Torvalds 3531da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 3548035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 3551da177e4SLinus Torvalds if (d->id == index) { 3561da177e4SLinus Torvalds hdev = hci_dev_hold(d); 3571da177e4SLinus Torvalds break; 3581da177e4SLinus Torvalds } 3591da177e4SLinus Torvalds } 3601da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 3611da177e4SLinus Torvalds return hdev; 3621da177e4SLinus Torvalds } 3631da177e4SLinus Torvalds 3641da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 365ff9ef578SJohan Hedberg 36630dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 36730dc78e1SJohan Hedberg { 36830dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 36930dc78e1SJohan Hedberg 3706fbe195dSAndre Guedes switch (discov->state) { 371343f935bSAndre Guedes case DISCOVERY_FINDING: 3726fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 37330dc78e1SJohan Hedberg return true; 37430dc78e1SJohan Hedberg 3756fbe195dSAndre Guedes default: 37630dc78e1SJohan Hedberg return false; 37730dc78e1SJohan Hedberg } 3786fbe195dSAndre Guedes } 37930dc78e1SJohan Hedberg 380ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 381ff9ef578SJohan Hedberg { 382ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 383ff9ef578SJohan Hedberg 384ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 385ff9ef578SJohan Hedberg return; 386ff9ef578SJohan Hedberg 387ff9ef578SJohan Hedberg switch (state) { 388ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 3897b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 390ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 391ff9ef578SJohan Hedberg break; 392ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 393ff9ef578SJohan Hedberg break; 394343f935bSAndre Guedes case DISCOVERY_FINDING: 395ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 396ff9ef578SJohan Hedberg break; 39730dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 39830dc78e1SJohan Hedberg break; 399ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 400ff9ef578SJohan Hedberg break; 401ff9ef578SJohan Hedberg } 402ff9ef578SJohan Hedberg 403ff9ef578SJohan Hedberg hdev->discovery.state = state; 404ff9ef578SJohan Hedberg } 405ff9ef578SJohan Hedberg 4061da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev) 4071da177e4SLinus Torvalds { 40830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 409b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 4101da177e4SLinus Torvalds 411561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 412561aafbcSJohan Hedberg list_del(&p->all); 413b57c1a56SJohan Hedberg kfree(p); 4141da177e4SLinus Torvalds } 415561aafbcSJohan Hedberg 416561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 417561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 4181da177e4SLinus Torvalds } 4191da177e4SLinus Torvalds 4201da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 4211da177e4SLinus Torvalds { 42230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 4231da177e4SLinus Torvalds struct inquiry_entry *e; 4241da177e4SLinus Torvalds 4251da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 4261da177e4SLinus Torvalds 427561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 4281da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 4291da177e4SLinus Torvalds return e; 4301da177e4SLinus Torvalds } 4311da177e4SLinus Torvalds 432b57c1a56SJohan Hedberg return NULL; 433b57c1a56SJohan Hedberg } 434b57c1a56SJohan Hedberg 435561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 436561aafbcSJohan Hedberg bdaddr_t *bdaddr) 437561aafbcSJohan Hedberg { 43830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 439561aafbcSJohan Hedberg struct inquiry_entry *e; 440561aafbcSJohan Hedberg 441561aafbcSJohan Hedberg BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 442561aafbcSJohan Hedberg 443561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 444561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 445561aafbcSJohan Hedberg return e; 446561aafbcSJohan Hedberg } 447561aafbcSJohan Hedberg 448561aafbcSJohan Hedberg return NULL; 449561aafbcSJohan Hedberg } 450561aafbcSJohan Hedberg 45130dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 45230dc78e1SJohan Hedberg bdaddr_t *bdaddr, 45330dc78e1SJohan Hedberg int state) 45430dc78e1SJohan Hedberg { 45530dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 45630dc78e1SJohan Hedberg struct inquiry_entry *e; 45730dc78e1SJohan Hedberg 45830dc78e1SJohan Hedberg BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state); 45930dc78e1SJohan Hedberg 46030dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 46130dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 46230dc78e1SJohan Hedberg return e; 46330dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 46430dc78e1SJohan Hedberg return e; 46530dc78e1SJohan Hedberg } 46630dc78e1SJohan Hedberg 46730dc78e1SJohan Hedberg return NULL; 46830dc78e1SJohan Hedberg } 46930dc78e1SJohan Hedberg 470a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 471a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 472a3d4e20aSJohan Hedberg { 473a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 474a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 475a3d4e20aSJohan Hedberg struct inquiry_entry *p; 476a3d4e20aSJohan Hedberg 477a3d4e20aSJohan Hedberg list_del(&ie->list); 478a3d4e20aSJohan Hedberg 479a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 480a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 481a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 482a3d4e20aSJohan Hedberg break; 483a3d4e20aSJohan Hedberg pos = &p->list; 484a3d4e20aSJohan Hedberg } 485a3d4e20aSJohan Hedberg 486a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 487a3d4e20aSJohan Hedberg } 488a3d4e20aSJohan Hedberg 4893175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 490388fc8faSJohan Hedberg bool name_known, bool *ssp) 4911da177e4SLinus Torvalds { 49230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 49370f23020SAndrei Emeltchenko struct inquiry_entry *ie; 4941da177e4SLinus Torvalds 4951da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr)); 4961da177e4SLinus Torvalds 497388fc8faSJohan Hedberg if (ssp) 498388fc8faSJohan Hedberg *ssp = data->ssp_mode; 499388fc8faSJohan Hedberg 50070f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 501a3d4e20aSJohan Hedberg if (ie) { 502388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 503388fc8faSJohan Hedberg *ssp = true; 504388fc8faSJohan Hedberg 505a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 506a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 507a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 508a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 509a3d4e20aSJohan Hedberg } 510a3d4e20aSJohan Hedberg 511561aafbcSJohan Hedberg goto update; 512a3d4e20aSJohan Hedberg } 513561aafbcSJohan Hedberg 5141da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 51570f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 51670f23020SAndrei Emeltchenko if (!ie) 5173175405bSJohan Hedberg return false; 51870f23020SAndrei Emeltchenko 519561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 520561aafbcSJohan Hedberg 521561aafbcSJohan Hedberg if (name_known) { 522561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 523561aafbcSJohan Hedberg } else { 524561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 525561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 526561aafbcSJohan Hedberg } 527561aafbcSJohan Hedberg 528561aafbcSJohan Hedberg update: 529561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 530561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 531561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 532561aafbcSJohan Hedberg list_del(&ie->list); 5331da177e4SLinus Torvalds } 5341da177e4SLinus Torvalds 53570f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 53670f23020SAndrei Emeltchenko ie->timestamp = jiffies; 5371da177e4SLinus Torvalds cache->timestamp = jiffies; 5383175405bSJohan Hedberg 5393175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 5403175405bSJohan Hedberg return false; 5413175405bSJohan Hedberg 5423175405bSJohan Hedberg return true; 5431da177e4SLinus Torvalds } 5441da177e4SLinus Torvalds 5451da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 5461da177e4SLinus Torvalds { 54730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 5481da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 5491da177e4SLinus Torvalds struct inquiry_entry *e; 5501da177e4SLinus Torvalds int copied = 0; 5511da177e4SLinus Torvalds 552561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 5531da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 554b57c1a56SJohan Hedberg 555b57c1a56SJohan Hedberg if (copied >= num) 556b57c1a56SJohan Hedberg break; 557b57c1a56SJohan Hedberg 5581da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 5591da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 5601da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 5611da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 5621da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 5631da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 564b57c1a56SJohan Hedberg 5651da177e4SLinus Torvalds info++; 566b57c1a56SJohan Hedberg copied++; 5671da177e4SLinus Torvalds } 5681da177e4SLinus Torvalds 5691da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 5701da177e4SLinus Torvalds return copied; 5711da177e4SLinus Torvalds } 5721da177e4SLinus Torvalds 5731da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt) 5741da177e4SLinus Torvalds { 5751da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 5761da177e4SLinus Torvalds struct hci_cp_inquiry cp; 5771da177e4SLinus Torvalds 5781da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 5791da177e4SLinus Torvalds 5801da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 5811da177e4SLinus Torvalds return; 5821da177e4SLinus Torvalds 5831da177e4SLinus Torvalds /* Start Inquiry */ 5841da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 5851da177e4SLinus Torvalds cp.length = ir->length; 5861da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 587a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 5881da177e4SLinus Torvalds } 5891da177e4SLinus Torvalds 5901da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 5911da177e4SLinus Torvalds { 5921da177e4SLinus Torvalds __u8 __user *ptr = arg; 5931da177e4SLinus Torvalds struct hci_inquiry_req ir; 5941da177e4SLinus Torvalds struct hci_dev *hdev; 5951da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 5961da177e4SLinus Torvalds long timeo; 5971da177e4SLinus Torvalds __u8 *buf; 5981da177e4SLinus Torvalds 5991da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 6001da177e4SLinus Torvalds return -EFAULT; 6011da177e4SLinus Torvalds 6025a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 6035a08ecceSAndrei Emeltchenko if (!hdev) 6041da177e4SLinus Torvalds return -ENODEV; 6051da177e4SLinus Torvalds 60609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 6071da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 6081da177e4SLinus Torvalds inquiry_cache_empty(hdev) || 6091da177e4SLinus Torvalds ir.flags & IREQ_CACHE_FLUSH) { 6101da177e4SLinus Torvalds inquiry_cache_flush(hdev); 6111da177e4SLinus Torvalds do_inquiry = 1; 6121da177e4SLinus Torvalds } 61309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 6141da177e4SLinus Torvalds 61504837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 61670f23020SAndrei Emeltchenko 61770f23020SAndrei Emeltchenko if (do_inquiry) { 61870f23020SAndrei Emeltchenko err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo); 61970f23020SAndrei Emeltchenko if (err < 0) 6201da177e4SLinus Torvalds goto done; 62170f23020SAndrei Emeltchenko } 6221da177e4SLinus Torvalds 6231da177e4SLinus Torvalds /* for unlimited number of responses we will use buffer with 255 entries */ 6241da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 6251da177e4SLinus Torvalds 6261da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 6271da177e4SLinus Torvalds * copy it to the user space. 6281da177e4SLinus Torvalds */ 62970f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 63070f23020SAndrei Emeltchenko if (!buf) { 6311da177e4SLinus Torvalds err = -ENOMEM; 6321da177e4SLinus Torvalds goto done; 6331da177e4SLinus Torvalds } 6341da177e4SLinus Torvalds 63509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 6361da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 63709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 6381da177e4SLinus Torvalds 6391da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 6401da177e4SLinus Torvalds 6411da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 6421da177e4SLinus Torvalds ptr += sizeof(ir); 6431da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 6441da177e4SLinus Torvalds ir.num_rsp)) 6451da177e4SLinus Torvalds err = -EFAULT; 6461da177e4SLinus Torvalds } else 6471da177e4SLinus Torvalds err = -EFAULT; 6481da177e4SLinus Torvalds 6491da177e4SLinus Torvalds kfree(buf); 6501da177e4SLinus Torvalds 6511da177e4SLinus Torvalds done: 6521da177e4SLinus Torvalds hci_dev_put(hdev); 6531da177e4SLinus Torvalds return err; 6541da177e4SLinus Torvalds } 6551da177e4SLinus Torvalds 6561da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */ 6571da177e4SLinus Torvalds 6581da177e4SLinus Torvalds int hci_dev_open(__u16 dev) 6591da177e4SLinus Torvalds { 6601da177e4SLinus Torvalds struct hci_dev *hdev; 6611da177e4SLinus Torvalds int ret = 0; 6621da177e4SLinus Torvalds 6635a08ecceSAndrei Emeltchenko hdev = hci_dev_get(dev); 6645a08ecceSAndrei Emeltchenko if (!hdev) 6651da177e4SLinus Torvalds return -ENODEV; 6661da177e4SLinus Torvalds 6671da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 6681da177e4SLinus Torvalds 6691da177e4SLinus Torvalds hci_req_lock(hdev); 6701da177e4SLinus Torvalds 67194324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 67294324962SJohan Hovold ret = -ENODEV; 67394324962SJohan Hovold goto done; 67494324962SJohan Hovold } 67594324962SJohan Hovold 676611b30f7SMarcel Holtmann if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { 677611b30f7SMarcel Holtmann ret = -ERFKILL; 678611b30f7SMarcel Holtmann goto done; 679611b30f7SMarcel Holtmann } 680611b30f7SMarcel Holtmann 6811da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 6821da177e4SLinus Torvalds ret = -EALREADY; 6831da177e4SLinus Torvalds goto done; 6841da177e4SLinus Torvalds } 6851da177e4SLinus Torvalds 6861da177e4SLinus Torvalds if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 6871da177e4SLinus Torvalds set_bit(HCI_RAW, &hdev->flags); 6881da177e4SLinus Torvalds 68907e3b94aSAndrei Emeltchenko /* Treat all non BR/EDR controllers as raw devices if 69007e3b94aSAndrei Emeltchenko enable_hs is not set */ 69107e3b94aSAndrei Emeltchenko if (hdev->dev_type != HCI_BREDR && !enable_hs) 692943da25dSMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 693943da25dSMarcel Holtmann 6941da177e4SLinus Torvalds if (hdev->open(hdev)) { 6951da177e4SLinus Torvalds ret = -EIO; 6961da177e4SLinus Torvalds goto done; 6971da177e4SLinus Torvalds } 6981da177e4SLinus Torvalds 6991da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 7001da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 7011da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 702a5040efaSJohan Hedberg hdev->init_last_cmd = 0; 7031da177e4SLinus Torvalds 70404837f64SMarcel Holtmann ret = __hci_request(hdev, hci_init_req, 0, 70504837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 7061da177e4SLinus Torvalds 707eead27daSAndre Guedes if (lmp_host_le_capable(hdev)) 7086ed58ec5SVille Tervo ret = __hci_request(hdev, hci_le_init_req, 0, 7096ed58ec5SVille Tervo msecs_to_jiffies(HCI_INIT_TIMEOUT)); 7106ed58ec5SVille Tervo 7111da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7121da177e4SLinus Torvalds } 7131da177e4SLinus Torvalds 7141da177e4SLinus Torvalds if (!ret) { 7151da177e4SLinus Torvalds hci_dev_hold(hdev); 7161da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 7171da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 718a8b2d5c2SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 71909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 720744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 72109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 72256e5cb86SJohan Hedberg } 7231da177e4SLinus Torvalds } else { 7241da177e4SLinus Torvalds /* Init failed, cleanup */ 7253eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 726c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 727b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7281da177e4SLinus Torvalds 7291da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7301da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7311da177e4SLinus Torvalds 7321da177e4SLinus Torvalds if (hdev->flush) 7331da177e4SLinus Torvalds hdev->flush(hdev); 7341da177e4SLinus Torvalds 7351da177e4SLinus Torvalds if (hdev->sent_cmd) { 7361da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 7371da177e4SLinus Torvalds hdev->sent_cmd = NULL; 7381da177e4SLinus Torvalds } 7391da177e4SLinus Torvalds 7401da177e4SLinus Torvalds hdev->close(hdev); 7411da177e4SLinus Torvalds hdev->flags = 0; 7421da177e4SLinus Torvalds } 7431da177e4SLinus Torvalds 7441da177e4SLinus Torvalds done: 7451da177e4SLinus Torvalds hci_req_unlock(hdev); 7461da177e4SLinus Torvalds hci_dev_put(hdev); 7471da177e4SLinus Torvalds return ret; 7481da177e4SLinus Torvalds } 7491da177e4SLinus Torvalds 7501da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 7511da177e4SLinus Torvalds { 7521da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 7531da177e4SLinus Torvalds 75428b75a89SAndre Guedes cancel_work_sync(&hdev->le_scan); 75528b75a89SAndre Guedes 7561da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 7571da177e4SLinus Torvalds hci_req_lock(hdev); 7581da177e4SLinus Torvalds 7591da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 760b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 7611da177e4SLinus Torvalds hci_req_unlock(hdev); 7621da177e4SLinus Torvalds return 0; 7631da177e4SLinus Torvalds } 7641da177e4SLinus Torvalds 7653eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 7663eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 767b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7681da177e4SLinus Torvalds 76916ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 770e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 77116ab91abSJohan Hedberg hdev->discov_timeout = 0; 7725e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 77316ab91abSJohan Hedberg } 77416ab91abSJohan Hedberg 775a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 7767d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 7777d78525dSJohan Hedberg 7787ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 7797ba8b4beSAndre Guedes 78009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 7811da177e4SLinus Torvalds inquiry_cache_flush(hdev); 7821da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 78309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 7841da177e4SLinus Torvalds 7851da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 7861da177e4SLinus Torvalds 7871da177e4SLinus Torvalds if (hdev->flush) 7881da177e4SLinus Torvalds hdev->flush(hdev); 7891da177e4SLinus Torvalds 7901da177e4SLinus Torvalds /* Reset device */ 7911da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7921da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 7938af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 7948af59467SJohan Hedberg test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { 7951da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 79604837f64SMarcel Holtmann __hci_request(hdev, hci_reset_req, 0, 797cad44c2bSGustavo F. Padovan msecs_to_jiffies(250)); 7981da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7991da177e4SLinus Torvalds } 8001da177e4SLinus Torvalds 801c347b765SGustavo F. Padovan /* flush cmd work */ 802c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 8031da177e4SLinus Torvalds 8041da177e4SLinus Torvalds /* Drop queues */ 8051da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 8061da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8071da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 8081da177e4SLinus Torvalds 8091da177e4SLinus Torvalds /* Drop last sent command */ 8101da177e4SLinus Torvalds if (hdev->sent_cmd) { 811b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 8121da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 8131da177e4SLinus Torvalds hdev->sent_cmd = NULL; 8141da177e4SLinus Torvalds } 8151da177e4SLinus Torvalds 8161da177e4SLinus Torvalds /* After this point our queues are empty 8171da177e4SLinus Torvalds * and no tasks are scheduled. */ 8181da177e4SLinus Torvalds hdev->close(hdev); 8191da177e4SLinus Torvalds 8208ee56540SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 82109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 822744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 82309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8248ee56540SMarcel Holtmann } 8255add6af8SJohan Hedberg 8261da177e4SLinus Torvalds /* Clear flags */ 8271da177e4SLinus Torvalds hdev->flags = 0; 8281da177e4SLinus Torvalds 829e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 83009b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 831e59fda8dSJohan Hedberg 8321da177e4SLinus Torvalds hci_req_unlock(hdev); 8331da177e4SLinus Torvalds 8341da177e4SLinus Torvalds hci_dev_put(hdev); 8351da177e4SLinus Torvalds return 0; 8361da177e4SLinus Torvalds } 8371da177e4SLinus Torvalds 8381da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 8391da177e4SLinus Torvalds { 8401da177e4SLinus Torvalds struct hci_dev *hdev; 8411da177e4SLinus Torvalds int err; 8421da177e4SLinus Torvalds 84370f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 84470f23020SAndrei Emeltchenko if (!hdev) 8451da177e4SLinus Torvalds return -ENODEV; 8468ee56540SMarcel Holtmann 8478ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 8488ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 8498ee56540SMarcel Holtmann 8501da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 8518ee56540SMarcel Holtmann 8521da177e4SLinus Torvalds hci_dev_put(hdev); 8531da177e4SLinus Torvalds return err; 8541da177e4SLinus Torvalds } 8551da177e4SLinus Torvalds 8561da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 8571da177e4SLinus Torvalds { 8581da177e4SLinus Torvalds struct hci_dev *hdev; 8591da177e4SLinus Torvalds int ret = 0; 8601da177e4SLinus Torvalds 86170f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 86270f23020SAndrei Emeltchenko if (!hdev) 8631da177e4SLinus Torvalds return -ENODEV; 8641da177e4SLinus Torvalds 8651da177e4SLinus Torvalds hci_req_lock(hdev); 8661da177e4SLinus Torvalds 8671da177e4SLinus Torvalds if (!test_bit(HCI_UP, &hdev->flags)) 8681da177e4SLinus Torvalds goto done; 8691da177e4SLinus Torvalds 8701da177e4SLinus Torvalds /* Drop queues */ 8711da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 8721da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8731da177e4SLinus Torvalds 87409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 8751da177e4SLinus Torvalds inquiry_cache_flush(hdev); 8761da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 87709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8781da177e4SLinus Torvalds 8791da177e4SLinus Torvalds if (hdev->flush) 8801da177e4SLinus Torvalds hdev->flush(hdev); 8811da177e4SLinus Torvalds 8821da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 8836ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 8841da177e4SLinus Torvalds 8851da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 88604837f64SMarcel Holtmann ret = __hci_request(hdev, hci_reset_req, 0, 88704837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 8881da177e4SLinus Torvalds 8891da177e4SLinus Torvalds done: 8901da177e4SLinus Torvalds hci_req_unlock(hdev); 8911da177e4SLinus Torvalds hci_dev_put(hdev); 8921da177e4SLinus Torvalds return ret; 8931da177e4SLinus Torvalds } 8941da177e4SLinus Torvalds 8951da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 8961da177e4SLinus Torvalds { 8971da177e4SLinus Torvalds struct hci_dev *hdev; 8981da177e4SLinus Torvalds int ret = 0; 8991da177e4SLinus Torvalds 90070f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 90170f23020SAndrei Emeltchenko if (!hdev) 9021da177e4SLinus Torvalds return -ENODEV; 9031da177e4SLinus Torvalds 9041da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 9051da177e4SLinus Torvalds 9061da177e4SLinus Torvalds hci_dev_put(hdev); 9071da177e4SLinus Torvalds 9081da177e4SLinus Torvalds return ret; 9091da177e4SLinus Torvalds } 9101da177e4SLinus Torvalds 9111da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 9121da177e4SLinus Torvalds { 9131da177e4SLinus Torvalds struct hci_dev *hdev; 9141da177e4SLinus Torvalds struct hci_dev_req dr; 9151da177e4SLinus Torvalds int err = 0; 9161da177e4SLinus Torvalds 9171da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 9181da177e4SLinus Torvalds return -EFAULT; 9191da177e4SLinus Torvalds 92070f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 92170f23020SAndrei Emeltchenko if (!hdev) 9221da177e4SLinus Torvalds return -ENODEV; 9231da177e4SLinus Torvalds 9241da177e4SLinus Torvalds switch (cmd) { 9251da177e4SLinus Torvalds case HCISETAUTH: 92604837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 92704837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9281da177e4SLinus Torvalds break; 9291da177e4SLinus Torvalds 9301da177e4SLinus Torvalds case HCISETENCRYPT: 9311da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 9321da177e4SLinus Torvalds err = -EOPNOTSUPP; 9331da177e4SLinus Torvalds break; 9341da177e4SLinus Torvalds } 9351da177e4SLinus Torvalds 9361da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 9371da177e4SLinus Torvalds /* Auth must be enabled first */ 93804837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 93904837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9401da177e4SLinus Torvalds if (err) 9411da177e4SLinus Torvalds break; 9421da177e4SLinus Torvalds } 9431da177e4SLinus Torvalds 94404837f64SMarcel Holtmann err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, 94504837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9461da177e4SLinus Torvalds break; 9471da177e4SLinus Torvalds 9481da177e4SLinus Torvalds case HCISETSCAN: 94904837f64SMarcel Holtmann err = hci_request(hdev, hci_scan_req, dr.dev_opt, 95004837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9511da177e4SLinus Torvalds break; 9521da177e4SLinus Torvalds 9531da177e4SLinus Torvalds case HCISETLINKPOL: 954e4e8e37cSMarcel Holtmann err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, 955e4e8e37cSMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9561da177e4SLinus Torvalds break; 9571da177e4SLinus Torvalds 9581da177e4SLinus Torvalds case HCISETLINKMODE: 959e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 960e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 961e4e8e37cSMarcel Holtmann break; 962e4e8e37cSMarcel Holtmann 963e4e8e37cSMarcel Holtmann case HCISETPTYPE: 964e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 9651da177e4SLinus Torvalds break; 9661da177e4SLinus Torvalds 9671da177e4SLinus Torvalds case HCISETACLMTU: 9681da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 9691da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 9701da177e4SLinus Torvalds break; 9711da177e4SLinus Torvalds 9721da177e4SLinus Torvalds case HCISETSCOMTU: 9731da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 9741da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 9751da177e4SLinus Torvalds break; 9761da177e4SLinus Torvalds 9771da177e4SLinus Torvalds default: 9781da177e4SLinus Torvalds err = -EINVAL; 9791da177e4SLinus Torvalds break; 9801da177e4SLinus Torvalds } 981e4e8e37cSMarcel Holtmann 9821da177e4SLinus Torvalds hci_dev_put(hdev); 9831da177e4SLinus Torvalds return err; 9841da177e4SLinus Torvalds } 9851da177e4SLinus Torvalds 9861da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 9871da177e4SLinus Torvalds { 9888035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 9891da177e4SLinus Torvalds struct hci_dev_list_req *dl; 9901da177e4SLinus Torvalds struct hci_dev_req *dr; 9911da177e4SLinus Torvalds int n = 0, size, err; 9921da177e4SLinus Torvalds __u16 dev_num; 9931da177e4SLinus Torvalds 9941da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 9951da177e4SLinus Torvalds return -EFAULT; 9961da177e4SLinus Torvalds 9971da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 9981da177e4SLinus Torvalds return -EINVAL; 9991da177e4SLinus Torvalds 10001da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 10011da177e4SLinus Torvalds 100270f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 100370f23020SAndrei Emeltchenko if (!dl) 10041da177e4SLinus Torvalds return -ENOMEM; 10051da177e4SLinus Torvalds 10061da177e4SLinus Torvalds dr = dl->dev_req; 10071da177e4SLinus Torvalds 1008f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 10098035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 1010a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1011e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 1012c542a06cSJohan Hedberg 1013a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1014a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1015c542a06cSJohan Hedberg 10161da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 10171da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 1018c542a06cSJohan Hedberg 10191da177e4SLinus Torvalds if (++n >= dev_num) 10201da177e4SLinus Torvalds break; 10211da177e4SLinus Torvalds } 1022f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 10231da177e4SLinus Torvalds 10241da177e4SLinus Torvalds dl->dev_num = n; 10251da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 10261da177e4SLinus Torvalds 10271da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 10281da177e4SLinus Torvalds kfree(dl); 10291da177e4SLinus Torvalds 10301da177e4SLinus Torvalds return err ? -EFAULT : 0; 10311da177e4SLinus Torvalds } 10321da177e4SLinus Torvalds 10331da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 10341da177e4SLinus Torvalds { 10351da177e4SLinus Torvalds struct hci_dev *hdev; 10361da177e4SLinus Torvalds struct hci_dev_info di; 10371da177e4SLinus Torvalds int err = 0; 10381da177e4SLinus Torvalds 10391da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 10401da177e4SLinus Torvalds return -EFAULT; 10411da177e4SLinus Torvalds 104270f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 104370f23020SAndrei Emeltchenko if (!hdev) 10441da177e4SLinus Torvalds return -ENODEV; 10451da177e4SLinus Torvalds 1046a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 10473243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 1048ab81cbf9SJohan Hedberg 1049a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1050a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1051c542a06cSJohan Hedberg 10521da177e4SLinus Torvalds strcpy(di.name, hdev->name); 10531da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 1054943da25dSMarcel Holtmann di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); 10551da177e4SLinus Torvalds di.flags = hdev->flags; 10561da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 10571da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 10581da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 10591da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 10601da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 10611da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 10621da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 10631da177e4SLinus Torvalds 10641da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 10651da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 10661da177e4SLinus Torvalds 10671da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 10681da177e4SLinus Torvalds err = -EFAULT; 10691da177e4SLinus Torvalds 10701da177e4SLinus Torvalds hci_dev_put(hdev); 10711da177e4SLinus Torvalds 10721da177e4SLinus Torvalds return err; 10731da177e4SLinus Torvalds } 10741da177e4SLinus Torvalds 10751da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 10761da177e4SLinus Torvalds 1077611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 1078611b30f7SMarcel Holtmann { 1079611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 1080611b30f7SMarcel Holtmann 1081611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 1082611b30f7SMarcel Holtmann 1083611b30f7SMarcel Holtmann if (!blocked) 1084611b30f7SMarcel Holtmann return 0; 1085611b30f7SMarcel Holtmann 1086611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 1087611b30f7SMarcel Holtmann 1088611b30f7SMarcel Holtmann return 0; 1089611b30f7SMarcel Holtmann } 1090611b30f7SMarcel Holtmann 1091611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 1092611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 1093611b30f7SMarcel Holtmann }; 1094611b30f7SMarcel Holtmann 1095ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 1096ab81cbf9SJohan Hedberg { 1097ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 1098ab81cbf9SJohan Hedberg 1099ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1100ab81cbf9SJohan Hedberg 1101ab81cbf9SJohan Hedberg if (hci_dev_open(hdev->id) < 0) 1102ab81cbf9SJohan Hedberg return; 1103ab81cbf9SJohan Hedberg 1104a8b2d5c2SJohan Hedberg if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 110580b7ab33SGustavo F. Padovan schedule_delayed_work(&hdev->power_off, 11063243553fSJohan Hedberg msecs_to_jiffies(AUTO_OFF_TIMEOUT)); 1107ab81cbf9SJohan Hedberg 1108a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 1109744cf19eSJohan Hedberg mgmt_index_added(hdev); 1110ab81cbf9SJohan Hedberg } 1111ab81cbf9SJohan Hedberg 1112ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1113ab81cbf9SJohan Hedberg { 11143243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 11153243553fSJohan Hedberg power_off.work); 1116ab81cbf9SJohan Hedberg 1117ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1118ab81cbf9SJohan Hedberg 11198ee56540SMarcel Holtmann hci_dev_do_close(hdev); 1120ab81cbf9SJohan Hedberg } 1121ab81cbf9SJohan Hedberg 112216ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 112316ab91abSJohan Hedberg { 112416ab91abSJohan Hedberg struct hci_dev *hdev; 112516ab91abSJohan Hedberg u8 scan = SCAN_PAGE; 112616ab91abSJohan Hedberg 112716ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 112816ab91abSJohan Hedberg 112916ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 113016ab91abSJohan Hedberg 113109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 113216ab91abSJohan Hedberg 113316ab91abSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); 113416ab91abSJohan Hedberg 113516ab91abSJohan Hedberg hdev->discov_timeout = 0; 113616ab91abSJohan Hedberg 113709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 113816ab91abSJohan Hedberg } 113916ab91abSJohan Hedberg 11402aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 11412aeb9a1aSJohan Hedberg { 11422aeb9a1aSJohan Hedberg struct list_head *p, *n; 11432aeb9a1aSJohan Hedberg 11442aeb9a1aSJohan Hedberg list_for_each_safe(p, n, &hdev->uuids) { 11452aeb9a1aSJohan Hedberg struct bt_uuid *uuid; 11462aeb9a1aSJohan Hedberg 11472aeb9a1aSJohan Hedberg uuid = list_entry(p, struct bt_uuid, list); 11482aeb9a1aSJohan Hedberg 11492aeb9a1aSJohan Hedberg list_del(p); 11502aeb9a1aSJohan Hedberg kfree(uuid); 11512aeb9a1aSJohan Hedberg } 11522aeb9a1aSJohan Hedberg 11532aeb9a1aSJohan Hedberg return 0; 11542aeb9a1aSJohan Hedberg } 11552aeb9a1aSJohan Hedberg 115655ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 115755ed8ca1SJohan Hedberg { 115855ed8ca1SJohan Hedberg struct list_head *p, *n; 115955ed8ca1SJohan Hedberg 116055ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 116155ed8ca1SJohan Hedberg struct link_key *key; 116255ed8ca1SJohan Hedberg 116355ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 116455ed8ca1SJohan Hedberg 116555ed8ca1SJohan Hedberg list_del(p); 116655ed8ca1SJohan Hedberg kfree(key); 116755ed8ca1SJohan Hedberg } 116855ed8ca1SJohan Hedberg 116955ed8ca1SJohan Hedberg return 0; 117055ed8ca1SJohan Hedberg } 117155ed8ca1SJohan Hedberg 1172b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 1173b899efafSVinicius Costa Gomes { 1174b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1175b899efafSVinicius Costa Gomes 1176b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1177b899efafSVinicius Costa Gomes list_del(&k->list); 1178b899efafSVinicius Costa Gomes kfree(k); 1179b899efafSVinicius Costa Gomes } 1180b899efafSVinicius Costa Gomes 1181b899efafSVinicius Costa Gomes return 0; 1182b899efafSVinicius Costa Gomes } 1183b899efafSVinicius Costa Gomes 118455ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 118555ed8ca1SJohan Hedberg { 118655ed8ca1SJohan Hedberg struct link_key *k; 118755ed8ca1SJohan Hedberg 11888035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 118955ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 119055ed8ca1SJohan Hedberg return k; 119155ed8ca1SJohan Hedberg 119255ed8ca1SJohan Hedberg return NULL; 119355ed8ca1SJohan Hedberg } 119455ed8ca1SJohan Hedberg 1195745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 1196d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 1197d25e28abSJohan Hedberg { 1198d25e28abSJohan Hedberg /* Legacy key */ 1199d25e28abSJohan Hedberg if (key_type < 0x03) 1200745c0ce3SVishal Agarwal return true; 1201d25e28abSJohan Hedberg 1202d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 1203d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 1204745c0ce3SVishal Agarwal return false; 1205d25e28abSJohan Hedberg 1206d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 1207d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 1208745c0ce3SVishal Agarwal return false; 1209d25e28abSJohan Hedberg 1210d25e28abSJohan Hedberg /* Security mode 3 case */ 1211d25e28abSJohan Hedberg if (!conn) 1212745c0ce3SVishal Agarwal return true; 1213d25e28abSJohan Hedberg 1214d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 1215d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 1216745c0ce3SVishal Agarwal return true; 1217d25e28abSJohan Hedberg 1218d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 1219d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 1220745c0ce3SVishal Agarwal return true; 1221d25e28abSJohan Hedberg 1222d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 1223d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 1224745c0ce3SVishal Agarwal return true; 1225d25e28abSJohan Hedberg 1226d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 1227d25e28abSJohan Hedberg * persistently */ 1228745c0ce3SVishal Agarwal return false; 1229d25e28abSJohan Hedberg } 1230d25e28abSJohan Hedberg 1231c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 123275d262c2SVinicius Costa Gomes { 1233c9839a11SVinicius Costa Gomes struct smp_ltk *k; 123475d262c2SVinicius Costa Gomes 1235c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 1236c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 1237c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 123875d262c2SVinicius Costa Gomes continue; 123975d262c2SVinicius Costa Gomes 124075d262c2SVinicius Costa Gomes return k; 124175d262c2SVinicius Costa Gomes } 124275d262c2SVinicius Costa Gomes 124375d262c2SVinicius Costa Gomes return NULL; 124475d262c2SVinicius Costa Gomes } 124575d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk); 124675d262c2SVinicius Costa Gomes 1247c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1248c9839a11SVinicius Costa Gomes u8 addr_type) 124975d262c2SVinicius Costa Gomes { 1250c9839a11SVinicius Costa Gomes struct smp_ltk *k; 125175d262c2SVinicius Costa Gomes 1252c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 1253c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 1254c9839a11SVinicius Costa Gomes bacmp(bdaddr, &k->bdaddr) == 0) 125575d262c2SVinicius Costa Gomes return k; 125675d262c2SVinicius Costa Gomes 125775d262c2SVinicius Costa Gomes return NULL; 125875d262c2SVinicius Costa Gomes } 1259c9839a11SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk_by_addr); 126075d262c2SVinicius Costa Gomes 1261d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 1262d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 126355ed8ca1SJohan Hedberg { 126455ed8ca1SJohan Hedberg struct link_key *key, *old_key; 1265745c0ce3SVishal Agarwal u8 old_key_type; 1266745c0ce3SVishal Agarwal bool persistent; 126755ed8ca1SJohan Hedberg 126855ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 126955ed8ca1SJohan Hedberg if (old_key) { 127055ed8ca1SJohan Hedberg old_key_type = old_key->type; 127155ed8ca1SJohan Hedberg key = old_key; 127255ed8ca1SJohan Hedberg } else { 127312adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 127455ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 127555ed8ca1SJohan Hedberg if (!key) 127655ed8ca1SJohan Hedberg return -ENOMEM; 127755ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 127855ed8ca1SJohan Hedberg } 127955ed8ca1SJohan Hedberg 128055ed8ca1SJohan Hedberg BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); 128155ed8ca1SJohan Hedberg 1282d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1283d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1284d25e28abSJohan Hedberg * previous key */ 1285d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1286d25e28abSJohan Hedberg (!conn || conn->remote_auth == 0xff) && 1287655fe6ecSJohan Hedberg old_key_type == 0xff) { 1288d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1289655fe6ecSJohan Hedberg if (conn) 1290655fe6ecSJohan Hedberg conn->key_type = type; 1291655fe6ecSJohan Hedberg } 1292d25e28abSJohan Hedberg 129355ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 129455ed8ca1SJohan Hedberg memcpy(key->val, val, 16); 129555ed8ca1SJohan Hedberg key->pin_len = pin_len; 129655ed8ca1SJohan Hedberg 1297b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 129855ed8ca1SJohan Hedberg key->type = old_key_type; 12994748fed2SJohan Hedberg else 13004748fed2SJohan Hedberg key->type = type; 13014748fed2SJohan Hedberg 13024df378a1SJohan Hedberg if (!new_key) 13034df378a1SJohan Hedberg return 0; 13044df378a1SJohan Hedberg 13054df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 13064df378a1SJohan Hedberg 1307744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 13084df378a1SJohan Hedberg 13096ec5bcadSVishal Agarwal if (conn) 13106ec5bcadSVishal Agarwal conn->flush_key = !persistent; 131155ed8ca1SJohan Hedberg 131255ed8ca1SJohan Hedberg return 0; 131355ed8ca1SJohan Hedberg } 131455ed8ca1SJohan Hedberg 1315c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 13169a006657SAndrei Emeltchenko int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 131704124681SGustavo F. Padovan ediv, u8 rand[8]) 131875d262c2SVinicius Costa Gomes { 1319c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 132075d262c2SVinicius Costa Gomes 1321c9839a11SVinicius Costa Gomes if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 1322c9839a11SVinicius Costa Gomes return 0; 132375d262c2SVinicius Costa Gomes 1324c9839a11SVinicius Costa Gomes old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 1325c9839a11SVinicius Costa Gomes if (old_key) 132675d262c2SVinicius Costa Gomes key = old_key; 1327c9839a11SVinicius Costa Gomes else { 1328c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 132975d262c2SVinicius Costa Gomes if (!key) 133075d262c2SVinicius Costa Gomes return -ENOMEM; 1331c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 133275d262c2SVinicius Costa Gomes } 133375d262c2SVinicius Costa Gomes 133475d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 1335c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 1336c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 1337c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 1338c9839a11SVinicius Costa Gomes key->ediv = ediv; 1339c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 1340c9839a11SVinicius Costa Gomes key->type = type; 1341c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 134275d262c2SVinicius Costa Gomes 1343c9839a11SVinicius Costa Gomes if (!new_key) 1344c9839a11SVinicius Costa Gomes return 0; 134575d262c2SVinicius Costa Gomes 1346261cc5aaSVinicius Costa Gomes if (type & HCI_SMP_LTK) 1347261cc5aaSVinicius Costa Gomes mgmt_new_ltk(hdev, key, 1); 1348261cc5aaSVinicius Costa Gomes 134975d262c2SVinicius Costa Gomes return 0; 135075d262c2SVinicius Costa Gomes } 135175d262c2SVinicius Costa Gomes 135255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 135355ed8ca1SJohan Hedberg { 135455ed8ca1SJohan Hedberg struct link_key *key; 135555ed8ca1SJohan Hedberg 135655ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 135755ed8ca1SJohan Hedberg if (!key) 135855ed8ca1SJohan Hedberg return -ENOENT; 135955ed8ca1SJohan Hedberg 136055ed8ca1SJohan Hedberg BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 136155ed8ca1SJohan Hedberg 136255ed8ca1SJohan Hedberg list_del(&key->list); 136355ed8ca1SJohan Hedberg kfree(key); 136455ed8ca1SJohan Hedberg 136555ed8ca1SJohan Hedberg return 0; 136655ed8ca1SJohan Hedberg } 136755ed8ca1SJohan Hedberg 1368b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 1369b899efafSVinicius Costa Gomes { 1370b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1371b899efafSVinicius Costa Gomes 1372b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1373b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 1374b899efafSVinicius Costa Gomes continue; 1375b899efafSVinicius Costa Gomes 1376b899efafSVinicius Costa Gomes BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 1377b899efafSVinicius Costa Gomes 1378b899efafSVinicius Costa Gomes list_del(&k->list); 1379b899efafSVinicius Costa Gomes kfree(k); 1380b899efafSVinicius Costa Gomes } 1381b899efafSVinicius Costa Gomes 1382b899efafSVinicius Costa Gomes return 0; 1383b899efafSVinicius Costa Gomes } 1384b899efafSVinicius Costa Gomes 13856bd32326SVille Tervo /* HCI command timer function */ 13866bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg) 13876bd32326SVille Tervo { 13886bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 13896bd32326SVille Tervo 13906bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 13916bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 1392c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 13936bd32326SVille Tervo } 13946bd32326SVille Tervo 13952763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 13962763eda6SSzymon Janc bdaddr_t *bdaddr) 13972763eda6SSzymon Janc { 13982763eda6SSzymon Janc struct oob_data *data; 13992763eda6SSzymon Janc 14002763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 14012763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 14022763eda6SSzymon Janc return data; 14032763eda6SSzymon Janc 14042763eda6SSzymon Janc return NULL; 14052763eda6SSzymon Janc } 14062763eda6SSzymon Janc 14072763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 14082763eda6SSzymon Janc { 14092763eda6SSzymon Janc struct oob_data *data; 14102763eda6SSzymon Janc 14112763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14122763eda6SSzymon Janc if (!data) 14132763eda6SSzymon Janc return -ENOENT; 14142763eda6SSzymon Janc 14152763eda6SSzymon Janc BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 14162763eda6SSzymon Janc 14172763eda6SSzymon Janc list_del(&data->list); 14182763eda6SSzymon Janc kfree(data); 14192763eda6SSzymon Janc 14202763eda6SSzymon Janc return 0; 14212763eda6SSzymon Janc } 14222763eda6SSzymon Janc 14232763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 14242763eda6SSzymon Janc { 14252763eda6SSzymon Janc struct oob_data *data, *n; 14262763eda6SSzymon Janc 14272763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 14282763eda6SSzymon Janc list_del(&data->list); 14292763eda6SSzymon Janc kfree(data); 14302763eda6SSzymon Janc } 14312763eda6SSzymon Janc 14322763eda6SSzymon Janc return 0; 14332763eda6SSzymon Janc } 14342763eda6SSzymon Janc 14352763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 14362763eda6SSzymon Janc u8 *randomizer) 14372763eda6SSzymon Janc { 14382763eda6SSzymon Janc struct oob_data *data; 14392763eda6SSzymon Janc 14402763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14412763eda6SSzymon Janc 14422763eda6SSzymon Janc if (!data) { 14432763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 14442763eda6SSzymon Janc if (!data) 14452763eda6SSzymon Janc return -ENOMEM; 14462763eda6SSzymon Janc 14472763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 14482763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 14492763eda6SSzymon Janc } 14502763eda6SSzymon Janc 14512763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 14522763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 14532763eda6SSzymon Janc 14542763eda6SSzymon Janc BT_DBG("%s for %s", hdev->name, batostr(bdaddr)); 14552763eda6SSzymon Janc 14562763eda6SSzymon Janc return 0; 14572763eda6SSzymon Janc } 14582763eda6SSzymon Janc 145904124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 1460b2a66aadSAntti Julku { 1461b2a66aadSAntti Julku struct bdaddr_list *b; 1462b2a66aadSAntti Julku 14638035ded4SLuiz Augusto von Dentz list_for_each_entry(b, &hdev->blacklist, list) 1464b2a66aadSAntti Julku if (bacmp(bdaddr, &b->bdaddr) == 0) 1465b2a66aadSAntti Julku return b; 1466b2a66aadSAntti Julku 1467b2a66aadSAntti Julku return NULL; 1468b2a66aadSAntti Julku } 1469b2a66aadSAntti Julku 1470b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 1471b2a66aadSAntti Julku { 1472b2a66aadSAntti Julku struct list_head *p, *n; 1473b2a66aadSAntti Julku 1474b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 1475b2a66aadSAntti Julku struct bdaddr_list *b; 1476b2a66aadSAntti Julku 1477b2a66aadSAntti Julku b = list_entry(p, struct bdaddr_list, list); 1478b2a66aadSAntti Julku 1479b2a66aadSAntti Julku list_del(p); 1480b2a66aadSAntti Julku kfree(b); 1481b2a66aadSAntti Julku } 1482b2a66aadSAntti Julku 1483b2a66aadSAntti Julku return 0; 1484b2a66aadSAntti Julku } 1485b2a66aadSAntti Julku 148688c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1487b2a66aadSAntti Julku { 1488b2a66aadSAntti Julku struct bdaddr_list *entry; 1489b2a66aadSAntti Julku 1490b2a66aadSAntti Julku if (bacmp(bdaddr, BDADDR_ANY) == 0) 1491b2a66aadSAntti Julku return -EBADF; 1492b2a66aadSAntti Julku 14935e762444SAntti Julku if (hci_blacklist_lookup(hdev, bdaddr)) 14945e762444SAntti Julku return -EEXIST; 1495b2a66aadSAntti Julku 1496b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 14975e762444SAntti Julku if (!entry) 14985e762444SAntti Julku return -ENOMEM; 1499b2a66aadSAntti Julku 1500b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 1501b2a66aadSAntti Julku 1502b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 1503b2a66aadSAntti Julku 150488c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 1505b2a66aadSAntti Julku } 1506b2a66aadSAntti Julku 150788c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1508b2a66aadSAntti Julku { 1509b2a66aadSAntti Julku struct bdaddr_list *entry; 1510b2a66aadSAntti Julku 15111ec918ceSSzymon Janc if (bacmp(bdaddr, BDADDR_ANY) == 0) 15125e762444SAntti Julku return hci_blacklist_clear(hdev); 1513b2a66aadSAntti Julku 1514b2a66aadSAntti Julku entry = hci_blacklist_lookup(hdev, bdaddr); 15151ec918ceSSzymon Janc if (!entry) 15165e762444SAntti Julku return -ENOENT; 1517b2a66aadSAntti Julku 1518b2a66aadSAntti Julku list_del(&entry->list); 1519b2a66aadSAntti Julku kfree(entry); 1520b2a66aadSAntti Julku 152188c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 1522b2a66aadSAntti Julku } 1523b2a66aadSAntti Julku 15247ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt) 15257ba8b4beSAndre Guedes { 15267ba8b4beSAndre Guedes struct le_scan_params *param = (struct le_scan_params *) opt; 15277ba8b4beSAndre Guedes struct hci_cp_le_set_scan_param cp; 15287ba8b4beSAndre Guedes 15297ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 15307ba8b4beSAndre Guedes cp.type = param->type; 15317ba8b4beSAndre Guedes cp.interval = cpu_to_le16(param->interval); 15327ba8b4beSAndre Guedes cp.window = cpu_to_le16(param->window); 15337ba8b4beSAndre Guedes 15347ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); 15357ba8b4beSAndre Guedes } 15367ba8b4beSAndre Guedes 15377ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt) 15387ba8b4beSAndre Guedes { 15397ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 15407ba8b4beSAndre Guedes 15417ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 15427ba8b4beSAndre Guedes cp.enable = 1; 15437ba8b4beSAndre Guedes 15447ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 15457ba8b4beSAndre Guedes } 15467ba8b4beSAndre Guedes 15477ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, 15487ba8b4beSAndre Guedes u16 window, int timeout) 15497ba8b4beSAndre Guedes { 15507ba8b4beSAndre Guedes long timeo = msecs_to_jiffies(3000); 15517ba8b4beSAndre Guedes struct le_scan_params param; 15527ba8b4beSAndre Guedes int err; 15537ba8b4beSAndre Guedes 15547ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 15557ba8b4beSAndre Guedes 15567ba8b4beSAndre Guedes if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 15577ba8b4beSAndre Guedes return -EINPROGRESS; 15587ba8b4beSAndre Guedes 15597ba8b4beSAndre Guedes param.type = type; 15607ba8b4beSAndre Guedes param.interval = interval; 15617ba8b4beSAndre Guedes param.window = window; 15627ba8b4beSAndre Guedes 15637ba8b4beSAndre Guedes hci_req_lock(hdev); 15647ba8b4beSAndre Guedes 15657ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_param_req, (unsigned long) ¶m, 15667ba8b4beSAndre Guedes timeo); 15677ba8b4beSAndre Guedes if (!err) 15687ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_enable_req, 0, timeo); 15697ba8b4beSAndre Guedes 15707ba8b4beSAndre Guedes hci_req_unlock(hdev); 15717ba8b4beSAndre Guedes 15727ba8b4beSAndre Guedes if (err < 0) 15737ba8b4beSAndre Guedes return err; 15747ba8b4beSAndre Guedes 15757ba8b4beSAndre Guedes schedule_delayed_work(&hdev->le_scan_disable, 15767ba8b4beSAndre Guedes msecs_to_jiffies(timeout)); 15777ba8b4beSAndre Guedes 15787ba8b4beSAndre Guedes return 0; 15797ba8b4beSAndre Guedes } 15807ba8b4beSAndre Guedes 15817dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev) 15827dbfac1dSAndre Guedes { 15837dbfac1dSAndre Guedes BT_DBG("%s", hdev->name); 15847dbfac1dSAndre Guedes 15857dbfac1dSAndre Guedes if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 15867dbfac1dSAndre Guedes return -EALREADY; 15877dbfac1dSAndre Guedes 15887dbfac1dSAndre Guedes if (cancel_delayed_work(&hdev->le_scan_disable)) { 15897dbfac1dSAndre Guedes struct hci_cp_le_set_scan_enable cp; 15907dbfac1dSAndre Guedes 15917dbfac1dSAndre Guedes /* Send HCI command to disable LE Scan */ 15927dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 15937dbfac1dSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 15947dbfac1dSAndre Guedes } 15957dbfac1dSAndre Guedes 15967dbfac1dSAndre Guedes return 0; 15977dbfac1dSAndre Guedes } 15987dbfac1dSAndre Guedes 15997ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 16007ba8b4beSAndre Guedes { 16017ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 16027ba8b4beSAndre Guedes le_scan_disable.work); 16037ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 16047ba8b4beSAndre Guedes 16057ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 16067ba8b4beSAndre Guedes 16077ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 16087ba8b4beSAndre Guedes 16097ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 16107ba8b4beSAndre Guedes } 16117ba8b4beSAndre Guedes 161228b75a89SAndre Guedes static void le_scan_work(struct work_struct *work) 161328b75a89SAndre Guedes { 161428b75a89SAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan); 161528b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 161628b75a89SAndre Guedes 161728b75a89SAndre Guedes BT_DBG("%s", hdev->name); 161828b75a89SAndre Guedes 161904124681SGustavo F. Padovan hci_do_le_scan(hdev, param->type, param->interval, param->window, 162004124681SGustavo F. Padovan param->timeout); 162128b75a89SAndre Guedes } 162228b75a89SAndre Guedes 162328b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, 162428b75a89SAndre Guedes int timeout) 162528b75a89SAndre Guedes { 162628b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 162728b75a89SAndre Guedes 162828b75a89SAndre Guedes BT_DBG("%s", hdev->name); 162928b75a89SAndre Guedes 163028b75a89SAndre Guedes if (work_busy(&hdev->le_scan)) 163128b75a89SAndre Guedes return -EINPROGRESS; 163228b75a89SAndre Guedes 163328b75a89SAndre Guedes param->type = type; 163428b75a89SAndre Guedes param->interval = interval; 163528b75a89SAndre Guedes param->window = window; 163628b75a89SAndre Guedes param->timeout = timeout; 163728b75a89SAndre Guedes 163828b75a89SAndre Guedes queue_work(system_long_wq, &hdev->le_scan); 163928b75a89SAndre Guedes 164028b75a89SAndre Guedes return 0; 164128b75a89SAndre Guedes } 164228b75a89SAndre Guedes 16439be0dab7SDavid Herrmann /* Alloc HCI device */ 16449be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 16459be0dab7SDavid Herrmann { 16469be0dab7SDavid Herrmann struct hci_dev *hdev; 16479be0dab7SDavid Herrmann 16489be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 16499be0dab7SDavid Herrmann if (!hdev) 16509be0dab7SDavid Herrmann return NULL; 16519be0dab7SDavid Herrmann 1652b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 1653b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 1654b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 1655b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 1656b1b813d4SDavid Herrmann 1657b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 1658b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 1659b1b813d4SDavid Herrmann 1660b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 1661b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 1662b1b813d4SDavid Herrmann 1663b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 1664b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 1665b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 1666b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 1667b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 1668b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 1669b1b813d4SDavid Herrmann 1670b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 1671b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 1672b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 1673b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 1674b1b813d4SDavid Herrmann INIT_WORK(&hdev->le_scan, le_scan_work); 1675b1b813d4SDavid Herrmann 1676b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 1677b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 1678b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 1679b1b813d4SDavid Herrmann 16809be0dab7SDavid Herrmann skb_queue_head_init(&hdev->driver_init); 1681b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 1682b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 1683b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 1684b1b813d4SDavid Herrmann 1685b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 1686b1b813d4SDavid Herrmann 1687b1b813d4SDavid Herrmann setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); 1688b1b813d4SDavid Herrmann 1689b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 1690b1b813d4SDavid Herrmann discovery_init(hdev); 1691b1b813d4SDavid Herrmann hci_conn_hash_init(hdev); 16929be0dab7SDavid Herrmann 16939be0dab7SDavid Herrmann return hdev; 16949be0dab7SDavid Herrmann } 16959be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 16969be0dab7SDavid Herrmann 16979be0dab7SDavid Herrmann /* Free HCI device */ 16989be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 16999be0dab7SDavid Herrmann { 17009be0dab7SDavid Herrmann skb_queue_purge(&hdev->driver_init); 17019be0dab7SDavid Herrmann 17029be0dab7SDavid Herrmann /* will free via device release */ 17039be0dab7SDavid Herrmann put_device(&hdev->dev); 17049be0dab7SDavid Herrmann } 17059be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 17069be0dab7SDavid Herrmann 17071da177e4SLinus Torvalds /* Register HCI device */ 17081da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 17091da177e4SLinus Torvalds { 1710fc50744cSUlisses Furquim struct list_head *head, *p; 1711b1b813d4SDavid Herrmann int id, error; 17121da177e4SLinus Torvalds 1713010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 17141da177e4SLinus Torvalds return -EINVAL; 17151da177e4SLinus Torvalds 1716fc50744cSUlisses Furquim write_lock(&hci_dev_list_lock); 1717fc50744cSUlisses Furquim 171808add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 171908add513SMat Martineau * so the index can be used as the AMP controller ID. 172008add513SMat Martineau */ 172108add513SMat Martineau id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; 1722fc50744cSUlisses Furquim head = &hci_dev_list; 17231da177e4SLinus Torvalds 17241da177e4SLinus Torvalds /* Find first available device id */ 17251da177e4SLinus Torvalds list_for_each(p, &hci_dev_list) { 1726fc50744cSUlisses Furquim int nid = list_entry(p, struct hci_dev, list)->id; 1727fc50744cSUlisses Furquim if (nid > id) 17281da177e4SLinus Torvalds break; 1729fc50744cSUlisses Furquim if (nid == id) 1730fc50744cSUlisses Furquim id++; 1731fc50744cSUlisses Furquim head = p; 17321da177e4SLinus Torvalds } 17331da177e4SLinus Torvalds 17341da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 17351da177e4SLinus Torvalds hdev->id = id; 17362d8b3a11SAndrei Emeltchenko 17372d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 17382d8b3a11SAndrei Emeltchenko 1739fc50744cSUlisses Furquim list_add(&hdev->list, head); 17401da177e4SLinus Torvalds 1741f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 17421da177e4SLinus Torvalds 174332845eb1SGustavo F. Padovan hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | 174432845eb1SGustavo F. Padovan WQ_MEM_RECLAIM, 1); 174533ca954dSDavid Herrmann if (!hdev->workqueue) { 174633ca954dSDavid Herrmann error = -ENOMEM; 174733ca954dSDavid Herrmann goto err; 174833ca954dSDavid Herrmann } 1749f48fd9c8SMarcel Holtmann 175033ca954dSDavid Herrmann error = hci_add_sysfs(hdev); 175133ca954dSDavid Herrmann if (error < 0) 175233ca954dSDavid Herrmann goto err_wqueue; 17531da177e4SLinus Torvalds 1754611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 1755611b30f7SMarcel Holtmann RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); 1756611b30f7SMarcel Holtmann if (hdev->rfkill) { 1757611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 1758611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1759611b30f7SMarcel Holtmann hdev->rfkill = NULL; 1760611b30f7SMarcel Holtmann } 1761611b30f7SMarcel Holtmann } 1762611b30f7SMarcel Holtmann 1763a8b2d5c2SJohan Hedberg set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 1764a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 17657f971041SGustavo F. Padovan schedule_work(&hdev->power_on); 1766ab81cbf9SJohan Hedberg 17671da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 1768dc946bd8SDavid Herrmann hci_dev_hold(hdev); 17691da177e4SLinus Torvalds 17701da177e4SLinus Torvalds return id; 1771f48fd9c8SMarcel Holtmann 177233ca954dSDavid Herrmann err_wqueue: 177333ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 177433ca954dSDavid Herrmann err: 1775f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 1776f48fd9c8SMarcel Holtmann list_del(&hdev->list); 1777f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 1778f48fd9c8SMarcel Holtmann 177933ca954dSDavid Herrmann return error; 17801da177e4SLinus Torvalds } 17811da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 17821da177e4SLinus Torvalds 17831da177e4SLinus Torvalds /* Unregister HCI device */ 178459735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 17851da177e4SLinus Torvalds { 1786ef222013SMarcel Holtmann int i; 1787ef222013SMarcel Holtmann 1788c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 17891da177e4SLinus Torvalds 179094324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 179194324962SJohan Hovold 1792f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 17931da177e4SLinus Torvalds list_del(&hdev->list); 1794f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 17951da177e4SLinus Torvalds 17961da177e4SLinus Torvalds hci_dev_do_close(hdev); 17971da177e4SLinus Torvalds 1798cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1799ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 1800ef222013SMarcel Holtmann 1801ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 1802a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 180309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1804744cf19eSJohan Hedberg mgmt_index_removed(hdev); 180509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 180656e5cb86SJohan Hedberg } 1807ab81cbf9SJohan Hedberg 18082e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 18092e58ef3eSJohan Hedberg * pending list */ 18102e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 18112e58ef3eSJohan Hedberg 18121da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 18131da177e4SLinus Torvalds 1814611b30f7SMarcel Holtmann if (hdev->rfkill) { 1815611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 1816611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1817611b30f7SMarcel Holtmann } 1818611b30f7SMarcel Holtmann 1819ce242970SDavid Herrmann hci_del_sysfs(hdev); 1820147e2d59SDave Young 1821f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 1822f48fd9c8SMarcel Holtmann 182309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1824e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 18252aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 182655ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 1827b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 18282763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 182909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 1830e2e0cacbSJohan Hedberg 1831dc946bd8SDavid Herrmann hci_dev_put(hdev); 18321da177e4SLinus Torvalds } 18331da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 18341da177e4SLinus Torvalds 18351da177e4SLinus Torvalds /* Suspend HCI device */ 18361da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 18371da177e4SLinus Torvalds { 18381da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 18391da177e4SLinus Torvalds return 0; 18401da177e4SLinus Torvalds } 18411da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 18421da177e4SLinus Torvalds 18431da177e4SLinus Torvalds /* Resume HCI device */ 18441da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 18451da177e4SLinus Torvalds { 18461da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 18471da177e4SLinus Torvalds return 0; 18481da177e4SLinus Torvalds } 18491da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 18501da177e4SLinus Torvalds 185176bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 185276bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb) 185376bca880SMarcel Holtmann { 185476bca880SMarcel Holtmann struct hci_dev *hdev = (struct hci_dev *) skb->dev; 185576bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 185676bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 185776bca880SMarcel Holtmann kfree_skb(skb); 185876bca880SMarcel Holtmann return -ENXIO; 185976bca880SMarcel Holtmann } 186076bca880SMarcel Holtmann 186176bca880SMarcel Holtmann /* Incomming skb */ 186276bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 186376bca880SMarcel Holtmann 186476bca880SMarcel Holtmann /* Time stamp */ 186576bca880SMarcel Holtmann __net_timestamp(skb); 186676bca880SMarcel Holtmann 186776bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 1868b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 1869c78ae283SMarcel Holtmann 187076bca880SMarcel Holtmann return 0; 187176bca880SMarcel Holtmann } 187276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 187376bca880SMarcel Holtmann 187433e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 18751e429f38SGustavo F. Padovan int count, __u8 index) 187633e882a5SSuraj Sumangala { 187733e882a5SSuraj Sumangala int len = 0; 187833e882a5SSuraj Sumangala int hlen = 0; 187933e882a5SSuraj Sumangala int remain = count; 188033e882a5SSuraj Sumangala struct sk_buff *skb; 188133e882a5SSuraj Sumangala struct bt_skb_cb *scb; 188233e882a5SSuraj Sumangala 188333e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 188433e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 188533e882a5SSuraj Sumangala return -EILSEQ; 188633e882a5SSuraj Sumangala 188733e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 188833e882a5SSuraj Sumangala 188933e882a5SSuraj Sumangala if (!skb) { 189033e882a5SSuraj Sumangala switch (type) { 189133e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 189233e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 189333e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 189433e882a5SSuraj Sumangala break; 189533e882a5SSuraj Sumangala case HCI_EVENT_PKT: 189633e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 189733e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 189833e882a5SSuraj Sumangala break; 189933e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 190033e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 190133e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 190233e882a5SSuraj Sumangala break; 190333e882a5SSuraj Sumangala } 190433e882a5SSuraj Sumangala 19051e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 190633e882a5SSuraj Sumangala if (!skb) 190733e882a5SSuraj Sumangala return -ENOMEM; 190833e882a5SSuraj Sumangala 190933e882a5SSuraj Sumangala scb = (void *) skb->cb; 191033e882a5SSuraj Sumangala scb->expect = hlen; 191133e882a5SSuraj Sumangala scb->pkt_type = type; 191233e882a5SSuraj Sumangala 191333e882a5SSuraj Sumangala skb->dev = (void *) hdev; 191433e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 191533e882a5SSuraj Sumangala } 191633e882a5SSuraj Sumangala 191733e882a5SSuraj Sumangala while (count) { 191833e882a5SSuraj Sumangala scb = (void *) skb->cb; 191989bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 192033e882a5SSuraj Sumangala 192133e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 192233e882a5SSuraj Sumangala 192333e882a5SSuraj Sumangala count -= len; 192433e882a5SSuraj Sumangala data += len; 192533e882a5SSuraj Sumangala scb->expect -= len; 192633e882a5SSuraj Sumangala remain = count; 192733e882a5SSuraj Sumangala 192833e882a5SSuraj Sumangala switch (type) { 192933e882a5SSuraj Sumangala case HCI_EVENT_PKT: 193033e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 193133e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 193233e882a5SSuraj Sumangala scb->expect = h->plen; 193333e882a5SSuraj Sumangala 193433e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 193533e882a5SSuraj Sumangala kfree_skb(skb); 193633e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 193733e882a5SSuraj Sumangala return -ENOMEM; 193833e882a5SSuraj Sumangala } 193933e882a5SSuraj Sumangala } 194033e882a5SSuraj Sumangala break; 194133e882a5SSuraj Sumangala 194233e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 194333e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 194433e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 194533e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 194633e882a5SSuraj Sumangala 194733e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 194833e882a5SSuraj Sumangala kfree_skb(skb); 194933e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 195033e882a5SSuraj Sumangala return -ENOMEM; 195133e882a5SSuraj Sumangala } 195233e882a5SSuraj Sumangala } 195333e882a5SSuraj Sumangala break; 195433e882a5SSuraj Sumangala 195533e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 195633e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 195733e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 195833e882a5SSuraj Sumangala scb->expect = h->dlen; 195933e882a5SSuraj Sumangala 196033e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 196133e882a5SSuraj Sumangala kfree_skb(skb); 196233e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 196333e882a5SSuraj Sumangala return -ENOMEM; 196433e882a5SSuraj Sumangala } 196533e882a5SSuraj Sumangala } 196633e882a5SSuraj Sumangala break; 196733e882a5SSuraj Sumangala } 196833e882a5SSuraj Sumangala 196933e882a5SSuraj Sumangala if (scb->expect == 0) { 197033e882a5SSuraj Sumangala /* Complete frame */ 197133e882a5SSuraj Sumangala 197233e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 197333e882a5SSuraj Sumangala hci_recv_frame(skb); 197433e882a5SSuraj Sumangala 197533e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 197633e882a5SSuraj Sumangala return remain; 197733e882a5SSuraj Sumangala } 197833e882a5SSuraj Sumangala } 197933e882a5SSuraj Sumangala 198033e882a5SSuraj Sumangala return remain; 198133e882a5SSuraj Sumangala } 198233e882a5SSuraj Sumangala 1983ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 1984ef222013SMarcel Holtmann { 1985f39a3c06SSuraj Sumangala int rem = 0; 1986f39a3c06SSuraj Sumangala 1987ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 1988ef222013SMarcel Holtmann return -EILSEQ; 1989ef222013SMarcel Holtmann 1990da5f6c37SGustavo F. Padovan while (count) { 19911e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 1992f39a3c06SSuraj Sumangala if (rem < 0) 1993f39a3c06SSuraj Sumangala return rem; 1994ef222013SMarcel Holtmann 1995f39a3c06SSuraj Sumangala data += (count - rem); 1996f39a3c06SSuraj Sumangala count = rem; 1997f81c6224SJoe Perches } 1998ef222013SMarcel Holtmann 1999f39a3c06SSuraj Sumangala return rem; 2000ef222013SMarcel Holtmann } 2001ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 2002ef222013SMarcel Holtmann 200399811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 200499811510SSuraj Sumangala 200599811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 200699811510SSuraj Sumangala { 200799811510SSuraj Sumangala int type; 200899811510SSuraj Sumangala int rem = 0; 200999811510SSuraj Sumangala 2010da5f6c37SGustavo F. Padovan while (count) { 201199811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 201299811510SSuraj Sumangala 201399811510SSuraj Sumangala if (!skb) { 201499811510SSuraj Sumangala struct { char type; } *pkt; 201599811510SSuraj Sumangala 201699811510SSuraj Sumangala /* Start of the frame */ 201799811510SSuraj Sumangala pkt = data; 201899811510SSuraj Sumangala type = pkt->type; 201999811510SSuraj Sumangala 202099811510SSuraj Sumangala data++; 202199811510SSuraj Sumangala count--; 202299811510SSuraj Sumangala } else 202399811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 202499811510SSuraj Sumangala 20251e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 20261e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 202799811510SSuraj Sumangala if (rem < 0) 202899811510SSuraj Sumangala return rem; 202999811510SSuraj Sumangala 203099811510SSuraj Sumangala data += (count - rem); 203199811510SSuraj Sumangala count = rem; 2032f81c6224SJoe Perches } 203399811510SSuraj Sumangala 203499811510SSuraj Sumangala return rem; 203599811510SSuraj Sumangala } 203699811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 203799811510SSuraj Sumangala 20381da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 20391da177e4SLinus Torvalds 20401da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 20411da177e4SLinus Torvalds { 20421da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 20431da177e4SLinus Torvalds 2044f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 20451da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 2046f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 20471da177e4SLinus Torvalds 20481da177e4SLinus Torvalds return 0; 20491da177e4SLinus Torvalds } 20501da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 20511da177e4SLinus Torvalds 20521da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 20531da177e4SLinus Torvalds { 20541da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 20551da177e4SLinus Torvalds 2056f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 20571da177e4SLinus Torvalds list_del(&cb->list); 2058f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 20591da177e4SLinus Torvalds 20601da177e4SLinus Torvalds return 0; 20611da177e4SLinus Torvalds } 20621da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 20631da177e4SLinus Torvalds 20641da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb) 20651da177e4SLinus Torvalds { 20661da177e4SLinus Torvalds struct hci_dev *hdev = (struct hci_dev *) skb->dev; 20671da177e4SLinus Torvalds 20681da177e4SLinus Torvalds if (!hdev) { 20691da177e4SLinus Torvalds kfree_skb(skb); 20701da177e4SLinus Torvalds return -ENODEV; 20711da177e4SLinus Torvalds } 20721da177e4SLinus Torvalds 20730d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 20741da177e4SLinus Torvalds 20751da177e4SLinus Torvalds /* Time stamp */ 2076a61bbcf2SPatrick McHardy __net_timestamp(skb); 20771da177e4SLinus Torvalds 2078cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2079cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2080cd82e61cSMarcel Holtmann 2081cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 2082cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 2083470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 20841da177e4SLinus Torvalds } 20851da177e4SLinus Torvalds 20861da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 20871da177e4SLinus Torvalds skb_orphan(skb); 20881da177e4SLinus Torvalds 20891da177e4SLinus Torvalds return hdev->send(skb); 20901da177e4SLinus Torvalds } 20911da177e4SLinus Torvalds 20921da177e4SLinus Torvalds /* Send HCI command */ 2093a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) 20941da177e4SLinus Torvalds { 20951da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 20961da177e4SLinus Torvalds struct hci_command_hdr *hdr; 20971da177e4SLinus Torvalds struct sk_buff *skb; 20981da177e4SLinus Torvalds 2099a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen); 21001da177e4SLinus Torvalds 21011da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 21021da177e4SLinus Torvalds if (!skb) { 2103ef222013SMarcel Holtmann BT_ERR("%s no memory for command", hdev->name); 21041da177e4SLinus Torvalds return -ENOMEM; 21051da177e4SLinus Torvalds } 21061da177e4SLinus Torvalds 21071da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 2108a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 21091da177e4SLinus Torvalds hdr->plen = plen; 21101da177e4SLinus Torvalds 21111da177e4SLinus Torvalds if (plen) 21121da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 21131da177e4SLinus Torvalds 21141da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 21151da177e4SLinus Torvalds 21160d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 21171da177e4SLinus Torvalds skb->dev = (void *) hdev; 2118c78ae283SMarcel Holtmann 2119a5040efaSJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags)) 2120a5040efaSJohan Hedberg hdev->init_last_cmd = opcode; 2121a5040efaSJohan Hedberg 21221da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 2123c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 21241da177e4SLinus Torvalds 21251da177e4SLinus Torvalds return 0; 21261da177e4SLinus Torvalds } 21271da177e4SLinus Torvalds 21281da177e4SLinus Torvalds /* Get data from the previously sent command */ 2129a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 21301da177e4SLinus Torvalds { 21311da177e4SLinus Torvalds struct hci_command_hdr *hdr; 21321da177e4SLinus Torvalds 21331da177e4SLinus Torvalds if (!hdev->sent_cmd) 21341da177e4SLinus Torvalds return NULL; 21351da177e4SLinus Torvalds 21361da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 21371da177e4SLinus Torvalds 2138a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 21391da177e4SLinus Torvalds return NULL; 21401da177e4SLinus Torvalds 2141a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 21421da177e4SLinus Torvalds 21431da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 21441da177e4SLinus Torvalds } 21451da177e4SLinus Torvalds 21461da177e4SLinus Torvalds /* Send ACL data */ 21471da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 21481da177e4SLinus Torvalds { 21491da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 21501da177e4SLinus Torvalds int len = skb->len; 21511da177e4SLinus Torvalds 2152badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 2153badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 21549c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 2155aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 2156aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 21571da177e4SLinus Torvalds } 21581da177e4SLinus Torvalds 215973d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, 216073d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 21611da177e4SLinus Torvalds { 21621da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 21631da177e4SLinus Torvalds struct sk_buff *list; 21641da177e4SLinus Torvalds 2165*087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 2166*087bfd99SGustavo Padovan skb->data_len = 0; 2167*087bfd99SGustavo Padovan 2168*087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2169*087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 2170*087bfd99SGustavo Padovan 217170f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 217270f23020SAndrei Emeltchenko if (!list) { 21731da177e4SLinus Torvalds /* Non fragmented */ 21741da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 21751da177e4SLinus Torvalds 217673d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 21771da177e4SLinus Torvalds } else { 21781da177e4SLinus Torvalds /* Fragmented */ 21791da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 21801da177e4SLinus Torvalds 21811da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 21821da177e4SLinus Torvalds 21831da177e4SLinus Torvalds /* Queue all fragments atomically */ 2184af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 21851da177e4SLinus Torvalds 218673d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 2187e702112fSAndrei Emeltchenko 2188e702112fSAndrei Emeltchenko flags &= ~ACL_START; 2189e702112fSAndrei Emeltchenko flags |= ACL_CONT; 21901da177e4SLinus Torvalds do { 21911da177e4SLinus Torvalds skb = list; list = list->next; 21921da177e4SLinus Torvalds 21931da177e4SLinus Torvalds skb->dev = (void *) hdev; 21940d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2195e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 21961da177e4SLinus Torvalds 21971da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 21981da177e4SLinus Torvalds 219973d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 22001da177e4SLinus Torvalds } while (list); 22011da177e4SLinus Torvalds 2202af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 22031da177e4SLinus Torvalds } 220473d80debSLuiz Augusto von Dentz } 220573d80debSLuiz Augusto von Dentz 220673d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 220773d80debSLuiz Augusto von Dentz { 220873d80debSLuiz Augusto von Dentz struct hci_conn *conn = chan->conn; 220973d80debSLuiz Augusto von Dentz struct hci_dev *hdev = conn->hdev; 221073d80debSLuiz Augusto von Dentz 221173d80debSLuiz Augusto von Dentz BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags); 221273d80debSLuiz Augusto von Dentz 221373d80debSLuiz Augusto von Dentz skb->dev = (void *) hdev; 221473d80debSLuiz Augusto von Dentz 221573d80debSLuiz Augusto von Dentz hci_queue_acl(conn, &chan->data_q, skb, flags); 22161da177e4SLinus Torvalds 22173eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 22181da177e4SLinus Torvalds } 22191da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl); 22201da177e4SLinus Torvalds 22211da177e4SLinus Torvalds /* Send SCO data */ 22220d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 22231da177e4SLinus Torvalds { 22241da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 22251da177e4SLinus Torvalds struct hci_sco_hdr hdr; 22261da177e4SLinus Torvalds 22271da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 22281da177e4SLinus Torvalds 2229aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 22301da177e4SLinus Torvalds hdr.dlen = skb->len; 22311da177e4SLinus Torvalds 2232badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 2233badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 22349c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 22351da177e4SLinus Torvalds 22361da177e4SLinus Torvalds skb->dev = (void *) hdev; 22370d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 2238c78ae283SMarcel Holtmann 22391da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 22403eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 22411da177e4SLinus Torvalds } 22421da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco); 22431da177e4SLinus Torvalds 22441da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 22451da177e4SLinus Torvalds 22461da177e4SLinus Torvalds /* HCI Connection scheduler */ 22471da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) 22481da177e4SLinus Torvalds { 22491da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 22508035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 2251abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 22521da177e4SLinus Torvalds 22531da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 22541da177e4SLinus Torvalds * added and removed with TX task disabled. */ 2255bf4c6325SGustavo F. Padovan 2256bf4c6325SGustavo F. Padovan rcu_read_lock(); 2257bf4c6325SGustavo F. Padovan 2258bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2259769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 22601da177e4SLinus Torvalds continue; 2261769be974SMarcel Holtmann 2262769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 2263769be974SMarcel Holtmann continue; 2264769be974SMarcel Holtmann 22651da177e4SLinus Torvalds num++; 22661da177e4SLinus Torvalds 22671da177e4SLinus Torvalds if (c->sent < min) { 22681da177e4SLinus Torvalds min = c->sent; 22691da177e4SLinus Torvalds conn = c; 22701da177e4SLinus Torvalds } 227152087a79SLuiz Augusto von Dentz 227252087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 227352087a79SLuiz Augusto von Dentz break; 22741da177e4SLinus Torvalds } 22751da177e4SLinus Torvalds 2276bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2277bf4c6325SGustavo F. Padovan 22781da177e4SLinus Torvalds if (conn) { 22796ed58ec5SVille Tervo int cnt, q; 22806ed58ec5SVille Tervo 22816ed58ec5SVille Tervo switch (conn->type) { 22826ed58ec5SVille Tervo case ACL_LINK: 22836ed58ec5SVille Tervo cnt = hdev->acl_cnt; 22846ed58ec5SVille Tervo break; 22856ed58ec5SVille Tervo case SCO_LINK: 22866ed58ec5SVille Tervo case ESCO_LINK: 22876ed58ec5SVille Tervo cnt = hdev->sco_cnt; 22886ed58ec5SVille Tervo break; 22896ed58ec5SVille Tervo case LE_LINK: 22906ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 22916ed58ec5SVille Tervo break; 22926ed58ec5SVille Tervo default: 22936ed58ec5SVille Tervo cnt = 0; 22946ed58ec5SVille Tervo BT_ERR("Unknown link type"); 22956ed58ec5SVille Tervo } 22966ed58ec5SVille Tervo 22976ed58ec5SVille Tervo q = cnt / num; 22981da177e4SLinus Torvalds *quote = q ? q : 1; 22991da177e4SLinus Torvalds } else 23001da177e4SLinus Torvalds *quote = 0; 23011da177e4SLinus Torvalds 23021da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 23031da177e4SLinus Torvalds return conn; 23041da177e4SLinus Torvalds } 23051da177e4SLinus Torvalds 2306bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 23071da177e4SLinus Torvalds { 23081da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 23091da177e4SLinus Torvalds struct hci_conn *c; 23101da177e4SLinus Torvalds 2311bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 23121da177e4SLinus Torvalds 2313bf4c6325SGustavo F. Padovan rcu_read_lock(); 2314bf4c6325SGustavo F. Padovan 23151da177e4SLinus Torvalds /* Kill stalled connections */ 2316bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2317bae1f5d9SVille Tervo if (c->type == type && c->sent) { 2318bae1f5d9SVille Tervo BT_ERR("%s killing stalled connection %s", 23191da177e4SLinus Torvalds hdev->name, batostr(&c->dst)); 23201da177e4SLinus Torvalds hci_acl_disconn(c, 0x13); 23211da177e4SLinus Torvalds } 23221da177e4SLinus Torvalds } 2323bf4c6325SGustavo F. Padovan 2324bf4c6325SGustavo F. Padovan rcu_read_unlock(); 23251da177e4SLinus Torvalds } 23261da177e4SLinus Torvalds 232773d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 232873d80debSLuiz Augusto von Dentz int *quote) 232973d80debSLuiz Augusto von Dentz { 233073d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 233173d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 2332abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 233373d80debSLuiz Augusto von Dentz struct hci_conn *conn; 233473d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 233573d80debSLuiz Augusto von Dentz 233673d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 233773d80debSLuiz Augusto von Dentz 2338bf4c6325SGustavo F. Padovan rcu_read_lock(); 2339bf4c6325SGustavo F. Padovan 2340bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 234173d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 234273d80debSLuiz Augusto von Dentz 234373d80debSLuiz Augusto von Dentz if (conn->type != type) 234473d80debSLuiz Augusto von Dentz continue; 234573d80debSLuiz Augusto von Dentz 234673d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 234773d80debSLuiz Augusto von Dentz continue; 234873d80debSLuiz Augusto von Dentz 234973d80debSLuiz Augusto von Dentz conn_num++; 235073d80debSLuiz Augusto von Dentz 23518192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 235273d80debSLuiz Augusto von Dentz struct sk_buff *skb; 235373d80debSLuiz Augusto von Dentz 235473d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 235573d80debSLuiz Augusto von Dentz continue; 235673d80debSLuiz Augusto von Dentz 235773d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 235873d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 235973d80debSLuiz Augusto von Dentz continue; 236073d80debSLuiz Augusto von Dentz 236173d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 236273d80debSLuiz Augusto von Dentz num = 0; 236373d80debSLuiz Augusto von Dentz min = ~0; 236473d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 236573d80debSLuiz Augusto von Dentz } 236673d80debSLuiz Augusto von Dentz 236773d80debSLuiz Augusto von Dentz num++; 236873d80debSLuiz Augusto von Dentz 236973d80debSLuiz Augusto von Dentz if (conn->sent < min) { 237073d80debSLuiz Augusto von Dentz min = conn->sent; 237173d80debSLuiz Augusto von Dentz chan = tmp; 237273d80debSLuiz Augusto von Dentz } 237373d80debSLuiz Augusto von Dentz } 237473d80debSLuiz Augusto von Dentz 237573d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 237673d80debSLuiz Augusto von Dentz break; 237773d80debSLuiz Augusto von Dentz } 237873d80debSLuiz Augusto von Dentz 2379bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2380bf4c6325SGustavo F. Padovan 238173d80debSLuiz Augusto von Dentz if (!chan) 238273d80debSLuiz Augusto von Dentz return NULL; 238373d80debSLuiz Augusto von Dentz 238473d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 238573d80debSLuiz Augusto von Dentz case ACL_LINK: 238673d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 238773d80debSLuiz Augusto von Dentz break; 238873d80debSLuiz Augusto von Dentz case SCO_LINK: 238973d80debSLuiz Augusto von Dentz case ESCO_LINK: 239073d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 239173d80debSLuiz Augusto von Dentz break; 239273d80debSLuiz Augusto von Dentz case LE_LINK: 239373d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 239473d80debSLuiz Augusto von Dentz break; 239573d80debSLuiz Augusto von Dentz default: 239673d80debSLuiz Augusto von Dentz cnt = 0; 239773d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 239873d80debSLuiz Augusto von Dentz } 239973d80debSLuiz Augusto von Dentz 240073d80debSLuiz Augusto von Dentz q = cnt / num; 240173d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 240273d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 240373d80debSLuiz Augusto von Dentz return chan; 240473d80debSLuiz Augusto von Dentz } 240573d80debSLuiz Augusto von Dentz 240602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 240702b20f0bSLuiz Augusto von Dentz { 240802b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 240902b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 241002b20f0bSLuiz Augusto von Dentz int num = 0; 241102b20f0bSLuiz Augusto von Dentz 241202b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 241302b20f0bSLuiz Augusto von Dentz 2414bf4c6325SGustavo F. Padovan rcu_read_lock(); 2415bf4c6325SGustavo F. Padovan 2416bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 241702b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 241802b20f0bSLuiz Augusto von Dentz 241902b20f0bSLuiz Augusto von Dentz if (conn->type != type) 242002b20f0bSLuiz Augusto von Dentz continue; 242102b20f0bSLuiz Augusto von Dentz 242202b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 242302b20f0bSLuiz Augusto von Dentz continue; 242402b20f0bSLuiz Augusto von Dentz 242502b20f0bSLuiz Augusto von Dentz num++; 242602b20f0bSLuiz Augusto von Dentz 24278192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 242802b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 242902b20f0bSLuiz Augusto von Dentz 243002b20f0bSLuiz Augusto von Dentz if (chan->sent) { 243102b20f0bSLuiz Augusto von Dentz chan->sent = 0; 243202b20f0bSLuiz Augusto von Dentz continue; 243302b20f0bSLuiz Augusto von Dentz } 243402b20f0bSLuiz Augusto von Dentz 243502b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 243602b20f0bSLuiz Augusto von Dentz continue; 243702b20f0bSLuiz Augusto von Dentz 243802b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 243902b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 244002b20f0bSLuiz Augusto von Dentz continue; 244102b20f0bSLuiz Augusto von Dentz 244202b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 244302b20f0bSLuiz Augusto von Dentz 244402b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 244502b20f0bSLuiz Augusto von Dentz skb->priority); 244602b20f0bSLuiz Augusto von Dentz } 244702b20f0bSLuiz Augusto von Dentz 244802b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 244902b20f0bSLuiz Augusto von Dentz break; 245002b20f0bSLuiz Augusto von Dentz } 2451bf4c6325SGustavo F. Padovan 2452bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2453bf4c6325SGustavo F. Padovan 245402b20f0bSLuiz Augusto von Dentz } 245502b20f0bSLuiz Augusto von Dentz 2456b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 2457b71d385aSAndrei Emeltchenko { 2458b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 2459b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 2460b71d385aSAndrei Emeltchenko } 2461b71d385aSAndrei Emeltchenko 246263d2bc1bSAndrei Emeltchenko static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 24631da177e4SLinus Torvalds { 24641da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 24651da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 24661da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 246763d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 2468cc48dc0aSAndrei Emeltchenko msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) 2469bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 24701da177e4SLinus Torvalds } 247163d2bc1bSAndrei Emeltchenko } 24721da177e4SLinus Torvalds 247363d2bc1bSAndrei Emeltchenko static inline void hci_sched_acl_pkt(struct hci_dev *hdev) 247463d2bc1bSAndrei Emeltchenko { 247563d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 247663d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 247763d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 247863d2bc1bSAndrei Emeltchenko int quote; 247963d2bc1bSAndrei Emeltchenko 248063d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 248104837f64SMarcel Holtmann 248273d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 248373d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2484ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2485ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 248673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 248773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 248873d80debSLuiz Augusto von Dentz 2489ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2490ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2491ec1cce24SLuiz Augusto von Dentz break; 2492ec1cce24SLuiz Augusto von Dentz 2493ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2494ec1cce24SLuiz Augusto von Dentz 249573d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 249673d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 249704837f64SMarcel Holtmann 24981da177e4SLinus Torvalds hci_send_frame(skb); 24991da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 25001da177e4SLinus Torvalds 25011da177e4SLinus Torvalds hdev->acl_cnt--; 250273d80debSLuiz Augusto von Dentz chan->sent++; 250373d80debSLuiz Augusto von Dentz chan->conn->sent++; 25041da177e4SLinus Torvalds } 25051da177e4SLinus Torvalds } 250602b20f0bSLuiz Augusto von Dentz 250702b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 250802b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 25091da177e4SLinus Torvalds } 25101da177e4SLinus Torvalds 2511b71d385aSAndrei Emeltchenko static inline void hci_sched_acl_blk(struct hci_dev *hdev) 2512b71d385aSAndrei Emeltchenko { 251363d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 2514b71d385aSAndrei Emeltchenko struct hci_chan *chan; 2515b71d385aSAndrei Emeltchenko struct sk_buff *skb; 2516b71d385aSAndrei Emeltchenko int quote; 2517b71d385aSAndrei Emeltchenko 251863d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 2519b71d385aSAndrei Emeltchenko 2520b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 2521b71d385aSAndrei Emeltchenko (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2522b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 2523b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 2524b71d385aSAndrei Emeltchenko int blocks; 2525b71d385aSAndrei Emeltchenko 2526b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 2527b71d385aSAndrei Emeltchenko skb->len, skb->priority); 2528b71d385aSAndrei Emeltchenko 2529b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 2530b71d385aSAndrei Emeltchenko if (skb->priority < priority) 2531b71d385aSAndrei Emeltchenko break; 2532b71d385aSAndrei Emeltchenko 2533b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 2534b71d385aSAndrei Emeltchenko 2535b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 2536b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 2537b71d385aSAndrei Emeltchenko return; 2538b71d385aSAndrei Emeltchenko 2539b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 2540b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 2541b71d385aSAndrei Emeltchenko 2542b71d385aSAndrei Emeltchenko hci_send_frame(skb); 2543b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 2544b71d385aSAndrei Emeltchenko 2545b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 2546b71d385aSAndrei Emeltchenko quote -= blocks; 2547b71d385aSAndrei Emeltchenko 2548b71d385aSAndrei Emeltchenko chan->sent += blocks; 2549b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 2550b71d385aSAndrei Emeltchenko } 2551b71d385aSAndrei Emeltchenko } 2552b71d385aSAndrei Emeltchenko 2553b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 2554b71d385aSAndrei Emeltchenko hci_prio_recalculate(hdev, ACL_LINK); 2555b71d385aSAndrei Emeltchenko } 2556b71d385aSAndrei Emeltchenko 2557b71d385aSAndrei Emeltchenko static inline void hci_sched_acl(struct hci_dev *hdev) 2558b71d385aSAndrei Emeltchenko { 2559b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 2560b71d385aSAndrei Emeltchenko 2561b71d385aSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK)) 2562b71d385aSAndrei Emeltchenko return; 2563b71d385aSAndrei Emeltchenko 2564b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 2565b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 2566b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 2567b71d385aSAndrei Emeltchenko break; 2568b71d385aSAndrei Emeltchenko 2569b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 2570b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 2571b71d385aSAndrei Emeltchenko break; 2572b71d385aSAndrei Emeltchenko } 2573b71d385aSAndrei Emeltchenko } 2574b71d385aSAndrei Emeltchenko 25751da177e4SLinus Torvalds /* Schedule SCO */ 25761da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev) 25771da177e4SLinus Torvalds { 25781da177e4SLinus Torvalds struct hci_conn *conn; 25791da177e4SLinus Torvalds struct sk_buff *skb; 25801da177e4SLinus Torvalds int quote; 25811da177e4SLinus Torvalds 25821da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 25831da177e4SLinus Torvalds 258452087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 258552087a79SLuiz Augusto von Dentz return; 258652087a79SLuiz Augusto von Dentz 25871da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 25881da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 25891da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 25901da177e4SLinus Torvalds hci_send_frame(skb); 25911da177e4SLinus Torvalds 25921da177e4SLinus Torvalds conn->sent++; 25931da177e4SLinus Torvalds if (conn->sent == ~0) 25941da177e4SLinus Torvalds conn->sent = 0; 25951da177e4SLinus Torvalds } 25961da177e4SLinus Torvalds } 25971da177e4SLinus Torvalds } 25981da177e4SLinus Torvalds 2599b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev) 2600b6a0dc82SMarcel Holtmann { 2601b6a0dc82SMarcel Holtmann struct hci_conn *conn; 2602b6a0dc82SMarcel Holtmann struct sk_buff *skb; 2603b6a0dc82SMarcel Holtmann int quote; 2604b6a0dc82SMarcel Holtmann 2605b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 2606b6a0dc82SMarcel Holtmann 260752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 260852087a79SLuiz Augusto von Dentz return; 260952087a79SLuiz Augusto von Dentz 2610b6a0dc82SMarcel Holtmann while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, "e))) { 2611b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 2612b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 2613b6a0dc82SMarcel Holtmann hci_send_frame(skb); 2614b6a0dc82SMarcel Holtmann 2615b6a0dc82SMarcel Holtmann conn->sent++; 2616b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 2617b6a0dc82SMarcel Holtmann conn->sent = 0; 2618b6a0dc82SMarcel Holtmann } 2619b6a0dc82SMarcel Holtmann } 2620b6a0dc82SMarcel Holtmann } 2621b6a0dc82SMarcel Holtmann 26226ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev) 26236ed58ec5SVille Tervo { 262473d80debSLuiz Augusto von Dentz struct hci_chan *chan; 26256ed58ec5SVille Tervo struct sk_buff *skb; 262602b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 26276ed58ec5SVille Tervo 26286ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 26296ed58ec5SVille Tervo 263052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 263152087a79SLuiz Augusto von Dentz return; 263252087a79SLuiz Augusto von Dentz 26336ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 26346ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 26356ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 2636bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 26376ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 2638bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 26396ed58ec5SVille Tervo } 26406ed58ec5SVille Tervo 26416ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 264202b20f0bSLuiz Augusto von Dentz tmp = cnt; 264373d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 2644ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2645ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 264673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 264773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 26486ed58ec5SVille Tervo 2649ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2650ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2651ec1cce24SLuiz Augusto von Dentz break; 2652ec1cce24SLuiz Augusto von Dentz 2653ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2654ec1cce24SLuiz Augusto von Dentz 26556ed58ec5SVille Tervo hci_send_frame(skb); 26566ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 26576ed58ec5SVille Tervo 26586ed58ec5SVille Tervo cnt--; 265973d80debSLuiz Augusto von Dentz chan->sent++; 266073d80debSLuiz Augusto von Dentz chan->conn->sent++; 26616ed58ec5SVille Tervo } 26626ed58ec5SVille Tervo } 266373d80debSLuiz Augusto von Dentz 26646ed58ec5SVille Tervo if (hdev->le_pkts) 26656ed58ec5SVille Tervo hdev->le_cnt = cnt; 26666ed58ec5SVille Tervo else 26676ed58ec5SVille Tervo hdev->acl_cnt = cnt; 266802b20f0bSLuiz Augusto von Dentz 266902b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 267002b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 26716ed58ec5SVille Tervo } 26726ed58ec5SVille Tervo 26733eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 26741da177e4SLinus Torvalds { 26753eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 26761da177e4SLinus Torvalds struct sk_buff *skb; 26771da177e4SLinus Torvalds 26786ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 26796ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 26801da177e4SLinus Torvalds 26811da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 26821da177e4SLinus Torvalds 26831da177e4SLinus Torvalds hci_sched_acl(hdev); 26841da177e4SLinus Torvalds 26851da177e4SLinus Torvalds hci_sched_sco(hdev); 26861da177e4SLinus Torvalds 2687b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 2688b6a0dc82SMarcel Holtmann 26896ed58ec5SVille Tervo hci_sched_le(hdev); 26906ed58ec5SVille Tervo 26911da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 26921da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 26931da177e4SLinus Torvalds hci_send_frame(skb); 26941da177e4SLinus Torvalds } 26951da177e4SLinus Torvalds 269625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 26971da177e4SLinus Torvalds 26981da177e4SLinus Torvalds /* ACL data packet */ 26991da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 27001da177e4SLinus Torvalds { 27011da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 27021da177e4SLinus Torvalds struct hci_conn *conn; 27031da177e4SLinus Torvalds __u16 handle, flags; 27041da177e4SLinus Torvalds 27051da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 27061da177e4SLinus Torvalds 27071da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 27081da177e4SLinus Torvalds flags = hci_flags(handle); 27091da177e4SLinus Torvalds handle = hci_handle(handle); 27101da177e4SLinus Torvalds 27111da177e4SLinus Torvalds BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags); 27121da177e4SLinus Torvalds 27131da177e4SLinus Torvalds hdev->stat.acl_rx++; 27141da177e4SLinus Torvalds 27151da177e4SLinus Torvalds hci_dev_lock(hdev); 27161da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 27171da177e4SLinus Torvalds hci_dev_unlock(hdev); 27181da177e4SLinus Torvalds 27191da177e4SLinus Torvalds if (conn) { 272065983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 272104837f64SMarcel Holtmann 2722671267bfSJohan Hedberg hci_dev_lock(hdev); 2723671267bfSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags) && 2724671267bfSJohan Hedberg !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 2725671267bfSJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 2726671267bfSJohan Hedberg conn->dst_type, 0, NULL, 0, 2727671267bfSJohan Hedberg conn->dev_class); 2728671267bfSJohan Hedberg hci_dev_unlock(hdev); 2729671267bfSJohan Hedberg 27301da177e4SLinus Torvalds /* Send to upper protocol */ 2731686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 27321da177e4SLinus Torvalds return; 27331da177e4SLinus Torvalds } else { 27341da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 27351da177e4SLinus Torvalds hdev->name, handle); 27361da177e4SLinus Torvalds } 27371da177e4SLinus Torvalds 27381da177e4SLinus Torvalds kfree_skb(skb); 27391da177e4SLinus Torvalds } 27401da177e4SLinus Torvalds 27411da177e4SLinus Torvalds /* SCO data packet */ 27421da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 27431da177e4SLinus Torvalds { 27441da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 27451da177e4SLinus Torvalds struct hci_conn *conn; 27461da177e4SLinus Torvalds __u16 handle; 27471da177e4SLinus Torvalds 27481da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 27491da177e4SLinus Torvalds 27501da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 27511da177e4SLinus Torvalds 27521da177e4SLinus Torvalds BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle); 27531da177e4SLinus Torvalds 27541da177e4SLinus Torvalds hdev->stat.sco_rx++; 27551da177e4SLinus Torvalds 27561da177e4SLinus Torvalds hci_dev_lock(hdev); 27571da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 27581da177e4SLinus Torvalds hci_dev_unlock(hdev); 27591da177e4SLinus Torvalds 27601da177e4SLinus Torvalds if (conn) { 27611da177e4SLinus Torvalds /* Send to upper protocol */ 2762686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 27631da177e4SLinus Torvalds return; 27641da177e4SLinus Torvalds } else { 27651da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 27661da177e4SLinus Torvalds hdev->name, handle); 27671da177e4SLinus Torvalds } 27681da177e4SLinus Torvalds 27691da177e4SLinus Torvalds kfree_skb(skb); 27701da177e4SLinus Torvalds } 27711da177e4SLinus Torvalds 2772b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 27731da177e4SLinus Torvalds { 2774b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 27751da177e4SLinus Torvalds struct sk_buff *skb; 27761da177e4SLinus Torvalds 27771da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 27781da177e4SLinus Torvalds 27791da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 2780cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2781cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2782cd82e61cSMarcel Holtmann 27831da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 27841da177e4SLinus Torvalds /* Send copy to the sockets */ 2785470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 27861da177e4SLinus Torvalds } 27871da177e4SLinus Torvalds 27881da177e4SLinus Torvalds if (test_bit(HCI_RAW, &hdev->flags)) { 27891da177e4SLinus Torvalds kfree_skb(skb); 27901da177e4SLinus Torvalds continue; 27911da177e4SLinus Torvalds } 27921da177e4SLinus Torvalds 27931da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 27941da177e4SLinus Torvalds /* Don't process data packets in this states. */ 27950d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 27961da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 27971da177e4SLinus Torvalds case HCI_SCODATA_PKT: 27981da177e4SLinus Torvalds kfree_skb(skb); 27991da177e4SLinus Torvalds continue; 28003ff50b79SStephen Hemminger } 28011da177e4SLinus Torvalds } 28021da177e4SLinus Torvalds 28031da177e4SLinus Torvalds /* Process frame */ 28040d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 28051da177e4SLinus Torvalds case HCI_EVENT_PKT: 2806b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 28071da177e4SLinus Torvalds hci_event_packet(hdev, skb); 28081da177e4SLinus Torvalds break; 28091da177e4SLinus Torvalds 28101da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 28111da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 28121da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 28131da177e4SLinus Torvalds break; 28141da177e4SLinus Torvalds 28151da177e4SLinus Torvalds case HCI_SCODATA_PKT: 28161da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 28171da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 28181da177e4SLinus Torvalds break; 28191da177e4SLinus Torvalds 28201da177e4SLinus Torvalds default: 28211da177e4SLinus Torvalds kfree_skb(skb); 28221da177e4SLinus Torvalds break; 28231da177e4SLinus Torvalds } 28241da177e4SLinus Torvalds } 28251da177e4SLinus Torvalds } 28261da177e4SLinus Torvalds 2827c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 28281da177e4SLinus Torvalds { 2829c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 28301da177e4SLinus Torvalds struct sk_buff *skb; 28311da177e4SLinus Torvalds 28321da177e4SLinus Torvalds BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); 28331da177e4SLinus Torvalds 28341da177e4SLinus Torvalds /* Send queued commands */ 28355a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 28365a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 28375a08ecceSAndrei Emeltchenko if (!skb) 28385a08ecceSAndrei Emeltchenko return; 28395a08ecceSAndrei Emeltchenko 28401da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 28411da177e4SLinus Torvalds 284270f23020SAndrei Emeltchenko hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC); 284370f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 28441da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 28451da177e4SLinus Torvalds hci_send_frame(skb); 28467bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 28477bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 28487bdb8a5cSSzymon Janc else 28496bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 28506bd32326SVille Tervo jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); 28511da177e4SLinus Torvalds } else { 28521da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 2853c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 28541da177e4SLinus Torvalds } 28551da177e4SLinus Torvalds } 28561da177e4SLinus Torvalds } 28572519a1fcSAndre Guedes 28582519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length) 28592519a1fcSAndre Guedes { 28602519a1fcSAndre Guedes /* General inquiry access code (GIAC) */ 28612519a1fcSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 28622519a1fcSAndre Guedes struct hci_cp_inquiry cp; 28632519a1fcSAndre Guedes 28642519a1fcSAndre Guedes BT_DBG("%s", hdev->name); 28652519a1fcSAndre Guedes 28662519a1fcSAndre Guedes if (test_bit(HCI_INQUIRY, &hdev->flags)) 28672519a1fcSAndre Guedes return -EINPROGRESS; 28682519a1fcSAndre Guedes 28694663262cSJohan Hedberg inquiry_cache_flush(hdev); 28704663262cSJohan Hedberg 28712519a1fcSAndre Guedes memset(&cp, 0, sizeof(cp)); 28722519a1fcSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 28732519a1fcSAndre Guedes cp.length = length; 28742519a1fcSAndre Guedes 28752519a1fcSAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 28762519a1fcSAndre Guedes } 2877023d5049SAndre Guedes 2878023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev) 2879023d5049SAndre Guedes { 2880023d5049SAndre Guedes BT_DBG("%s", hdev->name); 2881023d5049SAndre Guedes 2882023d5049SAndre Guedes if (!test_bit(HCI_INQUIRY, &hdev->flags)) 28837537e5c3SAndre Guedes return -EALREADY; 2884023d5049SAndre Guedes 2885023d5049SAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); 2886023d5049SAndre Guedes } 288731f7956cSAndre Guedes 288831f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type) 288931f7956cSAndre Guedes { 289031f7956cSAndre Guedes switch (bdaddr_type) { 289131f7956cSAndre Guedes case BDADDR_LE_PUBLIC: 289231f7956cSAndre Guedes return ADDR_LE_DEV_PUBLIC; 289331f7956cSAndre Guedes 289431f7956cSAndre Guedes default: 289531f7956cSAndre Guedes /* Fallback to LE Random address type */ 289631f7956cSAndre Guedes return ADDR_LE_DEV_RANDOM; 289731f7956cSAndre Guedes } 289831f7956cSAndre Guedes } 2899