11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 31da177e4SLinus Torvalds Copyright (C) 2000-2001 Qualcomm Incorporated 4590051deSGustavo F. Padovan Copyright (C) 2011 ProFUSION Embedded Systems 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 91da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 101da177e4SLinus Torvalds published by the Free Software Foundation; 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 131da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 141da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 151da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 161da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 171da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 181da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 191da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 221da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 231da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 241da177e4SLinus Torvalds */ 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds /* Bluetooth HCI core. */ 271da177e4SLinus Torvalds 2882453021SS.Çağlar Onur #include <linux/jiffies.h> 291da177e4SLinus Torvalds #include <linux/module.h> 301da177e4SLinus Torvalds #include <linux/kmod.h> 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds #include <linux/types.h> 331da177e4SLinus Torvalds #include <linux/errno.h> 341da177e4SLinus Torvalds #include <linux/kernel.h> 351da177e4SLinus Torvalds #include <linux/sched.h> 361da177e4SLinus Torvalds #include <linux/slab.h> 371da177e4SLinus Torvalds #include <linux/poll.h> 381da177e4SLinus Torvalds #include <linux/fcntl.h> 391da177e4SLinus Torvalds #include <linux/init.h> 401da177e4SLinus Torvalds #include <linux/skbuff.h> 41f48fd9c8SMarcel Holtmann #include <linux/workqueue.h> 421da177e4SLinus Torvalds #include <linux/interrupt.h> 43611b30f7SMarcel Holtmann #include <linux/rfkill.h> 446bd32326SVille Tervo #include <linux/timer.h> 453a0259bbSVinicius Costa Gomes #include <linux/crypto.h> 461da177e4SLinus Torvalds #include <net/sock.h> 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds #include <asm/system.h> 4970f23020SAndrei Emeltchenko #include <linux/uaccess.h> 501da177e4SLinus Torvalds #include <asm/unaligned.h> 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 531da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 541da177e4SLinus Torvalds 55ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000 56ab81cbf9SJohan Hedberg 57b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 58c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 593eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds /* HCI device list */ 621da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 631da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds /* HCI callback list */ 661da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 671da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 701da177e4SLinus Torvalds 716516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 721da177e4SLinus Torvalds { 73040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 741da177e4SLinus Torvalds } 751da177e4SLinus Torvalds 761da177e4SLinus Torvalds /* ---- HCI requests ---- */ 771da177e4SLinus Torvalds 7823bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) 791da177e4SLinus Torvalds { 8023bb5763SJohan Hedberg BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result); 8123bb5763SJohan Hedberg 82a5040efaSJohan Hedberg /* If this is the init phase check if the completed command matches 83a5040efaSJohan Hedberg * the last init command, and if not just return. 84a5040efaSJohan Hedberg */ 85a5040efaSJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) 8623bb5763SJohan Hedberg return; 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 891da177e4SLinus Torvalds hdev->req_result = result; 901da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 911da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 921da177e4SLinus Torvalds } 931da177e4SLinus Torvalds } 941da177e4SLinus Torvalds 951da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 961da177e4SLinus Torvalds { 971da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 981da177e4SLinus Torvalds 991da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 1001da177e4SLinus Torvalds hdev->req_result = err; 1011da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 1021da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 1031da177e4SLinus Torvalds } 1041da177e4SLinus Torvalds } 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds /* Execute request and wait for completion. */ 1071da177e4SLinus Torvalds static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), 1081da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 1091da177e4SLinus Torvalds { 1101da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 1111da177e4SLinus Torvalds int err = 0; 1121da177e4SLinus Torvalds 1131da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds add_wait_queue(&hdev->req_wait_q, &wait); 1181da177e4SLinus Torvalds set_current_state(TASK_INTERRUPTIBLE); 1191da177e4SLinus Torvalds 1201da177e4SLinus Torvalds req(hdev, opt); 1211da177e4SLinus Torvalds schedule_timeout(timeout); 1221da177e4SLinus Torvalds 1231da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 1241da177e4SLinus Torvalds 1251da177e4SLinus Torvalds if (signal_pending(current)) 1261da177e4SLinus Torvalds return -EINTR; 1271da177e4SLinus Torvalds 1281da177e4SLinus Torvalds switch (hdev->req_status) { 1291da177e4SLinus Torvalds case HCI_REQ_DONE: 130e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 1311da177e4SLinus Torvalds break; 1321da177e4SLinus Torvalds 1331da177e4SLinus Torvalds case HCI_REQ_CANCELED: 1341da177e4SLinus Torvalds err = -hdev->req_result; 1351da177e4SLinus Torvalds break; 1361da177e4SLinus Torvalds 1371da177e4SLinus Torvalds default: 1381da177e4SLinus Torvalds err = -ETIMEDOUT; 1391da177e4SLinus Torvalds break; 1403ff50b79SStephen Hemminger } 1411da177e4SLinus Torvalds 142a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 1431da177e4SLinus Torvalds 1441da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 1451da177e4SLinus Torvalds 1461da177e4SLinus Torvalds return err; 1471da177e4SLinus Torvalds } 1481da177e4SLinus Torvalds 1491da177e4SLinus Torvalds static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), 1501da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 1511da177e4SLinus Torvalds { 1521da177e4SLinus Torvalds int ret; 1531da177e4SLinus Torvalds 1547c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 1557c6a329eSMarcel Holtmann return -ENETDOWN; 1567c6a329eSMarcel Holtmann 1571da177e4SLinus Torvalds /* Serialize all requests */ 1581da177e4SLinus Torvalds hci_req_lock(hdev); 1591da177e4SLinus Torvalds ret = __hci_request(hdev, req, opt, timeout); 1601da177e4SLinus Torvalds hci_req_unlock(hdev); 1611da177e4SLinus Torvalds 1621da177e4SLinus Torvalds return ret; 1631da177e4SLinus Torvalds } 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) 1661da177e4SLinus Torvalds { 1671da177e4SLinus Torvalds BT_DBG("%s %ld", hdev->name, opt); 1681da177e4SLinus Torvalds 1691da177e4SLinus Torvalds /* Reset device */ 170f630cf0dSGustavo F. Padovan set_bit(HCI_RESET, &hdev->flags); 171a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 1721da177e4SLinus Torvalds } 1731da177e4SLinus Torvalds 174e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev) 1751da177e4SLinus Torvalds { 176b0916ea0SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 1771ebb9252SMarcel Holtmann __le16 param; 17889f2783dSMarcel Holtmann __u8 flt_type; 1791da177e4SLinus Torvalds 1802455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 1812455a3eaSAndrei Emeltchenko 1821da177e4SLinus Torvalds /* Mandatory initialization */ 1831da177e4SLinus Torvalds 1841da177e4SLinus Torvalds /* Reset */ 185f630cf0dSGustavo F. Padovan if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { 186f630cf0dSGustavo F. Padovan set_bit(HCI_RESET, &hdev->flags); 187a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 188f630cf0dSGustavo F. Padovan } 1891da177e4SLinus Torvalds 1901da177e4SLinus Torvalds /* Read Local Supported Features */ 191a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 1921da177e4SLinus Torvalds 1931143e5a6SMarcel Holtmann /* Read Local Version */ 194a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 1951143e5a6SMarcel Holtmann 1961da177e4SLinus Torvalds /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 197a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 1981da177e4SLinus Torvalds 1991da177e4SLinus Torvalds /* Read BD Address */ 200a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); 201a9de9248SMarcel Holtmann 202a9de9248SMarcel Holtmann /* Read Class of Device */ 203a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 204a9de9248SMarcel Holtmann 205a9de9248SMarcel Holtmann /* Read Local Name */ 206a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); 2071da177e4SLinus Torvalds 2081da177e4SLinus Torvalds /* Read Voice Setting */ 209a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); 2101da177e4SLinus Torvalds 2111da177e4SLinus Torvalds /* Optional initialization */ 2121da177e4SLinus Torvalds 2131da177e4SLinus Torvalds /* Clear Event Filters */ 21489f2783dSMarcel Holtmann flt_type = HCI_FLT_CLEAR_ALL; 215a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 2161da177e4SLinus Torvalds 2171da177e4SLinus Torvalds /* Connection accept timeout ~20 secs */ 218aca3192cSYOSHIFUJI Hideaki param = cpu_to_le16(0x7d00); 219a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 220b0916ea0SJohan Hedberg 221b0916ea0SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 222b0916ea0SJohan Hedberg cp.delete_all = 1; 223b0916ea0SJohan Hedberg hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); 2241da177e4SLinus Torvalds } 2251da177e4SLinus Torvalds 226e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev) 227e61ef499SAndrei Emeltchenko { 2282455a3eaSAndrei Emeltchenko hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 2292455a3eaSAndrei Emeltchenko 230e61ef499SAndrei Emeltchenko /* Reset */ 231e61ef499SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); 232e61ef499SAndrei Emeltchenko 233e61ef499SAndrei Emeltchenko /* Read Local Version */ 234e61ef499SAndrei Emeltchenko hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 235e61ef499SAndrei Emeltchenko } 236e61ef499SAndrei Emeltchenko 237e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt) 238e61ef499SAndrei Emeltchenko { 239e61ef499SAndrei Emeltchenko struct sk_buff *skb; 240e61ef499SAndrei Emeltchenko 241e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 242e61ef499SAndrei Emeltchenko 243e61ef499SAndrei Emeltchenko /* Driver initialization */ 244e61ef499SAndrei Emeltchenko 245e61ef499SAndrei Emeltchenko /* Special commands */ 246e61ef499SAndrei Emeltchenko while ((skb = skb_dequeue(&hdev->driver_init))) { 247e61ef499SAndrei Emeltchenko bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 248e61ef499SAndrei Emeltchenko skb->dev = (void *) hdev; 249e61ef499SAndrei Emeltchenko 250e61ef499SAndrei Emeltchenko skb_queue_tail(&hdev->cmd_q, skb); 251e61ef499SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->cmd_work); 252e61ef499SAndrei Emeltchenko } 253e61ef499SAndrei Emeltchenko skb_queue_purge(&hdev->driver_init); 254e61ef499SAndrei Emeltchenko 255e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 256e61ef499SAndrei Emeltchenko case HCI_BREDR: 257e61ef499SAndrei Emeltchenko bredr_init(hdev); 258e61ef499SAndrei Emeltchenko break; 259e61ef499SAndrei Emeltchenko 260e61ef499SAndrei Emeltchenko case HCI_AMP: 261e61ef499SAndrei Emeltchenko amp_init(hdev); 262e61ef499SAndrei Emeltchenko break; 263e61ef499SAndrei Emeltchenko 264e61ef499SAndrei Emeltchenko default: 265e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 266e61ef499SAndrei Emeltchenko break; 267e61ef499SAndrei Emeltchenko } 268e61ef499SAndrei Emeltchenko 269e61ef499SAndrei Emeltchenko } 270e61ef499SAndrei Emeltchenko 2716ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) 2726ed58ec5SVille Tervo { 2736ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 2746ed58ec5SVille Tervo 2756ed58ec5SVille Tervo /* Read LE buffer size */ 2766ed58ec5SVille Tervo hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 2776ed58ec5SVille Tervo } 2786ed58ec5SVille Tervo 2791da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) 2801da177e4SLinus Torvalds { 2811da177e4SLinus Torvalds __u8 scan = opt; 2821da177e4SLinus Torvalds 2831da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, scan); 2841da177e4SLinus Torvalds 2851da177e4SLinus Torvalds /* Inquiry and Page scans */ 286a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 2871da177e4SLinus Torvalds } 2881da177e4SLinus Torvalds 2891da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt) 2901da177e4SLinus Torvalds { 2911da177e4SLinus Torvalds __u8 auth = opt; 2921da177e4SLinus Torvalds 2931da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, auth); 2941da177e4SLinus Torvalds 2951da177e4SLinus Torvalds /* Authentication */ 296a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 2971da177e4SLinus Torvalds } 2981da177e4SLinus Torvalds 2991da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt) 3001da177e4SLinus Torvalds { 3011da177e4SLinus Torvalds __u8 encrypt = opt; 3021da177e4SLinus Torvalds 3031da177e4SLinus Torvalds BT_DBG("%s %x", hdev->name, encrypt); 3041da177e4SLinus Torvalds 305e4e8e37cSMarcel Holtmann /* Encryption */ 306a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 3071da177e4SLinus Torvalds } 3081da177e4SLinus Torvalds 309e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt) 310e4e8e37cSMarcel Holtmann { 311e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 312e4e8e37cSMarcel Holtmann 313a418b893SMarcel Holtmann BT_DBG("%s %x", hdev->name, policy); 314e4e8e37cSMarcel Holtmann 315e4e8e37cSMarcel Holtmann /* Default link policy */ 316e4e8e37cSMarcel Holtmann hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 317e4e8e37cSMarcel Holtmann } 318e4e8e37cSMarcel Holtmann 3191da177e4SLinus Torvalds /* Get HCI device by index. 3201da177e4SLinus Torvalds * Device is held on return. */ 3211da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 3221da177e4SLinus Torvalds { 3238035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 3241da177e4SLinus Torvalds 3251da177e4SLinus Torvalds BT_DBG("%d", index); 3261da177e4SLinus Torvalds 3271da177e4SLinus Torvalds if (index < 0) 3281da177e4SLinus Torvalds return NULL; 3291da177e4SLinus Torvalds 3301da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 3318035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 3321da177e4SLinus Torvalds if (d->id == index) { 3331da177e4SLinus Torvalds hdev = hci_dev_hold(d); 3341da177e4SLinus Torvalds break; 3351da177e4SLinus Torvalds } 3361da177e4SLinus Torvalds } 3371da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 3381da177e4SLinus Torvalds return hdev; 3391da177e4SLinus Torvalds } 3401da177e4SLinus Torvalds 3411da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 342ff9ef578SJohan Hedberg 34330dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 34430dc78e1SJohan Hedberg { 34530dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 34630dc78e1SJohan Hedberg 3476fbe195dSAndre Guedes switch (discov->state) { 348343f935bSAndre Guedes case DISCOVERY_FINDING: 3496fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 35030dc78e1SJohan Hedberg return true; 35130dc78e1SJohan Hedberg 3526fbe195dSAndre Guedes default: 35330dc78e1SJohan Hedberg return false; 35430dc78e1SJohan Hedberg } 3556fbe195dSAndre Guedes } 35630dc78e1SJohan Hedberg 357ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 358ff9ef578SJohan Hedberg { 359ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 360ff9ef578SJohan Hedberg 361ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 362ff9ef578SJohan Hedberg return; 363ff9ef578SJohan Hedberg 364ff9ef578SJohan Hedberg switch (state) { 365ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 3667b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 367ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 368f963e8e9SJohan Hedberg hdev->discovery.type = 0; 369ff9ef578SJohan Hedberg break; 370ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 371ff9ef578SJohan Hedberg break; 372343f935bSAndre Guedes case DISCOVERY_FINDING: 373ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 374ff9ef578SJohan Hedberg break; 37530dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 37630dc78e1SJohan Hedberg break; 377ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 378ff9ef578SJohan Hedberg break; 379ff9ef578SJohan Hedberg } 380ff9ef578SJohan Hedberg 381ff9ef578SJohan Hedberg hdev->discovery.state = state; 382ff9ef578SJohan Hedberg } 383ff9ef578SJohan Hedberg 3841da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev) 3851da177e4SLinus Torvalds { 38630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 387b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 3881da177e4SLinus Torvalds 389561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 390561aafbcSJohan Hedberg list_del(&p->all); 391b57c1a56SJohan Hedberg kfree(p); 3921da177e4SLinus Torvalds } 393561aafbcSJohan Hedberg 394561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 395561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 396ff9ef578SJohan Hedberg cache->state = DISCOVERY_STOPPED; 3971da177e4SLinus Torvalds } 3981da177e4SLinus Torvalds 3991da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 4001da177e4SLinus Torvalds { 40130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 4021da177e4SLinus Torvalds struct inquiry_entry *e; 4031da177e4SLinus Torvalds 4041da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 4051da177e4SLinus Torvalds 406561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 4071da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 4081da177e4SLinus Torvalds return e; 4091da177e4SLinus Torvalds } 4101da177e4SLinus Torvalds 411b57c1a56SJohan Hedberg return NULL; 412b57c1a56SJohan Hedberg } 413b57c1a56SJohan Hedberg 414561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 415561aafbcSJohan Hedberg bdaddr_t *bdaddr) 416561aafbcSJohan Hedberg { 41730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 418561aafbcSJohan Hedberg struct inquiry_entry *e; 419561aafbcSJohan Hedberg 420561aafbcSJohan Hedberg BT_DBG("cache %p, %s", cache, batostr(bdaddr)); 421561aafbcSJohan Hedberg 422561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 423561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 424561aafbcSJohan Hedberg return e; 425561aafbcSJohan Hedberg } 426561aafbcSJohan Hedberg 427561aafbcSJohan Hedberg return NULL; 428561aafbcSJohan Hedberg } 429561aafbcSJohan Hedberg 43030dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 43130dc78e1SJohan Hedberg bdaddr_t *bdaddr, 43230dc78e1SJohan Hedberg int state) 43330dc78e1SJohan Hedberg { 43430dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 43530dc78e1SJohan Hedberg struct inquiry_entry *e; 43630dc78e1SJohan Hedberg 43730dc78e1SJohan Hedberg BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state); 43830dc78e1SJohan Hedberg 43930dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 44030dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 44130dc78e1SJohan Hedberg return e; 44230dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 44330dc78e1SJohan Hedberg return e; 44430dc78e1SJohan Hedberg } 44530dc78e1SJohan Hedberg 44630dc78e1SJohan Hedberg return NULL; 44730dc78e1SJohan Hedberg } 44830dc78e1SJohan Hedberg 449a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 450a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 451a3d4e20aSJohan Hedberg { 452a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 453a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 454a3d4e20aSJohan Hedberg struct inquiry_entry *p; 455a3d4e20aSJohan Hedberg 456a3d4e20aSJohan Hedberg list_del(&ie->list); 457a3d4e20aSJohan Hedberg 458a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 459a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 460a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 461a3d4e20aSJohan Hedberg break; 462a3d4e20aSJohan Hedberg pos = &p->list; 463a3d4e20aSJohan Hedberg } 464a3d4e20aSJohan Hedberg 465a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 466a3d4e20aSJohan Hedberg } 467a3d4e20aSJohan Hedberg 4683175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 469561aafbcSJohan Hedberg bool name_known) 4701da177e4SLinus Torvalds { 47130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 47270f23020SAndrei Emeltchenko struct inquiry_entry *ie; 4731da177e4SLinus Torvalds 4741da177e4SLinus Torvalds BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr)); 4751da177e4SLinus Torvalds 47670f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 477a3d4e20aSJohan Hedberg if (ie) { 478a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 479a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 480a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 481a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 482a3d4e20aSJohan Hedberg } 483a3d4e20aSJohan Hedberg 484561aafbcSJohan Hedberg goto update; 485a3d4e20aSJohan Hedberg } 486561aafbcSJohan Hedberg 4871da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 48870f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 48970f23020SAndrei Emeltchenko if (!ie) 4903175405bSJohan Hedberg return false; 49170f23020SAndrei Emeltchenko 492561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 493561aafbcSJohan Hedberg 494561aafbcSJohan Hedberg if (name_known) { 495561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 496561aafbcSJohan Hedberg } else { 497561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 498561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 499561aafbcSJohan Hedberg } 500561aafbcSJohan Hedberg 501561aafbcSJohan Hedberg update: 502561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 503561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 504561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 505561aafbcSJohan Hedberg list_del(&ie->list); 5061da177e4SLinus Torvalds } 5071da177e4SLinus Torvalds 50870f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 50970f23020SAndrei Emeltchenko ie->timestamp = jiffies; 5101da177e4SLinus Torvalds cache->timestamp = jiffies; 5113175405bSJohan Hedberg 5123175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 5133175405bSJohan Hedberg return false; 5143175405bSJohan Hedberg 5153175405bSJohan Hedberg return true; 5161da177e4SLinus Torvalds } 5171da177e4SLinus Torvalds 5181da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 5191da177e4SLinus Torvalds { 52030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 5211da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 5221da177e4SLinus Torvalds struct inquiry_entry *e; 5231da177e4SLinus Torvalds int copied = 0; 5241da177e4SLinus Torvalds 525561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 5261da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 527b57c1a56SJohan Hedberg 528b57c1a56SJohan Hedberg if (copied >= num) 529b57c1a56SJohan Hedberg break; 530b57c1a56SJohan Hedberg 5311da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 5321da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 5331da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 5341da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 5351da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 5361da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 537b57c1a56SJohan Hedberg 5381da177e4SLinus Torvalds info++; 539b57c1a56SJohan Hedberg copied++; 5401da177e4SLinus Torvalds } 5411da177e4SLinus Torvalds 5421da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 5431da177e4SLinus Torvalds return copied; 5441da177e4SLinus Torvalds } 5451da177e4SLinus Torvalds 5461da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt) 5471da177e4SLinus Torvalds { 5481da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 5491da177e4SLinus Torvalds struct hci_cp_inquiry cp; 5501da177e4SLinus Torvalds 5511da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 5521da177e4SLinus Torvalds 5531da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 5541da177e4SLinus Torvalds return; 5551da177e4SLinus Torvalds 5561da177e4SLinus Torvalds /* Start Inquiry */ 5571da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 5581da177e4SLinus Torvalds cp.length = ir->length; 5591da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 560a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 5611da177e4SLinus Torvalds } 5621da177e4SLinus Torvalds 5631da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 5641da177e4SLinus Torvalds { 5651da177e4SLinus Torvalds __u8 __user *ptr = arg; 5661da177e4SLinus Torvalds struct hci_inquiry_req ir; 5671da177e4SLinus Torvalds struct hci_dev *hdev; 5681da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 5691da177e4SLinus Torvalds long timeo; 5701da177e4SLinus Torvalds __u8 *buf; 5711da177e4SLinus Torvalds 5721da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 5731da177e4SLinus Torvalds return -EFAULT; 5741da177e4SLinus Torvalds 5755a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 5765a08ecceSAndrei Emeltchenko if (!hdev) 5771da177e4SLinus Torvalds return -ENODEV; 5781da177e4SLinus Torvalds 57909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 5801da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 5811da177e4SLinus Torvalds inquiry_cache_empty(hdev) || 5821da177e4SLinus Torvalds ir.flags & IREQ_CACHE_FLUSH) { 5831da177e4SLinus Torvalds inquiry_cache_flush(hdev); 5841da177e4SLinus Torvalds do_inquiry = 1; 5851da177e4SLinus Torvalds } 58609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 5871da177e4SLinus Torvalds 58804837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 58970f23020SAndrei Emeltchenko 59070f23020SAndrei Emeltchenko if (do_inquiry) { 59170f23020SAndrei Emeltchenko err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo); 59270f23020SAndrei Emeltchenko if (err < 0) 5931da177e4SLinus Torvalds goto done; 59470f23020SAndrei Emeltchenko } 5951da177e4SLinus Torvalds 5961da177e4SLinus Torvalds /* for unlimited number of responses we will use buffer with 255 entries */ 5971da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 5981da177e4SLinus Torvalds 5991da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 6001da177e4SLinus Torvalds * copy it to the user space. 6011da177e4SLinus Torvalds */ 60270f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 60370f23020SAndrei Emeltchenko if (!buf) { 6041da177e4SLinus Torvalds err = -ENOMEM; 6051da177e4SLinus Torvalds goto done; 6061da177e4SLinus Torvalds } 6071da177e4SLinus Torvalds 60809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 6091da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 61009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 6111da177e4SLinus Torvalds 6121da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 6131da177e4SLinus Torvalds 6141da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 6151da177e4SLinus Torvalds ptr += sizeof(ir); 6161da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 6171da177e4SLinus Torvalds ir.num_rsp)) 6181da177e4SLinus Torvalds err = -EFAULT; 6191da177e4SLinus Torvalds } else 6201da177e4SLinus Torvalds err = -EFAULT; 6211da177e4SLinus Torvalds 6221da177e4SLinus Torvalds kfree(buf); 6231da177e4SLinus Torvalds 6241da177e4SLinus Torvalds done: 6251da177e4SLinus Torvalds hci_dev_put(hdev); 6261da177e4SLinus Torvalds return err; 6271da177e4SLinus Torvalds } 6281da177e4SLinus Torvalds 6291da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */ 6301da177e4SLinus Torvalds 6311da177e4SLinus Torvalds int hci_dev_open(__u16 dev) 6321da177e4SLinus Torvalds { 6331da177e4SLinus Torvalds struct hci_dev *hdev; 6341da177e4SLinus Torvalds int ret = 0; 6351da177e4SLinus Torvalds 6365a08ecceSAndrei Emeltchenko hdev = hci_dev_get(dev); 6375a08ecceSAndrei Emeltchenko if (!hdev) 6381da177e4SLinus Torvalds return -ENODEV; 6391da177e4SLinus Torvalds 6401da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 6411da177e4SLinus Torvalds 6421da177e4SLinus Torvalds hci_req_lock(hdev); 6431da177e4SLinus Torvalds 644611b30f7SMarcel Holtmann if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { 645611b30f7SMarcel Holtmann ret = -ERFKILL; 646611b30f7SMarcel Holtmann goto done; 647611b30f7SMarcel Holtmann } 648611b30f7SMarcel Holtmann 6491da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 6501da177e4SLinus Torvalds ret = -EALREADY; 6511da177e4SLinus Torvalds goto done; 6521da177e4SLinus Torvalds } 6531da177e4SLinus Torvalds 6541da177e4SLinus Torvalds if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 6551da177e4SLinus Torvalds set_bit(HCI_RAW, &hdev->flags); 6561da177e4SLinus Torvalds 65707e3b94aSAndrei Emeltchenko /* Treat all non BR/EDR controllers as raw devices if 65807e3b94aSAndrei Emeltchenko enable_hs is not set */ 65907e3b94aSAndrei Emeltchenko if (hdev->dev_type != HCI_BREDR && !enable_hs) 660943da25dSMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 661943da25dSMarcel Holtmann 6621da177e4SLinus Torvalds if (hdev->open(hdev)) { 6631da177e4SLinus Torvalds ret = -EIO; 6641da177e4SLinus Torvalds goto done; 6651da177e4SLinus Torvalds } 6661da177e4SLinus Torvalds 6671da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 6681da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 6691da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 670a5040efaSJohan Hedberg hdev->init_last_cmd = 0; 6711da177e4SLinus Torvalds 67204837f64SMarcel Holtmann ret = __hci_request(hdev, hci_init_req, 0, 67304837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 6741da177e4SLinus Torvalds 675eead27daSAndre Guedes if (lmp_host_le_capable(hdev)) 6766ed58ec5SVille Tervo ret = __hci_request(hdev, hci_le_init_req, 0, 6776ed58ec5SVille Tervo msecs_to_jiffies(HCI_INIT_TIMEOUT)); 6786ed58ec5SVille Tervo 6791da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 6801da177e4SLinus Torvalds } 6811da177e4SLinus Torvalds 6821da177e4SLinus Torvalds if (!ret) { 6831da177e4SLinus Torvalds hci_dev_hold(hdev); 6841da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 6851da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 686a8b2d5c2SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 68709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 688744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 68909fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 69056e5cb86SJohan Hedberg } 6911da177e4SLinus Torvalds } else { 6921da177e4SLinus Torvalds /* Init failed, cleanup */ 6933eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 694c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 695b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 6961da177e4SLinus Torvalds 6971da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 6981da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 6991da177e4SLinus Torvalds 7001da177e4SLinus Torvalds if (hdev->flush) 7011da177e4SLinus Torvalds hdev->flush(hdev); 7021da177e4SLinus Torvalds 7031da177e4SLinus Torvalds if (hdev->sent_cmd) { 7041da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 7051da177e4SLinus Torvalds hdev->sent_cmd = NULL; 7061da177e4SLinus Torvalds } 7071da177e4SLinus Torvalds 7081da177e4SLinus Torvalds hdev->close(hdev); 7091da177e4SLinus Torvalds hdev->flags = 0; 7101da177e4SLinus Torvalds } 7111da177e4SLinus Torvalds 7121da177e4SLinus Torvalds done: 7131da177e4SLinus Torvalds hci_req_unlock(hdev); 7141da177e4SLinus Torvalds hci_dev_put(hdev); 7151da177e4SLinus Torvalds return ret; 7161da177e4SLinus Torvalds } 7171da177e4SLinus Torvalds 7181da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 7191da177e4SLinus Torvalds { 7201da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 7211da177e4SLinus Torvalds 72228b75a89SAndre Guedes cancel_work_sync(&hdev->le_scan); 72328b75a89SAndre Guedes 7241da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 7251da177e4SLinus Torvalds hci_req_lock(hdev); 7261da177e4SLinus Torvalds 7271da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 728b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 7291da177e4SLinus Torvalds hci_req_unlock(hdev); 7301da177e4SLinus Torvalds return 0; 7311da177e4SLinus Torvalds } 7321da177e4SLinus Torvalds 7333eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 7343eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 735b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 7361da177e4SLinus Torvalds 73716ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 738e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 73916ab91abSJohan Hedberg hdev->discov_timeout = 0; 7405e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 74116ab91abSJohan Hedberg } 74216ab91abSJohan Hedberg 743a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 7447d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 7457d78525dSJohan Hedberg 7467ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 7477ba8b4beSAndre Guedes 74809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 7491da177e4SLinus Torvalds inquiry_cache_flush(hdev); 7501da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 75109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 7521da177e4SLinus Torvalds 7531da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 7541da177e4SLinus Torvalds 7551da177e4SLinus Torvalds if (hdev->flush) 7561da177e4SLinus Torvalds hdev->flush(hdev); 7571da177e4SLinus Torvalds 7581da177e4SLinus Torvalds /* Reset device */ 7591da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7601da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 7618af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 7628af59467SJohan Hedberg test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { 7631da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 76404837f64SMarcel Holtmann __hci_request(hdev, hci_reset_req, 0, 765cad44c2bSGustavo F. Padovan msecs_to_jiffies(250)); 7661da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 7671da177e4SLinus Torvalds } 7681da177e4SLinus Torvalds 769c347b765SGustavo F. Padovan /* flush cmd work */ 770c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 7711da177e4SLinus Torvalds 7721da177e4SLinus Torvalds /* Drop queues */ 7731da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 7741da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 7751da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 7761da177e4SLinus Torvalds 7771da177e4SLinus Torvalds /* Drop last sent command */ 7781da177e4SLinus Torvalds if (hdev->sent_cmd) { 779b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 7801da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 7811da177e4SLinus Torvalds hdev->sent_cmd = NULL; 7821da177e4SLinus Torvalds } 7831da177e4SLinus Torvalds 7841da177e4SLinus Torvalds /* After this point our queues are empty 7851da177e4SLinus Torvalds * and no tasks are scheduled. */ 7861da177e4SLinus Torvalds hdev->close(hdev); 7871da177e4SLinus Torvalds 7888ee56540SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 78909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 790744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 79109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 7928ee56540SMarcel Holtmann } 7935add6af8SJohan Hedberg 7941da177e4SLinus Torvalds /* Clear flags */ 7951da177e4SLinus Torvalds hdev->flags = 0; 7961da177e4SLinus Torvalds 797e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 79809b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 799e59fda8dSJohan Hedberg 8001da177e4SLinus Torvalds hci_req_unlock(hdev); 8011da177e4SLinus Torvalds 8021da177e4SLinus Torvalds hci_dev_put(hdev); 8031da177e4SLinus Torvalds return 0; 8041da177e4SLinus Torvalds } 8051da177e4SLinus Torvalds 8061da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 8071da177e4SLinus Torvalds { 8081da177e4SLinus Torvalds struct hci_dev *hdev; 8091da177e4SLinus Torvalds int err; 8101da177e4SLinus Torvalds 81170f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 81270f23020SAndrei Emeltchenko if (!hdev) 8131da177e4SLinus Torvalds return -ENODEV; 8148ee56540SMarcel Holtmann 8158ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 8168ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 8178ee56540SMarcel Holtmann 8181da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 8198ee56540SMarcel Holtmann 8201da177e4SLinus Torvalds hci_dev_put(hdev); 8211da177e4SLinus Torvalds return err; 8221da177e4SLinus Torvalds } 8231da177e4SLinus Torvalds 8241da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 8251da177e4SLinus Torvalds { 8261da177e4SLinus Torvalds struct hci_dev *hdev; 8271da177e4SLinus Torvalds int ret = 0; 8281da177e4SLinus Torvalds 82970f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 83070f23020SAndrei Emeltchenko if (!hdev) 8311da177e4SLinus Torvalds return -ENODEV; 8321da177e4SLinus Torvalds 8331da177e4SLinus Torvalds hci_req_lock(hdev); 8341da177e4SLinus Torvalds 8351da177e4SLinus Torvalds if (!test_bit(HCI_UP, &hdev->flags)) 8361da177e4SLinus Torvalds goto done; 8371da177e4SLinus Torvalds 8381da177e4SLinus Torvalds /* Drop queues */ 8391da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 8401da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 8411da177e4SLinus Torvalds 84209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 8431da177e4SLinus Torvalds inquiry_cache_flush(hdev); 8441da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 84509fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 8461da177e4SLinus Torvalds 8471da177e4SLinus Torvalds if (hdev->flush) 8481da177e4SLinus Torvalds hdev->flush(hdev); 8491da177e4SLinus Torvalds 8501da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 8516ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 8521da177e4SLinus Torvalds 8531da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 85404837f64SMarcel Holtmann ret = __hci_request(hdev, hci_reset_req, 0, 85504837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 8561da177e4SLinus Torvalds 8571da177e4SLinus Torvalds done: 8581da177e4SLinus Torvalds hci_req_unlock(hdev); 8591da177e4SLinus Torvalds hci_dev_put(hdev); 8601da177e4SLinus Torvalds return ret; 8611da177e4SLinus Torvalds } 8621da177e4SLinus Torvalds 8631da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 8641da177e4SLinus Torvalds { 8651da177e4SLinus Torvalds struct hci_dev *hdev; 8661da177e4SLinus Torvalds int ret = 0; 8671da177e4SLinus Torvalds 86870f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 86970f23020SAndrei Emeltchenko if (!hdev) 8701da177e4SLinus Torvalds return -ENODEV; 8711da177e4SLinus Torvalds 8721da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 8731da177e4SLinus Torvalds 8741da177e4SLinus Torvalds hci_dev_put(hdev); 8751da177e4SLinus Torvalds 8761da177e4SLinus Torvalds return ret; 8771da177e4SLinus Torvalds } 8781da177e4SLinus Torvalds 8791da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 8801da177e4SLinus Torvalds { 8811da177e4SLinus Torvalds struct hci_dev *hdev; 8821da177e4SLinus Torvalds struct hci_dev_req dr; 8831da177e4SLinus Torvalds int err = 0; 8841da177e4SLinus Torvalds 8851da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 8861da177e4SLinus Torvalds return -EFAULT; 8871da177e4SLinus Torvalds 88870f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 88970f23020SAndrei Emeltchenko if (!hdev) 8901da177e4SLinus Torvalds return -ENODEV; 8911da177e4SLinus Torvalds 8921da177e4SLinus Torvalds switch (cmd) { 8931da177e4SLinus Torvalds case HCISETAUTH: 89404837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 89504837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 8961da177e4SLinus Torvalds break; 8971da177e4SLinus Torvalds 8981da177e4SLinus Torvalds case HCISETENCRYPT: 8991da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 9001da177e4SLinus Torvalds err = -EOPNOTSUPP; 9011da177e4SLinus Torvalds break; 9021da177e4SLinus Torvalds } 9031da177e4SLinus Torvalds 9041da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 9051da177e4SLinus Torvalds /* Auth must be enabled first */ 90604837f64SMarcel Holtmann err = hci_request(hdev, hci_auth_req, dr.dev_opt, 90704837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9081da177e4SLinus Torvalds if (err) 9091da177e4SLinus Torvalds break; 9101da177e4SLinus Torvalds } 9111da177e4SLinus Torvalds 91204837f64SMarcel Holtmann err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, 91304837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9141da177e4SLinus Torvalds break; 9151da177e4SLinus Torvalds 9161da177e4SLinus Torvalds case HCISETSCAN: 91704837f64SMarcel Holtmann err = hci_request(hdev, hci_scan_req, dr.dev_opt, 91804837f64SMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9191da177e4SLinus Torvalds break; 9201da177e4SLinus Torvalds 9211da177e4SLinus Torvalds case HCISETLINKPOL: 922e4e8e37cSMarcel Holtmann err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, 923e4e8e37cSMarcel Holtmann msecs_to_jiffies(HCI_INIT_TIMEOUT)); 9241da177e4SLinus Torvalds break; 9251da177e4SLinus Torvalds 9261da177e4SLinus Torvalds case HCISETLINKMODE: 927e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 928e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 929e4e8e37cSMarcel Holtmann break; 930e4e8e37cSMarcel Holtmann 931e4e8e37cSMarcel Holtmann case HCISETPTYPE: 932e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 9331da177e4SLinus Torvalds break; 9341da177e4SLinus Torvalds 9351da177e4SLinus Torvalds case HCISETACLMTU: 9361da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 9371da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 9381da177e4SLinus Torvalds break; 9391da177e4SLinus Torvalds 9401da177e4SLinus Torvalds case HCISETSCOMTU: 9411da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 9421da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 9431da177e4SLinus Torvalds break; 9441da177e4SLinus Torvalds 9451da177e4SLinus Torvalds default: 9461da177e4SLinus Torvalds err = -EINVAL; 9471da177e4SLinus Torvalds break; 9481da177e4SLinus Torvalds } 949e4e8e37cSMarcel Holtmann 9501da177e4SLinus Torvalds hci_dev_put(hdev); 9511da177e4SLinus Torvalds return err; 9521da177e4SLinus Torvalds } 9531da177e4SLinus Torvalds 9541da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 9551da177e4SLinus Torvalds { 9568035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 9571da177e4SLinus Torvalds struct hci_dev_list_req *dl; 9581da177e4SLinus Torvalds struct hci_dev_req *dr; 9591da177e4SLinus Torvalds int n = 0, size, err; 9601da177e4SLinus Torvalds __u16 dev_num; 9611da177e4SLinus Torvalds 9621da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 9631da177e4SLinus Torvalds return -EFAULT; 9641da177e4SLinus Torvalds 9651da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 9661da177e4SLinus Torvalds return -EINVAL; 9671da177e4SLinus Torvalds 9681da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 9691da177e4SLinus Torvalds 97070f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 97170f23020SAndrei Emeltchenko if (!dl) 9721da177e4SLinus Torvalds return -ENOMEM; 9731da177e4SLinus Torvalds 9741da177e4SLinus Torvalds dr = dl->dev_req; 9751da177e4SLinus Torvalds 976f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 9778035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 978a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 979e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 980c542a06cSJohan Hedberg 981a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 982a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 983c542a06cSJohan Hedberg 9841da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 9851da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 986c542a06cSJohan Hedberg 9871da177e4SLinus Torvalds if (++n >= dev_num) 9881da177e4SLinus Torvalds break; 9891da177e4SLinus Torvalds } 990f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 9911da177e4SLinus Torvalds 9921da177e4SLinus Torvalds dl->dev_num = n; 9931da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 9941da177e4SLinus Torvalds 9951da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 9961da177e4SLinus Torvalds kfree(dl); 9971da177e4SLinus Torvalds 9981da177e4SLinus Torvalds return err ? -EFAULT : 0; 9991da177e4SLinus Torvalds } 10001da177e4SLinus Torvalds 10011da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 10021da177e4SLinus Torvalds { 10031da177e4SLinus Torvalds struct hci_dev *hdev; 10041da177e4SLinus Torvalds struct hci_dev_info di; 10051da177e4SLinus Torvalds int err = 0; 10061da177e4SLinus Torvalds 10071da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 10081da177e4SLinus Torvalds return -EFAULT; 10091da177e4SLinus Torvalds 101070f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 101170f23020SAndrei Emeltchenko if (!hdev) 10121da177e4SLinus Torvalds return -ENODEV; 10131da177e4SLinus Torvalds 1014a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 10153243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 1016ab81cbf9SJohan Hedberg 1017a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1018a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1019c542a06cSJohan Hedberg 10201da177e4SLinus Torvalds strcpy(di.name, hdev->name); 10211da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 1022943da25dSMarcel Holtmann di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); 10231da177e4SLinus Torvalds di.flags = hdev->flags; 10241da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 10251da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 10261da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 10271da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 10281da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 10291da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 10301da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 10311da177e4SLinus Torvalds 10321da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 10331da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 10341da177e4SLinus Torvalds 10351da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 10361da177e4SLinus Torvalds err = -EFAULT; 10371da177e4SLinus Torvalds 10381da177e4SLinus Torvalds hci_dev_put(hdev); 10391da177e4SLinus Torvalds 10401da177e4SLinus Torvalds return err; 10411da177e4SLinus Torvalds } 10421da177e4SLinus Torvalds 10431da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 10441da177e4SLinus Torvalds 1045611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 1046611b30f7SMarcel Holtmann { 1047611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 1048611b30f7SMarcel Holtmann 1049611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 1050611b30f7SMarcel Holtmann 1051611b30f7SMarcel Holtmann if (!blocked) 1052611b30f7SMarcel Holtmann return 0; 1053611b30f7SMarcel Holtmann 1054611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 1055611b30f7SMarcel Holtmann 1056611b30f7SMarcel Holtmann return 0; 1057611b30f7SMarcel Holtmann } 1058611b30f7SMarcel Holtmann 1059611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 1060611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 1061611b30f7SMarcel Holtmann }; 1062611b30f7SMarcel Holtmann 10631da177e4SLinus Torvalds /* Alloc HCI device */ 10641da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void) 10651da177e4SLinus Torvalds { 10661da177e4SLinus Torvalds struct hci_dev *hdev; 10671da177e4SLinus Torvalds 106825ea6db0SMarcel Holtmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 10691da177e4SLinus Torvalds if (!hdev) 10701da177e4SLinus Torvalds return NULL; 10711da177e4SLinus Torvalds 10720ac7e700SDavid Herrmann hci_init_sysfs(hdev); 10731da177e4SLinus Torvalds skb_queue_head_init(&hdev->driver_init); 10741da177e4SLinus Torvalds 10751da177e4SLinus Torvalds return hdev; 10761da177e4SLinus Torvalds } 10771da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev); 10781da177e4SLinus Torvalds 10791da177e4SLinus Torvalds /* Free HCI device */ 10801da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev) 10811da177e4SLinus Torvalds { 10821da177e4SLinus Torvalds skb_queue_purge(&hdev->driver_init); 10831da177e4SLinus Torvalds 1084a91f2e39SMarcel Holtmann /* will free via device release */ 1085a91f2e39SMarcel Holtmann put_device(&hdev->dev); 10861da177e4SLinus Torvalds } 10871da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev); 10881da177e4SLinus Torvalds 1089ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 1090ab81cbf9SJohan Hedberg { 1091ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 1092ab81cbf9SJohan Hedberg 1093ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1094ab81cbf9SJohan Hedberg 1095ab81cbf9SJohan Hedberg if (hci_dev_open(hdev->id) < 0) 1096ab81cbf9SJohan Hedberg return; 1097ab81cbf9SJohan Hedberg 1098a8b2d5c2SJohan Hedberg if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 109980b7ab33SGustavo F. Padovan schedule_delayed_work(&hdev->power_off, 11003243553fSJohan Hedberg msecs_to_jiffies(AUTO_OFF_TIMEOUT)); 1101ab81cbf9SJohan Hedberg 1102a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 1103744cf19eSJohan Hedberg mgmt_index_added(hdev); 1104ab81cbf9SJohan Hedberg } 1105ab81cbf9SJohan Hedberg 1106ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1107ab81cbf9SJohan Hedberg { 11083243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 11093243553fSJohan Hedberg power_off.work); 1110ab81cbf9SJohan Hedberg 1111ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1112ab81cbf9SJohan Hedberg 11138ee56540SMarcel Holtmann hci_dev_do_close(hdev); 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 1166b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 1167b899efafSVinicius Costa Gomes { 1168b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1169b899efafSVinicius Costa Gomes 1170b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1171b899efafSVinicius Costa Gomes list_del(&k->list); 1172b899efafSVinicius Costa Gomes kfree(k); 1173b899efafSVinicius Costa Gomes } 1174b899efafSVinicius Costa Gomes 1175b899efafSVinicius Costa Gomes return 0; 1176b899efafSVinicius Costa Gomes } 1177b899efafSVinicius 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 1225c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 122675d262c2SVinicius Costa Gomes { 1227c9839a11SVinicius Costa Gomes struct smp_ltk *k; 122875d262c2SVinicius Costa Gomes 1229c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 1230c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 1231c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 123275d262c2SVinicius Costa Gomes continue; 123375d262c2SVinicius Costa Gomes 123475d262c2SVinicius Costa Gomes return k; 123575d262c2SVinicius Costa Gomes } 123675d262c2SVinicius Costa Gomes 123775d262c2SVinicius Costa Gomes return NULL; 123875d262c2SVinicius Costa Gomes } 123975d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk); 124075d262c2SVinicius Costa Gomes 1241c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1242c9839a11SVinicius Costa Gomes u8 addr_type) 124375d262c2SVinicius Costa Gomes { 1244c9839a11SVinicius Costa Gomes struct smp_ltk *k; 124575d262c2SVinicius Costa Gomes 1246c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 1247c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 1248c9839a11SVinicius Costa Gomes bacmp(bdaddr, &k->bdaddr) == 0) 124975d262c2SVinicius Costa Gomes return k; 125075d262c2SVinicius Costa Gomes 125175d262c2SVinicius Costa Gomes return NULL; 125275d262c2SVinicius Costa Gomes } 1253c9839a11SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk_by_addr); 125475d262c2SVinicius Costa Gomes 1255d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 1256d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 125755ed8ca1SJohan Hedberg { 125855ed8ca1SJohan Hedberg struct link_key *key, *old_key; 12594df378a1SJohan Hedberg u8 old_key_type, persistent; 126055ed8ca1SJohan Hedberg 126155ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 126255ed8ca1SJohan Hedberg if (old_key) { 126355ed8ca1SJohan Hedberg old_key_type = old_key->type; 126455ed8ca1SJohan Hedberg key = old_key; 126555ed8ca1SJohan Hedberg } else { 126612adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 126755ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 126855ed8ca1SJohan Hedberg if (!key) 126955ed8ca1SJohan Hedberg return -ENOMEM; 127055ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 127155ed8ca1SJohan Hedberg } 127255ed8ca1SJohan Hedberg 127355ed8ca1SJohan Hedberg BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); 127455ed8ca1SJohan Hedberg 1275d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1276d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1277d25e28abSJohan Hedberg * previous key */ 1278d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1279d25e28abSJohan Hedberg (!conn || conn->remote_auth == 0xff) && 1280655fe6ecSJohan Hedberg old_key_type == 0xff) { 1281d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1282655fe6ecSJohan Hedberg if (conn) 1283655fe6ecSJohan Hedberg conn->key_type = type; 1284655fe6ecSJohan Hedberg } 1285d25e28abSJohan Hedberg 128655ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 128755ed8ca1SJohan Hedberg memcpy(key->val, val, 16); 128855ed8ca1SJohan Hedberg key->pin_len = pin_len; 128955ed8ca1SJohan Hedberg 1290b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 129155ed8ca1SJohan Hedberg key->type = old_key_type; 12924748fed2SJohan Hedberg else 12934748fed2SJohan Hedberg key->type = type; 12944748fed2SJohan Hedberg 12954df378a1SJohan Hedberg if (!new_key) 12964df378a1SJohan Hedberg return 0; 12974df378a1SJohan Hedberg 12984df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 12994df378a1SJohan Hedberg 1300744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 13014df378a1SJohan Hedberg 13024df378a1SJohan Hedberg if (!persistent) { 13034df378a1SJohan Hedberg list_del(&key->list); 13044df378a1SJohan Hedberg kfree(key); 13054df378a1SJohan Hedberg } 130655ed8ca1SJohan Hedberg 130755ed8ca1SJohan Hedberg return 0; 130855ed8ca1SJohan Hedberg } 130955ed8ca1SJohan Hedberg 1310c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 1311c9839a11SVinicius Costa Gomes int new_key, u8 authenticated, u8 tk[16], 1312c9839a11SVinicius Costa Gomes u8 enc_size, u16 ediv, u8 rand[8]) 131375d262c2SVinicius Costa Gomes { 1314c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 131575d262c2SVinicius Costa Gomes 1316c9839a11SVinicius Costa Gomes if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 1317c9839a11SVinicius Costa Gomes return 0; 131875d262c2SVinicius Costa Gomes 1319c9839a11SVinicius Costa Gomes old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 1320c9839a11SVinicius Costa Gomes if (old_key) 132175d262c2SVinicius Costa Gomes key = old_key; 1322c9839a11SVinicius Costa Gomes else { 1323c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 132475d262c2SVinicius Costa Gomes if (!key) 132575d262c2SVinicius Costa Gomes return -ENOMEM; 1326c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 132775d262c2SVinicius Costa Gomes } 132875d262c2SVinicius Costa Gomes 132975d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 1330c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 1331c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 1332c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 1333c9839a11SVinicius Costa Gomes key->ediv = ediv; 1334c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 1335c9839a11SVinicius Costa Gomes key->type = type; 1336c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 133775d262c2SVinicius Costa Gomes 1338c9839a11SVinicius Costa Gomes if (!new_key) 1339c9839a11SVinicius Costa Gomes return 0; 134075d262c2SVinicius Costa Gomes 1341261cc5aaSVinicius Costa Gomes if (type & HCI_SMP_LTK) 1342261cc5aaSVinicius Costa Gomes mgmt_new_ltk(hdev, key, 1); 1343261cc5aaSVinicius Costa Gomes 134475d262c2SVinicius Costa Gomes return 0; 134575d262c2SVinicius Costa Gomes } 134675d262c2SVinicius Costa Gomes 134755ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 134855ed8ca1SJohan Hedberg { 134955ed8ca1SJohan Hedberg struct link_key *key; 135055ed8ca1SJohan Hedberg 135155ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 135255ed8ca1SJohan Hedberg if (!key) 135355ed8ca1SJohan Hedberg return -ENOENT; 135455ed8ca1SJohan Hedberg 135555ed8ca1SJohan Hedberg BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 135655ed8ca1SJohan Hedberg 135755ed8ca1SJohan Hedberg list_del(&key->list); 135855ed8ca1SJohan Hedberg kfree(key); 135955ed8ca1SJohan Hedberg 136055ed8ca1SJohan Hedberg return 0; 136155ed8ca1SJohan Hedberg } 136255ed8ca1SJohan Hedberg 1363b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 1364b899efafSVinicius Costa Gomes { 1365b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1366b899efafSVinicius Costa Gomes 1367b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1368b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 1369b899efafSVinicius Costa Gomes continue; 1370b899efafSVinicius Costa Gomes 1371b899efafSVinicius Costa Gomes BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 1372b899efafSVinicius Costa Gomes 1373b899efafSVinicius Costa Gomes list_del(&k->list); 1374b899efafSVinicius Costa Gomes kfree(k); 1375b899efafSVinicius Costa Gomes } 1376b899efafSVinicius Costa Gomes 1377b899efafSVinicius Costa Gomes return 0; 1378b899efafSVinicius Costa Gomes } 1379b899efafSVinicius Costa Gomes 13806bd32326SVille Tervo /* HCI command timer function */ 13816bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg) 13826bd32326SVille Tervo { 13836bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 13846bd32326SVille Tervo 13856bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 13866bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 1387c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 13886bd32326SVille Tervo } 13896bd32326SVille Tervo 13902763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 13912763eda6SSzymon Janc bdaddr_t *bdaddr) 13922763eda6SSzymon Janc { 13932763eda6SSzymon Janc struct oob_data *data; 13942763eda6SSzymon Janc 13952763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 13962763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 13972763eda6SSzymon Janc return data; 13982763eda6SSzymon Janc 13992763eda6SSzymon Janc return NULL; 14002763eda6SSzymon Janc } 14012763eda6SSzymon Janc 14022763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 14032763eda6SSzymon Janc { 14042763eda6SSzymon Janc struct oob_data *data; 14052763eda6SSzymon Janc 14062763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14072763eda6SSzymon Janc if (!data) 14082763eda6SSzymon Janc return -ENOENT; 14092763eda6SSzymon Janc 14102763eda6SSzymon Janc BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); 14112763eda6SSzymon Janc 14122763eda6SSzymon Janc list_del(&data->list); 14132763eda6SSzymon Janc kfree(data); 14142763eda6SSzymon Janc 14152763eda6SSzymon Janc return 0; 14162763eda6SSzymon Janc } 14172763eda6SSzymon Janc 14182763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 14192763eda6SSzymon Janc { 14202763eda6SSzymon Janc struct oob_data *data, *n; 14212763eda6SSzymon Janc 14222763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 14232763eda6SSzymon Janc list_del(&data->list); 14242763eda6SSzymon Janc kfree(data); 14252763eda6SSzymon Janc } 14262763eda6SSzymon Janc 14272763eda6SSzymon Janc return 0; 14282763eda6SSzymon Janc } 14292763eda6SSzymon Janc 14302763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 14312763eda6SSzymon Janc u8 *randomizer) 14322763eda6SSzymon Janc { 14332763eda6SSzymon Janc struct oob_data *data; 14342763eda6SSzymon Janc 14352763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 14362763eda6SSzymon Janc 14372763eda6SSzymon Janc if (!data) { 14382763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 14392763eda6SSzymon Janc if (!data) 14402763eda6SSzymon Janc return -ENOMEM; 14412763eda6SSzymon Janc 14422763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 14432763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 14442763eda6SSzymon Janc } 14452763eda6SSzymon Janc 14462763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 14472763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 14482763eda6SSzymon Janc 14492763eda6SSzymon Janc BT_DBG("%s for %s", hdev->name, batostr(bdaddr)); 14502763eda6SSzymon Janc 14512763eda6SSzymon Janc return 0; 14522763eda6SSzymon Janc } 14532763eda6SSzymon Janc 1454b2a66aadSAntti Julku struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 1455b2a66aadSAntti Julku bdaddr_t *bdaddr) 1456b2a66aadSAntti Julku { 1457b2a66aadSAntti Julku struct bdaddr_list *b; 1458b2a66aadSAntti Julku 14598035ded4SLuiz Augusto von Dentz list_for_each_entry(b, &hdev->blacklist, list) 1460b2a66aadSAntti Julku if (bacmp(bdaddr, &b->bdaddr) == 0) 1461b2a66aadSAntti Julku return b; 1462b2a66aadSAntti Julku 1463b2a66aadSAntti Julku return NULL; 1464b2a66aadSAntti Julku } 1465b2a66aadSAntti Julku 1466b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 1467b2a66aadSAntti Julku { 1468b2a66aadSAntti Julku struct list_head *p, *n; 1469b2a66aadSAntti Julku 1470b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 1471b2a66aadSAntti Julku struct bdaddr_list *b; 1472b2a66aadSAntti Julku 1473b2a66aadSAntti Julku b = list_entry(p, struct bdaddr_list, list); 1474b2a66aadSAntti Julku 1475b2a66aadSAntti Julku list_del(p); 1476b2a66aadSAntti Julku kfree(b); 1477b2a66aadSAntti Julku } 1478b2a66aadSAntti Julku 1479b2a66aadSAntti Julku return 0; 1480b2a66aadSAntti Julku } 1481b2a66aadSAntti Julku 148288c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1483b2a66aadSAntti Julku { 1484b2a66aadSAntti Julku struct bdaddr_list *entry; 1485b2a66aadSAntti Julku 1486b2a66aadSAntti Julku if (bacmp(bdaddr, BDADDR_ANY) == 0) 1487b2a66aadSAntti Julku return -EBADF; 1488b2a66aadSAntti Julku 14895e762444SAntti Julku if (hci_blacklist_lookup(hdev, bdaddr)) 14905e762444SAntti Julku return -EEXIST; 1491b2a66aadSAntti Julku 1492b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 14935e762444SAntti Julku if (!entry) 14945e762444SAntti Julku return -ENOMEM; 1495b2a66aadSAntti Julku 1496b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 1497b2a66aadSAntti Julku 1498b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 1499b2a66aadSAntti Julku 150088c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 1501b2a66aadSAntti Julku } 1502b2a66aadSAntti Julku 150388c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 1504b2a66aadSAntti Julku { 1505b2a66aadSAntti Julku struct bdaddr_list *entry; 1506b2a66aadSAntti Julku 15071ec918ceSSzymon Janc if (bacmp(bdaddr, BDADDR_ANY) == 0) 15085e762444SAntti Julku return hci_blacklist_clear(hdev); 1509b2a66aadSAntti Julku 1510b2a66aadSAntti Julku entry = hci_blacklist_lookup(hdev, bdaddr); 15111ec918ceSSzymon Janc if (!entry) 15125e762444SAntti Julku return -ENOENT; 1513b2a66aadSAntti Julku 1514b2a66aadSAntti Julku list_del(&entry->list); 1515b2a66aadSAntti Julku kfree(entry); 1516b2a66aadSAntti Julku 151788c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 1518b2a66aadSAntti Julku } 1519b2a66aadSAntti Julku 1520db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work) 152135815085SAndre Guedes { 1522db323f2fSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, 1523db323f2fSGustavo F. Padovan adv_work.work); 152435815085SAndre Guedes 152535815085SAndre Guedes hci_dev_lock(hdev); 152635815085SAndre Guedes 152735815085SAndre Guedes hci_adv_entries_clear(hdev); 152835815085SAndre Guedes 152935815085SAndre Guedes hci_dev_unlock(hdev); 153035815085SAndre Guedes } 153135815085SAndre Guedes 153276c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev) 153376c8686fSAndre Guedes { 153476c8686fSAndre Guedes struct adv_entry *entry, *tmp; 153576c8686fSAndre Guedes 153676c8686fSAndre Guedes list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) { 153776c8686fSAndre Guedes list_del(&entry->list); 153876c8686fSAndre Guedes kfree(entry); 153976c8686fSAndre Guedes } 154076c8686fSAndre Guedes 154176c8686fSAndre Guedes BT_DBG("%s adv cache cleared", hdev->name); 154276c8686fSAndre Guedes 154376c8686fSAndre Guedes return 0; 154476c8686fSAndre Guedes } 154576c8686fSAndre Guedes 154676c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr) 154776c8686fSAndre Guedes { 154876c8686fSAndre Guedes struct adv_entry *entry; 154976c8686fSAndre Guedes 155076c8686fSAndre Guedes list_for_each_entry(entry, &hdev->adv_entries, list) 155176c8686fSAndre Guedes if (bacmp(bdaddr, &entry->bdaddr) == 0) 155276c8686fSAndre Guedes return entry; 155376c8686fSAndre Guedes 155476c8686fSAndre Guedes return NULL; 155576c8686fSAndre Guedes } 155676c8686fSAndre Guedes 155776c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type) 155876c8686fSAndre Guedes { 155976c8686fSAndre Guedes if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND) 156076c8686fSAndre Guedes return 1; 156176c8686fSAndre Guedes 156276c8686fSAndre Guedes return 0; 156376c8686fSAndre Guedes } 156476c8686fSAndre Guedes 156576c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev, 156676c8686fSAndre Guedes struct hci_ev_le_advertising_info *ev) 156776c8686fSAndre Guedes { 156876c8686fSAndre Guedes struct adv_entry *entry; 156976c8686fSAndre Guedes 157076c8686fSAndre Guedes if (!is_connectable_adv(ev->evt_type)) 157176c8686fSAndre Guedes return -EINVAL; 157276c8686fSAndre Guedes 157376c8686fSAndre Guedes /* Only new entries should be added to adv_entries. So, if 157476c8686fSAndre Guedes * bdaddr was found, don't add it. */ 157576c8686fSAndre Guedes if (hci_find_adv_entry(hdev, &ev->bdaddr)) 157676c8686fSAndre Guedes return 0; 157776c8686fSAndre Guedes 15784777bfdeSAndre Guedes entry = kzalloc(sizeof(*entry), GFP_KERNEL); 157976c8686fSAndre Guedes if (!entry) 158076c8686fSAndre Guedes return -ENOMEM; 158176c8686fSAndre Guedes 158276c8686fSAndre Guedes bacpy(&entry->bdaddr, &ev->bdaddr); 158376c8686fSAndre Guedes entry->bdaddr_type = ev->bdaddr_type; 158476c8686fSAndre Guedes 158576c8686fSAndre Guedes list_add(&entry->list, &hdev->adv_entries); 158676c8686fSAndre Guedes 158776c8686fSAndre Guedes BT_DBG("%s adv entry added: address %s type %u", hdev->name, 158876c8686fSAndre Guedes batostr(&entry->bdaddr), entry->bdaddr_type); 158976c8686fSAndre Guedes 159076c8686fSAndre Guedes return 0; 159176c8686fSAndre Guedes } 159276c8686fSAndre Guedes 15937ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt) 15947ba8b4beSAndre Guedes { 15957ba8b4beSAndre Guedes struct le_scan_params *param = (struct le_scan_params *) opt; 15967ba8b4beSAndre Guedes struct hci_cp_le_set_scan_param cp; 15977ba8b4beSAndre Guedes 15987ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 15997ba8b4beSAndre Guedes cp.type = param->type; 16007ba8b4beSAndre Guedes cp.interval = cpu_to_le16(param->interval); 16017ba8b4beSAndre Guedes cp.window = cpu_to_le16(param->window); 16027ba8b4beSAndre Guedes 16037ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); 16047ba8b4beSAndre Guedes } 16057ba8b4beSAndre Guedes 16067ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt) 16077ba8b4beSAndre Guedes { 16087ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 16097ba8b4beSAndre Guedes 16107ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 16117ba8b4beSAndre Guedes cp.enable = 1; 16127ba8b4beSAndre Guedes 16137ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 16147ba8b4beSAndre Guedes } 16157ba8b4beSAndre Guedes 16167ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, 16177ba8b4beSAndre Guedes u16 window, int timeout) 16187ba8b4beSAndre Guedes { 16197ba8b4beSAndre Guedes long timeo = msecs_to_jiffies(3000); 16207ba8b4beSAndre Guedes struct le_scan_params param; 16217ba8b4beSAndre Guedes int err; 16227ba8b4beSAndre Guedes 16237ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 16247ba8b4beSAndre Guedes 16257ba8b4beSAndre Guedes if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 16267ba8b4beSAndre Guedes return -EINPROGRESS; 16277ba8b4beSAndre Guedes 16287ba8b4beSAndre Guedes param.type = type; 16297ba8b4beSAndre Guedes param.interval = interval; 16307ba8b4beSAndre Guedes param.window = window; 16317ba8b4beSAndre Guedes 16327ba8b4beSAndre Guedes hci_req_lock(hdev); 16337ba8b4beSAndre Guedes 16347ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_param_req, (unsigned long) ¶m, 16357ba8b4beSAndre Guedes timeo); 16367ba8b4beSAndre Guedes if (!err) 16377ba8b4beSAndre Guedes err = __hci_request(hdev, le_scan_enable_req, 0, timeo); 16387ba8b4beSAndre Guedes 16397ba8b4beSAndre Guedes hci_req_unlock(hdev); 16407ba8b4beSAndre Guedes 16417ba8b4beSAndre Guedes if (err < 0) 16427ba8b4beSAndre Guedes return err; 16437ba8b4beSAndre Guedes 16447ba8b4beSAndre Guedes schedule_delayed_work(&hdev->le_scan_disable, 16457ba8b4beSAndre Guedes msecs_to_jiffies(timeout)); 16467ba8b4beSAndre Guedes 16477ba8b4beSAndre Guedes return 0; 16487ba8b4beSAndre Guedes } 16497ba8b4beSAndre Guedes 16507ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 16517ba8b4beSAndre Guedes { 16527ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 16537ba8b4beSAndre Guedes le_scan_disable.work); 16547ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 16557ba8b4beSAndre Guedes 16567ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 16577ba8b4beSAndre Guedes 16587ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 16597ba8b4beSAndre Guedes 16607ba8b4beSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 16617ba8b4beSAndre Guedes } 16627ba8b4beSAndre Guedes 166328b75a89SAndre Guedes static void le_scan_work(struct work_struct *work) 166428b75a89SAndre Guedes { 166528b75a89SAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan); 166628b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 166728b75a89SAndre Guedes 166828b75a89SAndre Guedes BT_DBG("%s", hdev->name); 166928b75a89SAndre Guedes 167028b75a89SAndre Guedes hci_do_le_scan(hdev, param->type, param->interval, 167128b75a89SAndre Guedes param->window, param->timeout); 167228b75a89SAndre Guedes } 167328b75a89SAndre Guedes 167428b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, 167528b75a89SAndre Guedes int timeout) 167628b75a89SAndre Guedes { 167728b75a89SAndre Guedes struct le_scan_params *param = &hdev->le_scan_params; 167828b75a89SAndre Guedes 167928b75a89SAndre Guedes BT_DBG("%s", hdev->name); 168028b75a89SAndre Guedes 168128b75a89SAndre Guedes if (work_busy(&hdev->le_scan)) 168228b75a89SAndre Guedes return -EINPROGRESS; 168328b75a89SAndre Guedes 168428b75a89SAndre Guedes param->type = type; 168528b75a89SAndre Guedes param->interval = interval; 168628b75a89SAndre Guedes param->window = window; 168728b75a89SAndre Guedes param->timeout = timeout; 168828b75a89SAndre Guedes 168928b75a89SAndre Guedes queue_work(system_long_wq, &hdev->le_scan); 169028b75a89SAndre Guedes 169128b75a89SAndre Guedes return 0; 169228b75a89SAndre Guedes } 169328b75a89SAndre Guedes 16941da177e4SLinus Torvalds /* Register HCI device */ 16951da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 16961da177e4SLinus Torvalds { 16971da177e4SLinus Torvalds struct list_head *head = &hci_dev_list, *p; 169808add513SMat Martineau int i, id, error; 16991da177e4SLinus Torvalds 1700e9b9cfa1SDavid Herrmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 17011da177e4SLinus Torvalds 1702010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 17031da177e4SLinus Torvalds return -EINVAL; 17041da177e4SLinus Torvalds 170508add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 170608add513SMat Martineau * so the index can be used as the AMP controller ID. 170708add513SMat Martineau */ 170808add513SMat Martineau id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; 170908add513SMat Martineau 1710f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 17111da177e4SLinus Torvalds 17121da177e4SLinus Torvalds /* Find first available device id */ 17131da177e4SLinus Torvalds list_for_each(p, &hci_dev_list) { 17141da177e4SLinus Torvalds if (list_entry(p, struct hci_dev, list)->id != id) 17151da177e4SLinus Torvalds break; 17161da177e4SLinus Torvalds head = p; id++; 17171da177e4SLinus Torvalds } 17181da177e4SLinus Torvalds 17191da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 17201da177e4SLinus Torvalds hdev->id = id; 1721c6feeb28SAndrei Emeltchenko list_add_tail(&hdev->list, head); 17221da177e4SLinus Torvalds 172309fd0de5SGustavo F. Padovan mutex_init(&hdev->lock); 17241da177e4SLinus Torvalds 17251da177e4SLinus Torvalds hdev->flags = 0; 1726d23264a8SAndre Guedes hdev->dev_flags = 0; 17271da177e4SLinus Torvalds hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 17285b7f9909SMarcel Holtmann hdev->esco_type = (ESCO_HV1); 17291da177e4SLinus Torvalds hdev->link_mode = (HCI_LM_ACCEPT); 173017fa4b9dSJohan Hedberg hdev->io_capability = 0x03; /* No Input No Output */ 17311da177e4SLinus Torvalds 173204837f64SMarcel Holtmann hdev->idle_timeout = 0; 173304837f64SMarcel Holtmann hdev->sniff_max_interval = 800; 173404837f64SMarcel Holtmann hdev->sniff_min_interval = 80; 173504837f64SMarcel Holtmann 1736b78752ccSMarcel Holtmann INIT_WORK(&hdev->rx_work, hci_rx_work); 1737c347b765SGustavo F. Padovan INIT_WORK(&hdev->cmd_work, hci_cmd_work); 17383eff45eaSGustavo F. Padovan INIT_WORK(&hdev->tx_work, hci_tx_work); 1739b78752ccSMarcel Holtmann 17401da177e4SLinus Torvalds 17411da177e4SLinus Torvalds skb_queue_head_init(&hdev->rx_q); 17421da177e4SLinus Torvalds skb_queue_head_init(&hdev->cmd_q); 17431da177e4SLinus Torvalds skb_queue_head_init(&hdev->raw_q); 17441da177e4SLinus Torvalds 17456bd32326SVille Tervo setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); 17466bd32326SVille Tervo 1747cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1748ef222013SMarcel Holtmann hdev->reassembly[i] = NULL; 1749ef222013SMarcel Holtmann 17501da177e4SLinus Torvalds init_waitqueue_head(&hdev->req_wait_q); 1751a6a67efdSThomas Gleixner mutex_init(&hdev->req_lock); 17521da177e4SLinus Torvalds 175330883512SJohan Hedberg discovery_init(hdev); 17541da177e4SLinus Torvalds 17551da177e4SLinus Torvalds hci_conn_hash_init(hdev); 17561da177e4SLinus Torvalds 17572e58ef3eSJohan Hedberg INIT_LIST_HEAD(&hdev->mgmt_pending); 17582e58ef3eSJohan Hedberg 1759ea4bd8baSDavid Miller INIT_LIST_HEAD(&hdev->blacklist); 1760f0358568SJohan Hedberg 17612aeb9a1aSJohan Hedberg INIT_LIST_HEAD(&hdev->uuids); 17622aeb9a1aSJohan Hedberg 176355ed8ca1SJohan Hedberg INIT_LIST_HEAD(&hdev->link_keys); 1764b899efafSVinicius Costa Gomes INIT_LIST_HEAD(&hdev->long_term_keys); 176555ed8ca1SJohan Hedberg 17662763eda6SSzymon Janc INIT_LIST_HEAD(&hdev->remote_oob_data); 17672763eda6SSzymon Janc 176876c8686fSAndre Guedes INIT_LIST_HEAD(&hdev->adv_entries); 176976c8686fSAndre Guedes 1770db323f2fSGustavo F. Padovan INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache); 1771ab81cbf9SJohan Hedberg INIT_WORK(&hdev->power_on, hci_power_on); 17723243553fSJohan Hedberg INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 1773ab81cbf9SJohan Hedberg 177416ab91abSJohan Hedberg INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 177516ab91abSJohan Hedberg 17761da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 17771da177e4SLinus Torvalds 17781da177e4SLinus Torvalds atomic_set(&hdev->promisc, 0); 17791da177e4SLinus Torvalds 178028b75a89SAndre Guedes INIT_WORK(&hdev->le_scan, le_scan_work); 178128b75a89SAndre Guedes 17827ba8b4beSAndre Guedes INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 17837ba8b4beSAndre Guedes 1784f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 17851da177e4SLinus Torvalds 178632845eb1SGustavo F. Padovan hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | 178732845eb1SGustavo F. Padovan WQ_MEM_RECLAIM, 1); 178833ca954dSDavid Herrmann if (!hdev->workqueue) { 178933ca954dSDavid Herrmann error = -ENOMEM; 179033ca954dSDavid Herrmann goto err; 179133ca954dSDavid Herrmann } 1792f48fd9c8SMarcel Holtmann 179333ca954dSDavid Herrmann error = hci_add_sysfs(hdev); 179433ca954dSDavid Herrmann if (error < 0) 179533ca954dSDavid Herrmann goto err_wqueue; 17961da177e4SLinus Torvalds 1797611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 1798611b30f7SMarcel Holtmann RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); 1799611b30f7SMarcel Holtmann if (hdev->rfkill) { 1800611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 1801611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1802611b30f7SMarcel Holtmann hdev->rfkill = NULL; 1803611b30f7SMarcel Holtmann } 1804611b30f7SMarcel Holtmann } 1805611b30f7SMarcel Holtmann 1806a8b2d5c2SJohan Hedberg set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 1807a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 18087f971041SGustavo F. Padovan schedule_work(&hdev->power_on); 1809ab81cbf9SJohan Hedberg 18101da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 1811dc946bd8SDavid Herrmann hci_dev_hold(hdev); 18121da177e4SLinus Torvalds 18131da177e4SLinus Torvalds return id; 1814f48fd9c8SMarcel Holtmann 181533ca954dSDavid Herrmann err_wqueue: 181633ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 181733ca954dSDavid Herrmann err: 1818f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 1819f48fd9c8SMarcel Holtmann list_del(&hdev->list); 1820f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 1821f48fd9c8SMarcel Holtmann 182233ca954dSDavid Herrmann return error; 18231da177e4SLinus Torvalds } 18241da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 18251da177e4SLinus Torvalds 18261da177e4SLinus Torvalds /* Unregister HCI device */ 182759735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 18281da177e4SLinus Torvalds { 1829ef222013SMarcel Holtmann int i; 1830ef222013SMarcel Holtmann 1831c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 18321da177e4SLinus Torvalds 1833f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 18341da177e4SLinus Torvalds list_del(&hdev->list); 1835f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 18361da177e4SLinus Torvalds 18371da177e4SLinus Torvalds hci_dev_do_close(hdev); 18381da177e4SLinus Torvalds 1839cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 1840ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 1841ef222013SMarcel Holtmann 1842ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 1843a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 184409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1845744cf19eSJohan Hedberg mgmt_index_removed(hdev); 184609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 184756e5cb86SJohan Hedberg } 1848ab81cbf9SJohan Hedberg 18492e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 18502e58ef3eSJohan Hedberg * pending list */ 18512e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 18522e58ef3eSJohan Hedberg 18531da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 18541da177e4SLinus Torvalds 1855611b30f7SMarcel Holtmann if (hdev->rfkill) { 1856611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 1857611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 1858611b30f7SMarcel Holtmann } 1859611b30f7SMarcel Holtmann 1860ce242970SDavid Herrmann hci_del_sysfs(hdev); 1861147e2d59SDave Young 1862db323f2fSGustavo F. Padovan cancel_delayed_work_sync(&hdev->adv_work); 1863c6f3c5f7SGustavo F. Padovan 1864f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 1865f48fd9c8SMarcel Holtmann 186609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1867e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 18682aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 186955ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 1870b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 18712763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 187276c8686fSAndre Guedes hci_adv_entries_clear(hdev); 187309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 1874e2e0cacbSJohan Hedberg 1875dc946bd8SDavid Herrmann hci_dev_put(hdev); 18761da177e4SLinus Torvalds } 18771da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 18781da177e4SLinus Torvalds 18791da177e4SLinus Torvalds /* Suspend HCI device */ 18801da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 18811da177e4SLinus Torvalds { 18821da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 18831da177e4SLinus Torvalds return 0; 18841da177e4SLinus Torvalds } 18851da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 18861da177e4SLinus Torvalds 18871da177e4SLinus Torvalds /* Resume HCI device */ 18881da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 18891da177e4SLinus Torvalds { 18901da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 18911da177e4SLinus Torvalds return 0; 18921da177e4SLinus Torvalds } 18931da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 18941da177e4SLinus Torvalds 189576bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 189676bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb) 189776bca880SMarcel Holtmann { 189876bca880SMarcel Holtmann struct hci_dev *hdev = (struct hci_dev *) skb->dev; 189976bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 190076bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 190176bca880SMarcel Holtmann kfree_skb(skb); 190276bca880SMarcel Holtmann return -ENXIO; 190376bca880SMarcel Holtmann } 190476bca880SMarcel Holtmann 190576bca880SMarcel Holtmann /* Incomming skb */ 190676bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 190776bca880SMarcel Holtmann 190876bca880SMarcel Holtmann /* Time stamp */ 190976bca880SMarcel Holtmann __net_timestamp(skb); 191076bca880SMarcel Holtmann 191176bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 1912b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 1913c78ae283SMarcel Holtmann 191476bca880SMarcel Holtmann return 0; 191576bca880SMarcel Holtmann } 191676bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 191776bca880SMarcel Holtmann 191833e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 19191e429f38SGustavo F. Padovan int count, __u8 index) 192033e882a5SSuraj Sumangala { 192133e882a5SSuraj Sumangala int len = 0; 192233e882a5SSuraj Sumangala int hlen = 0; 192333e882a5SSuraj Sumangala int remain = count; 192433e882a5SSuraj Sumangala struct sk_buff *skb; 192533e882a5SSuraj Sumangala struct bt_skb_cb *scb; 192633e882a5SSuraj Sumangala 192733e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 192833e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 192933e882a5SSuraj Sumangala return -EILSEQ; 193033e882a5SSuraj Sumangala 193133e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 193233e882a5SSuraj Sumangala 193333e882a5SSuraj Sumangala if (!skb) { 193433e882a5SSuraj Sumangala switch (type) { 193533e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 193633e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 193733e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 193833e882a5SSuraj Sumangala break; 193933e882a5SSuraj Sumangala case HCI_EVENT_PKT: 194033e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 194133e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 194233e882a5SSuraj Sumangala break; 194333e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 194433e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 194533e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 194633e882a5SSuraj Sumangala break; 194733e882a5SSuraj Sumangala } 194833e882a5SSuraj Sumangala 19491e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 195033e882a5SSuraj Sumangala if (!skb) 195133e882a5SSuraj Sumangala return -ENOMEM; 195233e882a5SSuraj Sumangala 195333e882a5SSuraj Sumangala scb = (void *) skb->cb; 195433e882a5SSuraj Sumangala scb->expect = hlen; 195533e882a5SSuraj Sumangala scb->pkt_type = type; 195633e882a5SSuraj Sumangala 195733e882a5SSuraj Sumangala skb->dev = (void *) hdev; 195833e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 195933e882a5SSuraj Sumangala } 196033e882a5SSuraj Sumangala 196133e882a5SSuraj Sumangala while (count) { 196233e882a5SSuraj Sumangala scb = (void *) skb->cb; 196370c1f20bSMarcel Holtmann len = min_t(__u16, scb->expect, count); 196433e882a5SSuraj Sumangala 196533e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 196633e882a5SSuraj Sumangala 196733e882a5SSuraj Sumangala count -= len; 196833e882a5SSuraj Sumangala data += len; 196933e882a5SSuraj Sumangala scb->expect -= len; 197033e882a5SSuraj Sumangala remain = count; 197133e882a5SSuraj Sumangala 197233e882a5SSuraj Sumangala switch (type) { 197333e882a5SSuraj Sumangala case HCI_EVENT_PKT: 197433e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 197533e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 197633e882a5SSuraj Sumangala scb->expect = h->plen; 197733e882a5SSuraj Sumangala 197833e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 197933e882a5SSuraj Sumangala kfree_skb(skb); 198033e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 198133e882a5SSuraj Sumangala return -ENOMEM; 198233e882a5SSuraj Sumangala } 198333e882a5SSuraj Sumangala } 198433e882a5SSuraj Sumangala break; 198533e882a5SSuraj Sumangala 198633e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 198733e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 198833e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 198933e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 199033e882a5SSuraj Sumangala 199133e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 199233e882a5SSuraj Sumangala kfree_skb(skb); 199333e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 199433e882a5SSuraj Sumangala return -ENOMEM; 199533e882a5SSuraj Sumangala } 199633e882a5SSuraj Sumangala } 199733e882a5SSuraj Sumangala break; 199833e882a5SSuraj Sumangala 199933e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 200033e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 200133e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 200233e882a5SSuraj Sumangala scb->expect = h->dlen; 200333e882a5SSuraj Sumangala 200433e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 200533e882a5SSuraj Sumangala kfree_skb(skb); 200633e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 200733e882a5SSuraj Sumangala return -ENOMEM; 200833e882a5SSuraj Sumangala } 200933e882a5SSuraj Sumangala } 201033e882a5SSuraj Sumangala break; 201133e882a5SSuraj Sumangala } 201233e882a5SSuraj Sumangala 201333e882a5SSuraj Sumangala if (scb->expect == 0) { 201433e882a5SSuraj Sumangala /* Complete frame */ 201533e882a5SSuraj Sumangala 201633e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 201733e882a5SSuraj Sumangala hci_recv_frame(skb); 201833e882a5SSuraj Sumangala 201933e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 202033e882a5SSuraj Sumangala return remain; 202133e882a5SSuraj Sumangala } 202233e882a5SSuraj Sumangala } 202333e882a5SSuraj Sumangala 202433e882a5SSuraj Sumangala return remain; 202533e882a5SSuraj Sumangala } 202633e882a5SSuraj Sumangala 2027ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 2028ef222013SMarcel Holtmann { 2029f39a3c06SSuraj Sumangala int rem = 0; 2030f39a3c06SSuraj Sumangala 2031ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 2032ef222013SMarcel Holtmann return -EILSEQ; 2033ef222013SMarcel Holtmann 2034da5f6c37SGustavo F. Padovan while (count) { 20351e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 2036f39a3c06SSuraj Sumangala if (rem < 0) 2037f39a3c06SSuraj Sumangala return rem; 2038ef222013SMarcel Holtmann 2039f39a3c06SSuraj Sumangala data += (count - rem); 2040f39a3c06SSuraj Sumangala count = rem; 2041f81c6224SJoe Perches } 2042ef222013SMarcel Holtmann 2043f39a3c06SSuraj Sumangala return rem; 2044ef222013SMarcel Holtmann } 2045ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 2046ef222013SMarcel Holtmann 204799811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 204899811510SSuraj Sumangala 204999811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 205099811510SSuraj Sumangala { 205199811510SSuraj Sumangala int type; 205299811510SSuraj Sumangala int rem = 0; 205399811510SSuraj Sumangala 2054da5f6c37SGustavo F. Padovan while (count) { 205599811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 205699811510SSuraj Sumangala 205799811510SSuraj Sumangala if (!skb) { 205899811510SSuraj Sumangala struct { char type; } *pkt; 205999811510SSuraj Sumangala 206099811510SSuraj Sumangala /* Start of the frame */ 206199811510SSuraj Sumangala pkt = data; 206299811510SSuraj Sumangala type = pkt->type; 206399811510SSuraj Sumangala 206499811510SSuraj Sumangala data++; 206599811510SSuraj Sumangala count--; 206699811510SSuraj Sumangala } else 206799811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 206899811510SSuraj Sumangala 20691e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 20701e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 207199811510SSuraj Sumangala if (rem < 0) 207299811510SSuraj Sumangala return rem; 207399811510SSuraj Sumangala 207499811510SSuraj Sumangala data += (count - rem); 207599811510SSuraj Sumangala count = rem; 2076f81c6224SJoe Perches } 207799811510SSuraj Sumangala 207899811510SSuraj Sumangala return rem; 207999811510SSuraj Sumangala } 208099811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 208199811510SSuraj Sumangala 20821da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 20831da177e4SLinus Torvalds 20841da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 20851da177e4SLinus Torvalds { 20861da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 20871da177e4SLinus Torvalds 2088f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 20891da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 2090f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 20911da177e4SLinus Torvalds 20921da177e4SLinus Torvalds return 0; 20931da177e4SLinus Torvalds } 20941da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 20951da177e4SLinus Torvalds 20961da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 20971da177e4SLinus Torvalds { 20981da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 20991da177e4SLinus Torvalds 2100f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 21011da177e4SLinus Torvalds list_del(&cb->list); 2102f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 21031da177e4SLinus Torvalds 21041da177e4SLinus Torvalds return 0; 21051da177e4SLinus Torvalds } 21061da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 21071da177e4SLinus Torvalds 21081da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb) 21091da177e4SLinus Torvalds { 21101da177e4SLinus Torvalds struct hci_dev *hdev = (struct hci_dev *) skb->dev; 21111da177e4SLinus Torvalds 21121da177e4SLinus Torvalds if (!hdev) { 21131da177e4SLinus Torvalds kfree_skb(skb); 21141da177e4SLinus Torvalds return -ENODEV; 21151da177e4SLinus Torvalds } 21161da177e4SLinus Torvalds 21170d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 21181da177e4SLinus Torvalds 21191da177e4SLinus Torvalds /* Time stamp */ 2120a61bbcf2SPatrick McHardy __net_timestamp(skb); 21211da177e4SLinus Torvalds 2122cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2123cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2124cd82e61cSMarcel Holtmann 2125cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 2126cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 2127470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 21281da177e4SLinus Torvalds } 21291da177e4SLinus Torvalds 21301da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 21311da177e4SLinus Torvalds skb_orphan(skb); 21321da177e4SLinus Torvalds 21331da177e4SLinus Torvalds return hdev->send(skb); 21341da177e4SLinus Torvalds } 21351da177e4SLinus Torvalds 21361da177e4SLinus Torvalds /* Send HCI command */ 2137a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) 21381da177e4SLinus Torvalds { 21391da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 21401da177e4SLinus Torvalds struct hci_command_hdr *hdr; 21411da177e4SLinus Torvalds struct sk_buff *skb; 21421da177e4SLinus Torvalds 2143a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen); 21441da177e4SLinus Torvalds 21451da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 21461da177e4SLinus Torvalds if (!skb) { 2147ef222013SMarcel Holtmann BT_ERR("%s no memory for command", hdev->name); 21481da177e4SLinus Torvalds return -ENOMEM; 21491da177e4SLinus Torvalds } 21501da177e4SLinus Torvalds 21511da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 2152a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 21531da177e4SLinus Torvalds hdr->plen = plen; 21541da177e4SLinus Torvalds 21551da177e4SLinus Torvalds if (plen) 21561da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 21571da177e4SLinus Torvalds 21581da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 21591da177e4SLinus Torvalds 21600d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 21611da177e4SLinus Torvalds skb->dev = (void *) hdev; 2162c78ae283SMarcel Holtmann 2163a5040efaSJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags)) 2164a5040efaSJohan Hedberg hdev->init_last_cmd = opcode; 2165a5040efaSJohan Hedberg 21661da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 2167c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 21681da177e4SLinus Torvalds 21691da177e4SLinus Torvalds return 0; 21701da177e4SLinus Torvalds } 21711da177e4SLinus Torvalds 21721da177e4SLinus Torvalds /* Get data from the previously sent command */ 2173a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 21741da177e4SLinus Torvalds { 21751da177e4SLinus Torvalds struct hci_command_hdr *hdr; 21761da177e4SLinus Torvalds 21771da177e4SLinus Torvalds if (!hdev->sent_cmd) 21781da177e4SLinus Torvalds return NULL; 21791da177e4SLinus Torvalds 21801da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 21811da177e4SLinus Torvalds 2182a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 21831da177e4SLinus Torvalds return NULL; 21841da177e4SLinus Torvalds 2185a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 21861da177e4SLinus Torvalds 21871da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 21881da177e4SLinus Torvalds } 21891da177e4SLinus Torvalds 21901da177e4SLinus Torvalds /* Send ACL data */ 21911da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 21921da177e4SLinus Torvalds { 21931da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 21941da177e4SLinus Torvalds int len = skb->len; 21951da177e4SLinus Torvalds 2196badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 2197badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 21989c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 2199aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 2200aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 22011da177e4SLinus Torvalds } 22021da177e4SLinus Torvalds 220373d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, 220473d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 22051da177e4SLinus Torvalds { 22061da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 22071da177e4SLinus Torvalds struct sk_buff *list; 22081da177e4SLinus Torvalds 220970f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 221070f23020SAndrei Emeltchenko if (!list) { 22111da177e4SLinus Torvalds /* Non fragmented */ 22121da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 22131da177e4SLinus Torvalds 221473d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 22151da177e4SLinus Torvalds } else { 22161da177e4SLinus Torvalds /* Fragmented */ 22171da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 22181da177e4SLinus Torvalds 22191da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 22201da177e4SLinus Torvalds 22211da177e4SLinus Torvalds /* Queue all fragments atomically */ 2222af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 22231da177e4SLinus Torvalds 222473d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 2225e702112fSAndrei Emeltchenko 2226e702112fSAndrei Emeltchenko flags &= ~ACL_START; 2227e702112fSAndrei Emeltchenko flags |= ACL_CONT; 22281da177e4SLinus Torvalds do { 22291da177e4SLinus Torvalds skb = list; list = list->next; 22301da177e4SLinus Torvalds 22311da177e4SLinus Torvalds skb->dev = (void *) hdev; 22320d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2233e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 22341da177e4SLinus Torvalds 22351da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 22361da177e4SLinus Torvalds 223773d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 22381da177e4SLinus Torvalds } while (list); 22391da177e4SLinus Torvalds 2240af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 22411da177e4SLinus Torvalds } 224273d80debSLuiz Augusto von Dentz } 224373d80debSLuiz Augusto von Dentz 224473d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 224573d80debSLuiz Augusto von Dentz { 224673d80debSLuiz Augusto von Dentz struct hci_conn *conn = chan->conn; 224773d80debSLuiz Augusto von Dentz struct hci_dev *hdev = conn->hdev; 224873d80debSLuiz Augusto von Dentz 224973d80debSLuiz Augusto von Dentz BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags); 225073d80debSLuiz Augusto von Dentz 225173d80debSLuiz Augusto von Dentz skb->dev = (void *) hdev; 225273d80debSLuiz Augusto von Dentz bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 225373d80debSLuiz Augusto von Dentz hci_add_acl_hdr(skb, conn->handle, flags); 225473d80debSLuiz Augusto von Dentz 225573d80debSLuiz Augusto von Dentz hci_queue_acl(conn, &chan->data_q, skb, flags); 22561da177e4SLinus Torvalds 22573eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 22581da177e4SLinus Torvalds } 22591da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl); 22601da177e4SLinus Torvalds 22611da177e4SLinus Torvalds /* Send SCO data */ 22620d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 22631da177e4SLinus Torvalds { 22641da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 22651da177e4SLinus Torvalds struct hci_sco_hdr hdr; 22661da177e4SLinus Torvalds 22671da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 22681da177e4SLinus Torvalds 2269aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 22701da177e4SLinus Torvalds hdr.dlen = skb->len; 22711da177e4SLinus Torvalds 2272badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 2273badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 22749c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 22751da177e4SLinus Torvalds 22761da177e4SLinus Torvalds skb->dev = (void *) hdev; 22770d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 2278c78ae283SMarcel Holtmann 22791da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 22803eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 22811da177e4SLinus Torvalds } 22821da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco); 22831da177e4SLinus Torvalds 22841da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 22851da177e4SLinus Torvalds 22861da177e4SLinus Torvalds /* HCI Connection scheduler */ 22871da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) 22881da177e4SLinus Torvalds { 22891da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 22908035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 22911da177e4SLinus Torvalds int num = 0, min = ~0; 22921da177e4SLinus Torvalds 22931da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 22941da177e4SLinus Torvalds * added and removed with TX task disabled. */ 2295bf4c6325SGustavo F. Padovan 2296bf4c6325SGustavo F. Padovan rcu_read_lock(); 2297bf4c6325SGustavo F. Padovan 2298bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2299769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 23001da177e4SLinus Torvalds continue; 2301769be974SMarcel Holtmann 2302769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 2303769be974SMarcel Holtmann continue; 2304769be974SMarcel Holtmann 23051da177e4SLinus Torvalds num++; 23061da177e4SLinus Torvalds 23071da177e4SLinus Torvalds if (c->sent < min) { 23081da177e4SLinus Torvalds min = c->sent; 23091da177e4SLinus Torvalds conn = c; 23101da177e4SLinus Torvalds } 231152087a79SLuiz Augusto von Dentz 231252087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 231352087a79SLuiz Augusto von Dentz break; 23141da177e4SLinus Torvalds } 23151da177e4SLinus Torvalds 2316bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2317bf4c6325SGustavo F. Padovan 23181da177e4SLinus Torvalds if (conn) { 23196ed58ec5SVille Tervo int cnt, q; 23206ed58ec5SVille Tervo 23216ed58ec5SVille Tervo switch (conn->type) { 23226ed58ec5SVille Tervo case ACL_LINK: 23236ed58ec5SVille Tervo cnt = hdev->acl_cnt; 23246ed58ec5SVille Tervo break; 23256ed58ec5SVille Tervo case SCO_LINK: 23266ed58ec5SVille Tervo case ESCO_LINK: 23276ed58ec5SVille Tervo cnt = hdev->sco_cnt; 23286ed58ec5SVille Tervo break; 23296ed58ec5SVille Tervo case LE_LINK: 23306ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 23316ed58ec5SVille Tervo break; 23326ed58ec5SVille Tervo default: 23336ed58ec5SVille Tervo cnt = 0; 23346ed58ec5SVille Tervo BT_ERR("Unknown link type"); 23356ed58ec5SVille Tervo } 23366ed58ec5SVille Tervo 23376ed58ec5SVille Tervo q = cnt / num; 23381da177e4SLinus Torvalds *quote = q ? q : 1; 23391da177e4SLinus Torvalds } else 23401da177e4SLinus Torvalds *quote = 0; 23411da177e4SLinus Torvalds 23421da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 23431da177e4SLinus Torvalds return conn; 23441da177e4SLinus Torvalds } 23451da177e4SLinus Torvalds 2346bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 23471da177e4SLinus Torvalds { 23481da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 23491da177e4SLinus Torvalds struct hci_conn *c; 23501da177e4SLinus Torvalds 2351bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 23521da177e4SLinus Torvalds 2353bf4c6325SGustavo F. Padovan rcu_read_lock(); 2354bf4c6325SGustavo F. Padovan 23551da177e4SLinus Torvalds /* Kill stalled connections */ 2356bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2357bae1f5d9SVille Tervo if (c->type == type && c->sent) { 2358bae1f5d9SVille Tervo BT_ERR("%s killing stalled connection %s", 23591da177e4SLinus Torvalds hdev->name, batostr(&c->dst)); 23601da177e4SLinus Torvalds hci_acl_disconn(c, 0x13); 23611da177e4SLinus Torvalds } 23621da177e4SLinus Torvalds } 2363bf4c6325SGustavo F. Padovan 2364bf4c6325SGustavo F. Padovan rcu_read_unlock(); 23651da177e4SLinus Torvalds } 23661da177e4SLinus Torvalds 236773d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 236873d80debSLuiz Augusto von Dentz int *quote) 236973d80debSLuiz Augusto von Dentz { 237073d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 237173d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 237273d80debSLuiz Augusto von Dentz int num = 0, min = ~0, cur_prio = 0; 237373d80debSLuiz Augusto von Dentz struct hci_conn *conn; 237473d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 237573d80debSLuiz Augusto von Dentz 237673d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 237773d80debSLuiz Augusto von Dentz 2378bf4c6325SGustavo F. Padovan rcu_read_lock(); 2379bf4c6325SGustavo F. Padovan 2380bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 238173d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 238273d80debSLuiz Augusto von Dentz 238373d80debSLuiz Augusto von Dentz if (conn->type != type) 238473d80debSLuiz Augusto von Dentz continue; 238573d80debSLuiz Augusto von Dentz 238673d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 238773d80debSLuiz Augusto von Dentz continue; 238873d80debSLuiz Augusto von Dentz 238973d80debSLuiz Augusto von Dentz conn_num++; 239073d80debSLuiz Augusto von Dentz 23918192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 239273d80debSLuiz Augusto von Dentz struct sk_buff *skb; 239373d80debSLuiz Augusto von Dentz 239473d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 239573d80debSLuiz Augusto von Dentz continue; 239673d80debSLuiz Augusto von Dentz 239773d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 239873d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 239973d80debSLuiz Augusto von Dentz continue; 240073d80debSLuiz Augusto von Dentz 240173d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 240273d80debSLuiz Augusto von Dentz num = 0; 240373d80debSLuiz Augusto von Dentz min = ~0; 240473d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 240573d80debSLuiz Augusto von Dentz } 240673d80debSLuiz Augusto von Dentz 240773d80debSLuiz Augusto von Dentz num++; 240873d80debSLuiz Augusto von Dentz 240973d80debSLuiz Augusto von Dentz if (conn->sent < min) { 241073d80debSLuiz Augusto von Dentz min = conn->sent; 241173d80debSLuiz Augusto von Dentz chan = tmp; 241273d80debSLuiz Augusto von Dentz } 241373d80debSLuiz Augusto von Dentz } 241473d80debSLuiz Augusto von Dentz 241573d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 241673d80debSLuiz Augusto von Dentz break; 241773d80debSLuiz Augusto von Dentz } 241873d80debSLuiz Augusto von Dentz 2419bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2420bf4c6325SGustavo F. Padovan 242173d80debSLuiz Augusto von Dentz if (!chan) 242273d80debSLuiz Augusto von Dentz return NULL; 242373d80debSLuiz Augusto von Dentz 242473d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 242573d80debSLuiz Augusto von Dentz case ACL_LINK: 242673d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 242773d80debSLuiz Augusto von Dentz break; 242873d80debSLuiz Augusto von Dentz case SCO_LINK: 242973d80debSLuiz Augusto von Dentz case ESCO_LINK: 243073d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 243173d80debSLuiz Augusto von Dentz break; 243273d80debSLuiz Augusto von Dentz case LE_LINK: 243373d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 243473d80debSLuiz Augusto von Dentz break; 243573d80debSLuiz Augusto von Dentz default: 243673d80debSLuiz Augusto von Dentz cnt = 0; 243773d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 243873d80debSLuiz Augusto von Dentz } 243973d80debSLuiz Augusto von Dentz 244073d80debSLuiz Augusto von Dentz q = cnt / num; 244173d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 244273d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 244373d80debSLuiz Augusto von Dentz return chan; 244473d80debSLuiz Augusto von Dentz } 244573d80debSLuiz Augusto von Dentz 244602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 244702b20f0bSLuiz Augusto von Dentz { 244802b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 244902b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 245002b20f0bSLuiz Augusto von Dentz int num = 0; 245102b20f0bSLuiz Augusto von Dentz 245202b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 245302b20f0bSLuiz Augusto von Dentz 2454bf4c6325SGustavo F. Padovan rcu_read_lock(); 2455bf4c6325SGustavo F. Padovan 2456bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 245702b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 245802b20f0bSLuiz Augusto von Dentz 245902b20f0bSLuiz Augusto von Dentz if (conn->type != type) 246002b20f0bSLuiz Augusto von Dentz continue; 246102b20f0bSLuiz Augusto von Dentz 246202b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 246302b20f0bSLuiz Augusto von Dentz continue; 246402b20f0bSLuiz Augusto von Dentz 246502b20f0bSLuiz Augusto von Dentz num++; 246602b20f0bSLuiz Augusto von Dentz 24678192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 246802b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 246902b20f0bSLuiz Augusto von Dentz 247002b20f0bSLuiz Augusto von Dentz if (chan->sent) { 247102b20f0bSLuiz Augusto von Dentz chan->sent = 0; 247202b20f0bSLuiz Augusto von Dentz continue; 247302b20f0bSLuiz Augusto von Dentz } 247402b20f0bSLuiz Augusto von Dentz 247502b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 247602b20f0bSLuiz Augusto von Dentz continue; 247702b20f0bSLuiz Augusto von Dentz 247802b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 247902b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 248002b20f0bSLuiz Augusto von Dentz continue; 248102b20f0bSLuiz Augusto von Dentz 248202b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 248302b20f0bSLuiz Augusto von Dentz 248402b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 248502b20f0bSLuiz Augusto von Dentz skb->priority); 248602b20f0bSLuiz Augusto von Dentz } 248702b20f0bSLuiz Augusto von Dentz 248802b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 248902b20f0bSLuiz Augusto von Dentz break; 249002b20f0bSLuiz Augusto von Dentz } 2491bf4c6325SGustavo F. Padovan 2492bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2493bf4c6325SGustavo F. Padovan 249402b20f0bSLuiz Augusto von Dentz } 249502b20f0bSLuiz Augusto von Dentz 2496b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 2497b71d385aSAndrei Emeltchenko { 2498b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 2499b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 2500b71d385aSAndrei Emeltchenko } 2501b71d385aSAndrei Emeltchenko 250263d2bc1bSAndrei Emeltchenko static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 25031da177e4SLinus Torvalds { 25041da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 25051da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 25061da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 250763d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 2508cc48dc0aSAndrei Emeltchenko msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) 2509bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 25101da177e4SLinus Torvalds } 251163d2bc1bSAndrei Emeltchenko } 25121da177e4SLinus Torvalds 251363d2bc1bSAndrei Emeltchenko static inline void hci_sched_acl_pkt(struct hci_dev *hdev) 251463d2bc1bSAndrei Emeltchenko { 251563d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 251663d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 251763d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 251863d2bc1bSAndrei Emeltchenko int quote; 251963d2bc1bSAndrei Emeltchenko 252063d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 252104837f64SMarcel Holtmann 252273d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 252373d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2524ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2525ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 252673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 252773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 252873d80debSLuiz Augusto von Dentz 2529ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2530ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2531ec1cce24SLuiz Augusto von Dentz break; 2532ec1cce24SLuiz Augusto von Dentz 2533ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2534ec1cce24SLuiz Augusto von Dentz 253573d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 253673d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 253704837f64SMarcel Holtmann 25381da177e4SLinus Torvalds hci_send_frame(skb); 25391da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 25401da177e4SLinus Torvalds 25411da177e4SLinus Torvalds hdev->acl_cnt--; 254273d80debSLuiz Augusto von Dentz chan->sent++; 254373d80debSLuiz Augusto von Dentz chan->conn->sent++; 25441da177e4SLinus Torvalds } 25451da177e4SLinus Torvalds } 254602b20f0bSLuiz Augusto von Dentz 254702b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 254802b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 25491da177e4SLinus Torvalds } 25501da177e4SLinus Torvalds 2551b71d385aSAndrei Emeltchenko static inline void hci_sched_acl_blk(struct hci_dev *hdev) 2552b71d385aSAndrei Emeltchenko { 255363d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 2554b71d385aSAndrei Emeltchenko struct hci_chan *chan; 2555b71d385aSAndrei Emeltchenko struct sk_buff *skb; 2556b71d385aSAndrei Emeltchenko int quote; 2557b71d385aSAndrei Emeltchenko 255863d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 2559b71d385aSAndrei Emeltchenko 2560b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 2561b71d385aSAndrei Emeltchenko (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 2562b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 2563b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 2564b71d385aSAndrei Emeltchenko int blocks; 2565b71d385aSAndrei Emeltchenko 2566b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 2567b71d385aSAndrei Emeltchenko skb->len, skb->priority); 2568b71d385aSAndrei Emeltchenko 2569b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 2570b71d385aSAndrei Emeltchenko if (skb->priority < priority) 2571b71d385aSAndrei Emeltchenko break; 2572b71d385aSAndrei Emeltchenko 2573b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 2574b71d385aSAndrei Emeltchenko 2575b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 2576b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 2577b71d385aSAndrei Emeltchenko return; 2578b71d385aSAndrei Emeltchenko 2579b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 2580b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 2581b71d385aSAndrei Emeltchenko 2582b71d385aSAndrei Emeltchenko hci_send_frame(skb); 2583b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 2584b71d385aSAndrei Emeltchenko 2585b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 2586b71d385aSAndrei Emeltchenko quote -= blocks; 2587b71d385aSAndrei Emeltchenko 2588b71d385aSAndrei Emeltchenko chan->sent += blocks; 2589b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 2590b71d385aSAndrei Emeltchenko } 2591b71d385aSAndrei Emeltchenko } 2592b71d385aSAndrei Emeltchenko 2593b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 2594b71d385aSAndrei Emeltchenko hci_prio_recalculate(hdev, ACL_LINK); 2595b71d385aSAndrei Emeltchenko } 2596b71d385aSAndrei Emeltchenko 2597b71d385aSAndrei Emeltchenko static inline void hci_sched_acl(struct hci_dev *hdev) 2598b71d385aSAndrei Emeltchenko { 2599b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 2600b71d385aSAndrei Emeltchenko 2601b71d385aSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK)) 2602b71d385aSAndrei Emeltchenko return; 2603b71d385aSAndrei Emeltchenko 2604b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 2605b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 2606b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 2607b71d385aSAndrei Emeltchenko break; 2608b71d385aSAndrei Emeltchenko 2609b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 2610b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 2611b71d385aSAndrei Emeltchenko break; 2612b71d385aSAndrei Emeltchenko } 2613b71d385aSAndrei Emeltchenko } 2614b71d385aSAndrei Emeltchenko 26151da177e4SLinus Torvalds /* Schedule SCO */ 26161da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev) 26171da177e4SLinus Torvalds { 26181da177e4SLinus Torvalds struct hci_conn *conn; 26191da177e4SLinus Torvalds struct sk_buff *skb; 26201da177e4SLinus Torvalds int quote; 26211da177e4SLinus Torvalds 26221da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 26231da177e4SLinus Torvalds 262452087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 262552087a79SLuiz Augusto von Dentz return; 262652087a79SLuiz Augusto von Dentz 26271da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 26281da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 26291da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 26301da177e4SLinus Torvalds hci_send_frame(skb); 26311da177e4SLinus Torvalds 26321da177e4SLinus Torvalds conn->sent++; 26331da177e4SLinus Torvalds if (conn->sent == ~0) 26341da177e4SLinus Torvalds conn->sent = 0; 26351da177e4SLinus Torvalds } 26361da177e4SLinus Torvalds } 26371da177e4SLinus Torvalds } 26381da177e4SLinus Torvalds 2639b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev) 2640b6a0dc82SMarcel Holtmann { 2641b6a0dc82SMarcel Holtmann struct hci_conn *conn; 2642b6a0dc82SMarcel Holtmann struct sk_buff *skb; 2643b6a0dc82SMarcel Holtmann int quote; 2644b6a0dc82SMarcel Holtmann 2645b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 2646b6a0dc82SMarcel Holtmann 264752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 264852087a79SLuiz Augusto von Dentz return; 264952087a79SLuiz Augusto von Dentz 2650b6a0dc82SMarcel Holtmann while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, "e))) { 2651b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 2652b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 2653b6a0dc82SMarcel Holtmann hci_send_frame(skb); 2654b6a0dc82SMarcel Holtmann 2655b6a0dc82SMarcel Holtmann conn->sent++; 2656b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 2657b6a0dc82SMarcel Holtmann conn->sent = 0; 2658b6a0dc82SMarcel Holtmann } 2659b6a0dc82SMarcel Holtmann } 2660b6a0dc82SMarcel Holtmann } 2661b6a0dc82SMarcel Holtmann 26626ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev) 26636ed58ec5SVille Tervo { 266473d80debSLuiz Augusto von Dentz struct hci_chan *chan; 26656ed58ec5SVille Tervo struct sk_buff *skb; 266602b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 26676ed58ec5SVille Tervo 26686ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 26696ed58ec5SVille Tervo 267052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 267152087a79SLuiz Augusto von Dentz return; 267252087a79SLuiz Augusto von Dentz 26736ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 26746ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 26756ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 2676bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 26776ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 2678bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 26796ed58ec5SVille Tervo } 26806ed58ec5SVille Tervo 26816ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 268202b20f0bSLuiz Augusto von Dentz tmp = cnt; 268373d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 2684ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 2685ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 268673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 268773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 26886ed58ec5SVille Tervo 2689ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 2690ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 2691ec1cce24SLuiz Augusto von Dentz break; 2692ec1cce24SLuiz Augusto von Dentz 2693ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 2694ec1cce24SLuiz Augusto von Dentz 26956ed58ec5SVille Tervo hci_send_frame(skb); 26966ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 26976ed58ec5SVille Tervo 26986ed58ec5SVille Tervo cnt--; 269973d80debSLuiz Augusto von Dentz chan->sent++; 270073d80debSLuiz Augusto von Dentz chan->conn->sent++; 27016ed58ec5SVille Tervo } 27026ed58ec5SVille Tervo } 270373d80debSLuiz Augusto von Dentz 27046ed58ec5SVille Tervo if (hdev->le_pkts) 27056ed58ec5SVille Tervo hdev->le_cnt = cnt; 27066ed58ec5SVille Tervo else 27076ed58ec5SVille Tervo hdev->acl_cnt = cnt; 270802b20f0bSLuiz Augusto von Dentz 270902b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 271002b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 27116ed58ec5SVille Tervo } 27126ed58ec5SVille Tervo 27133eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 27141da177e4SLinus Torvalds { 27153eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 27161da177e4SLinus Torvalds struct sk_buff *skb; 27171da177e4SLinus Torvalds 27186ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 27196ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 27201da177e4SLinus Torvalds 27211da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 27221da177e4SLinus Torvalds 27231da177e4SLinus Torvalds hci_sched_acl(hdev); 27241da177e4SLinus Torvalds 27251da177e4SLinus Torvalds hci_sched_sco(hdev); 27261da177e4SLinus Torvalds 2727b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 2728b6a0dc82SMarcel Holtmann 27296ed58ec5SVille Tervo hci_sched_le(hdev); 27306ed58ec5SVille Tervo 27311da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 27321da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 27331da177e4SLinus Torvalds hci_send_frame(skb); 27341da177e4SLinus Torvalds } 27351da177e4SLinus Torvalds 273625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 27371da177e4SLinus Torvalds 27381da177e4SLinus Torvalds /* ACL data packet */ 27391da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 27401da177e4SLinus Torvalds { 27411da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 27421da177e4SLinus Torvalds struct hci_conn *conn; 27431da177e4SLinus Torvalds __u16 handle, flags; 27441da177e4SLinus Torvalds 27451da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 27461da177e4SLinus Torvalds 27471da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 27481da177e4SLinus Torvalds flags = hci_flags(handle); 27491da177e4SLinus Torvalds handle = hci_handle(handle); 27501da177e4SLinus Torvalds 27511da177e4SLinus Torvalds BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags); 27521da177e4SLinus Torvalds 27531da177e4SLinus Torvalds hdev->stat.acl_rx++; 27541da177e4SLinus Torvalds 27551da177e4SLinus Torvalds hci_dev_lock(hdev); 27561da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 27571da177e4SLinus Torvalds hci_dev_unlock(hdev); 27581da177e4SLinus Torvalds 27591da177e4SLinus Torvalds if (conn) { 276065983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 276104837f64SMarcel Holtmann 27621da177e4SLinus Torvalds /* Send to upper protocol */ 2763686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 27641da177e4SLinus Torvalds return; 27651da177e4SLinus Torvalds } else { 27661da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 27671da177e4SLinus Torvalds hdev->name, handle); 27681da177e4SLinus Torvalds } 27691da177e4SLinus Torvalds 27701da177e4SLinus Torvalds kfree_skb(skb); 27711da177e4SLinus Torvalds } 27721da177e4SLinus Torvalds 27731da177e4SLinus Torvalds /* SCO data packet */ 27741da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 27751da177e4SLinus Torvalds { 27761da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 27771da177e4SLinus Torvalds struct hci_conn *conn; 27781da177e4SLinus Torvalds __u16 handle; 27791da177e4SLinus Torvalds 27801da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 27811da177e4SLinus Torvalds 27821da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 27831da177e4SLinus Torvalds 27841da177e4SLinus Torvalds BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle); 27851da177e4SLinus Torvalds 27861da177e4SLinus Torvalds hdev->stat.sco_rx++; 27871da177e4SLinus Torvalds 27881da177e4SLinus Torvalds hci_dev_lock(hdev); 27891da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 27901da177e4SLinus Torvalds hci_dev_unlock(hdev); 27911da177e4SLinus Torvalds 27921da177e4SLinus Torvalds if (conn) { 27931da177e4SLinus Torvalds /* Send to upper protocol */ 2794686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 27951da177e4SLinus Torvalds return; 27961da177e4SLinus Torvalds } else { 27971da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 27981da177e4SLinus Torvalds hdev->name, handle); 27991da177e4SLinus Torvalds } 28001da177e4SLinus Torvalds 28011da177e4SLinus Torvalds kfree_skb(skb); 28021da177e4SLinus Torvalds } 28031da177e4SLinus Torvalds 2804b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 28051da177e4SLinus Torvalds { 2806b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 28071da177e4SLinus Torvalds struct sk_buff *skb; 28081da177e4SLinus Torvalds 28091da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 28101da177e4SLinus Torvalds 28111da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 2812cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2813cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2814cd82e61cSMarcel Holtmann 28151da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 28161da177e4SLinus Torvalds /* Send copy to the sockets */ 2817470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 28181da177e4SLinus Torvalds } 28191da177e4SLinus Torvalds 28201da177e4SLinus Torvalds if (test_bit(HCI_RAW, &hdev->flags)) { 28211da177e4SLinus Torvalds kfree_skb(skb); 28221da177e4SLinus Torvalds continue; 28231da177e4SLinus Torvalds } 28241da177e4SLinus Torvalds 28251da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 28261da177e4SLinus Torvalds /* Don't process data packets in this states. */ 28270d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 28281da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 28291da177e4SLinus Torvalds case HCI_SCODATA_PKT: 28301da177e4SLinus Torvalds kfree_skb(skb); 28311da177e4SLinus Torvalds continue; 28323ff50b79SStephen Hemminger } 28331da177e4SLinus Torvalds } 28341da177e4SLinus Torvalds 28351da177e4SLinus Torvalds /* Process frame */ 28360d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 28371da177e4SLinus Torvalds case HCI_EVENT_PKT: 2838b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 28391da177e4SLinus Torvalds hci_event_packet(hdev, skb); 28401da177e4SLinus Torvalds break; 28411da177e4SLinus Torvalds 28421da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 28431da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 28441da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 28451da177e4SLinus Torvalds break; 28461da177e4SLinus Torvalds 28471da177e4SLinus Torvalds case HCI_SCODATA_PKT: 28481da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 28491da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 28501da177e4SLinus Torvalds break; 28511da177e4SLinus Torvalds 28521da177e4SLinus Torvalds default: 28531da177e4SLinus Torvalds kfree_skb(skb); 28541da177e4SLinus Torvalds break; 28551da177e4SLinus Torvalds } 28561da177e4SLinus Torvalds } 28571da177e4SLinus Torvalds } 28581da177e4SLinus Torvalds 2859c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 28601da177e4SLinus Torvalds { 2861c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 28621da177e4SLinus Torvalds struct sk_buff *skb; 28631da177e4SLinus Torvalds 28641da177e4SLinus Torvalds BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); 28651da177e4SLinus Torvalds 28661da177e4SLinus Torvalds /* Send queued commands */ 28675a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 28685a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 28695a08ecceSAndrei Emeltchenko if (!skb) 28705a08ecceSAndrei Emeltchenko return; 28715a08ecceSAndrei Emeltchenko 28721da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 28731da177e4SLinus Torvalds 287470f23020SAndrei Emeltchenko hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC); 287570f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 28761da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 28771da177e4SLinus Torvalds hci_send_frame(skb); 28787bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 28797bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 28807bdb8a5cSSzymon Janc else 28816bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 28826bd32326SVille Tervo jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); 28831da177e4SLinus Torvalds } else { 28841da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 2885c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 28861da177e4SLinus Torvalds } 28871da177e4SLinus Torvalds } 28881da177e4SLinus Torvalds } 28892519a1fcSAndre Guedes 28902519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length) 28912519a1fcSAndre Guedes { 28922519a1fcSAndre Guedes /* General inquiry access code (GIAC) */ 28932519a1fcSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 28942519a1fcSAndre Guedes struct hci_cp_inquiry cp; 28952519a1fcSAndre Guedes 28962519a1fcSAndre Guedes BT_DBG("%s", hdev->name); 28972519a1fcSAndre Guedes 28982519a1fcSAndre Guedes if (test_bit(HCI_INQUIRY, &hdev->flags)) 28992519a1fcSAndre Guedes return -EINPROGRESS; 29002519a1fcSAndre Guedes 29014663262cSJohan Hedberg inquiry_cache_flush(hdev); 29024663262cSJohan Hedberg 29032519a1fcSAndre Guedes memset(&cp, 0, sizeof(cp)); 29042519a1fcSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 29052519a1fcSAndre Guedes cp.length = length; 29062519a1fcSAndre Guedes 29072519a1fcSAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); 29082519a1fcSAndre Guedes } 2909023d5049SAndre Guedes 2910023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev) 2911023d5049SAndre Guedes { 2912023d5049SAndre Guedes BT_DBG("%s", hdev->name); 2913023d5049SAndre Guedes 2914023d5049SAndre Guedes if (!test_bit(HCI_INQUIRY, &hdev->flags)) 2915023d5049SAndre Guedes return -EPERM; 2916023d5049SAndre Guedes 2917023d5049SAndre Guedes return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); 2918023d5049SAndre Guedes } 2919