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 288c520a59SGustavo Padovan #include <linux/export.h> 293df92b31SSasha Levin #include <linux/idr.h> 301da177e4SLinus Torvalds 31611b30f7SMarcel Holtmann #include <linux/rfkill.h> 321da177e4SLinus Torvalds 331da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 341da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 351da177e4SLinus Torvalds 36b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work); 37c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work); 383eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work); 391da177e4SLinus Torvalds 401da177e4SLinus Torvalds /* HCI device list */ 411da177e4SLinus Torvalds LIST_HEAD(hci_dev_list); 421da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock); 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds /* HCI callback list */ 451da177e4SLinus Torvalds LIST_HEAD(hci_cb_list); 461da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock); 471da177e4SLinus Torvalds 483df92b31SSasha Levin /* HCI ID Numbering */ 493df92b31SSasha Levin static DEFINE_IDA(hci_index_ida); 503df92b31SSasha Levin 511da177e4SLinus Torvalds /* ---- HCI notifications ---- */ 521da177e4SLinus Torvalds 536516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event) 541da177e4SLinus Torvalds { 55040030efSMarcel Holtmann hci_sock_dev_event(hdev, event); 561da177e4SLinus Torvalds } 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds /* ---- HCI requests ---- */ 591da177e4SLinus Torvalds 6042c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) 611da177e4SLinus Torvalds { 6242c6b129SJohan Hedberg BT_DBG("%s result 0x%2.2x", hdev->name, result); 6375fb0e32SJohan Hedberg 641da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 651da177e4SLinus Torvalds hdev->req_result = result; 661da177e4SLinus Torvalds hdev->req_status = HCI_REQ_DONE; 671da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 681da177e4SLinus Torvalds } 691da177e4SLinus Torvalds } 701da177e4SLinus Torvalds 711da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err) 721da177e4SLinus Torvalds { 731da177e4SLinus Torvalds BT_DBG("%s err 0x%2.2x", hdev->name, err); 741da177e4SLinus Torvalds 751da177e4SLinus Torvalds if (hdev->req_status == HCI_REQ_PEND) { 761da177e4SLinus Torvalds hdev->req_result = err; 771da177e4SLinus Torvalds hdev->req_status = HCI_REQ_CANCELED; 781da177e4SLinus Torvalds wake_up_interruptible(&hdev->req_wait_q); 791da177e4SLinus Torvalds } 801da177e4SLinus Torvalds } 811da177e4SLinus Torvalds 8277a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 8377a63e0aSFengguang Wu u8 event) 8475e84b7cSJohan Hedberg { 8575e84b7cSJohan Hedberg struct hci_ev_cmd_complete *ev; 8675e84b7cSJohan Hedberg struct hci_event_hdr *hdr; 8775e84b7cSJohan Hedberg struct sk_buff *skb; 8875e84b7cSJohan Hedberg 8975e84b7cSJohan Hedberg hci_dev_lock(hdev); 9075e84b7cSJohan Hedberg 9175e84b7cSJohan Hedberg skb = hdev->recv_evt; 9275e84b7cSJohan Hedberg hdev->recv_evt = NULL; 9375e84b7cSJohan Hedberg 9475e84b7cSJohan Hedberg hci_dev_unlock(hdev); 9575e84b7cSJohan Hedberg 9675e84b7cSJohan Hedberg if (!skb) 9775e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 9875e84b7cSJohan Hedberg 9975e84b7cSJohan Hedberg if (skb->len < sizeof(*hdr)) { 10075e84b7cSJohan Hedberg BT_ERR("Too short HCI event"); 10175e84b7cSJohan Hedberg goto failed; 10275e84b7cSJohan Hedberg } 10375e84b7cSJohan Hedberg 10475e84b7cSJohan Hedberg hdr = (void *) skb->data; 10575e84b7cSJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 10675e84b7cSJohan Hedberg 1077b1abbbeSJohan Hedberg if (event) { 1087b1abbbeSJohan Hedberg if (hdr->evt != event) 1097b1abbbeSJohan Hedberg goto failed; 1107b1abbbeSJohan Hedberg return skb; 1117b1abbbeSJohan Hedberg } 1127b1abbbeSJohan Hedberg 11375e84b7cSJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 11475e84b7cSJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 11575e84b7cSJohan Hedberg goto failed; 11675e84b7cSJohan Hedberg } 11775e84b7cSJohan Hedberg 11875e84b7cSJohan Hedberg if (skb->len < sizeof(*ev)) { 11975e84b7cSJohan Hedberg BT_ERR("Too short cmd_complete event"); 12075e84b7cSJohan Hedberg goto failed; 12175e84b7cSJohan Hedberg } 12275e84b7cSJohan Hedberg 12375e84b7cSJohan Hedberg ev = (void *) skb->data; 12475e84b7cSJohan Hedberg skb_pull(skb, sizeof(*ev)); 12575e84b7cSJohan Hedberg 12675e84b7cSJohan Hedberg if (opcode == __le16_to_cpu(ev->opcode)) 12775e84b7cSJohan Hedberg return skb; 12875e84b7cSJohan Hedberg 12975e84b7cSJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 13075e84b7cSJohan Hedberg __le16_to_cpu(ev->opcode)); 13175e84b7cSJohan Hedberg 13275e84b7cSJohan Hedberg failed: 13375e84b7cSJohan Hedberg kfree_skb(skb); 13475e84b7cSJohan Hedberg return ERR_PTR(-ENODATA); 13575e84b7cSJohan Hedberg } 13675e84b7cSJohan Hedberg 1377b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 13807dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout) 13975e84b7cSJohan Hedberg { 14075e84b7cSJohan Hedberg DECLARE_WAITQUEUE(wait, current); 14175e84b7cSJohan Hedberg struct hci_request req; 14275e84b7cSJohan Hedberg int err = 0; 14375e84b7cSJohan Hedberg 14475e84b7cSJohan Hedberg BT_DBG("%s", hdev->name); 14575e84b7cSJohan Hedberg 14675e84b7cSJohan Hedberg hci_req_init(&req, hdev); 14775e84b7cSJohan Hedberg 1487b1abbbeSJohan Hedberg hci_req_add_ev(&req, opcode, plen, param, event); 14975e84b7cSJohan Hedberg 15075e84b7cSJohan Hedberg hdev->req_status = HCI_REQ_PEND; 15175e84b7cSJohan Hedberg 15275e84b7cSJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 15375e84b7cSJohan Hedberg if (err < 0) 15475e84b7cSJohan Hedberg return ERR_PTR(err); 15575e84b7cSJohan Hedberg 15675e84b7cSJohan Hedberg add_wait_queue(&hdev->req_wait_q, &wait); 15775e84b7cSJohan Hedberg set_current_state(TASK_INTERRUPTIBLE); 15875e84b7cSJohan Hedberg 15975e84b7cSJohan Hedberg schedule_timeout(timeout); 16075e84b7cSJohan Hedberg 16175e84b7cSJohan Hedberg remove_wait_queue(&hdev->req_wait_q, &wait); 16275e84b7cSJohan Hedberg 16375e84b7cSJohan Hedberg if (signal_pending(current)) 16475e84b7cSJohan Hedberg return ERR_PTR(-EINTR); 16575e84b7cSJohan Hedberg 16675e84b7cSJohan Hedberg switch (hdev->req_status) { 16775e84b7cSJohan Hedberg case HCI_REQ_DONE: 16875e84b7cSJohan Hedberg err = -bt_to_errno(hdev->req_result); 16975e84b7cSJohan Hedberg break; 17075e84b7cSJohan Hedberg 17175e84b7cSJohan Hedberg case HCI_REQ_CANCELED: 17275e84b7cSJohan Hedberg err = -hdev->req_result; 17375e84b7cSJohan Hedberg break; 17475e84b7cSJohan Hedberg 17575e84b7cSJohan Hedberg default: 17675e84b7cSJohan Hedberg err = -ETIMEDOUT; 17775e84b7cSJohan Hedberg break; 17875e84b7cSJohan Hedberg } 17975e84b7cSJohan Hedberg 18075e84b7cSJohan Hedberg hdev->req_status = hdev->req_result = 0; 18175e84b7cSJohan Hedberg 18275e84b7cSJohan Hedberg BT_DBG("%s end: err %d", hdev->name, err); 18375e84b7cSJohan Hedberg 18475e84b7cSJohan Hedberg if (err < 0) 18575e84b7cSJohan Hedberg return ERR_PTR(err); 18675e84b7cSJohan Hedberg 1877b1abbbeSJohan Hedberg return hci_get_cmd_complete(hdev, opcode, event); 1887b1abbbeSJohan Hedberg } 1897b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev); 1907b1abbbeSJohan Hedberg 1917b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 19207dc93ddSJohan Hedberg const void *param, u32 timeout) 1937b1abbbeSJohan Hedberg { 1947b1abbbeSJohan Hedberg return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); 19575e84b7cSJohan Hedberg } 19675e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync); 19775e84b7cSJohan Hedberg 1981da177e4SLinus Torvalds /* Execute request and wait for completion. */ 19901178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev, 20042c6b129SJohan Hedberg void (*func)(struct hci_request *req, 20142c6b129SJohan Hedberg unsigned long opt), 2021da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 2031da177e4SLinus Torvalds { 20442c6b129SJohan Hedberg struct hci_request req; 2051da177e4SLinus Torvalds DECLARE_WAITQUEUE(wait, current); 2061da177e4SLinus Torvalds int err = 0; 2071da177e4SLinus Torvalds 2081da177e4SLinus Torvalds BT_DBG("%s start", hdev->name); 2091da177e4SLinus Torvalds 21042c6b129SJohan Hedberg hci_req_init(&req, hdev); 21142c6b129SJohan Hedberg 2121da177e4SLinus Torvalds hdev->req_status = HCI_REQ_PEND; 2131da177e4SLinus Torvalds 21442c6b129SJohan Hedberg func(&req, opt); 21553cce22dSJohan Hedberg 21642c6b129SJohan Hedberg err = hci_req_run(&req, hci_req_sync_complete); 21742c6b129SJohan Hedberg if (err < 0) { 21853cce22dSJohan Hedberg hdev->req_status = 0; 219920c8300SAndre Guedes 220920c8300SAndre Guedes /* ENODATA means the HCI request command queue is empty. 221920c8300SAndre Guedes * This can happen when a request with conditionals doesn't 222920c8300SAndre Guedes * trigger any commands to be sent. This is normal behavior 223920c8300SAndre Guedes * and should not trigger an error return. 22442c6b129SJohan Hedberg */ 225920c8300SAndre Guedes if (err == -ENODATA) 22642c6b129SJohan Hedberg return 0; 227920c8300SAndre Guedes 228920c8300SAndre Guedes return err; 22953cce22dSJohan Hedberg } 23053cce22dSJohan Hedberg 231bc4445c7SAndre Guedes add_wait_queue(&hdev->req_wait_q, &wait); 232bc4445c7SAndre Guedes set_current_state(TASK_INTERRUPTIBLE); 233bc4445c7SAndre Guedes 2341da177e4SLinus Torvalds schedule_timeout(timeout); 2351da177e4SLinus Torvalds 2361da177e4SLinus Torvalds remove_wait_queue(&hdev->req_wait_q, &wait); 2371da177e4SLinus Torvalds 2381da177e4SLinus Torvalds if (signal_pending(current)) 2391da177e4SLinus Torvalds return -EINTR; 2401da177e4SLinus Torvalds 2411da177e4SLinus Torvalds switch (hdev->req_status) { 2421da177e4SLinus Torvalds case HCI_REQ_DONE: 243e175072fSJoe Perches err = -bt_to_errno(hdev->req_result); 2441da177e4SLinus Torvalds break; 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds case HCI_REQ_CANCELED: 2471da177e4SLinus Torvalds err = -hdev->req_result; 2481da177e4SLinus Torvalds break; 2491da177e4SLinus Torvalds 2501da177e4SLinus Torvalds default: 2511da177e4SLinus Torvalds err = -ETIMEDOUT; 2521da177e4SLinus Torvalds break; 2533ff50b79SStephen Hemminger } 2541da177e4SLinus Torvalds 255a5040efaSJohan Hedberg hdev->req_status = hdev->req_result = 0; 2561da177e4SLinus Torvalds 2571da177e4SLinus Torvalds BT_DBG("%s end: err %d", hdev->name, err); 2581da177e4SLinus Torvalds 2591da177e4SLinus Torvalds return err; 2601da177e4SLinus Torvalds } 2611da177e4SLinus Torvalds 26201178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev, 26342c6b129SJohan Hedberg void (*req)(struct hci_request *req, 26442c6b129SJohan Hedberg unsigned long opt), 2651da177e4SLinus Torvalds unsigned long opt, __u32 timeout) 2661da177e4SLinus Torvalds { 2671da177e4SLinus Torvalds int ret; 2681da177e4SLinus Torvalds 2697c6a329eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) 2707c6a329eSMarcel Holtmann return -ENETDOWN; 2717c6a329eSMarcel Holtmann 2721da177e4SLinus Torvalds /* Serialize all requests */ 2731da177e4SLinus Torvalds hci_req_lock(hdev); 27401178cd4SJohan Hedberg ret = __hci_req_sync(hdev, req, opt, timeout); 2751da177e4SLinus Torvalds hci_req_unlock(hdev); 2761da177e4SLinus Torvalds 2771da177e4SLinus Torvalds return ret; 2781da177e4SLinus Torvalds } 2791da177e4SLinus Torvalds 28042c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt) 2811da177e4SLinus Torvalds { 28242c6b129SJohan Hedberg BT_DBG("%s %ld", req->hdev->name, opt); 2831da177e4SLinus Torvalds 2841da177e4SLinus Torvalds /* Reset device */ 28542c6b129SJohan Hedberg set_bit(HCI_RESET, &req->hdev->flags); 28642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_RESET, 0, NULL); 2871da177e4SLinus Torvalds } 2881da177e4SLinus Torvalds 28942c6b129SJohan Hedberg static void bredr_init(struct hci_request *req) 2901da177e4SLinus Torvalds { 29142c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; 2922455a3eaSAndrei Emeltchenko 2931da177e4SLinus Torvalds /* Read Local Supported Features */ 29442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 2951da177e4SLinus Torvalds 2961143e5a6SMarcel Holtmann /* Read Local Version */ 29742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 2982177bab5SJohan Hedberg 2992177bab5SJohan Hedberg /* Read BD Address */ 30042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 3011da177e4SLinus Torvalds } 3021da177e4SLinus Torvalds 30342c6b129SJohan Hedberg static void amp_init(struct hci_request *req) 304e61ef499SAndrei Emeltchenko { 30542c6b129SJohan Hedberg req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 3062455a3eaSAndrei Emeltchenko 307e61ef499SAndrei Emeltchenko /* Read Local Version */ 30842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL); 3096bcbc489SAndrei Emeltchenko 310f6996cfeSMarcel Holtmann /* Read Local Supported Commands */ 311f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 312f6996cfeSMarcel Holtmann 313f6996cfeSMarcel Holtmann /* Read Local Supported Features */ 314f6996cfeSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); 315f6996cfeSMarcel Holtmann 3166bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 31742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 318e71dfabaSAndrei Emeltchenko 319e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 32042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 3217528ca1cSMarcel Holtmann 322f38ba941SMarcel Holtmann /* Read Flow Control Mode */ 323f38ba941SMarcel Holtmann hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL); 324f38ba941SMarcel Holtmann 3257528ca1cSMarcel Holtmann /* Read Location Data */ 3267528ca1cSMarcel Holtmann hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 327e61ef499SAndrei Emeltchenko } 328e61ef499SAndrei Emeltchenko 32942c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 330e61ef499SAndrei Emeltchenko { 33142c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 332e61ef499SAndrei Emeltchenko 333e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 334e61ef499SAndrei Emeltchenko 33511778716SAndrei Emeltchenko /* Reset */ 33611778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 33742c6b129SJohan Hedberg hci_reset_req(req, 0); 33811778716SAndrei Emeltchenko 339e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 340e61ef499SAndrei Emeltchenko case HCI_BREDR: 34142c6b129SJohan Hedberg bredr_init(req); 342e61ef499SAndrei Emeltchenko break; 343e61ef499SAndrei Emeltchenko 344e61ef499SAndrei Emeltchenko case HCI_AMP: 34542c6b129SJohan Hedberg amp_init(req); 346e61ef499SAndrei Emeltchenko break; 347e61ef499SAndrei Emeltchenko 348e61ef499SAndrei Emeltchenko default: 349e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 350e61ef499SAndrei Emeltchenko break; 351e61ef499SAndrei Emeltchenko } 352e61ef499SAndrei Emeltchenko } 353e61ef499SAndrei Emeltchenko 35442c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 3552177bab5SJohan Hedberg { 3564ca048e3SMarcel Holtmann struct hci_dev *hdev = req->hdev; 3574ca048e3SMarcel Holtmann 3582177bab5SJohan Hedberg __le16 param; 3592177bab5SJohan Hedberg __u8 flt_type; 3602177bab5SJohan Hedberg 3612177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 36242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 3632177bab5SJohan Hedberg 3642177bab5SJohan Hedberg /* Read Class of Device */ 36542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 3662177bab5SJohan Hedberg 3672177bab5SJohan Hedberg /* Read Local Name */ 36842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 3692177bab5SJohan Hedberg 3702177bab5SJohan Hedberg /* Read Voice Setting */ 37142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 3722177bab5SJohan Hedberg 373b4cb9fb2SMarcel Holtmann /* Read Number of Supported IAC */ 374b4cb9fb2SMarcel Holtmann hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL); 375b4cb9fb2SMarcel Holtmann 3764b836f39SMarcel Holtmann /* Read Current IAC LAP */ 3774b836f39SMarcel Holtmann hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL); 3784b836f39SMarcel Holtmann 3792177bab5SJohan Hedberg /* Clear Event Filters */ 3802177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 38142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 3822177bab5SJohan Hedberg 3832177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 3842177bab5SJohan Hedberg param = __constant_cpu_to_le16(0x7d00); 38542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 3862177bab5SJohan Hedberg 3874ca048e3SMarcel Holtmann /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, 3884ca048e3SMarcel Holtmann * but it does not support page scan related HCI commands. 3894ca048e3SMarcel Holtmann */ 3904ca048e3SMarcel Holtmann if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) { 391f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 392f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 393f332ec66SJohan Hedberg } 3942177bab5SJohan Hedberg } 3952177bab5SJohan Hedberg 39642c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 3972177bab5SJohan Hedberg { 398c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 399c73eee91SJohan Hedberg 4002177bab5SJohan Hedberg /* Read LE Buffer Size */ 40142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 4022177bab5SJohan Hedberg 4032177bab5SJohan Hedberg /* Read LE Local Supported Features */ 40442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 4052177bab5SJohan Hedberg 4062177bab5SJohan Hedberg /* Read LE Advertising Channel TX Power */ 40742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 4082177bab5SJohan Hedberg 4092177bab5SJohan Hedberg /* Read LE White List Size */ 41042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 4112177bab5SJohan Hedberg 4122177bab5SJohan Hedberg /* Read LE Supported States */ 41342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 414c73eee91SJohan Hedberg 415c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 416c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 417c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 4182177bab5SJohan Hedberg } 4192177bab5SJohan Hedberg 4202177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 4212177bab5SJohan Hedberg { 4222177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 4232177bab5SJohan Hedberg return 0x02; 4242177bab5SJohan Hedberg 4252177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 4262177bab5SJohan Hedberg return 0x01; 4272177bab5SJohan Hedberg 4282177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 4292177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 4302177bab5SJohan Hedberg return 0x01; 4312177bab5SJohan Hedberg 4322177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 4332177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 4342177bab5SJohan Hedberg return 0x01; 4352177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 4362177bab5SJohan Hedberg return 0x01; 4372177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 4382177bab5SJohan Hedberg return 0x01; 4392177bab5SJohan Hedberg } 4402177bab5SJohan Hedberg 4412177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 4422177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 4432177bab5SJohan Hedberg return 0x01; 4442177bab5SJohan Hedberg 4452177bab5SJohan Hedberg return 0x00; 4462177bab5SJohan Hedberg } 4472177bab5SJohan Hedberg 44842c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 4492177bab5SJohan Hedberg { 4502177bab5SJohan Hedberg u8 mode; 4512177bab5SJohan Hedberg 45242c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 4532177bab5SJohan Hedberg 45442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 4552177bab5SJohan Hedberg } 4562177bab5SJohan Hedberg 45742c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 4582177bab5SJohan Hedberg { 45942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 46042c6b129SJohan Hedberg 4612177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 4622177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 4632177bab5SJohan Hedberg * command otherwise. 4642177bab5SJohan Hedberg */ 4652177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 4662177bab5SJohan Hedberg 4672177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 4682177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 4692177bab5SJohan Hedberg */ 4702177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 4712177bab5SJohan Hedberg return; 4722177bab5SJohan Hedberg 4732177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 4742177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 4752177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 4762177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 4772177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 4782177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 479c7882cbdSMarcel Holtmann } else { 480c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 481c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 482c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 483c7882cbdSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 484c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 485c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 486c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 487c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 488c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 489c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 490c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 4912177bab5SJohan Hedberg } 4922177bab5SJohan Hedberg 4932177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 4942177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 4952177bab5SJohan Hedberg 4962177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 4972177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 4982177bab5SJohan Hedberg 4992177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 5002177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 5012177bab5SJohan Hedberg 5022177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 5032177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 5042177bab5SJohan Hedberg 5052177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 5062177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 5072177bab5SJohan Hedberg 5082177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 5092177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 5102177bab5SJohan Hedberg 5112177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 5122177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 5132177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 5142177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 5152177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 5162177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 5172177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 5182177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 5192177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 5202177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 5212177bab5SJohan Hedberg * Features Notification 5222177bab5SJohan Hedberg */ 5232177bab5SJohan Hedberg } 5242177bab5SJohan Hedberg 5252177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 5262177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 5272177bab5SJohan Hedberg 52842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 5292177bab5SJohan Hedberg 5302177bab5SJohan Hedberg if (lmp_le_capable(hdev)) { 5312177bab5SJohan Hedberg memset(events, 0, sizeof(events)); 5322177bab5SJohan Hedberg events[0] = 0x1f; 53342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, 5342177bab5SJohan Hedberg sizeof(events), events); 5352177bab5SJohan Hedberg } 5362177bab5SJohan Hedberg } 5372177bab5SJohan Hedberg 53842c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 5392177bab5SJohan Hedberg { 54042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 54142c6b129SJohan Hedberg 5422177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 54342c6b129SJohan Hedberg bredr_setup(req); 54456f87901SJohan Hedberg else 54556f87901SJohan Hedberg clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 5462177bab5SJohan Hedberg 5472177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 54842c6b129SJohan Hedberg le_setup(req); 5492177bab5SJohan Hedberg 55042c6b129SJohan Hedberg hci_setup_event_mask(req); 5512177bab5SJohan Hedberg 5523f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 5533f8e2d75SJohan Hedberg * local supported commands HCI command. 5543f8e2d75SJohan Hedberg */ 5553f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 55642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 5572177bab5SJohan Hedberg 5582177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 5592177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 5602177bab5SJohan Hedberg u8 mode = 0x01; 56142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 5622177bab5SJohan Hedberg sizeof(mode), &mode); 5632177bab5SJohan Hedberg } else { 5642177bab5SJohan Hedberg struct hci_cp_write_eir cp; 5652177bab5SJohan Hedberg 5662177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 5672177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 5682177bab5SJohan Hedberg 56942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 5702177bab5SJohan Hedberg } 5712177bab5SJohan Hedberg } 5722177bab5SJohan Hedberg 5732177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 57442c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 5752177bab5SJohan Hedberg 5762177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 57742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 5782177bab5SJohan Hedberg 5792177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 5802177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 5812177bab5SJohan Hedberg 5822177bab5SJohan Hedberg cp.page = 0x01; 58342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 58442c6b129SJohan Hedberg sizeof(cp), &cp); 5852177bab5SJohan Hedberg } 5862177bab5SJohan Hedberg 5872177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 5882177bab5SJohan Hedberg u8 enable = 1; 58942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 5902177bab5SJohan Hedberg &enable); 5912177bab5SJohan Hedberg } 5922177bab5SJohan Hedberg } 5932177bab5SJohan Hedberg 59442c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 5952177bab5SJohan Hedberg { 59642c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 5972177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 5982177bab5SJohan Hedberg u16 link_policy = 0; 5992177bab5SJohan Hedberg 6002177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 6012177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 6022177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 6032177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 6042177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 6052177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 6062177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 6072177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 6082177bab5SJohan Hedberg 6092177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 61042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 6112177bab5SJohan Hedberg } 6122177bab5SJohan Hedberg 61342c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 6142177bab5SJohan Hedberg { 61542c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 6162177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 6172177bab5SJohan Hedberg 618c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 619c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 620c73eee91SJohan Hedberg return; 621c73eee91SJohan Hedberg 6222177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 6232177bab5SJohan Hedberg 6242177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 6252177bab5SJohan Hedberg cp.le = 0x01; 6262177bab5SJohan Hedberg cp.simul = lmp_le_br_capable(hdev); 6272177bab5SJohan Hedberg } 6282177bab5SJohan Hedberg 6292177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 63042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 6312177bab5SJohan Hedberg &cp); 6322177bab5SJohan Hedberg } 6332177bab5SJohan Hedberg 634d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req) 635d62e6d67SJohan Hedberg { 636d62e6d67SJohan Hedberg struct hci_dev *hdev = req->hdev; 637d62e6d67SJohan Hedberg u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 638d62e6d67SJohan Hedberg 639d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast master role is supported 640d62e6d67SJohan Hedberg * enable all necessary events for it. 641d62e6d67SJohan Hedberg */ 642d62e6d67SJohan Hedberg if (hdev->features[2][0] & 0x01) { 643d62e6d67SJohan Hedberg events[1] |= 0x40; /* Triggered Clock Capture */ 644d62e6d67SJohan Hedberg events[1] |= 0x80; /* Synchronization Train Complete */ 645d62e6d67SJohan Hedberg events[2] |= 0x10; /* Slave Page Response Timeout */ 646d62e6d67SJohan Hedberg events[2] |= 0x20; /* CSB Channel Map Change */ 647d62e6d67SJohan Hedberg } 648d62e6d67SJohan Hedberg 649d62e6d67SJohan Hedberg /* If Connectionless Slave Broadcast slave role is supported 650d62e6d67SJohan Hedberg * enable all necessary events for it. 651d62e6d67SJohan Hedberg */ 652d62e6d67SJohan Hedberg if (hdev->features[2][0] & 0x02) { 653d62e6d67SJohan Hedberg events[2] |= 0x01; /* Synchronization Train Received */ 654d62e6d67SJohan Hedberg events[2] |= 0x02; /* CSB Receive */ 655d62e6d67SJohan Hedberg events[2] |= 0x04; /* CSB Timeout */ 656d62e6d67SJohan Hedberg events[2] |= 0x08; /* Truncated Page Complete */ 657d62e6d67SJohan Hedberg } 658d62e6d67SJohan Hedberg 659d62e6d67SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); 660d62e6d67SJohan Hedberg } 661d62e6d67SJohan Hedberg 66242c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 6632177bab5SJohan Hedberg { 66442c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 665d2c5d77fSJohan Hedberg u8 p; 66642c6b129SJohan Hedberg 667b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 668b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 669b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 670b8f4e068SGustavo Padovan * 671b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 672b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 673b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 674b8f4e068SGustavo Padovan * command redundant anyway. 675b8f4e068SGustavo Padovan */ 67659f45d57SJohan Hedberg if (hdev->commands[6] & 0x80) { 67759f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 67859f45d57SJohan Hedberg 67959f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 68059f45d57SJohan Hedberg cp.delete_all = 0x01; 68159f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 68259f45d57SJohan Hedberg sizeof(cp), &cp); 68359f45d57SJohan Hedberg } 68459f45d57SJohan Hedberg 6852177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 68642c6b129SJohan Hedberg hci_setup_link_policy(req); 6872177bab5SJohan Hedberg 68804b4edcbSJohan Hedberg if (lmp_le_capable(hdev)) { 68942c6b129SJohan Hedberg hci_set_le_support(req); 69004b4edcbSJohan Hedberg hci_update_ad(req); 69104b4edcbSJohan Hedberg } 692d2c5d77fSJohan Hedberg 693d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 694d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 695d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 696d2c5d77fSJohan Hedberg 697d2c5d77fSJohan Hedberg cp.page = p; 698d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 699d2c5d77fSJohan Hedberg sizeof(cp), &cp); 700d2c5d77fSJohan Hedberg } 7012177bab5SJohan Hedberg } 7022177bab5SJohan Hedberg 7035d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt) 7045d4e7e8dSJohan Hedberg { 7055d4e7e8dSJohan Hedberg struct hci_dev *hdev = req->hdev; 7065d4e7e8dSJohan Hedberg 707d62e6d67SJohan Hedberg /* Set event mask page 2 if the HCI command for it is supported */ 708d62e6d67SJohan Hedberg if (hdev->commands[22] & 0x04) 709d62e6d67SJohan Hedberg hci_set_event_mask_page_2(req); 710d62e6d67SJohan Hedberg 7115d4e7e8dSJohan Hedberg /* Check for Synchronization Train support */ 7125d4e7e8dSJohan Hedberg if (hdev->features[2][0] & 0x04) 7135d4e7e8dSJohan Hedberg hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); 7145d4e7e8dSJohan Hedberg } 7155d4e7e8dSJohan Hedberg 7162177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 7172177bab5SJohan Hedberg { 7182177bab5SJohan Hedberg int err; 7192177bab5SJohan Hedberg 7202177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 7212177bab5SJohan Hedberg if (err < 0) 7222177bab5SJohan Hedberg return err; 7232177bab5SJohan Hedberg 7242177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 7252177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 7262177bab5SJohan Hedberg * first stage init. 7272177bab5SJohan Hedberg */ 7282177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 7292177bab5SJohan Hedberg return 0; 7302177bab5SJohan Hedberg 7312177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 7322177bab5SJohan Hedberg if (err < 0) 7332177bab5SJohan Hedberg return err; 7342177bab5SJohan Hedberg 7355d4e7e8dSJohan Hedberg err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 7365d4e7e8dSJohan Hedberg if (err < 0) 7375d4e7e8dSJohan Hedberg return err; 7385d4e7e8dSJohan Hedberg 7395d4e7e8dSJohan Hedberg return __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); 7402177bab5SJohan Hedberg } 7412177bab5SJohan Hedberg 74242c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 7431da177e4SLinus Torvalds { 7441da177e4SLinus Torvalds __u8 scan = opt; 7451da177e4SLinus Torvalds 74642c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 7471da177e4SLinus Torvalds 7481da177e4SLinus Torvalds /* Inquiry and Page scans */ 74942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 7501da177e4SLinus Torvalds } 7511da177e4SLinus Torvalds 75242c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 7531da177e4SLinus Torvalds { 7541da177e4SLinus Torvalds __u8 auth = opt; 7551da177e4SLinus Torvalds 75642c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 7571da177e4SLinus Torvalds 7581da177e4SLinus Torvalds /* Authentication */ 75942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 7601da177e4SLinus Torvalds } 7611da177e4SLinus Torvalds 76242c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 7631da177e4SLinus Torvalds { 7641da177e4SLinus Torvalds __u8 encrypt = opt; 7651da177e4SLinus Torvalds 76642c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 7671da177e4SLinus Torvalds 768e4e8e37cSMarcel Holtmann /* Encryption */ 76942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 7701da177e4SLinus Torvalds } 7711da177e4SLinus Torvalds 77242c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 773e4e8e37cSMarcel Holtmann { 774e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 775e4e8e37cSMarcel Holtmann 77642c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 777e4e8e37cSMarcel Holtmann 778e4e8e37cSMarcel Holtmann /* Default link policy */ 77942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 780e4e8e37cSMarcel Holtmann } 781e4e8e37cSMarcel Holtmann 7821da177e4SLinus Torvalds /* Get HCI device by index. 7831da177e4SLinus Torvalds * Device is held on return. */ 7841da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 7851da177e4SLinus Torvalds { 7868035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 7871da177e4SLinus Torvalds 7881da177e4SLinus Torvalds BT_DBG("%d", index); 7891da177e4SLinus Torvalds 7901da177e4SLinus Torvalds if (index < 0) 7911da177e4SLinus Torvalds return NULL; 7921da177e4SLinus Torvalds 7931da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 7948035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 7951da177e4SLinus Torvalds if (d->id == index) { 7961da177e4SLinus Torvalds hdev = hci_dev_hold(d); 7971da177e4SLinus Torvalds break; 7981da177e4SLinus Torvalds } 7991da177e4SLinus Torvalds } 8001da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 8011da177e4SLinus Torvalds return hdev; 8021da177e4SLinus Torvalds } 8031da177e4SLinus Torvalds 8041da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 805ff9ef578SJohan Hedberg 80630dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 80730dc78e1SJohan Hedberg { 80830dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 80930dc78e1SJohan Hedberg 8106fbe195dSAndre Guedes switch (discov->state) { 811343f935bSAndre Guedes case DISCOVERY_FINDING: 8126fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 81330dc78e1SJohan Hedberg return true; 81430dc78e1SJohan Hedberg 8156fbe195dSAndre Guedes default: 81630dc78e1SJohan Hedberg return false; 81730dc78e1SJohan Hedberg } 8186fbe195dSAndre Guedes } 81930dc78e1SJohan Hedberg 820ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 821ff9ef578SJohan Hedberg { 822ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 823ff9ef578SJohan Hedberg 824ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 825ff9ef578SJohan Hedberg return; 826ff9ef578SJohan Hedberg 827ff9ef578SJohan Hedberg switch (state) { 828ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 8297b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 830ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 831ff9ef578SJohan Hedberg break; 832ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 833ff9ef578SJohan Hedberg break; 834343f935bSAndre Guedes case DISCOVERY_FINDING: 835ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 836ff9ef578SJohan Hedberg break; 83730dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 83830dc78e1SJohan Hedberg break; 839ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 840ff9ef578SJohan Hedberg break; 841ff9ef578SJohan Hedberg } 842ff9ef578SJohan Hedberg 843ff9ef578SJohan Hedberg hdev->discovery.state = state; 844ff9ef578SJohan Hedberg } 845ff9ef578SJohan Hedberg 8461f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 8471da177e4SLinus Torvalds { 84830883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 849b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 8501da177e4SLinus Torvalds 851561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 852561aafbcSJohan Hedberg list_del(&p->all); 853b57c1a56SJohan Hedberg kfree(p); 8541da177e4SLinus Torvalds } 855561aafbcSJohan Hedberg 856561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 857561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 8581da177e4SLinus Torvalds } 8591da177e4SLinus Torvalds 860a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 861a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 8621da177e4SLinus Torvalds { 86330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 8641da177e4SLinus Torvalds struct inquiry_entry *e; 8651da177e4SLinus Torvalds 8666ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 8671da177e4SLinus Torvalds 868561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 8691da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 8701da177e4SLinus Torvalds return e; 8711da177e4SLinus Torvalds } 8721da177e4SLinus Torvalds 873b57c1a56SJohan Hedberg return NULL; 874b57c1a56SJohan Hedberg } 875b57c1a56SJohan Hedberg 876561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 877561aafbcSJohan Hedberg bdaddr_t *bdaddr) 878561aafbcSJohan Hedberg { 87930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 880561aafbcSJohan Hedberg struct inquiry_entry *e; 881561aafbcSJohan Hedberg 8826ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 883561aafbcSJohan Hedberg 884561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 885561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 886561aafbcSJohan Hedberg return e; 887561aafbcSJohan Hedberg } 888561aafbcSJohan Hedberg 889561aafbcSJohan Hedberg return NULL; 890561aafbcSJohan Hedberg } 891561aafbcSJohan Hedberg 89230dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 89330dc78e1SJohan Hedberg bdaddr_t *bdaddr, 89430dc78e1SJohan Hedberg int state) 89530dc78e1SJohan Hedberg { 89630dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 89730dc78e1SJohan Hedberg struct inquiry_entry *e; 89830dc78e1SJohan Hedberg 8996ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 90030dc78e1SJohan Hedberg 90130dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 90230dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 90330dc78e1SJohan Hedberg return e; 90430dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 90530dc78e1SJohan Hedberg return e; 90630dc78e1SJohan Hedberg } 90730dc78e1SJohan Hedberg 90830dc78e1SJohan Hedberg return NULL; 90930dc78e1SJohan Hedberg } 91030dc78e1SJohan Hedberg 911a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 912a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 913a3d4e20aSJohan Hedberg { 914a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 915a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 916a3d4e20aSJohan Hedberg struct inquiry_entry *p; 917a3d4e20aSJohan Hedberg 918a3d4e20aSJohan Hedberg list_del(&ie->list); 919a3d4e20aSJohan Hedberg 920a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 921a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 922a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 923a3d4e20aSJohan Hedberg break; 924a3d4e20aSJohan Hedberg pos = &p->list; 925a3d4e20aSJohan Hedberg } 926a3d4e20aSJohan Hedberg 927a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 928a3d4e20aSJohan Hedberg } 929a3d4e20aSJohan Hedberg 9303175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 931388fc8faSJohan Hedberg bool name_known, bool *ssp) 9321da177e4SLinus Torvalds { 93330883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 93470f23020SAndrei Emeltchenko struct inquiry_entry *ie; 9351da177e4SLinus Torvalds 9366ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 9371da177e4SLinus Torvalds 9382b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 9392b2fec4dSSzymon Janc 940388fc8faSJohan Hedberg if (ssp) 941388fc8faSJohan Hedberg *ssp = data->ssp_mode; 942388fc8faSJohan Hedberg 94370f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 944a3d4e20aSJohan Hedberg if (ie) { 945388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 946388fc8faSJohan Hedberg *ssp = true; 947388fc8faSJohan Hedberg 948a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 949a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 950a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 951a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 952a3d4e20aSJohan Hedberg } 953a3d4e20aSJohan Hedberg 954561aafbcSJohan Hedberg goto update; 955a3d4e20aSJohan Hedberg } 956561aafbcSJohan Hedberg 9571da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 95870f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 95970f23020SAndrei Emeltchenko if (!ie) 9603175405bSJohan Hedberg return false; 96170f23020SAndrei Emeltchenko 962561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 963561aafbcSJohan Hedberg 964561aafbcSJohan Hedberg if (name_known) { 965561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 966561aafbcSJohan Hedberg } else { 967561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 968561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 969561aafbcSJohan Hedberg } 970561aafbcSJohan Hedberg 971561aafbcSJohan Hedberg update: 972561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 973561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 974561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 975561aafbcSJohan Hedberg list_del(&ie->list); 9761da177e4SLinus Torvalds } 9771da177e4SLinus Torvalds 97870f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 97970f23020SAndrei Emeltchenko ie->timestamp = jiffies; 9801da177e4SLinus Torvalds cache->timestamp = jiffies; 9813175405bSJohan Hedberg 9823175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 9833175405bSJohan Hedberg return false; 9843175405bSJohan Hedberg 9853175405bSJohan Hedberg return true; 9861da177e4SLinus Torvalds } 9871da177e4SLinus Torvalds 9881da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 9891da177e4SLinus Torvalds { 99030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 9911da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 9921da177e4SLinus Torvalds struct inquiry_entry *e; 9931da177e4SLinus Torvalds int copied = 0; 9941da177e4SLinus Torvalds 995561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 9961da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 997b57c1a56SJohan Hedberg 998b57c1a56SJohan Hedberg if (copied >= num) 999b57c1a56SJohan Hedberg break; 1000b57c1a56SJohan Hedberg 10011da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 10021da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 10031da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 10041da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 10051da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 10061da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 1007b57c1a56SJohan Hedberg 10081da177e4SLinus Torvalds info++; 1009b57c1a56SJohan Hedberg copied++; 10101da177e4SLinus Torvalds } 10111da177e4SLinus Torvalds 10121da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 10131da177e4SLinus Torvalds return copied; 10141da177e4SLinus Torvalds } 10151da177e4SLinus Torvalds 101642c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 10171da177e4SLinus Torvalds { 10181da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 101942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 10201da177e4SLinus Torvalds struct hci_cp_inquiry cp; 10211da177e4SLinus Torvalds 10221da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 10231da177e4SLinus Torvalds 10241da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 10251da177e4SLinus Torvalds return; 10261da177e4SLinus Torvalds 10271da177e4SLinus Torvalds /* Start Inquiry */ 10281da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 10291da177e4SLinus Torvalds cp.length = ir->length; 10301da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 103142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 10321da177e4SLinus Torvalds } 10331da177e4SLinus Torvalds 10343e13fa1eSAndre Guedes static int wait_inquiry(void *word) 10353e13fa1eSAndre Guedes { 10363e13fa1eSAndre Guedes schedule(); 10373e13fa1eSAndre Guedes return signal_pending(current); 10383e13fa1eSAndre Guedes } 10393e13fa1eSAndre Guedes 10401da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 10411da177e4SLinus Torvalds { 10421da177e4SLinus Torvalds __u8 __user *ptr = arg; 10431da177e4SLinus Torvalds struct hci_inquiry_req ir; 10441da177e4SLinus Torvalds struct hci_dev *hdev; 10451da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 10461da177e4SLinus Torvalds long timeo; 10471da177e4SLinus Torvalds __u8 *buf; 10481da177e4SLinus Torvalds 10491da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 10501da177e4SLinus Torvalds return -EFAULT; 10511da177e4SLinus Torvalds 10525a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 10535a08ecceSAndrei Emeltchenko if (!hdev) 10541da177e4SLinus Torvalds return -ENODEV; 10551da177e4SLinus Torvalds 10560736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 10570736cfa8SMarcel Holtmann err = -EBUSY; 10580736cfa8SMarcel Holtmann goto done; 10590736cfa8SMarcel Holtmann } 10600736cfa8SMarcel Holtmann 10615b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 10625b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 10635b69bef5SMarcel Holtmann goto done; 10645b69bef5SMarcel Holtmann } 10655b69bef5SMarcel Holtmann 106656f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 106756f87901SJohan Hedberg err = -EOPNOTSUPP; 106856f87901SJohan Hedberg goto done; 106956f87901SJohan Hedberg } 107056f87901SJohan Hedberg 107109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 10721da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 1073a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 10741f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 10751da177e4SLinus Torvalds do_inquiry = 1; 10761da177e4SLinus Torvalds } 107709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 10781da177e4SLinus Torvalds 107904837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 108070f23020SAndrei Emeltchenko 108170f23020SAndrei Emeltchenko if (do_inquiry) { 108201178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 108301178cd4SJohan Hedberg timeo); 108470f23020SAndrei Emeltchenko if (err < 0) 10851da177e4SLinus Torvalds goto done; 10863e13fa1eSAndre Guedes 10873e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 10883e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 10893e13fa1eSAndre Guedes */ 10903e13fa1eSAndre Guedes if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, 10913e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 10923e13fa1eSAndre Guedes return -EINTR; 109370f23020SAndrei Emeltchenko } 10941da177e4SLinus Torvalds 10958fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 10968fc9ced3SGustavo Padovan * 255 entries 10978fc9ced3SGustavo Padovan */ 10981da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 10991da177e4SLinus Torvalds 11001da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 11011da177e4SLinus Torvalds * copy it to the user space. 11021da177e4SLinus Torvalds */ 110370f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 110470f23020SAndrei Emeltchenko if (!buf) { 11051da177e4SLinus Torvalds err = -ENOMEM; 11061da177e4SLinus Torvalds goto done; 11071da177e4SLinus Torvalds } 11081da177e4SLinus Torvalds 110909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 11101da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 111109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 11121da177e4SLinus Torvalds 11131da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 11141da177e4SLinus Torvalds 11151da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 11161da177e4SLinus Torvalds ptr += sizeof(ir); 11171da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 11181da177e4SLinus Torvalds ir.num_rsp)) 11191da177e4SLinus Torvalds err = -EFAULT; 11201da177e4SLinus Torvalds } else 11211da177e4SLinus Torvalds err = -EFAULT; 11221da177e4SLinus Torvalds 11231da177e4SLinus Torvalds kfree(buf); 11241da177e4SLinus Torvalds 11251da177e4SLinus Torvalds done: 11261da177e4SLinus Torvalds hci_dev_put(hdev); 11271da177e4SLinus Torvalds return err; 11281da177e4SLinus Torvalds } 11291da177e4SLinus Torvalds 11303f0f524bSJohan Hedberg static u8 create_ad(struct hci_dev *hdev, u8 *ptr) 11313f0f524bSJohan Hedberg { 11323f0f524bSJohan Hedberg u8 ad_len = 0, flags = 0; 11333f0f524bSJohan Hedberg size_t name_len; 11343f0f524bSJohan Hedberg 1135f3d3444aSJohan Hedberg if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) 11363f0f524bSJohan Hedberg flags |= LE_AD_GENERAL; 11373f0f524bSJohan Hedberg 113811802b29SJohan Hedberg if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 11393f0f524bSJohan Hedberg if (lmp_le_br_capable(hdev)) 11403f0f524bSJohan Hedberg flags |= LE_AD_SIM_LE_BREDR_CTRL; 11413f0f524bSJohan Hedberg if (lmp_host_le_br_capable(hdev)) 11423f0f524bSJohan Hedberg flags |= LE_AD_SIM_LE_BREDR_HOST; 114311802b29SJohan Hedberg } else { 114411802b29SJohan Hedberg flags |= LE_AD_NO_BREDR; 114511802b29SJohan Hedberg } 11463f0f524bSJohan Hedberg 11473f0f524bSJohan Hedberg if (flags) { 11483f0f524bSJohan Hedberg BT_DBG("adv flags 0x%02x", flags); 11493f0f524bSJohan Hedberg 11503f0f524bSJohan Hedberg ptr[0] = 2; 11513f0f524bSJohan Hedberg ptr[1] = EIR_FLAGS; 11523f0f524bSJohan Hedberg ptr[2] = flags; 11533f0f524bSJohan Hedberg 11543f0f524bSJohan Hedberg ad_len += 3; 11553f0f524bSJohan Hedberg ptr += 3; 11563f0f524bSJohan Hedberg } 11573f0f524bSJohan Hedberg 11583f0f524bSJohan Hedberg if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) { 11593f0f524bSJohan Hedberg ptr[0] = 2; 11603f0f524bSJohan Hedberg ptr[1] = EIR_TX_POWER; 11613f0f524bSJohan Hedberg ptr[2] = (u8) hdev->adv_tx_power; 11623f0f524bSJohan Hedberg 11633f0f524bSJohan Hedberg ad_len += 3; 11643f0f524bSJohan Hedberg ptr += 3; 11653f0f524bSJohan Hedberg } 11663f0f524bSJohan Hedberg 11673f0f524bSJohan Hedberg name_len = strlen(hdev->dev_name); 11683f0f524bSJohan Hedberg if (name_len > 0) { 11693f0f524bSJohan Hedberg size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2; 11703f0f524bSJohan Hedberg 11713f0f524bSJohan Hedberg if (name_len > max_len) { 11723f0f524bSJohan Hedberg name_len = max_len; 11733f0f524bSJohan Hedberg ptr[1] = EIR_NAME_SHORT; 11743f0f524bSJohan Hedberg } else 11753f0f524bSJohan Hedberg ptr[1] = EIR_NAME_COMPLETE; 11763f0f524bSJohan Hedberg 11773f0f524bSJohan Hedberg ptr[0] = name_len + 1; 11783f0f524bSJohan Hedberg 11793f0f524bSJohan Hedberg memcpy(ptr + 2, hdev->dev_name, name_len); 11803f0f524bSJohan Hedberg 11813f0f524bSJohan Hedberg ad_len += (name_len + 2); 11823f0f524bSJohan Hedberg ptr += (name_len + 2); 11833f0f524bSJohan Hedberg } 11843f0f524bSJohan Hedberg 11853f0f524bSJohan Hedberg return ad_len; 11863f0f524bSJohan Hedberg } 11873f0f524bSJohan Hedberg 118804b4edcbSJohan Hedberg void hci_update_ad(struct hci_request *req) 11893f0f524bSJohan Hedberg { 119004b4edcbSJohan Hedberg struct hci_dev *hdev = req->hdev; 11913f0f524bSJohan Hedberg struct hci_cp_le_set_adv_data cp; 11923f0f524bSJohan Hedberg u8 len; 11933f0f524bSJohan Hedberg 119404b4edcbSJohan Hedberg if (!lmp_le_capable(hdev)) 119504b4edcbSJohan Hedberg return; 11963f0f524bSJohan Hedberg 11973f0f524bSJohan Hedberg memset(&cp, 0, sizeof(cp)); 11983f0f524bSJohan Hedberg 11993f0f524bSJohan Hedberg len = create_ad(hdev, cp.data); 12003f0f524bSJohan Hedberg 12013f0f524bSJohan Hedberg if (hdev->adv_data_len == len && 120204b4edcbSJohan Hedberg memcmp(cp.data, hdev->adv_data, len) == 0) 120304b4edcbSJohan Hedberg return; 12043f0f524bSJohan Hedberg 12053f0f524bSJohan Hedberg memcpy(hdev->adv_data, cp.data, sizeof(cp.data)); 12063f0f524bSJohan Hedberg hdev->adv_data_len = len; 12073f0f524bSJohan Hedberg 12083f0f524bSJohan Hedberg cp.length = len; 12093f0f524bSJohan Hedberg 121004b4edcbSJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp); 12113f0f524bSJohan Hedberg } 12123f0f524bSJohan Hedberg 1213cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev) 12141da177e4SLinus Torvalds { 12151da177e4SLinus Torvalds int ret = 0; 12161da177e4SLinus Torvalds 12171da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 12181da177e4SLinus Torvalds 12191da177e4SLinus Torvalds hci_req_lock(hdev); 12201da177e4SLinus Torvalds 122194324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 122294324962SJohan Hovold ret = -ENODEV; 122394324962SJohan Hovold goto done; 122494324962SJohan Hovold } 122594324962SJohan Hovold 1226a5c8f270SMarcel Holtmann if (!test_bit(HCI_SETUP, &hdev->dev_flags)) { 1227a5c8f270SMarcel Holtmann /* Check for rfkill but allow the HCI setup stage to 1228a5c8f270SMarcel Holtmann * proceed (which in itself doesn't cause any RF activity). 1229bf543036SJohan Hedberg */ 1230a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { 1231611b30f7SMarcel Holtmann ret = -ERFKILL; 1232611b30f7SMarcel Holtmann goto done; 1233611b30f7SMarcel Holtmann } 1234611b30f7SMarcel Holtmann 1235a5c8f270SMarcel Holtmann /* Check for valid public address or a configured static 1236a5c8f270SMarcel Holtmann * random adddress, but let the HCI setup proceed to 1237a5c8f270SMarcel Holtmann * be able to determine if there is a public address 1238a5c8f270SMarcel Holtmann * or not. 1239a5c8f270SMarcel Holtmann * 1240a5c8f270SMarcel Holtmann * This check is only valid for BR/EDR controllers 1241a5c8f270SMarcel Holtmann * since AMP controllers do not have an address. 1242a5c8f270SMarcel Holtmann */ 1243a5c8f270SMarcel Holtmann if (hdev->dev_type == HCI_BREDR && 1244a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1245a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY)) { 1246a5c8f270SMarcel Holtmann ret = -EADDRNOTAVAIL; 1247a5c8f270SMarcel Holtmann goto done; 1248a5c8f270SMarcel Holtmann } 1249a5c8f270SMarcel Holtmann } 1250a5c8f270SMarcel Holtmann 12511da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 12521da177e4SLinus Torvalds ret = -EALREADY; 12531da177e4SLinus Torvalds goto done; 12541da177e4SLinus Torvalds } 12551da177e4SLinus Torvalds 12561da177e4SLinus Torvalds if (hdev->open(hdev)) { 12571da177e4SLinus Torvalds ret = -EIO; 12581da177e4SLinus Torvalds goto done; 12591da177e4SLinus Torvalds } 12601da177e4SLinus Torvalds 12611da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 12621da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1263f41c70c4SMarcel Holtmann 1264f41c70c4SMarcel Holtmann if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags)) 1265f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1266f41c70c4SMarcel Holtmann 1267f41c70c4SMarcel Holtmann if (!ret) { 1268f41c70c4SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 1269f41c70c4SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 1270f41c70c4SMarcel Holtmann 12710736cfa8SMarcel Holtmann if (!test_bit(HCI_RAW, &hdev->flags) && 12720736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 12732177bab5SJohan Hedberg ret = __hci_init(hdev); 12741da177e4SLinus Torvalds } 12751da177e4SLinus Torvalds 1276f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1277f41c70c4SMarcel Holtmann 12781da177e4SLinus Torvalds if (!ret) { 12791da177e4SLinus Torvalds hci_dev_hold(hdev); 12801da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 12811da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 1282bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 12830736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 12841514b892SMarcel Holtmann hdev->dev_type == HCI_BREDR) { 128509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1286744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 128709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 128856e5cb86SJohan Hedberg } 12891da177e4SLinus Torvalds } else { 12901da177e4SLinus Torvalds /* Init failed, cleanup */ 12913eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1292c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 1293b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 12941da177e4SLinus Torvalds 12951da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 12961da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 12971da177e4SLinus Torvalds 12981da177e4SLinus Torvalds if (hdev->flush) 12991da177e4SLinus Torvalds hdev->flush(hdev); 13001da177e4SLinus Torvalds 13011da177e4SLinus Torvalds if (hdev->sent_cmd) { 13021da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 13031da177e4SLinus Torvalds hdev->sent_cmd = NULL; 13041da177e4SLinus Torvalds } 13051da177e4SLinus Torvalds 13061da177e4SLinus Torvalds hdev->close(hdev); 13071da177e4SLinus Torvalds hdev->flags = 0; 13081da177e4SLinus Torvalds } 13091da177e4SLinus Torvalds 13101da177e4SLinus Torvalds done: 13111da177e4SLinus Torvalds hci_req_unlock(hdev); 13121da177e4SLinus Torvalds return ret; 13131da177e4SLinus Torvalds } 13141da177e4SLinus Torvalds 1315cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */ 1316cbed0ca1SJohan Hedberg 1317cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev) 1318cbed0ca1SJohan Hedberg { 1319cbed0ca1SJohan Hedberg struct hci_dev *hdev; 1320cbed0ca1SJohan Hedberg int err; 1321cbed0ca1SJohan Hedberg 1322cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev); 1323cbed0ca1SJohan Hedberg if (!hdev) 1324cbed0ca1SJohan Hedberg return -ENODEV; 1325cbed0ca1SJohan Hedberg 1326e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending 1327e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is 1328e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet 1329e1d08f40SJohan Hedberg * completed. 1330e1d08f40SJohan Hedberg */ 1331e1d08f40SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1332e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off); 1333e1d08f40SJohan Hedberg 1334a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure 1335a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL 1336a5c8f270SMarcel Holtmann * or no valid public or static random address apply. 1337a5c8f270SMarcel Holtmann */ 1338e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue); 1339e1d08f40SJohan Hedberg 1340cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 1341cbed0ca1SJohan Hedberg 1342cbed0ca1SJohan Hedberg hci_dev_put(hdev); 1343cbed0ca1SJohan Hedberg 1344cbed0ca1SJohan Hedberg return err; 1345cbed0ca1SJohan Hedberg } 1346cbed0ca1SJohan Hedberg 13471da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 13481da177e4SLinus Torvalds { 13491da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 13501da177e4SLinus Torvalds 135178c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 135278c04c0bSVinicius Costa Gomes 13531da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 13541da177e4SLinus Torvalds hci_req_lock(hdev); 13551da177e4SLinus Torvalds 13561da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 1357b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 13581da177e4SLinus Torvalds hci_req_unlock(hdev); 13591da177e4SLinus Torvalds return 0; 13601da177e4SLinus Torvalds } 13611da177e4SLinus Torvalds 13623eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 13633eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1364b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 13651da177e4SLinus Torvalds 136616ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 1367e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 136816ab91abSJohan Hedberg hdev->discov_timeout = 0; 13695e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 137016ab91abSJohan Hedberg } 137116ab91abSJohan Hedberg 1372a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 13737d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 13747d78525dSJohan Hedberg 13757ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 13767ba8b4beSAndre Guedes 137709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 13781f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 13791da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 138009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13811da177e4SLinus Torvalds 13821da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 13831da177e4SLinus Torvalds 13841da177e4SLinus Torvalds if (hdev->flush) 13851da177e4SLinus Torvalds hdev->flush(hdev); 13861da177e4SLinus Torvalds 13871da177e4SLinus Torvalds /* Reset device */ 13881da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 13891da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 13908af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 13913a6afbd2SMarcel Holtmann !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 1392a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 13931da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 139401178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 13951da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 13961da177e4SLinus Torvalds } 13971da177e4SLinus Torvalds 1398c347b765SGustavo F. Padovan /* flush cmd work */ 1399c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 14001da177e4SLinus Torvalds 14011da177e4SLinus Torvalds /* Drop queues */ 14021da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 14031da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 14041da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 14051da177e4SLinus Torvalds 14061da177e4SLinus Torvalds /* Drop last sent command */ 14071da177e4SLinus Torvalds if (hdev->sent_cmd) { 1408b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 14091da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 14101da177e4SLinus Torvalds hdev->sent_cmd = NULL; 14111da177e4SLinus Torvalds } 14121da177e4SLinus Torvalds 1413b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 1414b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 1415b6ddb638SJohan Hedberg 14161da177e4SLinus Torvalds /* After this point our queues are empty 14171da177e4SLinus Torvalds * and no tasks are scheduled. */ 14181da177e4SLinus Torvalds hdev->close(hdev); 14191da177e4SLinus Torvalds 142035b973c9SJohan Hedberg /* Clear flags */ 142135b973c9SJohan Hedberg hdev->flags = 0; 142235b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 142335b973c9SJohan Hedberg 142493c311a0SMarcel Holtmann if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 142593c311a0SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 142609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1427744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 142809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 14298ee56540SMarcel Holtmann } 143093c311a0SMarcel Holtmann } 14315add6af8SJohan Hedberg 1432ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 1433536619e8SMarcel Holtmann hdev->amp_status = AMP_STATUS_POWERED_DOWN; 1434ced5c338SAndrei Emeltchenko 1435e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 143609b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 1437e59fda8dSJohan Hedberg 14381da177e4SLinus Torvalds hci_req_unlock(hdev); 14391da177e4SLinus Torvalds 14401da177e4SLinus Torvalds hci_dev_put(hdev); 14411da177e4SLinus Torvalds return 0; 14421da177e4SLinus Torvalds } 14431da177e4SLinus Torvalds 14441da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 14451da177e4SLinus Torvalds { 14461da177e4SLinus Torvalds struct hci_dev *hdev; 14471da177e4SLinus Torvalds int err; 14481da177e4SLinus Torvalds 144970f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 145070f23020SAndrei Emeltchenko if (!hdev) 14511da177e4SLinus Torvalds return -ENODEV; 14528ee56540SMarcel Holtmann 14530736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 14540736cfa8SMarcel Holtmann err = -EBUSY; 14550736cfa8SMarcel Holtmann goto done; 14560736cfa8SMarcel Holtmann } 14570736cfa8SMarcel Holtmann 14588ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 14598ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 14608ee56540SMarcel Holtmann 14611da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 14628ee56540SMarcel Holtmann 14630736cfa8SMarcel Holtmann done: 14641da177e4SLinus Torvalds hci_dev_put(hdev); 14651da177e4SLinus Torvalds return err; 14661da177e4SLinus Torvalds } 14671da177e4SLinus Torvalds 14681da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 14691da177e4SLinus Torvalds { 14701da177e4SLinus Torvalds struct hci_dev *hdev; 14711da177e4SLinus Torvalds int ret = 0; 14721da177e4SLinus Torvalds 147370f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 147470f23020SAndrei Emeltchenko if (!hdev) 14751da177e4SLinus Torvalds return -ENODEV; 14761da177e4SLinus Torvalds 14771da177e4SLinus Torvalds hci_req_lock(hdev); 14781da177e4SLinus Torvalds 1479808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 1480808a049eSMarcel Holtmann ret = -ENETDOWN; 14811da177e4SLinus Torvalds goto done; 1482808a049eSMarcel Holtmann } 14831da177e4SLinus Torvalds 14840736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 14850736cfa8SMarcel Holtmann ret = -EBUSY; 14860736cfa8SMarcel Holtmann goto done; 14870736cfa8SMarcel Holtmann } 14880736cfa8SMarcel Holtmann 14891da177e4SLinus Torvalds /* Drop queues */ 14901da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 14911da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 14921da177e4SLinus Torvalds 149309fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 14941f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 14951da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 149609fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 14971da177e4SLinus Torvalds 14981da177e4SLinus Torvalds if (hdev->flush) 14991da177e4SLinus Torvalds hdev->flush(hdev); 15001da177e4SLinus Torvalds 15011da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 15026ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 15031da177e4SLinus Torvalds 15041da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 150501178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 15061da177e4SLinus Torvalds 15071da177e4SLinus Torvalds done: 15081da177e4SLinus Torvalds hci_req_unlock(hdev); 15091da177e4SLinus Torvalds hci_dev_put(hdev); 15101da177e4SLinus Torvalds return ret; 15111da177e4SLinus Torvalds } 15121da177e4SLinus Torvalds 15131da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 15141da177e4SLinus Torvalds { 15151da177e4SLinus Torvalds struct hci_dev *hdev; 15161da177e4SLinus Torvalds int ret = 0; 15171da177e4SLinus Torvalds 151870f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 151970f23020SAndrei Emeltchenko if (!hdev) 15201da177e4SLinus Torvalds return -ENODEV; 15211da177e4SLinus Torvalds 15220736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 15230736cfa8SMarcel Holtmann ret = -EBUSY; 15240736cfa8SMarcel Holtmann goto done; 15250736cfa8SMarcel Holtmann } 15260736cfa8SMarcel Holtmann 15271da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 15281da177e4SLinus Torvalds 15290736cfa8SMarcel Holtmann done: 15301da177e4SLinus Torvalds hci_dev_put(hdev); 15311da177e4SLinus Torvalds return ret; 15321da177e4SLinus Torvalds } 15331da177e4SLinus Torvalds 15341da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 15351da177e4SLinus Torvalds { 15361da177e4SLinus Torvalds struct hci_dev *hdev; 15371da177e4SLinus Torvalds struct hci_dev_req dr; 15381da177e4SLinus Torvalds int err = 0; 15391da177e4SLinus Torvalds 15401da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 15411da177e4SLinus Torvalds return -EFAULT; 15421da177e4SLinus Torvalds 154370f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 154470f23020SAndrei Emeltchenko if (!hdev) 15451da177e4SLinus Torvalds return -ENODEV; 15461da177e4SLinus Torvalds 15470736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 15480736cfa8SMarcel Holtmann err = -EBUSY; 15490736cfa8SMarcel Holtmann goto done; 15500736cfa8SMarcel Holtmann } 15510736cfa8SMarcel Holtmann 15525b69bef5SMarcel Holtmann if (hdev->dev_type != HCI_BREDR) { 15535b69bef5SMarcel Holtmann err = -EOPNOTSUPP; 15545b69bef5SMarcel Holtmann goto done; 15555b69bef5SMarcel Holtmann } 15565b69bef5SMarcel Holtmann 155756f87901SJohan Hedberg if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 155856f87901SJohan Hedberg err = -EOPNOTSUPP; 155956f87901SJohan Hedberg goto done; 156056f87901SJohan Hedberg } 156156f87901SJohan Hedberg 15621da177e4SLinus Torvalds switch (cmd) { 15631da177e4SLinus Torvalds case HCISETAUTH: 156401178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 15655f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 15661da177e4SLinus Torvalds break; 15671da177e4SLinus Torvalds 15681da177e4SLinus Torvalds case HCISETENCRYPT: 15691da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 15701da177e4SLinus Torvalds err = -EOPNOTSUPP; 15711da177e4SLinus Torvalds break; 15721da177e4SLinus Torvalds } 15731da177e4SLinus Torvalds 15741da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 15751da177e4SLinus Torvalds /* Auth must be enabled first */ 157601178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 15775f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 15781da177e4SLinus Torvalds if (err) 15791da177e4SLinus Torvalds break; 15801da177e4SLinus Torvalds } 15811da177e4SLinus Torvalds 158201178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 15835f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 15841da177e4SLinus Torvalds break; 15851da177e4SLinus Torvalds 15861da177e4SLinus Torvalds case HCISETSCAN: 158701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 15885f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 15891da177e4SLinus Torvalds break; 15901da177e4SLinus Torvalds 15911da177e4SLinus Torvalds case HCISETLINKPOL: 159201178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 15935f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 15941da177e4SLinus Torvalds break; 15951da177e4SLinus Torvalds 15961da177e4SLinus Torvalds case HCISETLINKMODE: 1597e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 1598e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 1599e4e8e37cSMarcel Holtmann break; 1600e4e8e37cSMarcel Holtmann 1601e4e8e37cSMarcel Holtmann case HCISETPTYPE: 1602e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 16031da177e4SLinus Torvalds break; 16041da177e4SLinus Torvalds 16051da177e4SLinus Torvalds case HCISETACLMTU: 16061da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 16071da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 16081da177e4SLinus Torvalds break; 16091da177e4SLinus Torvalds 16101da177e4SLinus Torvalds case HCISETSCOMTU: 16111da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 16121da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 16131da177e4SLinus Torvalds break; 16141da177e4SLinus Torvalds 16151da177e4SLinus Torvalds default: 16161da177e4SLinus Torvalds err = -EINVAL; 16171da177e4SLinus Torvalds break; 16181da177e4SLinus Torvalds } 1619e4e8e37cSMarcel Holtmann 16200736cfa8SMarcel Holtmann done: 16211da177e4SLinus Torvalds hci_dev_put(hdev); 16221da177e4SLinus Torvalds return err; 16231da177e4SLinus Torvalds } 16241da177e4SLinus Torvalds 16251da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 16261da177e4SLinus Torvalds { 16278035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 16281da177e4SLinus Torvalds struct hci_dev_list_req *dl; 16291da177e4SLinus Torvalds struct hci_dev_req *dr; 16301da177e4SLinus Torvalds int n = 0, size, err; 16311da177e4SLinus Torvalds __u16 dev_num; 16321da177e4SLinus Torvalds 16331da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 16341da177e4SLinus Torvalds return -EFAULT; 16351da177e4SLinus Torvalds 16361da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 16371da177e4SLinus Torvalds return -EINVAL; 16381da177e4SLinus Torvalds 16391da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 16401da177e4SLinus Torvalds 164170f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 164270f23020SAndrei Emeltchenko if (!dl) 16431da177e4SLinus Torvalds return -ENOMEM; 16441da177e4SLinus Torvalds 16451da177e4SLinus Torvalds dr = dl->dev_req; 16461da177e4SLinus Torvalds 1647f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 16488035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 1649a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1650e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 1651c542a06cSJohan Hedberg 1652a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1653a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1654c542a06cSJohan Hedberg 16551da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 16561da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 1657c542a06cSJohan Hedberg 16581da177e4SLinus Torvalds if (++n >= dev_num) 16591da177e4SLinus Torvalds break; 16601da177e4SLinus Torvalds } 1661f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 16621da177e4SLinus Torvalds 16631da177e4SLinus Torvalds dl->dev_num = n; 16641da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 16651da177e4SLinus Torvalds 16661da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 16671da177e4SLinus Torvalds kfree(dl); 16681da177e4SLinus Torvalds 16691da177e4SLinus Torvalds return err ? -EFAULT : 0; 16701da177e4SLinus Torvalds } 16711da177e4SLinus Torvalds 16721da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 16731da177e4SLinus Torvalds { 16741da177e4SLinus Torvalds struct hci_dev *hdev; 16751da177e4SLinus Torvalds struct hci_dev_info di; 16761da177e4SLinus Torvalds int err = 0; 16771da177e4SLinus Torvalds 16781da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 16791da177e4SLinus Torvalds return -EFAULT; 16801da177e4SLinus Torvalds 168170f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 168270f23020SAndrei Emeltchenko if (!hdev) 16831da177e4SLinus Torvalds return -ENODEV; 16841da177e4SLinus Torvalds 1685a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 16863243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 1687ab81cbf9SJohan Hedberg 1688a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1689a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1690c542a06cSJohan Hedberg 16911da177e4SLinus Torvalds strcpy(di.name, hdev->name); 16921da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 169360f2a3edSMarcel Holtmann di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); 16941da177e4SLinus Torvalds di.flags = hdev->flags; 16951da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 1696572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 16971da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 16981da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 16991da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 17001da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 1701572c7f84SJohan Hedberg } else { 1702572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 1703572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 1704572c7f84SJohan Hedberg di.sco_mtu = 0; 1705572c7f84SJohan Hedberg di.sco_pkts = 0; 1706572c7f84SJohan Hedberg } 17071da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 17081da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 17091da177e4SLinus Torvalds 17101da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 17111da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 17121da177e4SLinus Torvalds 17131da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 17141da177e4SLinus Torvalds err = -EFAULT; 17151da177e4SLinus Torvalds 17161da177e4SLinus Torvalds hci_dev_put(hdev); 17171da177e4SLinus Torvalds 17181da177e4SLinus Torvalds return err; 17191da177e4SLinus Torvalds } 17201da177e4SLinus Torvalds 17211da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 17221da177e4SLinus Torvalds 1723611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 1724611b30f7SMarcel Holtmann { 1725611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 1726611b30f7SMarcel Holtmann 1727611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 1728611b30f7SMarcel Holtmann 17290736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 17300736cfa8SMarcel Holtmann return -EBUSY; 17310736cfa8SMarcel Holtmann 17325e130367SJohan Hedberg if (blocked) { 17335e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 1734bf543036SJohan Hedberg if (!test_bit(HCI_SETUP, &hdev->dev_flags)) 1735611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 17365e130367SJohan Hedberg } else { 17375e130367SJohan Hedberg clear_bit(HCI_RFKILLED, &hdev->dev_flags); 17385e130367SJohan Hedberg } 1739611b30f7SMarcel Holtmann 1740611b30f7SMarcel Holtmann return 0; 1741611b30f7SMarcel Holtmann } 1742611b30f7SMarcel Holtmann 1743611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 1744611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 1745611b30f7SMarcel Holtmann }; 1746611b30f7SMarcel Holtmann 1747ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 1748ab81cbf9SJohan Hedberg { 1749ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 175096570ffcSJohan Hedberg int err; 1751ab81cbf9SJohan Hedberg 1752ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1753ab81cbf9SJohan Hedberg 1754cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev); 175596570ffcSJohan Hedberg if (err < 0) { 175696570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 1757ab81cbf9SJohan Hedberg return; 175896570ffcSJohan Hedberg } 1759ab81cbf9SJohan Hedberg 1760a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are 1761a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still 1762a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off. 1763a5c8f270SMarcel Holtmann */ 1764a5c8f270SMarcel Holtmann if (test_bit(HCI_RFKILLED, &hdev->dev_flags) || 1765a5c8f270SMarcel Holtmann (hdev->dev_type == HCI_BREDR && 1766a5c8f270SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) && 1767a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) { 1768bf543036SJohan Hedberg clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); 1769bf543036SJohan Hedberg hci_dev_do_close(hdev); 1770bf543036SJohan Hedberg } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 177119202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 177219202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 1773bf543036SJohan Hedberg } 1774ab81cbf9SJohan Hedberg 1775a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 1776744cf19eSJohan Hedberg mgmt_index_added(hdev); 1777ab81cbf9SJohan Hedberg } 1778ab81cbf9SJohan Hedberg 1779ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1780ab81cbf9SJohan Hedberg { 17813243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 17823243553fSJohan Hedberg power_off.work); 1783ab81cbf9SJohan Hedberg 1784ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1785ab81cbf9SJohan Hedberg 17868ee56540SMarcel Holtmann hci_dev_do_close(hdev); 1787ab81cbf9SJohan Hedberg } 1788ab81cbf9SJohan Hedberg 178916ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 179016ab91abSJohan Hedberg { 179116ab91abSJohan Hedberg struct hci_dev *hdev; 179216ab91abSJohan Hedberg u8 scan = SCAN_PAGE; 179316ab91abSJohan Hedberg 179416ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 179516ab91abSJohan Hedberg 179616ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 179716ab91abSJohan Hedberg 179809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 179916ab91abSJohan Hedberg 180016ab91abSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); 180116ab91abSJohan Hedberg 180216ab91abSJohan Hedberg hdev->discov_timeout = 0; 180316ab91abSJohan Hedberg 180409fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 180516ab91abSJohan Hedberg } 180616ab91abSJohan Hedberg 18072aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 18082aeb9a1aSJohan Hedberg { 18094821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 18102aeb9a1aSJohan Hedberg 18114821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 18124821002cSJohan Hedberg list_del(&uuid->list); 18132aeb9a1aSJohan Hedberg kfree(uuid); 18142aeb9a1aSJohan Hedberg } 18152aeb9a1aSJohan Hedberg 18162aeb9a1aSJohan Hedberg return 0; 18172aeb9a1aSJohan Hedberg } 18182aeb9a1aSJohan Hedberg 181955ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 182055ed8ca1SJohan Hedberg { 182155ed8ca1SJohan Hedberg struct list_head *p, *n; 182255ed8ca1SJohan Hedberg 182355ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 182455ed8ca1SJohan Hedberg struct link_key *key; 182555ed8ca1SJohan Hedberg 182655ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 182755ed8ca1SJohan Hedberg 182855ed8ca1SJohan Hedberg list_del(p); 182955ed8ca1SJohan Hedberg kfree(key); 183055ed8ca1SJohan Hedberg } 183155ed8ca1SJohan Hedberg 183255ed8ca1SJohan Hedberg return 0; 183355ed8ca1SJohan Hedberg } 183455ed8ca1SJohan Hedberg 1835b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 1836b899efafSVinicius Costa Gomes { 1837b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1838b899efafSVinicius Costa Gomes 1839b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1840b899efafSVinicius Costa Gomes list_del(&k->list); 1841b899efafSVinicius Costa Gomes kfree(k); 1842b899efafSVinicius Costa Gomes } 1843b899efafSVinicius Costa Gomes 1844b899efafSVinicius Costa Gomes return 0; 1845b899efafSVinicius Costa Gomes } 1846b899efafSVinicius Costa Gomes 184755ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 184855ed8ca1SJohan Hedberg { 184955ed8ca1SJohan Hedberg struct link_key *k; 185055ed8ca1SJohan Hedberg 18518035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 185255ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 185355ed8ca1SJohan Hedberg return k; 185455ed8ca1SJohan Hedberg 185555ed8ca1SJohan Hedberg return NULL; 185655ed8ca1SJohan Hedberg } 185755ed8ca1SJohan Hedberg 1858745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 1859d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 1860d25e28abSJohan Hedberg { 1861d25e28abSJohan Hedberg /* Legacy key */ 1862d25e28abSJohan Hedberg if (key_type < 0x03) 1863745c0ce3SVishal Agarwal return true; 1864d25e28abSJohan Hedberg 1865d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 1866d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 1867745c0ce3SVishal Agarwal return false; 1868d25e28abSJohan Hedberg 1869d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 1870d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 1871745c0ce3SVishal Agarwal return false; 1872d25e28abSJohan Hedberg 1873d25e28abSJohan Hedberg /* Security mode 3 case */ 1874d25e28abSJohan Hedberg if (!conn) 1875745c0ce3SVishal Agarwal return true; 1876d25e28abSJohan Hedberg 1877d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 1878d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 1879745c0ce3SVishal Agarwal return true; 1880d25e28abSJohan Hedberg 1881d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 1882d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 1883745c0ce3SVishal Agarwal return true; 1884d25e28abSJohan Hedberg 1885d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 1886d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 1887745c0ce3SVishal Agarwal return true; 1888d25e28abSJohan Hedberg 1889d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 1890d25e28abSJohan Hedberg * persistently */ 1891745c0ce3SVishal Agarwal return false; 1892d25e28abSJohan Hedberg } 1893d25e28abSJohan Hedberg 1894c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 189575d262c2SVinicius Costa Gomes { 1896c9839a11SVinicius Costa Gomes struct smp_ltk *k; 189775d262c2SVinicius Costa Gomes 1898c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 1899c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 1900c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 190175d262c2SVinicius Costa Gomes continue; 190275d262c2SVinicius Costa Gomes 190375d262c2SVinicius Costa Gomes return k; 190475d262c2SVinicius Costa Gomes } 190575d262c2SVinicius Costa Gomes 190675d262c2SVinicius Costa Gomes return NULL; 190775d262c2SVinicius Costa Gomes } 190875d262c2SVinicius Costa Gomes 1909c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1910c9839a11SVinicius Costa Gomes u8 addr_type) 191175d262c2SVinicius Costa Gomes { 1912c9839a11SVinicius Costa Gomes struct smp_ltk *k; 191375d262c2SVinicius Costa Gomes 1914c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 1915c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 1916c9839a11SVinicius Costa Gomes bacmp(bdaddr, &k->bdaddr) == 0) 191775d262c2SVinicius Costa Gomes return k; 191875d262c2SVinicius Costa Gomes 191975d262c2SVinicius Costa Gomes return NULL; 192075d262c2SVinicius Costa Gomes } 192175d262c2SVinicius Costa Gomes 1922d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 1923d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 192455ed8ca1SJohan Hedberg { 192555ed8ca1SJohan Hedberg struct link_key *key, *old_key; 1926745c0ce3SVishal Agarwal u8 old_key_type; 1927745c0ce3SVishal Agarwal bool persistent; 192855ed8ca1SJohan Hedberg 192955ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 193055ed8ca1SJohan Hedberg if (old_key) { 193155ed8ca1SJohan Hedberg old_key_type = old_key->type; 193255ed8ca1SJohan Hedberg key = old_key; 193355ed8ca1SJohan Hedberg } else { 193412adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 193555ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 193655ed8ca1SJohan Hedberg if (!key) 193755ed8ca1SJohan Hedberg return -ENOMEM; 193855ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 193955ed8ca1SJohan Hedberg } 194055ed8ca1SJohan Hedberg 19416ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 194255ed8ca1SJohan Hedberg 1943d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1944d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1945d25e28abSJohan Hedberg * previous key */ 1946d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1947a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 1948d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1949655fe6ecSJohan Hedberg if (conn) 1950655fe6ecSJohan Hedberg conn->key_type = type; 1951655fe6ecSJohan Hedberg } 1952d25e28abSJohan Hedberg 195355ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 19549b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 195555ed8ca1SJohan Hedberg key->pin_len = pin_len; 195655ed8ca1SJohan Hedberg 1957b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 195855ed8ca1SJohan Hedberg key->type = old_key_type; 19594748fed2SJohan Hedberg else 19604748fed2SJohan Hedberg key->type = type; 19614748fed2SJohan Hedberg 19624df378a1SJohan Hedberg if (!new_key) 19634df378a1SJohan Hedberg return 0; 19644df378a1SJohan Hedberg 19654df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 19664df378a1SJohan Hedberg 1967744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 19684df378a1SJohan Hedberg 19696ec5bcadSVishal Agarwal if (conn) 19706ec5bcadSVishal Agarwal conn->flush_key = !persistent; 197155ed8ca1SJohan Hedberg 197255ed8ca1SJohan Hedberg return 0; 197355ed8ca1SJohan Hedberg } 197455ed8ca1SJohan Hedberg 1975c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 19769a006657SAndrei Emeltchenko int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 197704124681SGustavo F. Padovan ediv, u8 rand[8]) 197875d262c2SVinicius Costa Gomes { 1979c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 198075d262c2SVinicius Costa Gomes 1981c9839a11SVinicius Costa Gomes if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 1982c9839a11SVinicius Costa Gomes return 0; 198375d262c2SVinicius Costa Gomes 1984c9839a11SVinicius Costa Gomes old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 1985c9839a11SVinicius Costa Gomes if (old_key) 198675d262c2SVinicius Costa Gomes key = old_key; 1987c9839a11SVinicius Costa Gomes else { 1988c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 198975d262c2SVinicius Costa Gomes if (!key) 199075d262c2SVinicius Costa Gomes return -ENOMEM; 1991c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 199275d262c2SVinicius Costa Gomes } 199375d262c2SVinicius Costa Gomes 199475d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 1995c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 1996c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 1997c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 1998c9839a11SVinicius Costa Gomes key->ediv = ediv; 1999c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 2000c9839a11SVinicius Costa Gomes key->type = type; 2001c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 200275d262c2SVinicius Costa Gomes 2003c9839a11SVinicius Costa Gomes if (!new_key) 2004c9839a11SVinicius Costa Gomes return 0; 200575d262c2SVinicius Costa Gomes 2006261cc5aaSVinicius Costa Gomes if (type & HCI_SMP_LTK) 2007261cc5aaSVinicius Costa Gomes mgmt_new_ltk(hdev, key, 1); 2008261cc5aaSVinicius Costa Gomes 200975d262c2SVinicius Costa Gomes return 0; 201075d262c2SVinicius Costa Gomes } 201175d262c2SVinicius Costa Gomes 201255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 201355ed8ca1SJohan Hedberg { 201455ed8ca1SJohan Hedberg struct link_key *key; 201555ed8ca1SJohan Hedberg 201655ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 201755ed8ca1SJohan Hedberg if (!key) 201855ed8ca1SJohan Hedberg return -ENOENT; 201955ed8ca1SJohan Hedberg 20206ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 202155ed8ca1SJohan Hedberg 202255ed8ca1SJohan Hedberg list_del(&key->list); 202355ed8ca1SJohan Hedberg kfree(key); 202455ed8ca1SJohan Hedberg 202555ed8ca1SJohan Hedberg return 0; 202655ed8ca1SJohan Hedberg } 202755ed8ca1SJohan Hedberg 2028b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 2029b899efafSVinicius Costa Gomes { 2030b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 2031b899efafSVinicius Costa Gomes 2032b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 2033b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 2034b899efafSVinicius Costa Gomes continue; 2035b899efafSVinicius Costa Gomes 20366ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 2037b899efafSVinicius Costa Gomes 2038b899efafSVinicius Costa Gomes list_del(&k->list); 2039b899efafSVinicius Costa Gomes kfree(k); 2040b899efafSVinicius Costa Gomes } 2041b899efafSVinicius Costa Gomes 2042b899efafSVinicius Costa Gomes return 0; 2043b899efafSVinicius Costa Gomes } 2044b899efafSVinicius Costa Gomes 20456bd32326SVille Tervo /* HCI command timer function */ 2046bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg) 20476bd32326SVille Tervo { 20486bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 20496bd32326SVille Tervo 2050bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 2051bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 2052bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 2053bda4f23aSAndrei Emeltchenko 2054bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 2055bda4f23aSAndrei Emeltchenko } else { 20566bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 2057bda4f23aSAndrei Emeltchenko } 2058bda4f23aSAndrei Emeltchenko 20596bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 2060c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 20616bd32326SVille Tervo } 20626bd32326SVille Tervo 20632763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 20642763eda6SSzymon Janc bdaddr_t *bdaddr) 20652763eda6SSzymon Janc { 20662763eda6SSzymon Janc struct oob_data *data; 20672763eda6SSzymon Janc 20682763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 20692763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 20702763eda6SSzymon Janc return data; 20712763eda6SSzymon Janc 20722763eda6SSzymon Janc return NULL; 20732763eda6SSzymon Janc } 20742763eda6SSzymon Janc 20752763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 20762763eda6SSzymon Janc { 20772763eda6SSzymon Janc struct oob_data *data; 20782763eda6SSzymon Janc 20792763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 20802763eda6SSzymon Janc if (!data) 20812763eda6SSzymon Janc return -ENOENT; 20822763eda6SSzymon Janc 20836ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 20842763eda6SSzymon Janc 20852763eda6SSzymon Janc list_del(&data->list); 20862763eda6SSzymon Janc kfree(data); 20872763eda6SSzymon Janc 20882763eda6SSzymon Janc return 0; 20892763eda6SSzymon Janc } 20902763eda6SSzymon Janc 20912763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 20922763eda6SSzymon Janc { 20932763eda6SSzymon Janc struct oob_data *data, *n; 20942763eda6SSzymon Janc 20952763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 20962763eda6SSzymon Janc list_del(&data->list); 20972763eda6SSzymon Janc kfree(data); 20982763eda6SSzymon Janc } 20992763eda6SSzymon Janc 21002763eda6SSzymon Janc return 0; 21012763eda6SSzymon Janc } 21022763eda6SSzymon Janc 21032763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 21042763eda6SSzymon Janc u8 *randomizer) 21052763eda6SSzymon Janc { 21062763eda6SSzymon Janc struct oob_data *data; 21072763eda6SSzymon Janc 21082763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 21092763eda6SSzymon Janc 21102763eda6SSzymon Janc if (!data) { 21112763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 21122763eda6SSzymon Janc if (!data) 21132763eda6SSzymon Janc return -ENOMEM; 21142763eda6SSzymon Janc 21152763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 21162763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 21172763eda6SSzymon Janc } 21182763eda6SSzymon Janc 21192763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 21202763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 21212763eda6SSzymon Janc 21226ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 21232763eda6SSzymon Janc 21242763eda6SSzymon Janc return 0; 21252763eda6SSzymon Janc } 21262763eda6SSzymon Janc 212704124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 2128b2a66aadSAntti Julku { 2129b2a66aadSAntti Julku struct bdaddr_list *b; 2130b2a66aadSAntti Julku 21318035ded4SLuiz Augusto von Dentz list_for_each_entry(b, &hdev->blacklist, list) 2132b2a66aadSAntti Julku if (bacmp(bdaddr, &b->bdaddr) == 0) 2133b2a66aadSAntti Julku return b; 2134b2a66aadSAntti Julku 2135b2a66aadSAntti Julku return NULL; 2136b2a66aadSAntti Julku } 2137b2a66aadSAntti Julku 2138b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 2139b2a66aadSAntti Julku { 2140b2a66aadSAntti Julku struct list_head *p, *n; 2141b2a66aadSAntti Julku 2142b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 2143b2a66aadSAntti Julku struct bdaddr_list *b; 2144b2a66aadSAntti Julku 2145b2a66aadSAntti Julku b = list_entry(p, struct bdaddr_list, list); 2146b2a66aadSAntti Julku 2147b2a66aadSAntti Julku list_del(p); 2148b2a66aadSAntti Julku kfree(b); 2149b2a66aadSAntti Julku } 2150b2a66aadSAntti Julku 2151b2a66aadSAntti Julku return 0; 2152b2a66aadSAntti Julku } 2153b2a66aadSAntti Julku 215488c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2155b2a66aadSAntti Julku { 2156b2a66aadSAntti Julku struct bdaddr_list *entry; 2157b2a66aadSAntti Julku 2158b2a66aadSAntti Julku if (bacmp(bdaddr, BDADDR_ANY) == 0) 2159b2a66aadSAntti Julku return -EBADF; 2160b2a66aadSAntti Julku 21615e762444SAntti Julku if (hci_blacklist_lookup(hdev, bdaddr)) 21625e762444SAntti Julku return -EEXIST; 2163b2a66aadSAntti Julku 2164b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 21655e762444SAntti Julku if (!entry) 21665e762444SAntti Julku return -ENOMEM; 2167b2a66aadSAntti Julku 2168b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 2169b2a66aadSAntti Julku 2170b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 2171b2a66aadSAntti Julku 217288c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 2173b2a66aadSAntti Julku } 2174b2a66aadSAntti Julku 217588c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2176b2a66aadSAntti Julku { 2177b2a66aadSAntti Julku struct bdaddr_list *entry; 2178b2a66aadSAntti Julku 21791ec918ceSSzymon Janc if (bacmp(bdaddr, BDADDR_ANY) == 0) 21805e762444SAntti Julku return hci_blacklist_clear(hdev); 2181b2a66aadSAntti Julku 2182b2a66aadSAntti Julku entry = hci_blacklist_lookup(hdev, bdaddr); 21831ec918ceSSzymon Janc if (!entry) 21845e762444SAntti Julku return -ENOENT; 2185b2a66aadSAntti Julku 2186b2a66aadSAntti Julku list_del(&entry->list); 2187b2a66aadSAntti Julku kfree(entry); 2188b2a66aadSAntti Julku 218988c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 2190b2a66aadSAntti Julku } 2191b2a66aadSAntti Julku 21924c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 21937ba8b4beSAndre Guedes { 21944c87eaabSAndre Guedes if (status) { 21954c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 21967ba8b4beSAndre Guedes 21974c87eaabSAndre Guedes hci_dev_lock(hdev); 21984c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 21994c87eaabSAndre Guedes hci_dev_unlock(hdev); 22004c87eaabSAndre Guedes return; 22014c87eaabSAndre Guedes } 22027ba8b4beSAndre Guedes } 22037ba8b4beSAndre Guedes 22044c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 22057ba8b4beSAndre Guedes { 22064c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 22074c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 22084c87eaabSAndre Guedes struct hci_request req; 22094c87eaabSAndre Guedes struct hci_cp_inquiry cp; 22107ba8b4beSAndre Guedes int err; 22117ba8b4beSAndre Guedes 22124c87eaabSAndre Guedes if (status) { 22134c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 22144c87eaabSAndre Guedes return; 22157ba8b4beSAndre Guedes } 22167ba8b4beSAndre Guedes 22174c87eaabSAndre Guedes switch (hdev->discovery.type) { 22184c87eaabSAndre Guedes case DISCOV_TYPE_LE: 22194c87eaabSAndre Guedes hci_dev_lock(hdev); 22204c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 22214c87eaabSAndre Guedes hci_dev_unlock(hdev); 22224c87eaabSAndre Guedes break; 22237dbfac1dSAndre Guedes 22244c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 22254c87eaabSAndre Guedes hci_req_init(&req, hdev); 22267dbfac1dSAndre Guedes 22277dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 22284c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 22294c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 22304c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 22314c87eaabSAndre Guedes 22324c87eaabSAndre Guedes hci_dev_lock(hdev); 22334c87eaabSAndre Guedes 22344c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 22354c87eaabSAndre Guedes 22364c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 22374c87eaabSAndre Guedes if (err) { 22384c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 22394c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 22407dbfac1dSAndre Guedes } 22417dbfac1dSAndre Guedes 22424c87eaabSAndre Guedes hci_dev_unlock(hdev); 22434c87eaabSAndre Guedes break; 22444c87eaabSAndre Guedes } 22457dbfac1dSAndre Guedes } 22467dbfac1dSAndre Guedes 22477ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 22487ba8b4beSAndre Guedes { 22497ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 22507ba8b4beSAndre Guedes le_scan_disable.work); 22517ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 22524c87eaabSAndre Guedes struct hci_request req; 22534c87eaabSAndre Guedes int err; 22547ba8b4beSAndre Guedes 22557ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 22567ba8b4beSAndre Guedes 22574c87eaabSAndre Guedes hci_req_init(&req, hdev); 22587ba8b4beSAndre Guedes 22597ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 22604c87eaabSAndre Guedes cp.enable = LE_SCAN_DISABLE; 22614c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 22627ba8b4beSAndre Guedes 22634c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 22644c87eaabSAndre Guedes if (err) 22654c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 226628b75a89SAndre Guedes } 226728b75a89SAndre Guedes 22689be0dab7SDavid Herrmann /* Alloc HCI device */ 22699be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 22709be0dab7SDavid Herrmann { 22719be0dab7SDavid Herrmann struct hci_dev *hdev; 22729be0dab7SDavid Herrmann 22739be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 22749be0dab7SDavid Herrmann if (!hdev) 22759be0dab7SDavid Herrmann return NULL; 22769be0dab7SDavid Herrmann 2277b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 2278b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 2279b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 2280b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */ 2281b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 2282bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 2283bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2284b1b813d4SDavid Herrmann 2285b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 2286b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 2287b1b813d4SDavid Herrmann 2288bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060; 2289bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030; 2290bef64738SMarcel Holtmann 2291b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 2292b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 2293b1b813d4SDavid Herrmann 2294b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 2295b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 2296b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 2297b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 2298b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 2299b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 23006b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 2301b1b813d4SDavid Herrmann 2302b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 2303b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 2304b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 2305b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 2306b1b813d4SDavid Herrmann 2307b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 2308b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 2309b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 2310b1b813d4SDavid Herrmann 2311b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 2312b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 2313b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 2314b1b813d4SDavid Herrmann 2315b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 2316b1b813d4SDavid Herrmann 2317bda4f23aSAndrei Emeltchenko setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); 2318b1b813d4SDavid Herrmann 2319b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 2320b1b813d4SDavid Herrmann discovery_init(hdev); 23219be0dab7SDavid Herrmann 23229be0dab7SDavid Herrmann return hdev; 23239be0dab7SDavid Herrmann } 23249be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 23259be0dab7SDavid Herrmann 23269be0dab7SDavid Herrmann /* Free HCI device */ 23279be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 23289be0dab7SDavid Herrmann { 23299be0dab7SDavid Herrmann /* will free via device release */ 23309be0dab7SDavid Herrmann put_device(&hdev->dev); 23319be0dab7SDavid Herrmann } 23329be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 23339be0dab7SDavid Herrmann 23341da177e4SLinus Torvalds /* Register HCI device */ 23351da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 23361da177e4SLinus Torvalds { 2337b1b813d4SDavid Herrmann int id, error; 23381da177e4SLinus Torvalds 2339010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 23401da177e4SLinus Torvalds return -EINVAL; 23411da177e4SLinus Torvalds 234208add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 234308add513SMat Martineau * so the index can be used as the AMP controller ID. 234408add513SMat Martineau */ 23453df92b31SSasha Levin switch (hdev->dev_type) { 23463df92b31SSasha Levin case HCI_BREDR: 23473df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 23481da177e4SLinus Torvalds break; 23493df92b31SSasha Levin case HCI_AMP: 23503df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 23513df92b31SSasha Levin break; 23523df92b31SSasha Levin default: 23533df92b31SSasha Levin return -EINVAL; 23541da177e4SLinus Torvalds } 23551da177e4SLinus Torvalds 23563df92b31SSasha Levin if (id < 0) 23573df92b31SSasha Levin return id; 23583df92b31SSasha Levin 23591da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 23601da177e4SLinus Torvalds hdev->id = id; 23612d8b3a11SAndrei Emeltchenko 23622d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 23632d8b3a11SAndrei Emeltchenko 2364d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 2365d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 236633ca954dSDavid Herrmann if (!hdev->workqueue) { 236733ca954dSDavid Herrmann error = -ENOMEM; 236833ca954dSDavid Herrmann goto err; 236933ca954dSDavid Herrmann } 2370f48fd9c8SMarcel Holtmann 2371d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 2372d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 23736ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 23746ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 23756ead1bbcSJohan Hedberg error = -ENOMEM; 23766ead1bbcSJohan Hedberg goto err; 23776ead1bbcSJohan Hedberg } 23786ead1bbcSJohan Hedberg 237933ca954dSDavid Herrmann error = hci_add_sysfs(hdev); 238033ca954dSDavid Herrmann if (error < 0) 238133ca954dSDavid Herrmann goto err_wqueue; 23821da177e4SLinus Torvalds 2383611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 2384a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 2385a8c5fb1aSGustavo Padovan hdev); 2386611b30f7SMarcel Holtmann if (hdev->rfkill) { 2387611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 2388611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2389611b30f7SMarcel Holtmann hdev->rfkill = NULL; 2390611b30f7SMarcel Holtmann } 2391611b30f7SMarcel Holtmann } 2392611b30f7SMarcel Holtmann 23935e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) 23945e130367SJohan Hedberg set_bit(HCI_RFKILLED, &hdev->dev_flags); 23955e130367SJohan Hedberg 2396a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 2397004b0258SMarcel Holtmann set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2398ce2be9acSAndrei Emeltchenko 239901cd3404SMarcel Holtmann if (hdev->dev_type == HCI_BREDR) { 240056f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as 240156f87901SJohan Hedberg * through reading supported features during init. 240256f87901SJohan Hedberg */ 240356f87901SJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 240456f87901SJohan Hedberg } 2405ce2be9acSAndrei Emeltchenko 2406fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 2407fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 2408fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 2409fcee3377SGustavo Padovan 24101da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 2411dc946bd8SDavid Herrmann hci_dev_hold(hdev); 24121da177e4SLinus Torvalds 241319202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 2414fbe96d6fSMarcel Holtmann 24151da177e4SLinus Torvalds return id; 2416f48fd9c8SMarcel Holtmann 241733ca954dSDavid Herrmann err_wqueue: 241833ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 24196ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 242033ca954dSDavid Herrmann err: 24213df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 2422f48fd9c8SMarcel Holtmann 242333ca954dSDavid Herrmann return error; 24241da177e4SLinus Torvalds } 24251da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 24261da177e4SLinus Torvalds 24271da177e4SLinus Torvalds /* Unregister HCI device */ 242859735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 24291da177e4SLinus Torvalds { 24303df92b31SSasha Levin int i, id; 2431ef222013SMarcel Holtmann 2432c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 24331da177e4SLinus Torvalds 243494324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 243594324962SJohan Hovold 24363df92b31SSasha Levin id = hdev->id; 24373df92b31SSasha Levin 2438f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 24391da177e4SLinus Torvalds list_del(&hdev->list); 2440f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 24411da177e4SLinus Torvalds 24421da177e4SLinus Torvalds hci_dev_do_close(hdev); 24431da177e4SLinus Torvalds 2444cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 2445ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 2446ef222013SMarcel Holtmann 2447b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 2448b9b5ef18SGustavo Padovan 2449ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 2450a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 245109fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2452744cf19eSJohan Hedberg mgmt_index_removed(hdev); 245309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 245456e5cb86SJohan Hedberg } 2455ab81cbf9SJohan Hedberg 24562e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 24572e58ef3eSJohan Hedberg * pending list */ 24582e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 24592e58ef3eSJohan Hedberg 24601da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 24611da177e4SLinus Torvalds 2462611b30f7SMarcel Holtmann if (hdev->rfkill) { 2463611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 2464611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2465611b30f7SMarcel Holtmann } 2466611b30f7SMarcel Holtmann 2467ce242970SDavid Herrmann hci_del_sysfs(hdev); 2468147e2d59SDave Young 2469f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 24706ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 2471f48fd9c8SMarcel Holtmann 247209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2473e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 24742aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 247555ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 2476b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 24772763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 247809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 2479e2e0cacbSJohan Hedberg 2480dc946bd8SDavid Herrmann hci_dev_put(hdev); 24813df92b31SSasha Levin 24823df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 24831da177e4SLinus Torvalds } 24841da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 24851da177e4SLinus Torvalds 24861da177e4SLinus Torvalds /* Suspend HCI device */ 24871da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 24881da177e4SLinus Torvalds { 24891da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 24901da177e4SLinus Torvalds return 0; 24911da177e4SLinus Torvalds } 24921da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 24931da177e4SLinus Torvalds 24941da177e4SLinus Torvalds /* Resume HCI device */ 24951da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 24961da177e4SLinus Torvalds { 24971da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 24981da177e4SLinus Torvalds return 0; 24991da177e4SLinus Torvalds } 25001da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 25011da177e4SLinus Torvalds 250276bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 2503e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 250476bca880SMarcel Holtmann { 250576bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 250676bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 250776bca880SMarcel Holtmann kfree_skb(skb); 250876bca880SMarcel Holtmann return -ENXIO; 250976bca880SMarcel Holtmann } 251076bca880SMarcel Holtmann 2511d82603c6SJorrit Schippers /* Incoming skb */ 251276bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 251376bca880SMarcel Holtmann 251476bca880SMarcel Holtmann /* Time stamp */ 251576bca880SMarcel Holtmann __net_timestamp(skb); 251676bca880SMarcel Holtmann 251776bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 2518b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 2519c78ae283SMarcel Holtmann 252076bca880SMarcel Holtmann return 0; 252176bca880SMarcel Holtmann } 252276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 252376bca880SMarcel Holtmann 252433e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 25251e429f38SGustavo F. Padovan int count, __u8 index) 252633e882a5SSuraj Sumangala { 252733e882a5SSuraj Sumangala int len = 0; 252833e882a5SSuraj Sumangala int hlen = 0; 252933e882a5SSuraj Sumangala int remain = count; 253033e882a5SSuraj Sumangala struct sk_buff *skb; 253133e882a5SSuraj Sumangala struct bt_skb_cb *scb; 253233e882a5SSuraj Sumangala 253333e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 253433e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 253533e882a5SSuraj Sumangala return -EILSEQ; 253633e882a5SSuraj Sumangala 253733e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 253833e882a5SSuraj Sumangala 253933e882a5SSuraj Sumangala if (!skb) { 254033e882a5SSuraj Sumangala switch (type) { 254133e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 254233e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 254333e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 254433e882a5SSuraj Sumangala break; 254533e882a5SSuraj Sumangala case HCI_EVENT_PKT: 254633e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 254733e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 254833e882a5SSuraj Sumangala break; 254933e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 255033e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 255133e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 255233e882a5SSuraj Sumangala break; 255333e882a5SSuraj Sumangala } 255433e882a5SSuraj Sumangala 25551e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 255633e882a5SSuraj Sumangala if (!skb) 255733e882a5SSuraj Sumangala return -ENOMEM; 255833e882a5SSuraj Sumangala 255933e882a5SSuraj Sumangala scb = (void *) skb->cb; 256033e882a5SSuraj Sumangala scb->expect = hlen; 256133e882a5SSuraj Sumangala scb->pkt_type = type; 256233e882a5SSuraj Sumangala 256333e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 256433e882a5SSuraj Sumangala } 256533e882a5SSuraj Sumangala 256633e882a5SSuraj Sumangala while (count) { 256733e882a5SSuraj Sumangala scb = (void *) skb->cb; 256889bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 256933e882a5SSuraj Sumangala 257033e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 257133e882a5SSuraj Sumangala 257233e882a5SSuraj Sumangala count -= len; 257333e882a5SSuraj Sumangala data += len; 257433e882a5SSuraj Sumangala scb->expect -= len; 257533e882a5SSuraj Sumangala remain = count; 257633e882a5SSuraj Sumangala 257733e882a5SSuraj Sumangala switch (type) { 257833e882a5SSuraj Sumangala case HCI_EVENT_PKT: 257933e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 258033e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 258133e882a5SSuraj Sumangala scb->expect = h->plen; 258233e882a5SSuraj Sumangala 258333e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 258433e882a5SSuraj Sumangala kfree_skb(skb); 258533e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 258633e882a5SSuraj Sumangala return -ENOMEM; 258733e882a5SSuraj Sumangala } 258833e882a5SSuraj Sumangala } 258933e882a5SSuraj Sumangala break; 259033e882a5SSuraj Sumangala 259133e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 259233e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 259333e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 259433e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 259533e882a5SSuraj Sumangala 259633e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 259733e882a5SSuraj Sumangala kfree_skb(skb); 259833e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 259933e882a5SSuraj Sumangala return -ENOMEM; 260033e882a5SSuraj Sumangala } 260133e882a5SSuraj Sumangala } 260233e882a5SSuraj Sumangala break; 260333e882a5SSuraj Sumangala 260433e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 260533e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 260633e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 260733e882a5SSuraj Sumangala scb->expect = h->dlen; 260833e882a5SSuraj Sumangala 260933e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 261033e882a5SSuraj Sumangala kfree_skb(skb); 261133e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 261233e882a5SSuraj Sumangala return -ENOMEM; 261333e882a5SSuraj Sumangala } 261433e882a5SSuraj Sumangala } 261533e882a5SSuraj Sumangala break; 261633e882a5SSuraj Sumangala } 261733e882a5SSuraj Sumangala 261833e882a5SSuraj Sumangala if (scb->expect == 0) { 261933e882a5SSuraj Sumangala /* Complete frame */ 262033e882a5SSuraj Sumangala 262133e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 2622e1a26170SMarcel Holtmann hci_recv_frame(hdev, skb); 262333e882a5SSuraj Sumangala 262433e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 262533e882a5SSuraj Sumangala return remain; 262633e882a5SSuraj Sumangala } 262733e882a5SSuraj Sumangala } 262833e882a5SSuraj Sumangala 262933e882a5SSuraj Sumangala return remain; 263033e882a5SSuraj Sumangala } 263133e882a5SSuraj Sumangala 2632ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 2633ef222013SMarcel Holtmann { 2634f39a3c06SSuraj Sumangala int rem = 0; 2635f39a3c06SSuraj Sumangala 2636ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 2637ef222013SMarcel Holtmann return -EILSEQ; 2638ef222013SMarcel Holtmann 2639da5f6c37SGustavo F. Padovan while (count) { 26401e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 2641f39a3c06SSuraj Sumangala if (rem < 0) 2642f39a3c06SSuraj Sumangala return rem; 2643ef222013SMarcel Holtmann 2644f39a3c06SSuraj Sumangala data += (count - rem); 2645f39a3c06SSuraj Sumangala count = rem; 2646f81c6224SJoe Perches } 2647ef222013SMarcel Holtmann 2648f39a3c06SSuraj Sumangala return rem; 2649ef222013SMarcel Holtmann } 2650ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 2651ef222013SMarcel Holtmann 265299811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 265399811510SSuraj Sumangala 265499811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 265599811510SSuraj Sumangala { 265699811510SSuraj Sumangala int type; 265799811510SSuraj Sumangala int rem = 0; 265899811510SSuraj Sumangala 2659da5f6c37SGustavo F. Padovan while (count) { 266099811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 266199811510SSuraj Sumangala 266299811510SSuraj Sumangala if (!skb) { 266399811510SSuraj Sumangala struct { char type; } *pkt; 266499811510SSuraj Sumangala 266599811510SSuraj Sumangala /* Start of the frame */ 266699811510SSuraj Sumangala pkt = data; 266799811510SSuraj Sumangala type = pkt->type; 266899811510SSuraj Sumangala 266999811510SSuraj Sumangala data++; 267099811510SSuraj Sumangala count--; 267199811510SSuraj Sumangala } else 267299811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 267399811510SSuraj Sumangala 26741e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 26751e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 267699811510SSuraj Sumangala if (rem < 0) 267799811510SSuraj Sumangala return rem; 267899811510SSuraj Sumangala 267999811510SSuraj Sumangala data += (count - rem); 268099811510SSuraj Sumangala count = rem; 2681f81c6224SJoe Perches } 268299811510SSuraj Sumangala 268399811510SSuraj Sumangala return rem; 268499811510SSuraj Sumangala } 268599811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 268699811510SSuraj Sumangala 26871da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 26881da177e4SLinus Torvalds 26891da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 26901da177e4SLinus Torvalds { 26911da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 26921da177e4SLinus Torvalds 2693f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 26941da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 2695f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 26961da177e4SLinus Torvalds 26971da177e4SLinus Torvalds return 0; 26981da177e4SLinus Torvalds } 26991da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 27001da177e4SLinus Torvalds 27011da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 27021da177e4SLinus Torvalds { 27031da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 27041da177e4SLinus Torvalds 2705f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 27061da177e4SLinus Torvalds list_del(&cb->list); 2707f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 27081da177e4SLinus Torvalds 27091da177e4SLinus Torvalds return 0; 27101da177e4SLinus Torvalds } 27111da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 27121da177e4SLinus Torvalds 271351086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 27141da177e4SLinus Torvalds { 27150d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 27161da177e4SLinus Torvalds 27171da177e4SLinus Torvalds /* Time stamp */ 2718a61bbcf2SPatrick McHardy __net_timestamp(skb); 27191da177e4SLinus Torvalds 2720cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2721cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2722cd82e61cSMarcel Holtmann 2723cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 2724cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 2725470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 27261da177e4SLinus Torvalds } 27271da177e4SLinus Torvalds 27281da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 27291da177e4SLinus Torvalds skb_orphan(skb); 27301da177e4SLinus Torvalds 27317bd8f09fSMarcel Holtmann if (hdev->send(hdev, skb) < 0) 273251086991SMarcel Holtmann BT_ERR("%s sending frame failed", hdev->name); 27331da177e4SLinus Torvalds } 27341da177e4SLinus Torvalds 27353119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 27363119ae95SJohan Hedberg { 27373119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 27383119ae95SJohan Hedberg req->hdev = hdev; 27395d73e034SAndre Guedes req->err = 0; 27403119ae95SJohan Hedberg } 27413119ae95SJohan Hedberg 27423119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 27433119ae95SJohan Hedberg { 27443119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 27453119ae95SJohan Hedberg struct sk_buff *skb; 27463119ae95SJohan Hedberg unsigned long flags; 27473119ae95SJohan Hedberg 27483119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 27493119ae95SJohan Hedberg 27505d73e034SAndre Guedes /* If an error occured during request building, remove all HCI 27515d73e034SAndre Guedes * commands queued on the HCI request queue. 27525d73e034SAndre Guedes */ 27535d73e034SAndre Guedes if (req->err) { 27545d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 27555d73e034SAndre Guedes return req->err; 27565d73e034SAndre Guedes } 27575d73e034SAndre Guedes 27583119ae95SJohan Hedberg /* Do not allow empty requests */ 27593119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 2760382b0c39SAndre Guedes return -ENODATA; 27613119ae95SJohan Hedberg 27623119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 27633119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 27643119ae95SJohan Hedberg 27653119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 27663119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 27673119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 27683119ae95SJohan Hedberg 27693119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 27703119ae95SJohan Hedberg 27713119ae95SJohan Hedberg return 0; 27723119ae95SJohan Hedberg } 27733119ae95SJohan Hedberg 27741ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 277507dc93ddSJohan Hedberg u32 plen, const void *param) 27761da177e4SLinus Torvalds { 27771da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 27781da177e4SLinus Torvalds struct hci_command_hdr *hdr; 27791da177e4SLinus Torvalds struct sk_buff *skb; 27801da177e4SLinus Torvalds 27811da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 27821ca3a9d0SJohan Hedberg if (!skb) 27831ca3a9d0SJohan Hedberg return NULL; 27841da177e4SLinus Torvalds 27851da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 2786a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 27871da177e4SLinus Torvalds hdr->plen = plen; 27881da177e4SLinus Torvalds 27891da177e4SLinus Torvalds if (plen) 27901da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 27911da177e4SLinus Torvalds 27921da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 27931da177e4SLinus Torvalds 27940d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 2795c78ae283SMarcel Holtmann 27961ca3a9d0SJohan Hedberg return skb; 27971ca3a9d0SJohan Hedberg } 27981ca3a9d0SJohan Hedberg 27991ca3a9d0SJohan Hedberg /* Send HCI command */ 280007dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 280107dc93ddSJohan Hedberg const void *param) 28021ca3a9d0SJohan Hedberg { 28031ca3a9d0SJohan Hedberg struct sk_buff *skb; 28041ca3a9d0SJohan Hedberg 28051ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 28061ca3a9d0SJohan Hedberg 28071ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 28081ca3a9d0SJohan Hedberg if (!skb) { 28091ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 28101ca3a9d0SJohan Hedberg return -ENOMEM; 28111ca3a9d0SJohan Hedberg } 28121ca3a9d0SJohan Hedberg 281311714b3dSJohan Hedberg /* Stand-alone HCI commands must be flaged as 281411714b3dSJohan Hedberg * single-command requests. 281511714b3dSJohan Hedberg */ 281611714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 281711714b3dSJohan Hedberg 28181da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 2819c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 28201da177e4SLinus Torvalds 28211da177e4SLinus Torvalds return 0; 28221da177e4SLinus Torvalds } 28231da177e4SLinus Torvalds 282471c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 282507dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 282607dc93ddSJohan Hedberg const void *param, u8 event) 282771c76a17SJohan Hedberg { 282871c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 282971c76a17SJohan Hedberg struct sk_buff *skb; 283071c76a17SJohan Hedberg 283171c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 283271c76a17SJohan Hedberg 283334739c1eSAndre Guedes /* If an error occured during request building, there is no point in 283434739c1eSAndre Guedes * queueing the HCI command. We can simply return. 283534739c1eSAndre Guedes */ 283634739c1eSAndre Guedes if (req->err) 283734739c1eSAndre Guedes return; 283834739c1eSAndre Guedes 283971c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 284071c76a17SJohan Hedberg if (!skb) { 28415d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 28425d73e034SAndre Guedes hdev->name, opcode); 28435d73e034SAndre Guedes req->err = -ENOMEM; 2844e348fe6bSAndre Guedes return; 284571c76a17SJohan Hedberg } 284671c76a17SJohan Hedberg 284771c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 284871c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 284971c76a17SJohan Hedberg 285002350a72SJohan Hedberg bt_cb(skb)->req.event = event; 285102350a72SJohan Hedberg 285271c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 285371c76a17SJohan Hedberg } 285471c76a17SJohan Hedberg 285507dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 285607dc93ddSJohan Hedberg const void *param) 285702350a72SJohan Hedberg { 285802350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 285902350a72SJohan Hedberg } 286002350a72SJohan Hedberg 28611da177e4SLinus Torvalds /* Get data from the previously sent command */ 2862a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 28631da177e4SLinus Torvalds { 28641da177e4SLinus Torvalds struct hci_command_hdr *hdr; 28651da177e4SLinus Torvalds 28661da177e4SLinus Torvalds if (!hdev->sent_cmd) 28671da177e4SLinus Torvalds return NULL; 28681da177e4SLinus Torvalds 28691da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 28701da177e4SLinus Torvalds 2871a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 28721da177e4SLinus Torvalds return NULL; 28731da177e4SLinus Torvalds 2874f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 28751da177e4SLinus Torvalds 28761da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 28771da177e4SLinus Torvalds } 28781da177e4SLinus Torvalds 28791da177e4SLinus Torvalds /* Send ACL data */ 28801da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 28811da177e4SLinus Torvalds { 28821da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 28831da177e4SLinus Torvalds int len = skb->len; 28841da177e4SLinus Torvalds 2885badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 2886badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 28879c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 2888aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 2889aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 28901da177e4SLinus Torvalds } 28911da177e4SLinus Torvalds 2892ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 289373d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 28941da177e4SLinus Torvalds { 2895ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 28961da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 28971da177e4SLinus Torvalds struct sk_buff *list; 28981da177e4SLinus Torvalds 2899087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 2900087bfd99SGustavo Padovan skb->data_len = 0; 2901087bfd99SGustavo Padovan 2902087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2903204a6e54SAndrei Emeltchenko 2904204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 2905204a6e54SAndrei Emeltchenko case HCI_BREDR: 2906087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 2907204a6e54SAndrei Emeltchenko break; 2908204a6e54SAndrei Emeltchenko case HCI_AMP: 2909204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 2910204a6e54SAndrei Emeltchenko break; 2911204a6e54SAndrei Emeltchenko default: 2912204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 2913204a6e54SAndrei Emeltchenko return; 2914204a6e54SAndrei Emeltchenko } 2915087bfd99SGustavo Padovan 291670f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 291770f23020SAndrei Emeltchenko if (!list) { 29181da177e4SLinus Torvalds /* Non fragmented */ 29191da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 29201da177e4SLinus Torvalds 292173d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 29221da177e4SLinus Torvalds } else { 29231da177e4SLinus Torvalds /* Fragmented */ 29241da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 29251da177e4SLinus Torvalds 29261da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 29271da177e4SLinus Torvalds 29281da177e4SLinus Torvalds /* Queue all fragments atomically */ 2929af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 29301da177e4SLinus Torvalds 293173d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 2932e702112fSAndrei Emeltchenko 2933e702112fSAndrei Emeltchenko flags &= ~ACL_START; 2934e702112fSAndrei Emeltchenko flags |= ACL_CONT; 29351da177e4SLinus Torvalds do { 29361da177e4SLinus Torvalds skb = list; list = list->next; 29371da177e4SLinus Torvalds 29380d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2939e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 29401da177e4SLinus Torvalds 29411da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 29421da177e4SLinus Torvalds 294373d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 29441da177e4SLinus Torvalds } while (list); 29451da177e4SLinus Torvalds 2946af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 29471da177e4SLinus Torvalds } 294873d80debSLuiz Augusto von Dentz } 294973d80debSLuiz Augusto von Dentz 295073d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 295173d80debSLuiz Augusto von Dentz { 2952ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 295373d80debSLuiz Augusto von Dentz 2954f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 295573d80debSLuiz Augusto von Dentz 2956ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 29571da177e4SLinus Torvalds 29583eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 29591da177e4SLinus Torvalds } 29601da177e4SLinus Torvalds 29611da177e4SLinus Torvalds /* Send SCO data */ 29620d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 29631da177e4SLinus Torvalds { 29641da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 29651da177e4SLinus Torvalds struct hci_sco_hdr hdr; 29661da177e4SLinus Torvalds 29671da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 29681da177e4SLinus Torvalds 2969aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 29701da177e4SLinus Torvalds hdr.dlen = skb->len; 29711da177e4SLinus Torvalds 2972badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 2973badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 29749c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 29751da177e4SLinus Torvalds 29760d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 2977c78ae283SMarcel Holtmann 29781da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 29793eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 29801da177e4SLinus Torvalds } 29811da177e4SLinus Torvalds 29821da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 29831da177e4SLinus Torvalds 29841da177e4SLinus Torvalds /* HCI Connection scheduler */ 29856039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 2986a8c5fb1aSGustavo Padovan int *quote) 29871da177e4SLinus Torvalds { 29881da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 29898035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 2990abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 29911da177e4SLinus Torvalds 29921da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 29931da177e4SLinus Torvalds * added and removed with TX task disabled. */ 2994bf4c6325SGustavo F. Padovan 2995bf4c6325SGustavo F. Padovan rcu_read_lock(); 2996bf4c6325SGustavo F. Padovan 2997bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2998769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 29991da177e4SLinus Torvalds continue; 3000769be974SMarcel Holtmann 3001769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 3002769be974SMarcel Holtmann continue; 3003769be974SMarcel Holtmann 30041da177e4SLinus Torvalds num++; 30051da177e4SLinus Torvalds 30061da177e4SLinus Torvalds if (c->sent < min) { 30071da177e4SLinus Torvalds min = c->sent; 30081da177e4SLinus Torvalds conn = c; 30091da177e4SLinus Torvalds } 301052087a79SLuiz Augusto von Dentz 301152087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 301252087a79SLuiz Augusto von Dentz break; 30131da177e4SLinus Torvalds } 30141da177e4SLinus Torvalds 3015bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3016bf4c6325SGustavo F. Padovan 30171da177e4SLinus Torvalds if (conn) { 30186ed58ec5SVille Tervo int cnt, q; 30196ed58ec5SVille Tervo 30206ed58ec5SVille Tervo switch (conn->type) { 30216ed58ec5SVille Tervo case ACL_LINK: 30226ed58ec5SVille Tervo cnt = hdev->acl_cnt; 30236ed58ec5SVille Tervo break; 30246ed58ec5SVille Tervo case SCO_LINK: 30256ed58ec5SVille Tervo case ESCO_LINK: 30266ed58ec5SVille Tervo cnt = hdev->sco_cnt; 30276ed58ec5SVille Tervo break; 30286ed58ec5SVille Tervo case LE_LINK: 30296ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 30306ed58ec5SVille Tervo break; 30316ed58ec5SVille Tervo default: 30326ed58ec5SVille Tervo cnt = 0; 30336ed58ec5SVille Tervo BT_ERR("Unknown link type"); 30346ed58ec5SVille Tervo } 30356ed58ec5SVille Tervo 30366ed58ec5SVille Tervo q = cnt / num; 30371da177e4SLinus Torvalds *quote = q ? q : 1; 30381da177e4SLinus Torvalds } else 30391da177e4SLinus Torvalds *quote = 0; 30401da177e4SLinus Torvalds 30411da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 30421da177e4SLinus Torvalds return conn; 30431da177e4SLinus Torvalds } 30441da177e4SLinus Torvalds 30456039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 30461da177e4SLinus Torvalds { 30471da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 30481da177e4SLinus Torvalds struct hci_conn *c; 30491da177e4SLinus Torvalds 3050bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 30511da177e4SLinus Torvalds 3052bf4c6325SGustavo F. Padovan rcu_read_lock(); 3053bf4c6325SGustavo F. Padovan 30541da177e4SLinus Torvalds /* Kill stalled connections */ 3055bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 3056bae1f5d9SVille Tervo if (c->type == type && c->sent) { 30576ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 30586ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 3059bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 30601da177e4SLinus Torvalds } 30611da177e4SLinus Torvalds } 3062bf4c6325SGustavo F. Padovan 3063bf4c6325SGustavo F. Padovan rcu_read_unlock(); 30641da177e4SLinus Torvalds } 30651da177e4SLinus Torvalds 30666039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 306773d80debSLuiz Augusto von Dentz int *quote) 306873d80debSLuiz Augusto von Dentz { 306973d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 307073d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 3071abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 307273d80debSLuiz Augusto von Dentz struct hci_conn *conn; 307373d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 307473d80debSLuiz Augusto von Dentz 307573d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 307673d80debSLuiz Augusto von Dentz 3077bf4c6325SGustavo F. Padovan rcu_read_lock(); 3078bf4c6325SGustavo F. Padovan 3079bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 308073d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 308173d80debSLuiz Augusto von Dentz 308273d80debSLuiz Augusto von Dentz if (conn->type != type) 308373d80debSLuiz Augusto von Dentz continue; 308473d80debSLuiz Augusto von Dentz 308573d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 308673d80debSLuiz Augusto von Dentz continue; 308773d80debSLuiz Augusto von Dentz 308873d80debSLuiz Augusto von Dentz conn_num++; 308973d80debSLuiz Augusto von Dentz 30908192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 309173d80debSLuiz Augusto von Dentz struct sk_buff *skb; 309273d80debSLuiz Augusto von Dentz 309373d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 309473d80debSLuiz Augusto von Dentz continue; 309573d80debSLuiz Augusto von Dentz 309673d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 309773d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 309873d80debSLuiz Augusto von Dentz continue; 309973d80debSLuiz Augusto von Dentz 310073d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 310173d80debSLuiz Augusto von Dentz num = 0; 310273d80debSLuiz Augusto von Dentz min = ~0; 310373d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 310473d80debSLuiz Augusto von Dentz } 310573d80debSLuiz Augusto von Dentz 310673d80debSLuiz Augusto von Dentz num++; 310773d80debSLuiz Augusto von Dentz 310873d80debSLuiz Augusto von Dentz if (conn->sent < min) { 310973d80debSLuiz Augusto von Dentz min = conn->sent; 311073d80debSLuiz Augusto von Dentz chan = tmp; 311173d80debSLuiz Augusto von Dentz } 311273d80debSLuiz Augusto von Dentz } 311373d80debSLuiz Augusto von Dentz 311473d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 311573d80debSLuiz Augusto von Dentz break; 311673d80debSLuiz Augusto von Dentz } 311773d80debSLuiz Augusto von Dentz 3118bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3119bf4c6325SGustavo F. Padovan 312073d80debSLuiz Augusto von Dentz if (!chan) 312173d80debSLuiz Augusto von Dentz return NULL; 312273d80debSLuiz Augusto von Dentz 312373d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 312473d80debSLuiz Augusto von Dentz case ACL_LINK: 312573d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 312673d80debSLuiz Augusto von Dentz break; 3127bd1eb66bSAndrei Emeltchenko case AMP_LINK: 3128bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 3129bd1eb66bSAndrei Emeltchenko break; 313073d80debSLuiz Augusto von Dentz case SCO_LINK: 313173d80debSLuiz Augusto von Dentz case ESCO_LINK: 313273d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 313373d80debSLuiz Augusto von Dentz break; 313473d80debSLuiz Augusto von Dentz case LE_LINK: 313573d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 313673d80debSLuiz Augusto von Dentz break; 313773d80debSLuiz Augusto von Dentz default: 313873d80debSLuiz Augusto von Dentz cnt = 0; 313973d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 314073d80debSLuiz Augusto von Dentz } 314173d80debSLuiz Augusto von Dentz 314273d80debSLuiz Augusto von Dentz q = cnt / num; 314373d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 314473d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 314573d80debSLuiz Augusto von Dentz return chan; 314673d80debSLuiz Augusto von Dentz } 314773d80debSLuiz Augusto von Dentz 314802b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 314902b20f0bSLuiz Augusto von Dentz { 315002b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 315102b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 315202b20f0bSLuiz Augusto von Dentz int num = 0; 315302b20f0bSLuiz Augusto von Dentz 315402b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 315502b20f0bSLuiz Augusto von Dentz 3156bf4c6325SGustavo F. Padovan rcu_read_lock(); 3157bf4c6325SGustavo F. Padovan 3158bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 315902b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 316002b20f0bSLuiz Augusto von Dentz 316102b20f0bSLuiz Augusto von Dentz if (conn->type != type) 316202b20f0bSLuiz Augusto von Dentz continue; 316302b20f0bSLuiz Augusto von Dentz 316402b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 316502b20f0bSLuiz Augusto von Dentz continue; 316602b20f0bSLuiz Augusto von Dentz 316702b20f0bSLuiz Augusto von Dentz num++; 316802b20f0bSLuiz Augusto von Dentz 31698192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 317002b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 317102b20f0bSLuiz Augusto von Dentz 317202b20f0bSLuiz Augusto von Dentz if (chan->sent) { 317302b20f0bSLuiz Augusto von Dentz chan->sent = 0; 317402b20f0bSLuiz Augusto von Dentz continue; 317502b20f0bSLuiz Augusto von Dentz } 317602b20f0bSLuiz Augusto von Dentz 317702b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 317802b20f0bSLuiz Augusto von Dentz continue; 317902b20f0bSLuiz Augusto von Dentz 318002b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 318102b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 318202b20f0bSLuiz Augusto von Dentz continue; 318302b20f0bSLuiz Augusto von Dentz 318402b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 318502b20f0bSLuiz Augusto von Dentz 318602b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 318702b20f0bSLuiz Augusto von Dentz skb->priority); 318802b20f0bSLuiz Augusto von Dentz } 318902b20f0bSLuiz Augusto von Dentz 319002b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 319102b20f0bSLuiz Augusto von Dentz break; 319202b20f0bSLuiz Augusto von Dentz } 3193bf4c6325SGustavo F. Padovan 3194bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3195bf4c6325SGustavo F. Padovan 319602b20f0bSLuiz Augusto von Dentz } 319702b20f0bSLuiz Augusto von Dentz 3198b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 3199b71d385aSAndrei Emeltchenko { 3200b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 3201b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 3202b71d385aSAndrei Emeltchenko } 3203b71d385aSAndrei Emeltchenko 32046039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 32051da177e4SLinus Torvalds { 32061da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 32071da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 32081da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 320963d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 32105f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 3211bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 32121da177e4SLinus Torvalds } 321363d2bc1bSAndrei Emeltchenko } 32141da177e4SLinus Torvalds 32156039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 321663d2bc1bSAndrei Emeltchenko { 321763d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 321863d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 321963d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 322063d2bc1bSAndrei Emeltchenko int quote; 322163d2bc1bSAndrei Emeltchenko 322263d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 322304837f64SMarcel Holtmann 322473d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 322573d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 3226ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3227ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 322873d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 322973d80debSLuiz Augusto von Dentz skb->len, skb->priority); 323073d80debSLuiz Augusto von Dentz 3231ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3232ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3233ec1cce24SLuiz Augusto von Dentz break; 3234ec1cce24SLuiz Augusto von Dentz 3235ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3236ec1cce24SLuiz Augusto von Dentz 323773d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 323873d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 323904837f64SMarcel Holtmann 324057d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 32411da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 32421da177e4SLinus Torvalds 32431da177e4SLinus Torvalds hdev->acl_cnt--; 324473d80debSLuiz Augusto von Dentz chan->sent++; 324573d80debSLuiz Augusto von Dentz chan->conn->sent++; 32461da177e4SLinus Torvalds } 32471da177e4SLinus Torvalds } 324802b20f0bSLuiz Augusto von Dentz 324902b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 325002b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 32511da177e4SLinus Torvalds } 32521da177e4SLinus Torvalds 32536039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 3254b71d385aSAndrei Emeltchenko { 325563d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 3256b71d385aSAndrei Emeltchenko struct hci_chan *chan; 3257b71d385aSAndrei Emeltchenko struct sk_buff *skb; 3258b71d385aSAndrei Emeltchenko int quote; 3259bd1eb66bSAndrei Emeltchenko u8 type; 3260b71d385aSAndrei Emeltchenko 326163d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 3262b71d385aSAndrei Emeltchenko 3263bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3264bd1eb66bSAndrei Emeltchenko 3265bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 3266bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 3267bd1eb66bSAndrei Emeltchenko else 3268bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 3269bd1eb66bSAndrei Emeltchenko 3270b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 3271bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 3272b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 3273b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 3274b71d385aSAndrei Emeltchenko int blocks; 3275b71d385aSAndrei Emeltchenko 3276b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 3277b71d385aSAndrei Emeltchenko skb->len, skb->priority); 3278b71d385aSAndrei Emeltchenko 3279b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 3280b71d385aSAndrei Emeltchenko if (skb->priority < priority) 3281b71d385aSAndrei Emeltchenko break; 3282b71d385aSAndrei Emeltchenko 3283b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 3284b71d385aSAndrei Emeltchenko 3285b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 3286b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 3287b71d385aSAndrei Emeltchenko return; 3288b71d385aSAndrei Emeltchenko 3289b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 3290b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 3291b71d385aSAndrei Emeltchenko 329257d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 3293b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 3294b71d385aSAndrei Emeltchenko 3295b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 3296b71d385aSAndrei Emeltchenko quote -= blocks; 3297b71d385aSAndrei Emeltchenko 3298b71d385aSAndrei Emeltchenko chan->sent += blocks; 3299b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 3300b71d385aSAndrei Emeltchenko } 3301b71d385aSAndrei Emeltchenko } 3302b71d385aSAndrei Emeltchenko 3303b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 3304bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 3305b71d385aSAndrei Emeltchenko } 3306b71d385aSAndrei Emeltchenko 33076039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 3308b71d385aSAndrei Emeltchenko { 3309b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3310b71d385aSAndrei Emeltchenko 3311bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 3312bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 3313bd1eb66bSAndrei Emeltchenko return; 3314bd1eb66bSAndrei Emeltchenko 3315bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 3316bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 3317b71d385aSAndrei Emeltchenko return; 3318b71d385aSAndrei Emeltchenko 3319b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 3320b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 3321b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 3322b71d385aSAndrei Emeltchenko break; 3323b71d385aSAndrei Emeltchenko 3324b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 3325b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 3326b71d385aSAndrei Emeltchenko break; 3327b71d385aSAndrei Emeltchenko } 3328b71d385aSAndrei Emeltchenko } 3329b71d385aSAndrei Emeltchenko 33301da177e4SLinus Torvalds /* Schedule SCO */ 33316039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 33321da177e4SLinus Torvalds { 33331da177e4SLinus Torvalds struct hci_conn *conn; 33341da177e4SLinus Torvalds struct sk_buff *skb; 33351da177e4SLinus Torvalds int quote; 33361da177e4SLinus Torvalds 33371da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 33381da177e4SLinus Torvalds 333952087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 334052087a79SLuiz Augusto von Dentz return; 334152087a79SLuiz Augusto von Dentz 33421da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 33431da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 33441da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 334557d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 33461da177e4SLinus Torvalds 33471da177e4SLinus Torvalds conn->sent++; 33481da177e4SLinus Torvalds if (conn->sent == ~0) 33491da177e4SLinus Torvalds conn->sent = 0; 33501da177e4SLinus Torvalds } 33511da177e4SLinus Torvalds } 33521da177e4SLinus Torvalds } 33531da177e4SLinus Torvalds 33546039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 3355b6a0dc82SMarcel Holtmann { 3356b6a0dc82SMarcel Holtmann struct hci_conn *conn; 3357b6a0dc82SMarcel Holtmann struct sk_buff *skb; 3358b6a0dc82SMarcel Holtmann int quote; 3359b6a0dc82SMarcel Holtmann 3360b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 3361b6a0dc82SMarcel Holtmann 336252087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 336352087a79SLuiz Augusto von Dentz return; 336452087a79SLuiz Augusto von Dentz 33658fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 33668fc9ced3SGustavo Padovan "e))) { 3367b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 3368b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 336957d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 3370b6a0dc82SMarcel Holtmann 3371b6a0dc82SMarcel Holtmann conn->sent++; 3372b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 3373b6a0dc82SMarcel Holtmann conn->sent = 0; 3374b6a0dc82SMarcel Holtmann } 3375b6a0dc82SMarcel Holtmann } 3376b6a0dc82SMarcel Holtmann } 3377b6a0dc82SMarcel Holtmann 33786039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 33796ed58ec5SVille Tervo { 338073d80debSLuiz Augusto von Dentz struct hci_chan *chan; 33816ed58ec5SVille Tervo struct sk_buff *skb; 338202b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 33836ed58ec5SVille Tervo 33846ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 33856ed58ec5SVille Tervo 338652087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 338752087a79SLuiz Augusto von Dentz return; 338852087a79SLuiz Augusto von Dentz 33896ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 33906ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 33916ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 3392bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 33936ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 3394bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 33956ed58ec5SVille Tervo } 33966ed58ec5SVille Tervo 33976ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 339802b20f0bSLuiz Augusto von Dentz tmp = cnt; 339973d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 3400ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3401ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 340273d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 340373d80debSLuiz Augusto von Dentz skb->len, skb->priority); 34046ed58ec5SVille Tervo 3405ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3406ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3407ec1cce24SLuiz Augusto von Dentz break; 3408ec1cce24SLuiz Augusto von Dentz 3409ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3410ec1cce24SLuiz Augusto von Dentz 341157d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 34126ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 34136ed58ec5SVille Tervo 34146ed58ec5SVille Tervo cnt--; 341573d80debSLuiz Augusto von Dentz chan->sent++; 341673d80debSLuiz Augusto von Dentz chan->conn->sent++; 34176ed58ec5SVille Tervo } 34186ed58ec5SVille Tervo } 341973d80debSLuiz Augusto von Dentz 34206ed58ec5SVille Tervo if (hdev->le_pkts) 34216ed58ec5SVille Tervo hdev->le_cnt = cnt; 34226ed58ec5SVille Tervo else 34236ed58ec5SVille Tervo hdev->acl_cnt = cnt; 342402b20f0bSLuiz Augusto von Dentz 342502b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 342602b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 34276ed58ec5SVille Tervo } 34286ed58ec5SVille Tervo 34293eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 34301da177e4SLinus Torvalds { 34313eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 34321da177e4SLinus Torvalds struct sk_buff *skb; 34331da177e4SLinus Torvalds 34346ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 34356ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 34361da177e4SLinus Torvalds 343752de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 34381da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 34391da177e4SLinus Torvalds hci_sched_acl(hdev); 34401da177e4SLinus Torvalds hci_sched_sco(hdev); 3441b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 34426ed58ec5SVille Tervo hci_sched_le(hdev); 344352de599eSMarcel Holtmann } 34446ed58ec5SVille Tervo 34451da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 34461da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 344757d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 34481da177e4SLinus Torvalds } 34491da177e4SLinus Torvalds 345025985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 34511da177e4SLinus Torvalds 34521da177e4SLinus Torvalds /* ACL data packet */ 34536039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 34541da177e4SLinus Torvalds { 34551da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 34561da177e4SLinus Torvalds struct hci_conn *conn; 34571da177e4SLinus Torvalds __u16 handle, flags; 34581da177e4SLinus Torvalds 34591da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 34601da177e4SLinus Torvalds 34611da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 34621da177e4SLinus Torvalds flags = hci_flags(handle); 34631da177e4SLinus Torvalds handle = hci_handle(handle); 34641da177e4SLinus Torvalds 3465f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 3466a8c5fb1aSGustavo Padovan handle, flags); 34671da177e4SLinus Torvalds 34681da177e4SLinus Torvalds hdev->stat.acl_rx++; 34691da177e4SLinus Torvalds 34701da177e4SLinus Torvalds hci_dev_lock(hdev); 34711da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 34721da177e4SLinus Torvalds hci_dev_unlock(hdev); 34731da177e4SLinus Torvalds 34741da177e4SLinus Torvalds if (conn) { 347565983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 347604837f64SMarcel Holtmann 34771da177e4SLinus Torvalds /* Send to upper protocol */ 3478686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 34791da177e4SLinus Torvalds return; 34801da177e4SLinus Torvalds } else { 34811da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 34821da177e4SLinus Torvalds hdev->name, handle); 34831da177e4SLinus Torvalds } 34841da177e4SLinus Torvalds 34851da177e4SLinus Torvalds kfree_skb(skb); 34861da177e4SLinus Torvalds } 34871da177e4SLinus Torvalds 34881da177e4SLinus Torvalds /* SCO data packet */ 34896039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 34901da177e4SLinus Torvalds { 34911da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 34921da177e4SLinus Torvalds struct hci_conn *conn; 34931da177e4SLinus Torvalds __u16 handle; 34941da177e4SLinus Torvalds 34951da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 34961da177e4SLinus Torvalds 34971da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 34981da177e4SLinus Torvalds 3499f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 35001da177e4SLinus Torvalds 35011da177e4SLinus Torvalds hdev->stat.sco_rx++; 35021da177e4SLinus Torvalds 35031da177e4SLinus Torvalds hci_dev_lock(hdev); 35041da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 35051da177e4SLinus Torvalds hci_dev_unlock(hdev); 35061da177e4SLinus Torvalds 35071da177e4SLinus Torvalds if (conn) { 35081da177e4SLinus Torvalds /* Send to upper protocol */ 3509686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 35101da177e4SLinus Torvalds return; 35111da177e4SLinus Torvalds } else { 35121da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 35131da177e4SLinus Torvalds hdev->name, handle); 35141da177e4SLinus Torvalds } 35151da177e4SLinus Torvalds 35161da177e4SLinus Torvalds kfree_skb(skb); 35171da177e4SLinus Torvalds } 35181da177e4SLinus Torvalds 35199238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 35209238f36aSJohan Hedberg { 35219238f36aSJohan Hedberg struct sk_buff *skb; 35229238f36aSJohan Hedberg 35239238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 35249238f36aSJohan Hedberg if (!skb) 35259238f36aSJohan Hedberg return true; 35269238f36aSJohan Hedberg 35279238f36aSJohan Hedberg return bt_cb(skb)->req.start; 35289238f36aSJohan Hedberg } 35299238f36aSJohan Hedberg 353042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 353142c6b129SJohan Hedberg { 353242c6b129SJohan Hedberg struct hci_command_hdr *sent; 353342c6b129SJohan Hedberg struct sk_buff *skb; 353442c6b129SJohan Hedberg u16 opcode; 353542c6b129SJohan Hedberg 353642c6b129SJohan Hedberg if (!hdev->sent_cmd) 353742c6b129SJohan Hedberg return; 353842c6b129SJohan Hedberg 353942c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 354042c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 354142c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 354242c6b129SJohan Hedberg return; 354342c6b129SJohan Hedberg 354442c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 354542c6b129SJohan Hedberg if (!skb) 354642c6b129SJohan Hedberg return; 354742c6b129SJohan Hedberg 354842c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 354942c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 355042c6b129SJohan Hedberg } 355142c6b129SJohan Hedberg 35529238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 35539238f36aSJohan Hedberg { 35549238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 35559238f36aSJohan Hedberg struct sk_buff *skb; 35569238f36aSJohan Hedberg unsigned long flags; 35579238f36aSJohan Hedberg 35589238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 35599238f36aSJohan Hedberg 356042c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 356142c6b129SJohan Hedberg * sent we need to do special handling of it. 35629238f36aSJohan Hedberg */ 356342c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 356442c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 356542c6b129SJohan Hedberg * reset complete event during init and any pending 356642c6b129SJohan Hedberg * command will never be completed. In such a case we 356742c6b129SJohan Hedberg * need to resend whatever was the last sent 356842c6b129SJohan Hedberg * command. 356942c6b129SJohan Hedberg */ 357042c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 357142c6b129SJohan Hedberg hci_resend_last(hdev); 357242c6b129SJohan Hedberg 35739238f36aSJohan Hedberg return; 357442c6b129SJohan Hedberg } 35759238f36aSJohan Hedberg 35769238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 35779238f36aSJohan Hedberg * this request the request is not yet complete. 35789238f36aSJohan Hedberg */ 35799238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 35809238f36aSJohan Hedberg return; 35819238f36aSJohan Hedberg 35829238f36aSJohan Hedberg /* If this was the last command in a request the complete 35839238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 35849238f36aSJohan Hedberg * command queue (hdev->cmd_q). 35859238f36aSJohan Hedberg */ 35869238f36aSJohan Hedberg if (hdev->sent_cmd) { 35879238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 358853e21fbcSJohan Hedberg 358953e21fbcSJohan Hedberg if (req_complete) { 359053e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 359153e21fbcSJohan Hedberg * avoid calling the callback more than once if 359253e21fbcSJohan Hedberg * this function gets called again. 359353e21fbcSJohan Hedberg */ 359453e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 359553e21fbcSJohan Hedberg 35969238f36aSJohan Hedberg goto call_complete; 35979238f36aSJohan Hedberg } 359853e21fbcSJohan Hedberg } 35999238f36aSJohan Hedberg 36009238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 36019238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 36029238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 36039238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 36049238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 36059238f36aSJohan Hedberg break; 36069238f36aSJohan Hedberg } 36079238f36aSJohan Hedberg 36089238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 36099238f36aSJohan Hedberg kfree_skb(skb); 36109238f36aSJohan Hedberg } 36119238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 36129238f36aSJohan Hedberg 36139238f36aSJohan Hedberg call_complete: 36149238f36aSJohan Hedberg if (req_complete) 36159238f36aSJohan Hedberg req_complete(hdev, status); 36169238f36aSJohan Hedberg } 36179238f36aSJohan Hedberg 3618b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 36191da177e4SLinus Torvalds { 3620b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 36211da177e4SLinus Torvalds struct sk_buff *skb; 36221da177e4SLinus Torvalds 36231da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 36241da177e4SLinus Torvalds 36251da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 3626cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3627cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3628cd82e61cSMarcel Holtmann 36291da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 36301da177e4SLinus Torvalds /* Send copy to the sockets */ 3631470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 36321da177e4SLinus Torvalds } 36331da177e4SLinus Torvalds 36340736cfa8SMarcel Holtmann if (test_bit(HCI_RAW, &hdev->flags) || 36350736cfa8SMarcel Holtmann test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 36361da177e4SLinus Torvalds kfree_skb(skb); 36371da177e4SLinus Torvalds continue; 36381da177e4SLinus Torvalds } 36391da177e4SLinus Torvalds 36401da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 36411da177e4SLinus Torvalds /* Don't process data packets in this states. */ 36420d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 36431da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 36441da177e4SLinus Torvalds case HCI_SCODATA_PKT: 36451da177e4SLinus Torvalds kfree_skb(skb); 36461da177e4SLinus Torvalds continue; 36473ff50b79SStephen Hemminger } 36481da177e4SLinus Torvalds } 36491da177e4SLinus Torvalds 36501da177e4SLinus Torvalds /* Process frame */ 36510d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 36521da177e4SLinus Torvalds case HCI_EVENT_PKT: 3653b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 36541da177e4SLinus Torvalds hci_event_packet(hdev, skb); 36551da177e4SLinus Torvalds break; 36561da177e4SLinus Torvalds 36571da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 36581da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 36591da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 36601da177e4SLinus Torvalds break; 36611da177e4SLinus Torvalds 36621da177e4SLinus Torvalds case HCI_SCODATA_PKT: 36631da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 36641da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 36651da177e4SLinus Torvalds break; 36661da177e4SLinus Torvalds 36671da177e4SLinus Torvalds default: 36681da177e4SLinus Torvalds kfree_skb(skb); 36691da177e4SLinus Torvalds break; 36701da177e4SLinus Torvalds } 36711da177e4SLinus Torvalds } 36721da177e4SLinus Torvalds } 36731da177e4SLinus Torvalds 3674c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 36751da177e4SLinus Torvalds { 3676c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 36771da177e4SLinus Torvalds struct sk_buff *skb; 36781da177e4SLinus Torvalds 36792104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 36802104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 36811da177e4SLinus Torvalds 36821da177e4SLinus Torvalds /* Send queued commands */ 36835a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 36845a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 36855a08ecceSAndrei Emeltchenko if (!skb) 36865a08ecceSAndrei Emeltchenko return; 36875a08ecceSAndrei Emeltchenko 36881da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 36891da177e4SLinus Torvalds 3690a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 369170f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 36921da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 369357d17d70SMarcel Holtmann hci_send_frame(hdev, skb); 36947bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 36957bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 36967bdb8a5cSSzymon Janc else 36976bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 36985f246e89SAndrei Emeltchenko jiffies + HCI_CMD_TIMEOUT); 36991da177e4SLinus Torvalds } else { 37001da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 3701c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 37021da177e4SLinus Torvalds } 37031da177e4SLinus Torvalds } 37041da177e4SLinus Torvalds } 3705