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> 431da177e4SLinus Torvalds #include <linux/notifier.h> 44611b30f7SMarcel Holtmann #include <linux/rfkill.h> 456bd32326SVille Tervo #include <linux/timer.h> 463a0259bbSVinicius Costa Gomes #include <linux/crypto.h> 471da177e4SLinus Torvalds #include <net/sock.h> 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds #include <asm/system.h> 5070f23020SAndrei Emeltchenko #include <linux/uaccess.h> 511da177e4SLinus Torvalds #include <asm/unaligned.h> 521da177e4SLinus Torvalds 531da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 541da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 551da177e4SLinus Torvalds 56ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000 57ab81cbf9SJohan Hedberg 588b281b9cSFabio Estevam bool enable_hs; 597784d78fSAndrei Emeltchenko 60b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 61c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 623eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds /* HCI device list */ 651da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 661da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 671da177e4SLinus Torvalds 681da177e4SLinus Torvalds /* HCI callback list */ 691da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 701da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds /* HCI notifiers list */ 73e041c683SAlan Stern static ATOMIC_NOTIFIER_HEAD(hci_notifier); 741da177e4SLinus Torvalds 751da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds int hci_register_notifier(struct notifier_block *nb) 781da177e4SLinus Torvalds { 79e041c683SAlan Stern return atomic_notifier_chain_register(&hci_notifier, nb); 801da177e4SLinus Torvalds } 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds int hci_unregister_notifier(struct notifier_block *nb) 831da177e4SLinus Torvalds { 84e041c683SAlan Stern return atomic_notifier_chain_unregister(&hci_notifier, nb); 851da177e4SLinus Torvalds } 861da177e4SLinus Torvalds 876516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 881da177e4SLinus Torvalds { 89e041c683SAlan Stern atomic_notifier_call_chain(&hci_notifier, event, hdev); 901da177e4SLinus Torvalds } 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds /* ---- HCI requests ---- */ 931da177e4SLinus Torvalds 9423bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) 951da177e4SLinus Torvalds { 9623bb5763SJohan Hedberg BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result); 9723bb5763SJohan Hedberg 98a5040efaSJohan Hedberg /* If this is the init phase check if the completed command matches 99a5040efaSJohan Hedberg * the last init command, and if not just return. 100a5040efaSJohan Hedberg */ 101a5040efaSJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) 10223bb5763SJohan Hedberg return; 1031da177e4SLinus Torvalds 1041da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 1051da177e4SLinus Torvalds hdev->req_result = result; 1061da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 1071da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 1081da177e4SLinus Torvalds } 1091da177e4SLinus Torvalds } 1101da177e4SLinus Torvalds 1111da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 1121da177e4SLinus Torvalds { 1131da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 1161da177e4SLinus Torvalds hdev->req_result = err; 1171da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 1181da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 1191da177e4SLinus Torvalds } 1201da177e4SLinus Torvalds } 1211da177e4SLinus Torvalds 1221da177e4SLinus Torvalds /* Execute request and wait for completion. */ 1231da177e4SLinus Torvalds static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), 1241da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 1251da177e4SLinus Torvalds { 1261da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 1271da177e4SLinus Torvalds int err = 0; 1281da177e4SLinus Torvalds 1291da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 1301da177e4SLinus Torvalds 1311da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 1321da177e4SLinus Torvalds 1331da177e4SLinus Torvalds add_wait_queue(&hdev->req_wait_q, &wait); 1341da177e4SLinus Torvalds set_current_state(TASK_INTERRUPTIBLE); 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds req(hdev, opt); 1371da177e4SLinus Torvalds schedule_timeout(timeout); 1381da177e4SLinus Torvalds 1391da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds if (signal_pending(current)) 1421da177e4SLinus Torvalds return -EINTR; 1431da177e4SLinus Torvalds 1441da177e4SLinus Torvalds switch (hdev->req_status) { 1451da177e4SLinus Torvalds case HCI_REQ_DONE: 146e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 1471da177e4SLinus Torvalds break; 1481da177e4SLinus Torvalds 1491da177e4SLinus Torvalds case HCI_REQ_CANCELED: 1501da177e4SLinus Torvalds err = -hdev->req_result; 1511da177e4SLinus Torvalds break; 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds default: 1541da177e4SLinus Torvalds err = -ETIMEDOUT; 1551da177e4SLinus Torvalds break; 1563ff50b79SStephen Hemminger } 1571da177e4SLinus Torvalds 158a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 1591da177e4SLinus Torvalds 1601da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 1611da177e4SLinus Torvalds 1621da177e4SLinus Torvalds return err; 1631da177e4SLinus Torvalds } 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), 1661da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 1671da177e4SLinus Torvalds { 1681da177e4SLinus Torvalds int ret; 1691da177e4SLinus Torvalds 1707c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 1717c6a329eSMarcel Holtmann return -ENETDOWN; 1727c6a329eSMarcel Holtmann 1731da177e4SLinus Torvalds /* Serialize all requests */ 1741da177e4SLinus Torvalds hci_req_lock(hdev); 1751da177e4SLinus Torvalds ret = __hci_request(hdev, req, opt, timeout); 1761da177e4SLinus Torvalds hci_req_unlock(hdev); 1771da177e4SLinus Torvalds 1781da177e4SLinus Torvalds return ret; 1791da177e4SLinus Torvalds } 1801da177e4SLinus Torvalds 1811da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) 1821da177e4SLinus Torvalds { 1831da177e4SLinus Torvalds BT_DBG("%s %ld", hdev->name, opt); 1841da177e4SLinus Torvalds 1851da177e4SLinus Torvalds /* Reset device */ 186f630cf0dSGustavo F. Padovan set_bit(HCI_RESET, &hdev->flags); 187a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 1881da177e4SLinus Torvalds } 1891da177e4SLinus Torvalds 190e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev) 1911da177e4SLinus Torvalds { 192b0916ea0SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 1931ebb9252SMarcel Holtmann __le16 param; 19489f2783dSMarcel Holtmann __u8 flt_type; 1951da177e4SLinus Torvalds 1962455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 1972455a3eaSAndrei Emeltchenko 1981da177e4SLinus Torvalds /* Mandatory initialization */ 1991da177e4SLinus Torvalds 2001da177e4SLinus Torvalds /* Reset */ 201f630cf0dSGustavo F. Padovan if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { 202f630cf0dSGustavo F. Padovan set_bit(HCI_RESET, &hdev->flags); 203a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 204f630cf0dSGustavo F. Padovan } 2051da177e4SLinus Torvalds 2061da177e4SLinus Torvalds /* Read Local Supported Features */ 207a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 2081da177e4SLinus Torvalds 2091143e5a6SMarcel Holtmann /* Read Local Version */ 210a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2111143e5a6SMarcel Holtmann 2121da177e4SLinus Torvalds /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 213a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 2141da177e4SLinus Torvalds 2151da177e4SLinus Torvalds /* Read BD Address */ 216a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); 217a9de9248SMarcel Holtmann 218a9de9248SMarcel Holtmann /* Read Class of Device */ 219a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 220a9de9248SMarcel Holtmann 221a9de9248SMarcel Holtmann /* Read Local Name */ 222a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); 2231da177e4SLinus Torvalds 2241da177e4SLinus Torvalds /* Read Voice Setting */ 225a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); 2261da177e4SLinus Torvalds 2271da177e4SLinus Torvalds /* Optional initialization */ 2281da177e4SLinus Torvalds 2291da177e4SLinus Torvalds /* Clear Event Filters */ 23089f2783dSMarcel Holtmann flt_type = HCI_FLT_CLEAR_ALL; 231a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 2321da177e4SLinus Torvalds 2331da177e4SLinus Torvalds /* Connection accept timeout ~20 secs */ 234aca3192cSYOSHIFUJI Hideaki param = cpu_to_le16(0x7d00); 235a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 236b0916ea0SJohan Hedberg 237b0916ea0SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 238b0916ea0SJohan Hedberg cp.delete_all = 1; 239b0916ea0SJohan Hedberg hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); 2401da177e4SLinus Torvalds } 2411da177e4SLinus Torvalds 242e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev) 243e61ef499SAndrei Emeltchenko { 2442455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 2452455a3eaSAndrei Emeltchenko 246e61ef499SAndrei Emeltchenko /* Reset */ 247e61ef499SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 248e61ef499SAndrei Emeltchenko 249e61ef499SAndrei Emeltchenko /* Read Local Version */ 250e61ef499SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 251e61ef499SAndrei Emeltchenko } 252e61ef499SAndrei Emeltchenko 253e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt) 254e61ef499SAndrei Emeltchenko { 255e61ef499SAndrei Emeltchenko struct sk_buff *skb; 256e61ef499SAndrei Emeltchenko 257e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 258e61ef499SAndrei Emeltchenko 259e61ef499SAndrei Emeltchenko /* Driver initialization */ 260e61ef499SAndrei Emeltchenko 261e61ef499SAndrei Emeltchenko /* Special commands */ 262e61ef499SAndrei Emeltchenko while ((skb = skb_dequeue(&hdev->driver_init))) { 263e61ef499SAndrei Emeltchenko bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 264e61ef499SAndrei Emeltchenko skb->dev = (void *) hdev; 265e61ef499SAndrei Emeltchenko 266e61ef499SAndrei Emeltchenko skb_queue_tail(&hdev->cmd_q, skb); 267e61ef499SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->cmd_work); 268e61ef499SAndrei Emeltchenko } 269e61ef499SAndrei Emeltchenko skb_queue_purge(&hdev->driver_init); 270e61ef499SAndrei Emeltchenko 271e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 272e61ef499SAndrei Emeltchenko case HCI_BREDR: 273e61ef499SAndrei Emeltchenko bredr_init(hdev); 274e61ef499SAndrei Emeltchenko break; 275e61ef499SAndrei Emeltchenko 276e61ef499SAndrei Emeltchenko case HCI_AMP: 277e61ef499SAndrei Emeltchenko amp_init(hdev); 278e61ef499SAndrei Emeltchenko break; 279e61ef499SAndrei Emeltchenko 280e61ef499SAndrei Emeltchenko default: 281e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 282e61ef499SAndrei Emeltchenko break; 283e61ef499SAndrei Emeltchenko } 284e61ef499SAndrei Emeltchenko 285e61ef499SAndrei Emeltchenko } 286e61ef499SAndrei Emeltchenko 2876ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) 2886ed58ec5SVille Tervo { 2896ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 2906ed58ec5SVille Tervo 2916ed58ec5SVille Tervo /* Read LE buffer size */ 2926ed58ec5SVille Tervo hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 2936ed58ec5SVille Tervo } 2946ed58ec5SVille Tervo 2951da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) 2961da177e4SLinus Torvalds { 2971da177e4SLinus Torvalds __u8 scan = opt; 2981da177e4SLinus Torvalds 2991da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, scan); 3001da177e4SLinus Torvalds 3011da177e4SLinus Torvalds /* Inquiry and Page scans */ 302a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 3031da177e4SLinus Torvalds } 3041da177e4SLinus Torvalds 3051da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt) 3061da177e4SLinus Torvalds { 3071da177e4SLinus Torvalds __u8 auth = opt; 3081da177e4SLinus Torvalds 3091da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, auth); 3101da177e4SLinus Torvalds 3111da177e4SLinus Torvalds /* Authentication */ 312a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 3131da177e4SLinus Torvalds } 3141da177e4SLinus Torvalds 3151da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt) 3161da177e4SLinus Torvalds { 3171da177e4SLinus Torvalds __u8 encrypt = opt; 3181da177e4SLinus Torvalds 3191da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, encrypt); 3201da177e4SLinus Torvalds 321e4e8e37cSMarcel Holtmann /* Encryption */ 322a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 3231da177e4SLinus Torvalds } 3241da177e4SLinus Torvalds 325e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt) 326e4e8e37cSMarcel Holtmann { 327e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 328e4e8e37cSMarcel Holtmann 329a418b893SMarcel Holtmann BT_DBG("%s %x", hdev->name, policy); 330e4e8e37cSMarcel Holtmann 331e4e8e37cSMarcel Holtmann /* Default link policy */ 332e4e8e37cSMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 333e4e8e37cSMarcel Holtmann } 334e4e8e37cSMarcel Holtmann 3351da177e4SLinus Torvalds /* Get HCI device by index. 3361da177e4SLinus Torvalds * Device is held on return. */ 3371da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 3381da177e4SLinus Torvalds { 3398035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 3401da177e4SLinus Torvalds 3411da177e4SLinus Torvalds BT_DBG("%d", index); 3421da177e4SLinus Torvalds 3431da177e4SLinus Torvalds if (index < 0) 3441da177e4SLinus Torvalds return NULL; 3451da177e4SLinus Torvalds 3461da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 3478035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 3481da177e4SLinus Torvalds if (d->id == index) { 3491da177e4SLinus Torvalds hdev = hci_dev_hold(d); 3501da177e4SLinus Torvalds break; 3511da177e4SLinus Torvalds } 3521da177e4SLinus Torvalds } 3531da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 3541da177e4SLinus Torvalds return hdev; 3551da177e4SLinus Torvalds } 3561da177e4SLinus Torvalds 3571da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 358ff9ef578SJohan Hedberg 35930dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 36030dc78e1SJohan Hedberg { 36130dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 36230dc78e1SJohan Hedberg 36330dc78e1SJohan Hedberg if (discov->state == DISCOVERY_INQUIRY || 36430dc78e1SJohan Hedberg discov->state == DISCOVERY_RESOLVING) 36530dc78e1SJohan Hedberg return true; 36630dc78e1SJohan Hedberg 36730dc78e1SJohan Hedberg return false; 36830dc78e1SJohan Hedberg } 36930dc78e1SJohan Hedberg 370ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 371ff9ef578SJohan Hedberg { 372ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 373ff9ef578SJohan Hedberg 374ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 375ff9ef578SJohan Hedberg return; 376ff9ef578SJohan Hedberg 377ff9ef578SJohan Hedberg switch (state) { 378ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 379ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 380ff9ef578SJohan Hedberg break; 381ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 382ff9ef578SJohan Hedberg break; 38330dc78e1SJohan Hedberg case DISCOVERY_INQUIRY: 384ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 385ff9ef578SJohan Hedberg break; 38630dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 38730dc78e1SJohan Hedberg break; 388ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 389ff9ef578SJohan Hedberg break; 390ff9ef578SJohan Hedberg } 391ff9ef578SJohan Hedberg 392ff9ef578SJohan Hedberg hdev->discovery.state = state; 393ff9ef578SJohan Hedberg } 394ff9ef578SJohan Hedberg 3951da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev) 3961da177e4SLinus Torvalds { 39730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 398b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 3991da177e4SLinus Torvalds 400561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 401561aafbcSJohan Hedberg list_del(&p->all); 402b57c1a56SJohan Hedberg kfree(p); 4031da177e4SLinus Torvalds } 404561aafbcSJohan Hedberg 405561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 406561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 407ff9ef578SJohan Hedberg cache->state = DISCOVERY_STOPPED; 4081da177e4SLinus Torvalds } 4091da177e4SLinus Torvalds 4101da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 4111da177e4SLinus Torvalds { 41230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 4131da177e4SLinus Torvalds struct inquiry_entry *e; 4141da177e4SLinus Torvalds 4151da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 4161da177e4SLinus Torvalds 417561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 4181da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 4191da177e4SLinus Torvalds return e; 4201da177e4SLinus Torvalds } 4211da177e4SLinus Torvalds 422b57c1a56SJohan Hedberg return NULL; 423b57c1a56SJohan Hedberg } 424b57c1a56SJohan Hedberg 425561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 426561aafbcSJohan Hedberg bdaddr_t *bdaddr) 427561aafbcSJohan Hedberg { 42830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 429561aafbcSJohan Hedberg struct inquiry_entry *e; 430561aafbcSJohan Hedberg 431561aafbcSJohan Hedberg BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 432561aafbcSJohan Hedberg 433561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 434561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 435561aafbcSJohan Hedberg return e; 436561aafbcSJohan Hedberg } 437561aafbcSJohan Hedberg 438561aafbcSJohan Hedberg return NULL; 439561aafbcSJohan Hedberg } 440561aafbcSJohan Hedberg 44130dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 44230dc78e1SJohan Hedberg bdaddr_t *bdaddr, 44330dc78e1SJohan Hedberg int state) 44430dc78e1SJohan Hedberg { 44530dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 44630dc78e1SJohan Hedberg struct inquiry_entry *e; 44730dc78e1SJohan Hedberg 44830dc78e1SJohan Hedberg BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state); 44930dc78e1SJohan Hedberg 45030dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 45130dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 45230dc78e1SJohan Hedberg return e; 45330dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 45430dc78e1SJohan Hedberg return e; 45530dc78e1SJohan Hedberg } 45630dc78e1SJohan Hedberg 45730dc78e1SJohan Hedberg return NULL; 45830dc78e1SJohan Hedberg } 45930dc78e1SJohan Hedberg 460a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 461a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 462a3d4e20aSJohan Hedberg { 463a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 464a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 465a3d4e20aSJohan Hedberg struct inquiry_entry *p; 466a3d4e20aSJohan Hedberg 467a3d4e20aSJohan Hedberg list_del(&ie->list); 468a3d4e20aSJohan Hedberg 469a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 470a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 471a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 472a3d4e20aSJohan Hedberg break; 473a3d4e20aSJohan Hedberg pos = &p->list; 474a3d4e20aSJohan Hedberg } 475a3d4e20aSJohan Hedberg 476a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 477a3d4e20aSJohan Hedberg } 478a3d4e20aSJohan Hedberg 4793175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 480561aafbcSJohan Hedberg bool name_known) 4811da177e4SLinus Torvalds { 48230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 48370f23020SAndrei Emeltchenko struct inquiry_entry *ie; 4841da177e4SLinus Torvalds 4851da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr)); 4861da177e4SLinus Torvalds 48770f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 488a3d4e20aSJohan Hedberg if (ie) { 489a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 490a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 491a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 492a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 493a3d4e20aSJohan Hedberg } 494a3d4e20aSJohan Hedberg 495561aafbcSJohan Hedberg goto update; 496a3d4e20aSJohan Hedberg } 497561aafbcSJohan Hedberg 4981da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 49970f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 50070f23020SAndrei Emeltchenko if (!ie) 5013175405bSJohan Hedberg return false; 50270f23020SAndrei Emeltchenko 503561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 504561aafbcSJohan Hedberg 505561aafbcSJohan Hedberg if (name_known) { 506561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 507561aafbcSJohan Hedberg } else { 508561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 509561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 510561aafbcSJohan Hedberg } 511561aafbcSJohan Hedberg 512561aafbcSJohan Hedberg update: 513561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 514561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 515561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 516561aafbcSJohan Hedberg list_del(&ie->list); 5171da177e4SLinus Torvalds } 5181da177e4SLinus Torvalds 51970f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 52070f23020SAndrei Emeltchenko ie->timestamp = jiffies; 5211da177e4SLinus Torvalds cache->timestamp = jiffies; 5223175405bSJohan Hedberg 5233175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 5243175405bSJohan Hedberg return false; 5253175405bSJohan Hedberg 5263175405bSJohan Hedberg return true; 5271da177e4SLinus Torvalds } 5281da177e4SLinus Torvalds 5291da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 5301da177e4SLinus Torvalds { 53130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 5321da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 5331da177e4SLinus Torvalds struct inquiry_entry *e; 5341da177e4SLinus Torvalds int copied = 0; 5351da177e4SLinus Torvalds 536561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 5371da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 538b57c1a56SJohan Hedberg 539b57c1a56SJohan Hedberg if (copied >= num) 540b57c1a56SJohan Hedberg break; 541b57c1a56SJohan Hedberg 5421da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 5431da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 5441da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 5451da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 5461da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 5471da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 548b57c1a56SJohan Hedberg 5491da177e4SLinus Torvalds info++; 550b57c1a56SJohan Hedberg copied++; 5511da177e4SLinus Torvalds } 5521da177e4SLinus Torvalds 5531da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 5541da177e4SLinus Torvalds return copied; 5551da177e4SLinus Torvalds } 5561da177e4SLinus Torvalds 5571da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt) 5581da177e4SLinus Torvalds { 5591da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 5601da177e4SLinus Torvalds struct hci_cp_inquiry cp; 5611da177e4SLinus Torvalds 5621da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 5631da177e4SLinus Torvalds 5641da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 5651da177e4SLinus Torvalds return; 5661da177e4SLinus Torvalds 5671da177e4SLinus Torvalds /* Start Inquiry */ 5681da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 5691da177e4SLinus Torvalds cp.length = ir->length; 5701da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 571a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 5721da177e4SLinus Torvalds } 5731da177e4SLinus Torvalds 5741da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 5751da177e4SLinus Torvalds { 5761da177e4SLinus Torvalds __u8 __user *ptr = arg; 5771da177e4SLinus Torvalds struct hci_inquiry_req ir; 5781da177e4SLinus Torvalds struct hci_dev *hdev; 5791da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 5801da177e4SLinus Torvalds long timeo; 5811da177e4SLinus Torvalds __u8 *buf; 5821da177e4SLinus Torvalds 5831da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 5841da177e4SLinus Torvalds return -EFAULT; 5851da177e4SLinus Torvalds 5865a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 5875a08ecceSAndrei Emeltchenko if (!hdev) 5881da177e4SLinus Torvalds return -ENODEV; 5891da177e4SLinus Torvalds 59009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 5911da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 5921da177e4SLinus Torvalds inquiry_cache_empty(hdev) || 5931da177e4SLinus Torvalds ir.flags & IREQ_CACHE_FLUSH) { 5941da177e4SLinus Torvalds inquiry_cache_flush(hdev); 5951da177e4SLinus Torvalds do_inquiry = 1; 5961da177e4SLinus Torvalds } 59709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 5981da177e4SLinus Torvalds 59904837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 60070f23020SAndrei Emeltchenko 60170f23020SAndrei Emeltchenko if (do_inquiry) { 60270f23020SAndrei Emeltchenko err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo); 60370f23020SAndrei Emeltchenko if (err < 0) 6041da177e4SLinus Torvalds goto done; 60570f23020SAndrei Emeltchenko } 6061da177e4SLinus Torvalds 6071da177e4SLinus Torvalds /* for unlimited number of responses we will use buffer with 255 entries */ 6081da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 6091da177e4SLinus Torvalds 6101da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 6111da177e4SLinus Torvalds * copy it to the user space. 6121da177e4SLinus Torvalds */ 61370f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 61470f23020SAndrei Emeltchenko if (!buf) { 6151da177e4SLinus Torvalds err = -ENOMEM; 6161da177e4SLinus Torvalds goto done; 6171da177e4SLinus Torvalds } 6181da177e4SLinus Torvalds 61909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 6201da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 62109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 6221da177e4SLinus Torvalds 6231da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 6241da177e4SLinus Torvalds 6251da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 6261da177e4SLinus Torvalds ptr += sizeof(ir); 6271da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 6281da177e4SLinus Torvalds ir.num_rsp)) 6291da177e4SLinus Torvalds err = -EFAULT; 6301da177e4SLinus Torvalds } else 6311da177e4SLinus Torvalds err = -EFAULT; 6321da177e4SLinus Torvalds 6331da177e4SLinus Torvalds kfree(buf); 6341da177e4SLinus Torvalds 6351da177e4SLinus Torvalds done: 6361da177e4SLinus Torvalds hci_dev_put(hdev); 6371da177e4SLinus Torvalds return err; 6381da177e4SLinus Torvalds } 6391da177e4SLinus Torvalds 6401da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */ 6411da177e4SLinus Torvalds 6421da177e4SLinus Torvalds int hci_dev_open(__u16 dev) 6431da177e4SLinus Torvalds { 6441da177e4SLinus Torvalds struct hci_dev *hdev; 6451da177e4SLinus Torvalds int ret = 0; 6461da177e4SLinus Torvalds 6475a08ecceSAndrei Emeltchenko hdev = hci_dev_get(dev); 6485a08ecceSAndrei Emeltchenko if (!hdev) 6491da177e4SLinus Torvalds return -ENODEV; 6501da177e4SLinus Torvalds 6511da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 6521da177e4SLinus Torvalds 6531da177e4SLinus Torvalds hci_req_lock(hdev); 6541da177e4SLinus Torvalds 655611b30f7SMarcel Holtmann if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { 656611b30f7SMarcel Holtmann ret = -ERFKILL; 657611b30f7SMarcel Holtmann goto done; 658611b30f7SMarcel Holtmann } 659611b30f7SMarcel Holtmann 6601da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 6611da177e4SLinus Torvalds ret = -EALREADY; 6621da177e4SLinus Torvalds goto done; 6631da177e4SLinus Torvalds } 6641da177e4SLinus Torvalds 6651da177e4SLinus Torvalds if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 6661da177e4SLinus Torvalds set_bit(HCI_RAW, &hdev->flags); 6671da177e4SLinus Torvalds 66807e3b94aSAndrei Emeltchenko /* Treat all non BR/EDR controllers as raw devices if 66907e3b94aSAndrei Emeltchenko enable_hs is not set */ 67007e3b94aSAndrei Emeltchenko if (hdev->dev_type != HCI_BREDR && !enable_hs) 671943da25dSMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 672943da25dSMarcel Holtmann 6731da177e4SLinus Torvalds if (hdev->open(hdev)) { 6741da177e4SLinus Torvalds ret = -EIO; 6751da177e4SLinus Torvalds goto done; 6761da177e4SLinus Torvalds } 6771da177e4SLinus Torvalds 6781da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 6791da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 6801da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 681a5040efaSJohan Hedberg hdev->init_last_cmd = 0; 6821da177e4SLinus Torvalds 68304837f64SMarcel Holtmann ret = __hci_request(hdev, hci_init_req, 0, 68404837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 6851da177e4SLinus Torvalds 686eead27daSAndre Guedes if (lmp_host_le_capable(hdev)) 6876ed58ec5SVille Tervo ret = __hci_request(hdev, hci_le_init_req, 0, 6886ed58ec5SVille Tervo msecs_to_jiffies(HCI_INIT_TIMEOUT)); 6896ed58ec5SVille Tervo 6901da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 6911da177e4SLinus Torvalds } 6921da177e4SLinus Torvalds 6931da177e4SLinus Torvalds if (!ret) { 6941da177e4SLinus Torvalds hci_dev_hold(hdev); 6951da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 6961da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 697a8b2d5c2SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 69809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 699744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 70009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 70156e5cb86SJohan Hedberg } 7021da177e4SLinus Torvalds } else { 7031da177e4SLinus Torvalds /* Init failed, cleanup */ 7043eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 705c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 706b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7071da177e4SLinus Torvalds 7081da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7091da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7101da177e4SLinus Torvalds 7111da177e4SLinus Torvalds if (hdev->flush) 7121da177e4SLinus Torvalds hdev->flush(hdev); 7131da177e4SLinus Torvalds 7141da177e4SLinus Torvalds if (hdev->sent_cmd) { 7151da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 7161da177e4SLinus Torvalds hdev->sent_cmd = NULL; 7171da177e4SLinus Torvalds } 7181da177e4SLinus Torvalds 7191da177e4SLinus Torvalds hdev->close(hdev); 7201da177e4SLinus Torvalds hdev->flags = 0; 7211da177e4SLinus Torvalds } 7221da177e4SLinus Torvalds 7231da177e4SLinus Torvalds done: 7241da177e4SLinus Torvalds hci_req_unlock(hdev); 7251da177e4SLinus Torvalds hci_dev_put(hdev); 7261da177e4SLinus Torvalds return ret; 7271da177e4SLinus Torvalds } 7281da177e4SLinus Torvalds 7291da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 7301da177e4SLinus Torvalds { 7311da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 7321da177e4SLinus Torvalds 7331da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 7341da177e4SLinus Torvalds hci_req_lock(hdev); 7351da177e4SLinus Torvalds 7361da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 737b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 7381da177e4SLinus Torvalds hci_req_unlock(hdev); 7391da177e4SLinus Torvalds return 0; 7401da177e4SLinus Torvalds } 7411da177e4SLinus Torvalds 7423eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 7433eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 744b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7451da177e4SLinus Torvalds 74616ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 747e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 74816ab91abSJohan Hedberg hdev->discov_timeout = 0; 74916ab91abSJohan Hedberg } 75016ab91abSJohan Hedberg 751a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 752e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 7533243553fSJohan Hedberg 754a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 7557d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 7567d78525dSJohan Hedberg 75709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 7581da177e4SLinus Torvalds inquiry_cache_flush(hdev); 7591da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 76009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 7611da177e4SLinus Torvalds 7621da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 7631da177e4SLinus Torvalds 7641da177e4SLinus Torvalds if (hdev->flush) 7651da177e4SLinus Torvalds hdev->flush(hdev); 7661da177e4SLinus Torvalds 7671da177e4SLinus Torvalds /* Reset device */ 7681da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7691da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 7701da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 7711da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 77204837f64SMarcel Holtmann __hci_request(hdev, hci_reset_req, 0, 773cad44c2bSGustavo F. Padovan msecs_to_jiffies(250)); 7741da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7751da177e4SLinus Torvalds } 7761da177e4SLinus Torvalds 777c347b765SGustavo F. Padovan /* flush cmd work */ 778c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 7791da177e4SLinus Torvalds 7801da177e4SLinus Torvalds /* Drop queues */ 7811da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7821da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7831da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 7841da177e4SLinus Torvalds 7851da177e4SLinus Torvalds /* Drop last sent command */ 7861da177e4SLinus Torvalds if (hdev->sent_cmd) { 787b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 7881da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 7891da177e4SLinus Torvalds hdev->sent_cmd = NULL; 7901da177e4SLinus Torvalds } 7911da177e4SLinus Torvalds 7921da177e4SLinus Torvalds /* After this point our queues are empty 7931da177e4SLinus Torvalds * and no tasks are scheduled. */ 7941da177e4SLinus Torvalds hdev->close(hdev); 7951da177e4SLinus Torvalds 79609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 797744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 79809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 7995add6af8SJohan Hedberg 8001da177e4SLinus Torvalds /* Clear flags */ 8011da177e4SLinus Torvalds hdev->flags = 0; 8021da177e4SLinus Torvalds 8031da177e4SLinus Torvalds hci_req_unlock(hdev); 8041da177e4SLinus Torvalds 8051da177e4SLinus Torvalds hci_dev_put(hdev); 8061da177e4SLinus Torvalds return 0; 8071da177e4SLinus Torvalds } 8081da177e4SLinus Torvalds 8091da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 8101da177e4SLinus Torvalds { 8111da177e4SLinus Torvalds struct hci_dev *hdev; 8121da177e4SLinus Torvalds int err; 8131da177e4SLinus Torvalds 81470f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 81570f23020SAndrei Emeltchenko if (!hdev) 8161da177e4SLinus Torvalds return -ENODEV; 8171da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 8181da177e4SLinus Torvalds hci_dev_put(hdev); 8191da177e4SLinus Torvalds return err; 8201da177e4SLinus Torvalds } 8211da177e4SLinus Torvalds 8221da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 8231da177e4SLinus Torvalds { 8241da177e4SLinus Torvalds struct hci_dev *hdev; 8251da177e4SLinus Torvalds int ret = 0; 8261da177e4SLinus Torvalds 82770f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 82870f23020SAndrei Emeltchenko if (!hdev) 8291da177e4SLinus Torvalds return -ENODEV; 8301da177e4SLinus Torvalds 8311da177e4SLinus Torvalds hci_req_lock(hdev); 8321da177e4SLinus Torvalds 8331da177e4SLinus Torvalds if (!test_bit(HCI_UP, &hdev->flags)) 8341da177e4SLinus Torvalds goto done; 8351da177e4SLinus Torvalds 8361da177e4SLinus Torvalds /* Drop queues */ 8371da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 8381da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8391da177e4SLinus Torvalds 84009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 8411da177e4SLinus Torvalds inquiry_cache_flush(hdev); 8421da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 84309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8441da177e4SLinus Torvalds 8451da177e4SLinus Torvalds if (hdev->flush) 8461da177e4SLinus Torvalds hdev->flush(hdev); 8471da177e4SLinus Torvalds 8481da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 8496ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 8501da177e4SLinus Torvalds 8511da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 85204837f64SMarcel Holtmann ret = __hci_request(hdev, hci_reset_req, 0, 85304837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 8541da177e4SLinus Torvalds 8551da177e4SLinus Torvalds done: 8561da177e4SLinus Torvalds hci_req_unlock(hdev); 8571da177e4SLinus Torvalds hci_dev_put(hdev); 8581da177e4SLinus Torvalds return ret; 8591da177e4SLinus Torvalds } 8601da177e4SLinus Torvalds 8611da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 8621da177e4SLinus Torvalds { 8631da177e4SLinus Torvalds struct hci_dev *hdev; 8641da177e4SLinus Torvalds int ret = 0; 8651da177e4SLinus Torvalds 86670f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 86770f23020SAndrei Emeltchenko if (!hdev) 8681da177e4SLinus Torvalds return -ENODEV; 8691da177e4SLinus Torvalds 8701da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 8711da177e4SLinus Torvalds 8721da177e4SLinus Torvalds hci_dev_put(hdev); 8731da177e4SLinus Torvalds 8741da177e4SLinus Torvalds return ret; 8751da177e4SLinus Torvalds } 8761da177e4SLinus Torvalds 8771da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 8781da177e4SLinus Torvalds { 8791da177e4SLinus Torvalds struct hci_dev *hdev; 8801da177e4SLinus Torvalds struct hci_dev_req dr; 8811da177e4SLinus Torvalds int err = 0; 8821da177e4SLinus Torvalds 8831da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 8841da177e4SLinus Torvalds return -EFAULT; 8851da177e4SLinus Torvalds 88670f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 88770f23020SAndrei Emeltchenko if (!hdev) 8881da177e4SLinus Torvalds return -ENODEV; 8891da177e4SLinus Torvalds 8901da177e4SLinus Torvalds switch (cmd) { 8911da177e4SLinus Torvalds case HCISETAUTH: 89204837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 89304837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 8941da177e4SLinus Torvalds break; 8951da177e4SLinus Torvalds 8961da177e4SLinus Torvalds case HCISETENCRYPT: 8971da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 8981da177e4SLinus Torvalds err = -EOPNOTSUPP; 8991da177e4SLinus Torvalds break; 9001da177e4SLinus Torvalds } 9011da177e4SLinus Torvalds 9021da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 9031da177e4SLinus Torvalds /* Auth must be enabled first */ 90404837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 90504837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9061da177e4SLinus Torvalds if (err) 9071da177e4SLinus Torvalds break; 9081da177e4SLinus Torvalds } 9091da177e4SLinus Torvalds 91004837f64SMarcel Holtmann err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, 91104837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9121da177e4SLinus Torvalds break; 9131da177e4SLinus Torvalds 9141da177e4SLinus Torvalds case HCISETSCAN: 91504837f64SMarcel Holtmann err = hci_request(hdev, hci_scan_req, dr.dev_opt, 91604837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9171da177e4SLinus Torvalds break; 9181da177e4SLinus Torvalds 9191da177e4SLinus Torvalds case HCISETLINKPOL: 920e4e8e37cSMarcel Holtmann err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, 921e4e8e37cSMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9221da177e4SLinus Torvalds break; 9231da177e4SLinus Torvalds 9241da177e4SLinus Torvalds case HCISETLINKMODE: 925e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 926e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 927e4e8e37cSMarcel Holtmann break; 928e4e8e37cSMarcel Holtmann 929e4e8e37cSMarcel Holtmann case HCISETPTYPE: 930e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 9311da177e4SLinus Torvalds break; 9321da177e4SLinus Torvalds 9331da177e4SLinus Torvalds case HCISETACLMTU: 9341da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 9351da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 9361da177e4SLinus Torvalds break; 9371da177e4SLinus Torvalds 9381da177e4SLinus Torvalds case HCISETSCOMTU: 9391da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 9401da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 9411da177e4SLinus Torvalds break; 9421da177e4SLinus Torvalds 9431da177e4SLinus Torvalds default: 9441da177e4SLinus Torvalds err = -EINVAL; 9451da177e4SLinus Torvalds break; 9461da177e4SLinus Torvalds } 947e4e8e37cSMarcel Holtmann 9481da177e4SLinus Torvalds hci_dev_put(hdev); 9491da177e4SLinus Torvalds return err; 9501da177e4SLinus Torvalds } 9511da177e4SLinus Torvalds 9521da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 9531da177e4SLinus Torvalds { 9548035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 9551da177e4SLinus Torvalds struct hci_dev_list_req *dl; 9561da177e4SLinus Torvalds struct hci_dev_req *dr; 9571da177e4SLinus Torvalds int n = 0, size, err; 9581da177e4SLinus Torvalds __u16 dev_num; 9591da177e4SLinus Torvalds 9601da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 9611da177e4SLinus Torvalds return -EFAULT; 9621da177e4SLinus Torvalds 9631da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 9641da177e4SLinus Torvalds return -EINVAL; 9651da177e4SLinus Torvalds 9661da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 9671da177e4SLinus Torvalds 96870f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 96970f23020SAndrei Emeltchenko if (!dl) 9701da177e4SLinus Torvalds return -ENOMEM; 9711da177e4SLinus Torvalds 9721da177e4SLinus Torvalds dr = dl->dev_req; 9731da177e4SLinus Torvalds 974f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 9758035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 976a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 977e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 978c542a06cSJohan Hedberg 979a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 980a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 981c542a06cSJohan Hedberg 9821da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 9831da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 984c542a06cSJohan Hedberg 9851da177e4SLinus Torvalds if (++n >= dev_num) 9861da177e4SLinus Torvalds break; 9871da177e4SLinus Torvalds } 988f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 9891da177e4SLinus Torvalds 9901da177e4SLinus Torvalds dl->dev_num = n; 9911da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 9921da177e4SLinus Torvalds 9931da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 9941da177e4SLinus Torvalds kfree(dl); 9951da177e4SLinus Torvalds 9961da177e4SLinus Torvalds return err ? -EFAULT : 0; 9971da177e4SLinus Torvalds } 9981da177e4SLinus Torvalds 9991da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 10001da177e4SLinus Torvalds { 10011da177e4SLinus Torvalds struct hci_dev *hdev; 10021da177e4SLinus Torvalds struct hci_dev_info di; 10031da177e4SLinus Torvalds int err = 0; 10041da177e4SLinus Torvalds 10051da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 10061da177e4SLinus Torvalds return -EFAULT; 10071da177e4SLinus Torvalds 100870f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 100970f23020SAndrei Emeltchenko if (!hdev) 10101da177e4SLinus Torvalds return -ENODEV; 10111da177e4SLinus Torvalds 1012a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 10133243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 1014ab81cbf9SJohan Hedberg 1015a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1016a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1017c542a06cSJohan Hedberg 10181da177e4SLinus Torvalds strcpy(di.name, hdev->name); 10191da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 1020943da25dSMarcel Holtmann di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); 10211da177e4SLinus Torvalds di.flags = hdev->flags; 10221da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 10231da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 10241da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 10251da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 10261da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 10271da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 10281da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 10291da177e4SLinus Torvalds 10301da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 10311da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 10321da177e4SLinus Torvalds 10331da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 10341da177e4SLinus Torvalds err = -EFAULT; 10351da177e4SLinus Torvalds 10361da177e4SLinus Torvalds hci_dev_put(hdev); 10371da177e4SLinus Torvalds 10381da177e4SLinus Torvalds return err; 10391da177e4SLinus Torvalds } 10401da177e4SLinus Torvalds 10411da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 10421da177e4SLinus Torvalds 1043611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 1044611b30f7SMarcel Holtmann { 1045611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 1046611b30f7SMarcel Holtmann 1047611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 1048611b30f7SMarcel Holtmann 1049611b30f7SMarcel Holtmann if (!blocked) 1050611b30f7SMarcel Holtmann return 0; 1051611b30f7SMarcel Holtmann 1052611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 1053611b30f7SMarcel Holtmann 1054611b30f7SMarcel Holtmann return 0; 1055611b30f7SMarcel Holtmann } 1056611b30f7SMarcel Holtmann 1057611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 1058611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 1059611b30f7SMarcel Holtmann }; 1060611b30f7SMarcel Holtmann 10611da177e4SLinus Torvalds /* Alloc HCI device */ 10621da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void) 10631da177e4SLinus Torvalds { 10641da177e4SLinus Torvalds struct hci_dev *hdev; 10651da177e4SLinus Torvalds 106625ea6db0SMarcel Holtmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 10671da177e4SLinus Torvalds if (!hdev) 10681da177e4SLinus Torvalds return NULL; 10691da177e4SLinus Torvalds 10700ac7e700SDavid Herrmann hci_init_sysfs(hdev); 10711da177e4SLinus Torvalds skb_queue_head_init(&hdev->driver_init); 10721da177e4SLinus Torvalds 10731da177e4SLinus Torvalds return hdev; 10741da177e4SLinus Torvalds } 10751da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev); 10761da177e4SLinus Torvalds 10771da177e4SLinus Torvalds /* Free HCI device */ 10781da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev) 10791da177e4SLinus Torvalds { 10801da177e4SLinus Torvalds skb_queue_purge(&hdev->driver_init); 10811da177e4SLinus Torvalds 1082a91f2e39SMarcel Holtmann /* will free via device release */ 1083a91f2e39SMarcel Holtmann put_device(&hdev->dev); 10841da177e4SLinus Torvalds } 10851da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev); 10861da177e4SLinus Torvalds 1087ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 1088ab81cbf9SJohan Hedberg { 1089ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 1090ab81cbf9SJohan Hedberg 1091ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1092ab81cbf9SJohan Hedberg 1093ab81cbf9SJohan Hedberg if (hci_dev_open(hdev->id) < 0) 1094ab81cbf9SJohan Hedberg return; 1095ab81cbf9SJohan Hedberg 1096a8b2d5c2SJohan Hedberg if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 109780b7ab33SGustavo F. Padovan schedule_delayed_work(&hdev->power_off, 10983243553fSJohan Hedberg msecs_to_jiffies(AUTO_OFF_TIMEOUT)); 1099ab81cbf9SJohan Hedberg 1100a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 1101744cf19eSJohan Hedberg mgmt_index_added(hdev); 1102ab81cbf9SJohan Hedberg } 1103ab81cbf9SJohan Hedberg 1104ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1105ab81cbf9SJohan Hedberg { 11063243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 11073243553fSJohan Hedberg power_off.work); 1108ab81cbf9SJohan Hedberg 1109ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1110ab81cbf9SJohan Hedberg 1111a8b2d5c2SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 11123243553fSJohan Hedberg 1113ab81cbf9SJohan Hedberg hci_dev_close(hdev->id); 1114ab81cbf9SJohan Hedberg } 1115ab81cbf9SJohan Hedberg 111616ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 111716ab91abSJohan Hedberg { 111816ab91abSJohan Hedberg struct hci_dev *hdev; 111916ab91abSJohan Hedberg u8 scan = SCAN_PAGE; 112016ab91abSJohan Hedberg 112116ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 112216ab91abSJohan Hedberg 112316ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 112416ab91abSJohan Hedberg 112509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 112616ab91abSJohan Hedberg 112716ab91abSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); 112816ab91abSJohan Hedberg 112916ab91abSJohan Hedberg hdev->discov_timeout = 0; 113016ab91abSJohan Hedberg 113109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 113216ab91abSJohan Hedberg } 113316ab91abSJohan Hedberg 11342aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 11352aeb9a1aSJohan Hedberg { 11362aeb9a1aSJohan Hedberg struct list_head *p, *n; 11372aeb9a1aSJohan Hedberg 11382aeb9a1aSJohan Hedberg list_for_each_safe(p, n, &hdev->uuids) { 11392aeb9a1aSJohan Hedberg struct bt_uuid *uuid; 11402aeb9a1aSJohan Hedberg 11412aeb9a1aSJohan Hedberg uuid = list_entry(p, struct bt_uuid, list); 11422aeb9a1aSJohan Hedberg 11432aeb9a1aSJohan Hedberg list_del(p); 11442aeb9a1aSJohan Hedberg kfree(uuid); 11452aeb9a1aSJohan Hedberg } 11462aeb9a1aSJohan Hedberg 11472aeb9a1aSJohan Hedberg return 0; 11482aeb9a1aSJohan Hedberg } 11492aeb9a1aSJohan Hedberg 115055ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 115155ed8ca1SJohan Hedberg { 115255ed8ca1SJohan Hedberg struct list_head *p, *n; 115355ed8ca1SJohan Hedberg 115455ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 115555ed8ca1SJohan Hedberg struct link_key *key; 115655ed8ca1SJohan Hedberg 115755ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 115855ed8ca1SJohan Hedberg 115955ed8ca1SJohan Hedberg list_del(p); 116055ed8ca1SJohan Hedberg kfree(key); 116155ed8ca1SJohan Hedberg } 116255ed8ca1SJohan Hedberg 116355ed8ca1SJohan Hedberg return 0; 116455ed8ca1SJohan Hedberg } 116555ed8ca1SJohan Hedberg 1166*b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 1167*b899efafSVinicius Costa Gomes { 1168*b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1169*b899efafSVinicius Costa Gomes 1170*b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1171*b899efafSVinicius Costa Gomes list_del(&k->list); 1172*b899efafSVinicius Costa Gomes kfree(k); 1173*b899efafSVinicius Costa Gomes } 1174*b899efafSVinicius Costa Gomes 1175*b899efafSVinicius Costa Gomes return 0; 1176*b899efafSVinicius Costa Gomes } 1177*b899efafSVinicius Costa Gomes 117855ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 117955ed8ca1SJohan Hedberg { 118055ed8ca1SJohan Hedberg struct link_key *k; 118155ed8ca1SJohan Hedberg 11828035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 118355ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 118455ed8ca1SJohan Hedberg return k; 118555ed8ca1SJohan Hedberg 118655ed8ca1SJohan Hedberg return NULL; 118755ed8ca1SJohan Hedberg } 118855ed8ca1SJohan Hedberg 1189d25e28abSJohan Hedberg static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 1190d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 1191d25e28abSJohan Hedberg { 1192d25e28abSJohan Hedberg /* Legacy key */ 1193d25e28abSJohan Hedberg if (key_type < 0x03) 1194d25e28abSJohan Hedberg return 1; 1195d25e28abSJohan Hedberg 1196d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 1197d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 1198d25e28abSJohan Hedberg return 0; 1199d25e28abSJohan Hedberg 1200d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 1201d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 1202d25e28abSJohan Hedberg return 0; 1203d25e28abSJohan Hedberg 1204d25e28abSJohan Hedberg /* Security mode 3 case */ 1205d25e28abSJohan Hedberg if (!conn) 1206d25e28abSJohan Hedberg return 1; 1207d25e28abSJohan Hedberg 1208d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 1209d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 1210d25e28abSJohan Hedberg return 1; 1211d25e28abSJohan Hedberg 1212d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 1213d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 1214d25e28abSJohan Hedberg return 1; 1215d25e28abSJohan Hedberg 1216d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 1217d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 1218d25e28abSJohan Hedberg return 1; 1219d25e28abSJohan Hedberg 1220d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 1221d25e28abSJohan Hedberg * persistently */ 1222d25e28abSJohan Hedberg return 0; 1223d25e28abSJohan Hedberg } 1224d25e28abSJohan Hedberg 122575d262c2SVinicius Costa Gomes struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 122675d262c2SVinicius Costa Gomes { 122775d262c2SVinicius Costa Gomes struct link_key *k; 122875d262c2SVinicius Costa Gomes 122975d262c2SVinicius Costa Gomes list_for_each_entry(k, &hdev->link_keys, list) { 123075d262c2SVinicius Costa Gomes struct key_master_id *id; 123175d262c2SVinicius Costa Gomes 123275d262c2SVinicius Costa Gomes if (k->type != HCI_LK_SMP_LTK) 123375d262c2SVinicius Costa Gomes continue; 123475d262c2SVinicius Costa Gomes 123575d262c2SVinicius Costa Gomes if (k->dlen != sizeof(*id)) 123675d262c2SVinicius Costa Gomes continue; 123775d262c2SVinicius Costa Gomes 123875d262c2SVinicius Costa Gomes id = (void *) &k->data; 123975d262c2SVinicius Costa Gomes if (id->ediv == ediv && 124075d262c2SVinicius Costa Gomes (memcmp(rand, id->rand, sizeof(id->rand)) == 0)) 124175d262c2SVinicius Costa Gomes return k; 124275d262c2SVinicius Costa Gomes } 124375d262c2SVinicius Costa Gomes 124475d262c2SVinicius Costa Gomes return NULL; 124575d262c2SVinicius Costa Gomes } 124675d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk); 124775d262c2SVinicius Costa Gomes 124875d262c2SVinicius Costa Gomes struct link_key *hci_find_link_key_type(struct hci_dev *hdev, 124975d262c2SVinicius Costa Gomes bdaddr_t *bdaddr, u8 type) 125075d262c2SVinicius Costa Gomes { 125175d262c2SVinicius Costa Gomes struct link_key *k; 125275d262c2SVinicius Costa Gomes 125375d262c2SVinicius Costa Gomes list_for_each_entry(k, &hdev->link_keys, list) 125475d262c2SVinicius Costa Gomes if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0) 125575d262c2SVinicius Costa Gomes return k; 125675d262c2SVinicius Costa Gomes 125775d262c2SVinicius Costa Gomes return NULL; 125875d262c2SVinicius Costa Gomes } 125975d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_link_key_type); 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; 12654df378a1SJohan Hedberg u8 old_key_type, persistent; 126655ed8ca1SJohan Hedberg 126755ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 126855ed8ca1SJohan Hedberg if (old_key) { 126955ed8ca1SJohan Hedberg old_key_type = old_key->type; 127055ed8ca1SJohan Hedberg key = old_key; 127155ed8ca1SJohan Hedberg } else { 127212adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 127355ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 127455ed8ca1SJohan Hedberg if (!key) 127555ed8ca1SJohan Hedberg return -ENOMEM; 127655ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 127755ed8ca1SJohan Hedberg } 127855ed8ca1SJohan Hedberg 127955ed8ca1SJohan Hedberg BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); 128055ed8ca1SJohan Hedberg 1281d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1282d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1283d25e28abSJohan Hedberg * previous key */ 1284d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1285d25e28abSJohan Hedberg (!conn || conn->remote_auth == 0xff) && 1286655fe6ecSJohan Hedberg old_key_type == 0xff) { 1287d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1288655fe6ecSJohan Hedberg if (conn) 1289655fe6ecSJohan Hedberg conn->key_type = type; 1290655fe6ecSJohan Hedberg } 1291d25e28abSJohan Hedberg 129255ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 129355ed8ca1SJohan Hedberg memcpy(key->val, val, 16); 129455ed8ca1SJohan Hedberg key->pin_len = pin_len; 129555ed8ca1SJohan Hedberg 1296b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 129755ed8ca1SJohan Hedberg key->type = old_key_type; 12984748fed2SJohan Hedberg else 12994748fed2SJohan Hedberg key->type = type; 13004748fed2SJohan Hedberg 13014df378a1SJohan Hedberg if (!new_key) 13024df378a1SJohan Hedberg return 0; 13034df378a1SJohan Hedberg 13044df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 13054df378a1SJohan Hedberg 1306744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 13074df378a1SJohan Hedberg 13084df378a1SJohan Hedberg if (!persistent) { 13094df378a1SJohan Hedberg list_del(&key->list); 13104df378a1SJohan Hedberg kfree(key); 13114df378a1SJohan Hedberg } 131255ed8ca1SJohan Hedberg 131355ed8ca1SJohan Hedberg return 0; 131455ed8ca1SJohan Hedberg } 131555ed8ca1SJohan Hedberg 131675d262c2SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, 1317726b4ffcSVinicius Costa Gomes u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]) 131875d262c2SVinicius Costa Gomes { 131975d262c2SVinicius Costa Gomes struct link_key *key, *old_key; 132075d262c2SVinicius Costa Gomes struct key_master_id *id; 132175d262c2SVinicius Costa Gomes u8 old_key_type; 132275d262c2SVinicius Costa Gomes 132375d262c2SVinicius Costa Gomes BT_DBG("%s addr %s", hdev->name, batostr(bdaddr)); 132475d262c2SVinicius Costa Gomes 132575d262c2SVinicius Costa Gomes old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK); 132675d262c2SVinicius Costa Gomes if (old_key) { 132775d262c2SVinicius Costa Gomes key = old_key; 132875d262c2SVinicius Costa Gomes old_key_type = old_key->type; 132975d262c2SVinicius Costa Gomes } else { 133075d262c2SVinicius Costa Gomes key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC); 133175d262c2SVinicius Costa Gomes if (!key) 133275d262c2SVinicius Costa Gomes return -ENOMEM; 133375d262c2SVinicius Costa Gomes list_add(&key->list, &hdev->link_keys); 133475d262c2SVinicius Costa Gomes old_key_type = 0xff; 133575d262c2SVinicius Costa Gomes } 133675d262c2SVinicius Costa Gomes 133775d262c2SVinicius Costa Gomes key->dlen = sizeof(*id); 133875d262c2SVinicius Costa Gomes 133975d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 134075d262c2SVinicius Costa Gomes memcpy(key->val, ltk, sizeof(key->val)); 134175d262c2SVinicius Costa Gomes key->type = HCI_LK_SMP_LTK; 1342726b4ffcSVinicius Costa Gomes key->pin_len = key_size; 134375d262c2SVinicius Costa Gomes 134475d262c2SVinicius Costa Gomes id = (void *) &key->data; 134575d262c2SVinicius Costa Gomes id->ediv = ediv; 134675d262c2SVinicius Costa Gomes memcpy(id->rand, rand, sizeof(id->rand)); 134775d262c2SVinicius Costa Gomes 134875d262c2SVinicius Costa Gomes if (new_key) 1349744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, old_key_type); 135075d262c2SVinicius Costa Gomes 135175d262c2SVinicius Costa Gomes return 0; 135275d262c2SVinicius Costa Gomes } 135375d262c2SVinicius Costa Gomes 135455ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 135555ed8ca1SJohan Hedberg { 135655ed8ca1SJohan Hedberg struct link_key *key; 135755ed8ca1SJohan Hedberg 135855ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 135955ed8ca1SJohan Hedberg if (!key) 136055ed8ca1SJohan Hedberg return -ENOENT; 136155ed8ca1SJohan Hedberg 136255ed8ca1SJohan Hedberg BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 136355ed8ca1SJohan Hedberg 136455ed8ca1SJohan Hedberg list_del(&key->list); 136555ed8ca1SJohan Hedberg kfree(key); 136655ed8ca1SJohan Hedberg 136755ed8ca1SJohan Hedberg return 0; 136855ed8ca1SJohan Hedberg } 136955ed8ca1SJohan Hedberg 1370*b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 1371*b899efafSVinicius Costa Gomes { 1372*b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1373*b899efafSVinicius Costa Gomes 1374*b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1375*b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 1376*b899efafSVinicius Costa Gomes continue; 1377*b899efafSVinicius Costa Gomes 1378*b899efafSVinicius Costa Gomes BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 1379*b899efafSVinicius Costa Gomes 1380*b899efafSVinicius Costa Gomes list_del(&k->list); 1381*b899efafSVinicius Costa Gomes kfree(k); 1382*b899efafSVinicius Costa Gomes } 1383*b899efafSVinicius Costa Gomes 1384*b899efafSVinicius Costa Gomes return 0; 1385*b899efafSVinicius Costa Gomes } 1386*b899efafSVinicius Costa Gomes 13876bd32326SVille Tervo /* HCI command timer function */ 13886bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg) 13896bd32326SVille Tervo { 13906bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 13916bd32326SVille Tervo 13926bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 13936bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 1394c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 13956bd32326SVille Tervo } 13966bd32326SVille Tervo 13972763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 13982763eda6SSzymon Janc bdaddr_t *bdaddr) 13992763eda6SSzymon Janc { 14002763eda6SSzymon Janc struct oob_data *data; 14012763eda6SSzymon Janc 14022763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 14032763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 14042763eda6SSzymon Janc return data; 14052763eda6SSzymon Janc 14062763eda6SSzymon Janc return NULL; 14072763eda6SSzymon Janc } 14082763eda6SSzymon Janc 14092763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 14102763eda6SSzymon Janc { 14112763eda6SSzymon Janc struct oob_data *data; 14122763eda6SSzymon Janc 14132763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14142763eda6SSzymon Janc if (!data) 14152763eda6SSzymon Janc return -ENOENT; 14162763eda6SSzymon Janc 14172763eda6SSzymon Janc BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 14182763eda6SSzymon Janc 14192763eda6SSzymon Janc list_del(&data->list); 14202763eda6SSzymon Janc kfree(data); 14212763eda6SSzymon Janc 14222763eda6SSzymon Janc return 0; 14232763eda6SSzymon Janc } 14242763eda6SSzymon Janc 14252763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 14262763eda6SSzymon Janc { 14272763eda6SSzymon Janc struct oob_data *data, *n; 14282763eda6SSzymon Janc 14292763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 14302763eda6SSzymon Janc list_del(&data->list); 14312763eda6SSzymon Janc kfree(data); 14322763eda6SSzymon Janc } 14332763eda6SSzymon Janc 14342763eda6SSzymon Janc return 0; 14352763eda6SSzymon Janc } 14362763eda6SSzymon Janc 14372763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 14382763eda6SSzymon Janc u8 *randomizer) 14392763eda6SSzymon Janc { 14402763eda6SSzymon Janc struct oob_data *data; 14412763eda6SSzymon Janc 14422763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14432763eda6SSzymon Janc 14442763eda6SSzymon Janc if (!data) { 14452763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 14462763eda6SSzymon Janc if (!data) 14472763eda6SSzymon Janc return -ENOMEM; 14482763eda6SSzymon Janc 14492763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 14502763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 14512763eda6SSzymon Janc } 14522763eda6SSzymon Janc 14532763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 14542763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 14552763eda6SSzymon Janc 14562763eda6SSzymon Janc BT_DBG("%s for %s", hdev->name, batostr(bdaddr)); 14572763eda6SSzymon Janc 14582763eda6SSzymon Janc return 0; 14592763eda6SSzymon Janc } 14602763eda6SSzymon Janc 1461b2a66aadSAntti Julku struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 1462b2a66aadSAntti Julku bdaddr_t *bdaddr) 1463b2a66aadSAntti Julku { 1464b2a66aadSAntti Julku struct bdaddr_list *b; 1465b2a66aadSAntti Julku 14668035ded4SLuiz Augusto von Dentz list_for_each_entry(b, &hdev->blacklist, list) 1467b2a66aadSAntti Julku if (bacmp(bdaddr, &b->bdaddr) == 0) 1468b2a66aadSAntti Julku return b; 1469b2a66aadSAntti Julku 1470b2a66aadSAntti Julku return NULL; 1471b2a66aadSAntti Julku } 1472b2a66aadSAntti Julku 1473b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 1474b2a66aadSAntti Julku { 1475b2a66aadSAntti Julku struct list_head *p, *n; 1476b2a66aadSAntti Julku 1477b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 1478b2a66aadSAntti Julku struct bdaddr_list *b; 1479b2a66aadSAntti Julku 1480b2a66aadSAntti Julku b = list_entry(p, struct bdaddr_list, list); 1481b2a66aadSAntti Julku 1482b2a66aadSAntti Julku list_del(p); 1483b2a66aadSAntti Julku kfree(b); 1484b2a66aadSAntti Julku } 1485b2a66aadSAntti Julku 1486b2a66aadSAntti Julku return 0; 1487b2a66aadSAntti Julku } 1488b2a66aadSAntti Julku 1489b2a66aadSAntti Julku int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) 1490b2a66aadSAntti Julku { 1491b2a66aadSAntti Julku struct bdaddr_list *entry; 1492b2a66aadSAntti Julku 1493b2a66aadSAntti Julku if (bacmp(bdaddr, BDADDR_ANY) == 0) 1494b2a66aadSAntti Julku return -EBADF; 1495b2a66aadSAntti Julku 14965e762444SAntti Julku if (hci_blacklist_lookup(hdev, bdaddr)) 14975e762444SAntti Julku return -EEXIST; 1498b2a66aadSAntti Julku 1499b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 15005e762444SAntti Julku if (!entry) 15015e762444SAntti Julku return -ENOMEM; 1502b2a66aadSAntti Julku 1503b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 1504b2a66aadSAntti Julku 1505b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 1506b2a66aadSAntti Julku 1507744cf19eSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr); 1508b2a66aadSAntti Julku } 1509b2a66aadSAntti Julku 1510b2a66aadSAntti Julku int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) 1511b2a66aadSAntti Julku { 1512b2a66aadSAntti Julku struct bdaddr_list *entry; 1513b2a66aadSAntti Julku 15141ec918ceSSzymon Janc if (bacmp(bdaddr, BDADDR_ANY) == 0) 15155e762444SAntti Julku return hci_blacklist_clear(hdev); 1516b2a66aadSAntti Julku 1517b2a66aadSAntti Julku entry = hci_blacklist_lookup(hdev, bdaddr); 15181ec918ceSSzymon Janc if (!entry) 15195e762444SAntti Julku return -ENOENT; 1520b2a66aadSAntti Julku 1521b2a66aadSAntti Julku list_del(&entry->list); 1522b2a66aadSAntti Julku kfree(entry); 1523b2a66aadSAntti Julku 1524744cf19eSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr); 1525b2a66aadSAntti Julku } 1526b2a66aadSAntti Julku 1527db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work) 152835815085SAndre Guedes { 1529db323f2fSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, 1530db323f2fSGustavo F. Padovan adv_work.work); 153135815085SAndre Guedes 153235815085SAndre Guedes hci_dev_lock(hdev); 153335815085SAndre Guedes 153435815085SAndre Guedes hci_adv_entries_clear(hdev); 153535815085SAndre Guedes 153635815085SAndre Guedes hci_dev_unlock(hdev); 153735815085SAndre Guedes } 153835815085SAndre Guedes 153976c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev) 154076c8686fSAndre Guedes { 154176c8686fSAndre Guedes struct adv_entry *entry, *tmp; 154276c8686fSAndre Guedes 154376c8686fSAndre Guedes list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) { 154476c8686fSAndre Guedes list_del(&entry->list); 154576c8686fSAndre Guedes kfree(entry); 154676c8686fSAndre Guedes } 154776c8686fSAndre Guedes 154876c8686fSAndre Guedes BT_DBG("%s adv cache cleared", hdev->name); 154976c8686fSAndre Guedes 155076c8686fSAndre Guedes return 0; 155176c8686fSAndre Guedes } 155276c8686fSAndre Guedes 155376c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr) 155476c8686fSAndre Guedes { 155576c8686fSAndre Guedes struct adv_entry *entry; 155676c8686fSAndre Guedes 155776c8686fSAndre Guedes list_for_each_entry(entry, &hdev->adv_entries, list) 155876c8686fSAndre Guedes if (bacmp(bdaddr, &entry->bdaddr) == 0) 155976c8686fSAndre Guedes return entry; 156076c8686fSAndre Guedes 156176c8686fSAndre Guedes return NULL; 156276c8686fSAndre Guedes } 156376c8686fSAndre Guedes 156476c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type) 156576c8686fSAndre Guedes { 156676c8686fSAndre Guedes if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND) 156776c8686fSAndre Guedes return 1; 156876c8686fSAndre Guedes 156976c8686fSAndre Guedes return 0; 157076c8686fSAndre Guedes } 157176c8686fSAndre Guedes 157276c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev, 157376c8686fSAndre Guedes struct hci_ev_le_advertising_info *ev) 157476c8686fSAndre Guedes { 157576c8686fSAndre Guedes struct adv_entry *entry; 157676c8686fSAndre Guedes 157776c8686fSAndre Guedes if (!is_connectable_adv(ev->evt_type)) 157876c8686fSAndre Guedes return -EINVAL; 157976c8686fSAndre Guedes 158076c8686fSAndre Guedes /* Only new entries should be added to adv_entries. So, if 158176c8686fSAndre Guedes * bdaddr was found, don't add it. */ 158276c8686fSAndre Guedes if (hci_find_adv_entry(hdev, &ev->bdaddr)) 158376c8686fSAndre Guedes return 0; 158476c8686fSAndre Guedes 15854777bfdeSAndre Guedes entry = kzalloc(sizeof(*entry), GFP_KERNEL); 158676c8686fSAndre Guedes if (!entry) 158776c8686fSAndre Guedes return -ENOMEM; 158876c8686fSAndre Guedes 158976c8686fSAndre Guedes bacpy(&entry->bdaddr, &ev->bdaddr); 159076c8686fSAndre Guedes entry->bdaddr_type = ev->bdaddr_type; 159176c8686fSAndre Guedes 159276c8686fSAndre Guedes list_add(&entry->list, &hdev->adv_entries); 159376c8686fSAndre Guedes 159476c8686fSAndre Guedes BT_DBG("%s adv entry added: address %s type %u", hdev->name, 159576c8686fSAndre Guedes batostr(&entry->bdaddr), entry->bdaddr_type); 159676c8686fSAndre Guedes 159776c8686fSAndre Guedes return 0; 159876c8686fSAndre Guedes } 159976c8686fSAndre Guedes 16001da177e4SLinus Torvalds /* Register HCI device */ 16011da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 16021da177e4SLinus Torvalds { 16031da177e4SLinus Torvalds struct list_head *head = &hci_dev_list, *p; 160408add513SMat Martineau int i, id, error; 16051da177e4SLinus Torvalds 1606e9b9cfa1SDavid Herrmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 16071da177e4SLinus Torvalds 1608010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 16091da177e4SLinus Torvalds return -EINVAL; 16101da177e4SLinus Torvalds 161108add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 161208add513SMat Martineau * so the index can be used as the AMP controller ID. 161308add513SMat Martineau */ 161408add513SMat Martineau id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; 161508add513SMat Martineau 1616f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 16171da177e4SLinus Torvalds 16181da177e4SLinus Torvalds /* Find first available device id */ 16191da177e4SLinus Torvalds list_for_each(p, &hci_dev_list) { 16201da177e4SLinus Torvalds if (list_entry(p, struct hci_dev, list)->id != id) 16211da177e4SLinus Torvalds break; 16221da177e4SLinus Torvalds head = p; id++; 16231da177e4SLinus Torvalds } 16241da177e4SLinus Torvalds 16251da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 16261da177e4SLinus Torvalds hdev->id = id; 1627c6feeb28SAndrei Emeltchenko list_add_tail(&hdev->list, head); 16281da177e4SLinus Torvalds 162909fd0de5SGustavo F. Padovan mutex_init(&hdev->lock); 16301da177e4SLinus Torvalds 16311da177e4SLinus Torvalds hdev->flags = 0; 1632d23264a8SAndre Guedes hdev->dev_flags = 0; 16331da177e4SLinus Torvalds hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 16345b7f9909SMarcel Holtmann hdev->esco_type = (ESCO_HV1); 16351da177e4SLinus Torvalds hdev->link_mode = (HCI_LM_ACCEPT); 163617fa4b9dSJohan Hedberg hdev->io_capability = 0x03; /* No Input No Output */ 16371da177e4SLinus Torvalds 163804837f64SMarcel Holtmann hdev->idle_timeout = 0; 163904837f64SMarcel Holtmann hdev->sniff_max_interval = 800; 164004837f64SMarcel Holtmann hdev->sniff_min_interval = 80; 164104837f64SMarcel Holtmann 1642b78752ccSMarcel Holtmann INIT_WORK(&hdev->rx_work, hci_rx_work); 1643c347b765SGustavo F. Padovan INIT_WORK(&hdev->cmd_work, hci_cmd_work); 16443eff45eaSGustavo F. Padovan INIT_WORK(&hdev->tx_work, hci_tx_work); 1645b78752ccSMarcel Holtmann 16461da177e4SLinus Torvalds 16471da177e4SLinus Torvalds skb_queue_head_init(&hdev->rx_q); 16481da177e4SLinus Torvalds skb_queue_head_init(&hdev->cmd_q); 16491da177e4SLinus Torvalds skb_queue_head_init(&hdev->raw_q); 16501da177e4SLinus Torvalds 16516bd32326SVille Tervo setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); 16526bd32326SVille Tervo 1653cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1654ef222013SMarcel Holtmann hdev->reassembly[i] = NULL; 1655ef222013SMarcel Holtmann 16561da177e4SLinus Torvalds init_waitqueue_head(&hdev->req_wait_q); 1657a6a67efdSThomas Gleixner mutex_init(&hdev->req_lock); 16581da177e4SLinus Torvalds 165930883512SJohan Hedberg discovery_init(hdev); 16601da177e4SLinus Torvalds 16611da177e4SLinus Torvalds hci_conn_hash_init(hdev); 16621da177e4SLinus Torvalds 16632e58ef3eSJohan Hedberg INIT_LIST_HEAD(&hdev->mgmt_pending); 16642e58ef3eSJohan Hedberg 1665ea4bd8baSDavid Miller INIT_LIST_HEAD(&hdev->blacklist); 1666f0358568SJohan Hedberg 16672aeb9a1aSJohan Hedberg INIT_LIST_HEAD(&hdev->uuids); 16682aeb9a1aSJohan Hedberg 166955ed8ca1SJohan Hedberg INIT_LIST_HEAD(&hdev->link_keys); 1670*b899efafSVinicius Costa Gomes INIT_LIST_HEAD(&hdev->long_term_keys); 167155ed8ca1SJohan Hedberg 16722763eda6SSzymon Janc INIT_LIST_HEAD(&hdev->remote_oob_data); 16732763eda6SSzymon Janc 167476c8686fSAndre Guedes INIT_LIST_HEAD(&hdev->adv_entries); 167576c8686fSAndre Guedes 1676db323f2fSGustavo F. Padovan INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache); 1677ab81cbf9SJohan Hedberg INIT_WORK(&hdev->power_on, hci_power_on); 16783243553fSJohan Hedberg INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 1679ab81cbf9SJohan Hedberg 168016ab91abSJohan Hedberg INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 168116ab91abSJohan Hedberg 16821da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 16831da177e4SLinus Torvalds 16841da177e4SLinus Torvalds atomic_set(&hdev->promisc, 0); 16851da177e4SLinus Torvalds 1686f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 16871da177e4SLinus Torvalds 168832845eb1SGustavo F. Padovan hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | 168932845eb1SGustavo F. Padovan WQ_MEM_RECLAIM, 1); 169033ca954dSDavid Herrmann if (!hdev->workqueue) { 169133ca954dSDavid Herrmann error = -ENOMEM; 169233ca954dSDavid Herrmann goto err; 169333ca954dSDavid Herrmann } 1694f48fd9c8SMarcel Holtmann 169533ca954dSDavid Herrmann error = hci_add_sysfs(hdev); 169633ca954dSDavid Herrmann if (error < 0) 169733ca954dSDavid Herrmann goto err_wqueue; 16981da177e4SLinus Torvalds 1699611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 1700611b30f7SMarcel Holtmann RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); 1701611b30f7SMarcel Holtmann if (hdev->rfkill) { 1702611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 1703611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1704611b30f7SMarcel Holtmann hdev->rfkill = NULL; 1705611b30f7SMarcel Holtmann } 1706611b30f7SMarcel Holtmann } 1707611b30f7SMarcel Holtmann 1708a8b2d5c2SJohan Hedberg set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 1709a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 17107f971041SGustavo F. Padovan schedule_work(&hdev->power_on); 1711ab81cbf9SJohan Hedberg 17121da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 1713dc946bd8SDavid Herrmann hci_dev_hold(hdev); 17141da177e4SLinus Torvalds 17151da177e4SLinus Torvalds return id; 1716f48fd9c8SMarcel Holtmann 171733ca954dSDavid Herrmann err_wqueue: 171833ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 171933ca954dSDavid Herrmann err: 1720f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 1721f48fd9c8SMarcel Holtmann list_del(&hdev->list); 1722f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 1723f48fd9c8SMarcel Holtmann 172433ca954dSDavid Herrmann return error; 17251da177e4SLinus Torvalds } 17261da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 17271da177e4SLinus Torvalds 17281da177e4SLinus Torvalds /* Unregister HCI device */ 172959735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 17301da177e4SLinus Torvalds { 1731ef222013SMarcel Holtmann int i; 1732ef222013SMarcel Holtmann 1733c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 17341da177e4SLinus Torvalds 1735f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 17361da177e4SLinus Torvalds list_del(&hdev->list); 1737f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 17381da177e4SLinus Torvalds 17391da177e4SLinus Torvalds hci_dev_do_close(hdev); 17401da177e4SLinus Torvalds 1741cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1742ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 1743ef222013SMarcel Holtmann 1744ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 1745a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 174609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1747744cf19eSJohan Hedberg mgmt_index_removed(hdev); 174809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 174956e5cb86SJohan Hedberg } 1750ab81cbf9SJohan Hedberg 17512e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 17522e58ef3eSJohan Hedberg * pending list */ 17532e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 17542e58ef3eSJohan Hedberg 17551da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 17561da177e4SLinus Torvalds 1757611b30f7SMarcel Holtmann if (hdev->rfkill) { 1758611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 1759611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1760611b30f7SMarcel Holtmann } 1761611b30f7SMarcel Holtmann 1762ce242970SDavid Herrmann hci_del_sysfs(hdev); 1763147e2d59SDave Young 1764db323f2fSGustavo F. Padovan cancel_delayed_work_sync(&hdev->adv_work); 1765c6f3c5f7SGustavo F. Padovan 1766f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 1767f48fd9c8SMarcel Holtmann 176809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1769e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 17702aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 177155ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 1772*b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 17732763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 177476c8686fSAndre Guedes hci_adv_entries_clear(hdev); 177509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 1776e2e0cacbSJohan Hedberg 1777dc946bd8SDavid Herrmann hci_dev_put(hdev); 17781da177e4SLinus Torvalds } 17791da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 17801da177e4SLinus Torvalds 17811da177e4SLinus Torvalds /* Suspend HCI device */ 17821da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 17831da177e4SLinus Torvalds { 17841da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 17851da177e4SLinus Torvalds return 0; 17861da177e4SLinus Torvalds } 17871da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 17881da177e4SLinus Torvalds 17891da177e4SLinus Torvalds /* Resume HCI device */ 17901da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 17911da177e4SLinus Torvalds { 17921da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 17931da177e4SLinus Torvalds return 0; 17941da177e4SLinus Torvalds } 17951da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 17961da177e4SLinus Torvalds 179776bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 179876bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb) 179976bca880SMarcel Holtmann { 180076bca880SMarcel Holtmann struct hci_dev *hdev = (struct hci_dev *) skb->dev; 180176bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 180276bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 180376bca880SMarcel Holtmann kfree_skb(skb); 180476bca880SMarcel Holtmann return -ENXIO; 180576bca880SMarcel Holtmann } 180676bca880SMarcel Holtmann 180776bca880SMarcel Holtmann /* Incomming skb */ 180876bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 180976bca880SMarcel Holtmann 181076bca880SMarcel Holtmann /* Time stamp */ 181176bca880SMarcel Holtmann __net_timestamp(skb); 181276bca880SMarcel Holtmann 181376bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 1814b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 1815c78ae283SMarcel Holtmann 181676bca880SMarcel Holtmann return 0; 181776bca880SMarcel Holtmann } 181876bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 181976bca880SMarcel Holtmann 182033e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 18211e429f38SGustavo F. Padovan int count, __u8 index) 182233e882a5SSuraj Sumangala { 182333e882a5SSuraj Sumangala int len = 0; 182433e882a5SSuraj Sumangala int hlen = 0; 182533e882a5SSuraj Sumangala int remain = count; 182633e882a5SSuraj Sumangala struct sk_buff *skb; 182733e882a5SSuraj Sumangala struct bt_skb_cb *scb; 182833e882a5SSuraj Sumangala 182933e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 183033e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 183133e882a5SSuraj Sumangala return -EILSEQ; 183233e882a5SSuraj Sumangala 183333e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 183433e882a5SSuraj Sumangala 183533e882a5SSuraj Sumangala if (!skb) { 183633e882a5SSuraj Sumangala switch (type) { 183733e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 183833e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 183933e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 184033e882a5SSuraj Sumangala break; 184133e882a5SSuraj Sumangala case HCI_EVENT_PKT: 184233e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 184333e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 184433e882a5SSuraj Sumangala break; 184533e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 184633e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 184733e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 184833e882a5SSuraj Sumangala break; 184933e882a5SSuraj Sumangala } 185033e882a5SSuraj Sumangala 18511e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 185233e882a5SSuraj Sumangala if (!skb) 185333e882a5SSuraj Sumangala return -ENOMEM; 185433e882a5SSuraj Sumangala 185533e882a5SSuraj Sumangala scb = (void *) skb->cb; 185633e882a5SSuraj Sumangala scb->expect = hlen; 185733e882a5SSuraj Sumangala scb->pkt_type = type; 185833e882a5SSuraj Sumangala 185933e882a5SSuraj Sumangala skb->dev = (void *) hdev; 186033e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 186133e882a5SSuraj Sumangala } 186233e882a5SSuraj Sumangala 186333e882a5SSuraj Sumangala while (count) { 186433e882a5SSuraj Sumangala scb = (void *) skb->cb; 186533e882a5SSuraj Sumangala len = min(scb->expect, (__u16)count); 186633e882a5SSuraj Sumangala 186733e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 186833e882a5SSuraj Sumangala 186933e882a5SSuraj Sumangala count -= len; 187033e882a5SSuraj Sumangala data += len; 187133e882a5SSuraj Sumangala scb->expect -= len; 187233e882a5SSuraj Sumangala remain = count; 187333e882a5SSuraj Sumangala 187433e882a5SSuraj Sumangala switch (type) { 187533e882a5SSuraj Sumangala case HCI_EVENT_PKT: 187633e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 187733e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 187833e882a5SSuraj Sumangala scb->expect = h->plen; 187933e882a5SSuraj Sumangala 188033e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 188133e882a5SSuraj Sumangala kfree_skb(skb); 188233e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 188333e882a5SSuraj Sumangala return -ENOMEM; 188433e882a5SSuraj Sumangala } 188533e882a5SSuraj Sumangala } 188633e882a5SSuraj Sumangala break; 188733e882a5SSuraj Sumangala 188833e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 188933e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 189033e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 189133e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 189233e882a5SSuraj Sumangala 189333e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 189433e882a5SSuraj Sumangala kfree_skb(skb); 189533e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 189633e882a5SSuraj Sumangala return -ENOMEM; 189733e882a5SSuraj Sumangala } 189833e882a5SSuraj Sumangala } 189933e882a5SSuraj Sumangala break; 190033e882a5SSuraj Sumangala 190133e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 190233e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 190333e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 190433e882a5SSuraj Sumangala scb->expect = h->dlen; 190533e882a5SSuraj Sumangala 190633e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 190733e882a5SSuraj Sumangala kfree_skb(skb); 190833e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 190933e882a5SSuraj Sumangala return -ENOMEM; 191033e882a5SSuraj Sumangala } 191133e882a5SSuraj Sumangala } 191233e882a5SSuraj Sumangala break; 191333e882a5SSuraj Sumangala } 191433e882a5SSuraj Sumangala 191533e882a5SSuraj Sumangala if (scb->expect == 0) { 191633e882a5SSuraj Sumangala /* Complete frame */ 191733e882a5SSuraj Sumangala 191833e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 191933e882a5SSuraj Sumangala hci_recv_frame(skb); 192033e882a5SSuraj Sumangala 192133e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 192233e882a5SSuraj Sumangala return remain; 192333e882a5SSuraj Sumangala } 192433e882a5SSuraj Sumangala } 192533e882a5SSuraj Sumangala 192633e882a5SSuraj Sumangala return remain; 192733e882a5SSuraj Sumangala } 192833e882a5SSuraj Sumangala 1929ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 1930ef222013SMarcel Holtmann { 1931f39a3c06SSuraj Sumangala int rem = 0; 1932f39a3c06SSuraj Sumangala 1933ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 1934ef222013SMarcel Holtmann return -EILSEQ; 1935ef222013SMarcel Holtmann 1936da5f6c37SGustavo F. Padovan while (count) { 19371e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 1938f39a3c06SSuraj Sumangala if (rem < 0) 1939f39a3c06SSuraj Sumangala return rem; 1940ef222013SMarcel Holtmann 1941f39a3c06SSuraj Sumangala data += (count - rem); 1942f39a3c06SSuraj Sumangala count = rem; 1943f81c6224SJoe Perches } 1944ef222013SMarcel Holtmann 1945f39a3c06SSuraj Sumangala return rem; 1946ef222013SMarcel Holtmann } 1947ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 1948ef222013SMarcel Holtmann 194999811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 195099811510SSuraj Sumangala 195199811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 195299811510SSuraj Sumangala { 195399811510SSuraj Sumangala int type; 195499811510SSuraj Sumangala int rem = 0; 195599811510SSuraj Sumangala 1956da5f6c37SGustavo F. Padovan while (count) { 195799811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 195899811510SSuraj Sumangala 195999811510SSuraj Sumangala if (!skb) { 196099811510SSuraj Sumangala struct { char type; } *pkt; 196199811510SSuraj Sumangala 196299811510SSuraj Sumangala /* Start of the frame */ 196399811510SSuraj Sumangala pkt = data; 196499811510SSuraj Sumangala type = pkt->type; 196599811510SSuraj Sumangala 196699811510SSuraj Sumangala data++; 196799811510SSuraj Sumangala count--; 196899811510SSuraj Sumangala } else 196999811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 197099811510SSuraj Sumangala 19711e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 19721e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 197399811510SSuraj Sumangala if (rem < 0) 197499811510SSuraj Sumangala return rem; 197599811510SSuraj Sumangala 197699811510SSuraj Sumangala data += (count - rem); 197799811510SSuraj Sumangala count = rem; 1978f81c6224SJoe Perches } 197999811510SSuraj Sumangala 198099811510SSuraj Sumangala return rem; 198199811510SSuraj Sumangala } 198299811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 198399811510SSuraj Sumangala 19841da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 19851da177e4SLinus Torvalds 19861da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 19871da177e4SLinus Torvalds { 19881da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 19891da177e4SLinus Torvalds 1990f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 19911da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 1992f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 19931da177e4SLinus Torvalds 19941da177e4SLinus Torvalds return 0; 19951da177e4SLinus Torvalds } 19961da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 19971da177e4SLinus Torvalds 19981da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 19991da177e4SLinus Torvalds { 20001da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 20011da177e4SLinus Torvalds 2002f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 20031da177e4SLinus Torvalds list_del(&cb->list); 2004f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 20051da177e4SLinus Torvalds 20061da177e4SLinus Torvalds return 0; 20071da177e4SLinus Torvalds } 20081da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 20091da177e4SLinus Torvalds 20101da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb) 20111da177e4SLinus Torvalds { 20121da177e4SLinus Torvalds struct hci_dev *hdev = (struct hci_dev *) skb->dev; 20131da177e4SLinus Torvalds 20141da177e4SLinus Torvalds if (!hdev) { 20151da177e4SLinus Torvalds kfree_skb(skb); 20161da177e4SLinus Torvalds return -ENODEV; 20171da177e4SLinus Torvalds } 20181da177e4SLinus Torvalds 20190d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 20201da177e4SLinus Torvalds 20211da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 20221da177e4SLinus Torvalds /* Time stamp */ 2023a61bbcf2SPatrick McHardy __net_timestamp(skb); 20241da177e4SLinus Torvalds 2025eec8d2bcSJohan Hedberg hci_send_to_sock(hdev, skb, NULL); 20261da177e4SLinus Torvalds } 20271da177e4SLinus Torvalds 20281da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 20291da177e4SLinus Torvalds skb_orphan(skb); 20301da177e4SLinus Torvalds 20311da177e4SLinus Torvalds return hdev->send(skb); 20321da177e4SLinus Torvalds } 20331da177e4SLinus Torvalds 20341da177e4SLinus Torvalds /* Send HCI command */ 2035a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) 20361da177e4SLinus Torvalds { 20371da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 20381da177e4SLinus Torvalds struct hci_command_hdr *hdr; 20391da177e4SLinus Torvalds struct sk_buff *skb; 20401da177e4SLinus Torvalds 2041a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen); 20421da177e4SLinus Torvalds 20431da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 20441da177e4SLinus Torvalds if (!skb) { 2045ef222013SMarcel Holtmann BT_ERR("%s no memory for command", hdev->name); 20461da177e4SLinus Torvalds return -ENOMEM; 20471da177e4SLinus Torvalds } 20481da177e4SLinus Torvalds 20491da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 2050a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 20511da177e4SLinus Torvalds hdr->plen = plen; 20521da177e4SLinus Torvalds 20531da177e4SLinus Torvalds if (plen) 20541da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 20551da177e4SLinus Torvalds 20561da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 20571da177e4SLinus Torvalds 20580d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 20591da177e4SLinus Torvalds skb->dev = (void *) hdev; 2060c78ae283SMarcel Holtmann 2061a5040efaSJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags)) 2062a5040efaSJohan Hedberg hdev->init_last_cmd = opcode; 2063a5040efaSJohan Hedberg 20641da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 2065c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 20661da177e4SLinus Torvalds 20671da177e4SLinus Torvalds return 0; 20681da177e4SLinus Torvalds } 20691da177e4SLinus Torvalds 20701da177e4SLinus Torvalds /* Get data from the previously sent command */ 2071a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 20721da177e4SLinus Torvalds { 20731da177e4SLinus Torvalds struct hci_command_hdr *hdr; 20741da177e4SLinus Torvalds 20751da177e4SLinus Torvalds if (!hdev->sent_cmd) 20761da177e4SLinus Torvalds return NULL; 20771da177e4SLinus Torvalds 20781da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 20791da177e4SLinus Torvalds 2080a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 20811da177e4SLinus Torvalds return NULL; 20821da177e4SLinus Torvalds 2083a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 20841da177e4SLinus Torvalds 20851da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 20861da177e4SLinus Torvalds } 20871da177e4SLinus Torvalds 20881da177e4SLinus Torvalds /* Send ACL data */ 20891da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 20901da177e4SLinus Torvalds { 20911da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 20921da177e4SLinus Torvalds int len = skb->len; 20931da177e4SLinus Torvalds 2094badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 2095badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 20969c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 2097aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 2098aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 20991da177e4SLinus Torvalds } 21001da177e4SLinus Torvalds 210173d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, 210273d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 21031da177e4SLinus Torvalds { 21041da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 21051da177e4SLinus Torvalds struct sk_buff *list; 21061da177e4SLinus Torvalds 210770f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 210870f23020SAndrei Emeltchenko if (!list) { 21091da177e4SLinus Torvalds /* Non fragmented */ 21101da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 21111da177e4SLinus Torvalds 211273d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 21131da177e4SLinus Torvalds } else { 21141da177e4SLinus Torvalds /* Fragmented */ 21151da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 21161da177e4SLinus Torvalds 21171da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 21181da177e4SLinus Torvalds 21191da177e4SLinus Torvalds /* Queue all fragments atomically */ 2120af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 21211da177e4SLinus Torvalds 212273d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 2123e702112fSAndrei Emeltchenko 2124e702112fSAndrei Emeltchenko flags &= ~ACL_START; 2125e702112fSAndrei Emeltchenko flags |= ACL_CONT; 21261da177e4SLinus Torvalds do { 21271da177e4SLinus Torvalds skb = list; list = list->next; 21281da177e4SLinus Torvalds 21291da177e4SLinus Torvalds skb->dev = (void *) hdev; 21300d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2131e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 21321da177e4SLinus Torvalds 21331da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 21341da177e4SLinus Torvalds 213573d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 21361da177e4SLinus Torvalds } while (list); 21371da177e4SLinus Torvalds 2138af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 21391da177e4SLinus Torvalds } 214073d80debSLuiz Augusto von Dentz } 214173d80debSLuiz Augusto von Dentz 214273d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 214373d80debSLuiz Augusto von Dentz { 214473d80debSLuiz Augusto von Dentz struct hci_conn *conn = chan->conn; 214573d80debSLuiz Augusto von Dentz struct hci_dev *hdev = conn->hdev; 214673d80debSLuiz Augusto von Dentz 214773d80debSLuiz Augusto von Dentz BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags); 214873d80debSLuiz Augusto von Dentz 214973d80debSLuiz Augusto von Dentz skb->dev = (void *) hdev; 215073d80debSLuiz Augusto von Dentz bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 215173d80debSLuiz Augusto von Dentz hci_add_acl_hdr(skb, conn->handle, flags); 215273d80debSLuiz Augusto von Dentz 215373d80debSLuiz Augusto von Dentz hci_queue_acl(conn, &chan->data_q, skb, flags); 21541da177e4SLinus Torvalds 21553eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 21561da177e4SLinus Torvalds } 21571da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl); 21581da177e4SLinus Torvalds 21591da177e4SLinus Torvalds /* Send SCO data */ 21600d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 21611da177e4SLinus Torvalds { 21621da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 21631da177e4SLinus Torvalds struct hci_sco_hdr hdr; 21641da177e4SLinus Torvalds 21651da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 21661da177e4SLinus Torvalds 2167aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 21681da177e4SLinus Torvalds hdr.dlen = skb->len; 21691da177e4SLinus Torvalds 2170badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 2171badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 21729c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 21731da177e4SLinus Torvalds 21741da177e4SLinus Torvalds skb->dev = (void *) hdev; 21750d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 2176c78ae283SMarcel Holtmann 21771da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 21783eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 21791da177e4SLinus Torvalds } 21801da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco); 21811da177e4SLinus Torvalds 21821da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 21831da177e4SLinus Torvalds 21841da177e4SLinus Torvalds /* HCI Connection scheduler */ 21851da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) 21861da177e4SLinus Torvalds { 21871da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 21888035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 21891da177e4SLinus Torvalds int num = 0, min = ~0; 21901da177e4SLinus Torvalds 21911da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 21921da177e4SLinus Torvalds * added and removed with TX task disabled. */ 2193bf4c6325SGustavo F. Padovan 2194bf4c6325SGustavo F. Padovan rcu_read_lock(); 2195bf4c6325SGustavo F. Padovan 2196bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2197769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 21981da177e4SLinus Torvalds continue; 2199769be974SMarcel Holtmann 2200769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 2201769be974SMarcel Holtmann continue; 2202769be974SMarcel Holtmann 22031da177e4SLinus Torvalds num++; 22041da177e4SLinus Torvalds 22051da177e4SLinus Torvalds if (c->sent < min) { 22061da177e4SLinus Torvalds min = c->sent; 22071da177e4SLinus Torvalds conn = c; 22081da177e4SLinus Torvalds } 220952087a79SLuiz Augusto von Dentz 221052087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 221152087a79SLuiz Augusto von Dentz break; 22121da177e4SLinus Torvalds } 22131da177e4SLinus Torvalds 2214bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2215bf4c6325SGustavo F. Padovan 22161da177e4SLinus Torvalds if (conn) { 22176ed58ec5SVille Tervo int cnt, q; 22186ed58ec5SVille Tervo 22196ed58ec5SVille Tervo switch (conn->type) { 22206ed58ec5SVille Tervo case ACL_LINK: 22216ed58ec5SVille Tervo cnt = hdev->acl_cnt; 22226ed58ec5SVille Tervo break; 22236ed58ec5SVille Tervo case SCO_LINK: 22246ed58ec5SVille Tervo case ESCO_LINK: 22256ed58ec5SVille Tervo cnt = hdev->sco_cnt; 22266ed58ec5SVille Tervo break; 22276ed58ec5SVille Tervo case LE_LINK: 22286ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 22296ed58ec5SVille Tervo break; 22306ed58ec5SVille Tervo default: 22316ed58ec5SVille Tervo cnt = 0; 22326ed58ec5SVille Tervo BT_ERR("Unknown link type"); 22336ed58ec5SVille Tervo } 22346ed58ec5SVille Tervo 22356ed58ec5SVille Tervo q = cnt / num; 22361da177e4SLinus Torvalds *quote = q ? q : 1; 22371da177e4SLinus Torvalds } else 22381da177e4SLinus Torvalds *quote = 0; 22391da177e4SLinus Torvalds 22401da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 22411da177e4SLinus Torvalds return conn; 22421da177e4SLinus Torvalds } 22431da177e4SLinus Torvalds 2244bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 22451da177e4SLinus Torvalds { 22461da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 22471da177e4SLinus Torvalds struct hci_conn *c; 22481da177e4SLinus Torvalds 2249bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 22501da177e4SLinus Torvalds 2251bf4c6325SGustavo F. Padovan rcu_read_lock(); 2252bf4c6325SGustavo F. Padovan 22531da177e4SLinus Torvalds /* Kill stalled connections */ 2254bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2255bae1f5d9SVille Tervo if (c->type == type && c->sent) { 2256bae1f5d9SVille Tervo BT_ERR("%s killing stalled connection %s", 22571da177e4SLinus Torvalds hdev->name, batostr(&c->dst)); 22581da177e4SLinus Torvalds hci_acl_disconn(c, 0x13); 22591da177e4SLinus Torvalds } 22601da177e4SLinus Torvalds } 2261bf4c6325SGustavo F. Padovan 2262bf4c6325SGustavo F. Padovan rcu_read_unlock(); 22631da177e4SLinus Torvalds } 22641da177e4SLinus Torvalds 226573d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 226673d80debSLuiz Augusto von Dentz int *quote) 226773d80debSLuiz Augusto von Dentz { 226873d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 226973d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 227073d80debSLuiz Augusto von Dentz int num = 0, min = ~0, cur_prio = 0; 227173d80debSLuiz Augusto von Dentz struct hci_conn *conn; 227273d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 227373d80debSLuiz Augusto von Dentz 227473d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 227573d80debSLuiz Augusto von Dentz 2276bf4c6325SGustavo F. Padovan rcu_read_lock(); 2277bf4c6325SGustavo F. Padovan 2278bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 227973d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 228073d80debSLuiz Augusto von Dentz 228173d80debSLuiz Augusto von Dentz if (conn->type != type) 228273d80debSLuiz Augusto von Dentz continue; 228373d80debSLuiz Augusto von Dentz 228473d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 228573d80debSLuiz Augusto von Dentz continue; 228673d80debSLuiz Augusto von Dentz 228773d80debSLuiz Augusto von Dentz conn_num++; 228873d80debSLuiz Augusto von Dentz 22898192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 229073d80debSLuiz Augusto von Dentz struct sk_buff *skb; 229173d80debSLuiz Augusto von Dentz 229273d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 229373d80debSLuiz Augusto von Dentz continue; 229473d80debSLuiz Augusto von Dentz 229573d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 229673d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 229773d80debSLuiz Augusto von Dentz continue; 229873d80debSLuiz Augusto von Dentz 229973d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 230073d80debSLuiz Augusto von Dentz num = 0; 230173d80debSLuiz Augusto von Dentz min = ~0; 230273d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 230373d80debSLuiz Augusto von Dentz } 230473d80debSLuiz Augusto von Dentz 230573d80debSLuiz Augusto von Dentz num++; 230673d80debSLuiz Augusto von Dentz 230773d80debSLuiz Augusto von Dentz if (conn->sent < min) { 230873d80debSLuiz Augusto von Dentz min = conn->sent; 230973d80debSLuiz Augusto von Dentz chan = tmp; 231073d80debSLuiz Augusto von Dentz } 231173d80debSLuiz Augusto von Dentz } 231273d80debSLuiz Augusto von Dentz 231373d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 231473d80debSLuiz Augusto von Dentz break; 231573d80debSLuiz Augusto von Dentz } 231673d80debSLuiz Augusto von Dentz 2317bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2318bf4c6325SGustavo F. Padovan 231973d80debSLuiz Augusto von Dentz if (!chan) 232073d80debSLuiz Augusto von Dentz return NULL; 232173d80debSLuiz Augusto von Dentz 232273d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 232373d80debSLuiz Augusto von Dentz case ACL_LINK: 232473d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 232573d80debSLuiz Augusto von Dentz break; 232673d80debSLuiz Augusto von Dentz case SCO_LINK: 232773d80debSLuiz Augusto von Dentz case ESCO_LINK: 232873d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 232973d80debSLuiz Augusto von Dentz break; 233073d80debSLuiz Augusto von Dentz case LE_LINK: 233173d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 233273d80debSLuiz Augusto von Dentz break; 233373d80debSLuiz Augusto von Dentz default: 233473d80debSLuiz Augusto von Dentz cnt = 0; 233573d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 233673d80debSLuiz Augusto von Dentz } 233773d80debSLuiz Augusto von Dentz 233873d80debSLuiz Augusto von Dentz q = cnt / num; 233973d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 234073d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 234173d80debSLuiz Augusto von Dentz return chan; 234273d80debSLuiz Augusto von Dentz } 234373d80debSLuiz Augusto von Dentz 234402b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 234502b20f0bSLuiz Augusto von Dentz { 234602b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 234702b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 234802b20f0bSLuiz Augusto von Dentz int num = 0; 234902b20f0bSLuiz Augusto von Dentz 235002b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 235102b20f0bSLuiz Augusto von Dentz 2352bf4c6325SGustavo F. Padovan rcu_read_lock(); 2353bf4c6325SGustavo F. Padovan 2354bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 235502b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 235602b20f0bSLuiz Augusto von Dentz 235702b20f0bSLuiz Augusto von Dentz if (conn->type != type) 235802b20f0bSLuiz Augusto von Dentz continue; 235902b20f0bSLuiz Augusto von Dentz 236002b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 236102b20f0bSLuiz Augusto von Dentz continue; 236202b20f0bSLuiz Augusto von Dentz 236302b20f0bSLuiz Augusto von Dentz num++; 236402b20f0bSLuiz Augusto von Dentz 23658192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 236602b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 236702b20f0bSLuiz Augusto von Dentz 236802b20f0bSLuiz Augusto von Dentz if (chan->sent) { 236902b20f0bSLuiz Augusto von Dentz chan->sent = 0; 237002b20f0bSLuiz Augusto von Dentz continue; 237102b20f0bSLuiz Augusto von Dentz } 237202b20f0bSLuiz Augusto von Dentz 237302b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 237402b20f0bSLuiz Augusto von Dentz continue; 237502b20f0bSLuiz Augusto von Dentz 237602b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 237702b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 237802b20f0bSLuiz Augusto von Dentz continue; 237902b20f0bSLuiz Augusto von Dentz 238002b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 238102b20f0bSLuiz Augusto von Dentz 238202b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 238302b20f0bSLuiz Augusto von Dentz skb->priority); 238402b20f0bSLuiz Augusto von Dentz } 238502b20f0bSLuiz Augusto von Dentz 238602b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 238702b20f0bSLuiz Augusto von Dentz break; 238802b20f0bSLuiz Augusto von Dentz } 2389bf4c6325SGustavo F. Padovan 2390bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2391bf4c6325SGustavo F. Padovan 239202b20f0bSLuiz Augusto von Dentz } 239302b20f0bSLuiz Augusto von Dentz 23941da177e4SLinus Torvalds static inline void hci_sched_acl(struct hci_dev *hdev) 23951da177e4SLinus Torvalds { 239673d80debSLuiz Augusto von Dentz struct hci_chan *chan; 23971da177e4SLinus Torvalds struct sk_buff *skb; 23981da177e4SLinus Torvalds int quote; 239973d80debSLuiz Augusto von Dentz unsigned int cnt; 24001da177e4SLinus Torvalds 24011da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 24021da177e4SLinus Torvalds 240352087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ACL_LINK)) 240452087a79SLuiz Augusto von Dentz return; 240552087a79SLuiz Augusto von Dentz 24061da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 24071da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 24081da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 2409cc48dc0aSAndrei Emeltchenko if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + 2410cc48dc0aSAndrei Emeltchenko msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) 2411bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 24121da177e4SLinus Torvalds } 24131da177e4SLinus Torvalds 241473d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 241504837f64SMarcel Holtmann 241673d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 241773d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2418ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2419ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 242073d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 242173d80debSLuiz Augusto von Dentz skb->len, skb->priority); 242273d80debSLuiz Augusto von Dentz 2423ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2424ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2425ec1cce24SLuiz Augusto von Dentz break; 2426ec1cce24SLuiz Augusto von Dentz 2427ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2428ec1cce24SLuiz Augusto von Dentz 242973d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 243073d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 243104837f64SMarcel Holtmann 24321da177e4SLinus Torvalds hci_send_frame(skb); 24331da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 24341da177e4SLinus Torvalds 24351da177e4SLinus Torvalds hdev->acl_cnt--; 243673d80debSLuiz Augusto von Dentz chan->sent++; 243773d80debSLuiz Augusto von Dentz chan->conn->sent++; 24381da177e4SLinus Torvalds } 24391da177e4SLinus Torvalds } 244002b20f0bSLuiz Augusto von Dentz 244102b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 244202b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 24431da177e4SLinus Torvalds } 24441da177e4SLinus Torvalds 24451da177e4SLinus Torvalds /* Schedule SCO */ 24461da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev) 24471da177e4SLinus Torvalds { 24481da177e4SLinus Torvalds struct hci_conn *conn; 24491da177e4SLinus Torvalds struct sk_buff *skb; 24501da177e4SLinus Torvalds int quote; 24511da177e4SLinus Torvalds 24521da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 24531da177e4SLinus Torvalds 245452087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 245552087a79SLuiz Augusto von Dentz return; 245652087a79SLuiz Augusto von Dentz 24571da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 24581da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 24591da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 24601da177e4SLinus Torvalds hci_send_frame(skb); 24611da177e4SLinus Torvalds 24621da177e4SLinus Torvalds conn->sent++; 24631da177e4SLinus Torvalds if (conn->sent == ~0) 24641da177e4SLinus Torvalds conn->sent = 0; 24651da177e4SLinus Torvalds } 24661da177e4SLinus Torvalds } 24671da177e4SLinus Torvalds } 24681da177e4SLinus Torvalds 2469b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev) 2470b6a0dc82SMarcel Holtmann { 2471b6a0dc82SMarcel Holtmann struct hci_conn *conn; 2472b6a0dc82SMarcel Holtmann struct sk_buff *skb; 2473b6a0dc82SMarcel Holtmann int quote; 2474b6a0dc82SMarcel Holtmann 2475b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 2476b6a0dc82SMarcel Holtmann 247752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 247852087a79SLuiz Augusto von Dentz return; 247952087a79SLuiz Augusto von Dentz 2480b6a0dc82SMarcel Holtmann while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, "e))) { 2481b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 2482b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 2483b6a0dc82SMarcel Holtmann hci_send_frame(skb); 2484b6a0dc82SMarcel Holtmann 2485b6a0dc82SMarcel Holtmann conn->sent++; 2486b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 2487b6a0dc82SMarcel Holtmann conn->sent = 0; 2488b6a0dc82SMarcel Holtmann } 2489b6a0dc82SMarcel Holtmann } 2490b6a0dc82SMarcel Holtmann } 2491b6a0dc82SMarcel Holtmann 24926ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev) 24936ed58ec5SVille Tervo { 249473d80debSLuiz Augusto von Dentz struct hci_chan *chan; 24956ed58ec5SVille Tervo struct sk_buff *skb; 249602b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 24976ed58ec5SVille Tervo 24986ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 24996ed58ec5SVille Tervo 250052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 250152087a79SLuiz Augusto von Dentz return; 250252087a79SLuiz Augusto von Dentz 25036ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 25046ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 25056ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 2506bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 25076ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 2508bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 25096ed58ec5SVille Tervo } 25106ed58ec5SVille Tervo 25116ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 251202b20f0bSLuiz Augusto von Dentz tmp = cnt; 251373d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 2514ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2515ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 251673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 251773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 25186ed58ec5SVille Tervo 2519ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2520ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2521ec1cce24SLuiz Augusto von Dentz break; 2522ec1cce24SLuiz Augusto von Dentz 2523ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2524ec1cce24SLuiz Augusto von Dentz 25256ed58ec5SVille Tervo hci_send_frame(skb); 25266ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 25276ed58ec5SVille Tervo 25286ed58ec5SVille Tervo cnt--; 252973d80debSLuiz Augusto von Dentz chan->sent++; 253073d80debSLuiz Augusto von Dentz chan->conn->sent++; 25316ed58ec5SVille Tervo } 25326ed58ec5SVille Tervo } 253373d80debSLuiz Augusto von Dentz 25346ed58ec5SVille Tervo if (hdev->le_pkts) 25356ed58ec5SVille Tervo hdev->le_cnt = cnt; 25366ed58ec5SVille Tervo else 25376ed58ec5SVille Tervo hdev->acl_cnt = cnt; 253802b20f0bSLuiz Augusto von Dentz 253902b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 254002b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 25416ed58ec5SVille Tervo } 25426ed58ec5SVille Tervo 25433eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 25441da177e4SLinus Torvalds { 25453eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 25461da177e4SLinus Torvalds struct sk_buff *skb; 25471da177e4SLinus Torvalds 25486ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 25496ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 25501da177e4SLinus Torvalds 25511da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 25521da177e4SLinus Torvalds 25531da177e4SLinus Torvalds hci_sched_acl(hdev); 25541da177e4SLinus Torvalds 25551da177e4SLinus Torvalds hci_sched_sco(hdev); 25561da177e4SLinus Torvalds 2557b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 2558b6a0dc82SMarcel Holtmann 25596ed58ec5SVille Tervo hci_sched_le(hdev); 25606ed58ec5SVille Tervo 25611da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 25621da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 25631da177e4SLinus Torvalds hci_send_frame(skb); 25641da177e4SLinus Torvalds } 25651da177e4SLinus Torvalds 256625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 25671da177e4SLinus Torvalds 25681da177e4SLinus Torvalds /* ACL data packet */ 25691da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 25701da177e4SLinus Torvalds { 25711da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 25721da177e4SLinus Torvalds struct hci_conn *conn; 25731da177e4SLinus Torvalds __u16 handle, flags; 25741da177e4SLinus Torvalds 25751da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 25761da177e4SLinus Torvalds 25771da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 25781da177e4SLinus Torvalds flags = hci_flags(handle); 25791da177e4SLinus Torvalds handle = hci_handle(handle); 25801da177e4SLinus Torvalds 25811da177e4SLinus Torvalds BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags); 25821da177e4SLinus Torvalds 25831da177e4SLinus Torvalds hdev->stat.acl_rx++; 25841da177e4SLinus Torvalds 25851da177e4SLinus Torvalds hci_dev_lock(hdev); 25861da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 25871da177e4SLinus Torvalds hci_dev_unlock(hdev); 25881da177e4SLinus Torvalds 25891da177e4SLinus Torvalds if (conn) { 259065983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 259104837f64SMarcel Holtmann 25921da177e4SLinus Torvalds /* Send to upper protocol */ 2593686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 25941da177e4SLinus Torvalds return; 25951da177e4SLinus Torvalds } else { 25961da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 25971da177e4SLinus Torvalds hdev->name, handle); 25981da177e4SLinus Torvalds } 25991da177e4SLinus Torvalds 26001da177e4SLinus Torvalds kfree_skb(skb); 26011da177e4SLinus Torvalds } 26021da177e4SLinus Torvalds 26031da177e4SLinus Torvalds /* SCO data packet */ 26041da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 26051da177e4SLinus Torvalds { 26061da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 26071da177e4SLinus Torvalds struct hci_conn *conn; 26081da177e4SLinus Torvalds __u16 handle; 26091da177e4SLinus Torvalds 26101da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 26111da177e4SLinus Torvalds 26121da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 26131da177e4SLinus Torvalds 26141da177e4SLinus Torvalds BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle); 26151da177e4SLinus Torvalds 26161da177e4SLinus Torvalds hdev->stat.sco_rx++; 26171da177e4SLinus Torvalds 26181da177e4SLinus Torvalds hci_dev_lock(hdev); 26191da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 26201da177e4SLinus Torvalds hci_dev_unlock(hdev); 26211da177e4SLinus Torvalds 26221da177e4SLinus Torvalds if (conn) { 26231da177e4SLinus Torvalds /* Send to upper protocol */ 2624686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 26251da177e4SLinus Torvalds return; 26261da177e4SLinus Torvalds } else { 26271da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 26281da177e4SLinus Torvalds hdev->name, handle); 26291da177e4SLinus Torvalds } 26301da177e4SLinus Torvalds 26311da177e4SLinus Torvalds kfree_skb(skb); 26321da177e4SLinus Torvalds } 26331da177e4SLinus Torvalds 2634b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 26351da177e4SLinus Torvalds { 2636b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 26371da177e4SLinus Torvalds struct sk_buff *skb; 26381da177e4SLinus Torvalds 26391da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 26401da177e4SLinus Torvalds 26411da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 26421da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 26431da177e4SLinus Torvalds /* Send copy to the sockets */ 2644eec8d2bcSJohan Hedberg hci_send_to_sock(hdev, skb, NULL); 26451da177e4SLinus Torvalds } 26461da177e4SLinus Torvalds 26471da177e4SLinus Torvalds if (test_bit(HCI_RAW, &hdev->flags)) { 26481da177e4SLinus Torvalds kfree_skb(skb); 26491da177e4SLinus Torvalds continue; 26501da177e4SLinus Torvalds } 26511da177e4SLinus Torvalds 26521da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 26531da177e4SLinus Torvalds /* Don't process data packets in this states. */ 26540d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 26551da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 26561da177e4SLinus Torvalds case HCI_SCODATA_PKT: 26571da177e4SLinus Torvalds kfree_skb(skb); 26581da177e4SLinus Torvalds continue; 26593ff50b79SStephen Hemminger } 26601da177e4SLinus Torvalds } 26611da177e4SLinus Torvalds 26621da177e4SLinus Torvalds /* Process frame */ 26630d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 26641da177e4SLinus Torvalds case HCI_EVENT_PKT: 2665b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 26661da177e4SLinus Torvalds hci_event_packet(hdev, skb); 26671da177e4SLinus Torvalds break; 26681da177e4SLinus Torvalds 26691da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 26701da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 26711da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 26721da177e4SLinus Torvalds break; 26731da177e4SLinus Torvalds 26741da177e4SLinus Torvalds case HCI_SCODATA_PKT: 26751da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 26761da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 26771da177e4SLinus Torvalds break; 26781da177e4SLinus Torvalds 26791da177e4SLinus Torvalds default: 26801da177e4SLinus Torvalds kfree_skb(skb); 26811da177e4SLinus Torvalds break; 26821da177e4SLinus Torvalds } 26831da177e4SLinus Torvalds } 26841da177e4SLinus Torvalds } 26851da177e4SLinus Torvalds 2686c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 26871da177e4SLinus Torvalds { 2688c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 26891da177e4SLinus Torvalds struct sk_buff *skb; 26901da177e4SLinus Torvalds 26911da177e4SLinus Torvalds BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); 26921da177e4SLinus Torvalds 26931da177e4SLinus Torvalds /* Send queued commands */ 26945a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 26955a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 26965a08ecceSAndrei Emeltchenko if (!skb) 26975a08ecceSAndrei Emeltchenko return; 26985a08ecceSAndrei Emeltchenko 26991da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 27001da177e4SLinus Torvalds 270170f23020SAndrei Emeltchenko hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC); 270270f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 27031da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 27041da177e4SLinus Torvalds hci_send_frame(skb); 27057bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 27067bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 27077bdb8a5cSSzymon Janc else 27086bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 27096bd32326SVille Tervo jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); 27101da177e4SLinus Torvalds } else { 27111da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 2712c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 27131da177e4SLinus Torvalds } 27141da177e4SLinus Torvalds } 27151da177e4SLinus Torvalds } 27162519a1fcSAndre Guedes 27172519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length) 27182519a1fcSAndre Guedes { 27192519a1fcSAndre Guedes /* General inquiry access code (GIAC) */ 27202519a1fcSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 27212519a1fcSAndre Guedes struct hci_cp_inquiry cp; 27222519a1fcSAndre Guedes 27232519a1fcSAndre Guedes BT_DBG("%s", hdev->name); 27242519a1fcSAndre Guedes 27252519a1fcSAndre Guedes if (test_bit(HCI_INQUIRY, &hdev->flags)) 27262519a1fcSAndre Guedes return -EINPROGRESS; 27272519a1fcSAndre Guedes 27284663262cSJohan Hedberg inquiry_cache_flush(hdev); 27294663262cSJohan Hedberg 27302519a1fcSAndre Guedes memset(&cp, 0, sizeof(cp)); 27312519a1fcSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 27322519a1fcSAndre Guedes cp.length = length; 27332519a1fcSAndre Guedes 27342519a1fcSAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 27352519a1fcSAndre Guedes } 2736023d5049SAndre Guedes 2737023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev) 2738023d5049SAndre Guedes { 2739023d5049SAndre Guedes BT_DBG("%s", hdev->name); 2740023d5049SAndre Guedes 2741023d5049SAndre Guedes if (!test_bit(HCI_INQUIRY, &hdev->flags)) 2742023d5049SAndre Guedes return -EPERM; 2743023d5049SAndre Guedes 2744023d5049SAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); 2745023d5049SAndre Guedes } 27467784d78fSAndrei Emeltchenko 27477784d78fSAndrei Emeltchenko module_param(enable_hs, bool, 0644); 27487784d78fSAndrei Emeltchenko MODULE_PARM_DESC(enable_hs, "Enable High Speed"); 2749