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 3106bcbc489SAndrei Emeltchenko /* Read Local AMP Info */ 31142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 312e71dfabaSAndrei Emeltchenko 313e71dfabaSAndrei Emeltchenko /* Read Data Blk size */ 31442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); 315e61ef499SAndrei Emeltchenko } 316e61ef499SAndrei Emeltchenko 31742c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt) 318e61ef499SAndrei Emeltchenko { 31942c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 320e61ef499SAndrei Emeltchenko 321e61ef499SAndrei Emeltchenko BT_DBG("%s %ld", hdev->name, opt); 322e61ef499SAndrei Emeltchenko 32311778716SAndrei Emeltchenko /* Reset */ 32411778716SAndrei Emeltchenko if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) 32542c6b129SJohan Hedberg hci_reset_req(req, 0); 32611778716SAndrei Emeltchenko 327e61ef499SAndrei Emeltchenko switch (hdev->dev_type) { 328e61ef499SAndrei Emeltchenko case HCI_BREDR: 32942c6b129SJohan Hedberg bredr_init(req); 330e61ef499SAndrei Emeltchenko break; 331e61ef499SAndrei Emeltchenko 332e61ef499SAndrei Emeltchenko case HCI_AMP: 33342c6b129SJohan Hedberg amp_init(req); 334e61ef499SAndrei Emeltchenko break; 335e61ef499SAndrei Emeltchenko 336e61ef499SAndrei Emeltchenko default: 337e61ef499SAndrei Emeltchenko BT_ERR("Unknown device type %d", hdev->dev_type); 338e61ef499SAndrei Emeltchenko break; 339e61ef499SAndrei Emeltchenko } 340e61ef499SAndrei Emeltchenko } 341e61ef499SAndrei Emeltchenko 34242c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req) 3432177bab5SJohan Hedberg { 3442177bab5SJohan Hedberg __le16 param; 3452177bab5SJohan Hedberg __u8 flt_type; 3462177bab5SJohan Hedberg 3472177bab5SJohan Hedberg /* Read Buffer Size (ACL mtu, max pkt, etc.) */ 34842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL); 3492177bab5SJohan Hedberg 3502177bab5SJohan Hedberg /* Read Class of Device */ 35142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); 3522177bab5SJohan Hedberg 3532177bab5SJohan Hedberg /* Read Local Name */ 35442c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL); 3552177bab5SJohan Hedberg 3562177bab5SJohan Hedberg /* Read Voice Setting */ 35742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL); 3582177bab5SJohan Hedberg 3592177bab5SJohan Hedberg /* Clear Event Filters */ 3602177bab5SJohan Hedberg flt_type = HCI_FLT_CLEAR_ALL; 36142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); 3622177bab5SJohan Hedberg 3632177bab5SJohan Hedberg /* Connection accept timeout ~20 secs */ 3642177bab5SJohan Hedberg param = __constant_cpu_to_le16(0x7d00); 36542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); 3662177bab5SJohan Hedberg 367f332ec66SJohan Hedberg /* Read page scan parameters */ 368f332ec66SJohan Hedberg if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) { 369f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 370f332ec66SJohan Hedberg hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL); 371f332ec66SJohan Hedberg } 3722177bab5SJohan Hedberg } 3732177bab5SJohan Hedberg 37442c6b129SJohan Hedberg static void le_setup(struct hci_request *req) 3752177bab5SJohan Hedberg { 376c73eee91SJohan Hedberg struct hci_dev *hdev = req->hdev; 377c73eee91SJohan Hedberg 3782177bab5SJohan Hedberg /* Read LE Buffer Size */ 37942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 3802177bab5SJohan Hedberg 3812177bab5SJohan Hedberg /* Read LE Local Supported Features */ 38242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); 3832177bab5SJohan Hedberg 3842177bab5SJohan Hedberg /* Read LE Advertising Channel TX Power */ 38542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 3862177bab5SJohan Hedberg 3872177bab5SJohan Hedberg /* Read LE White List Size */ 38842c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); 3892177bab5SJohan Hedberg 3902177bab5SJohan Hedberg /* Read LE Supported States */ 39142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); 392c73eee91SJohan Hedberg 393c73eee91SJohan Hedberg /* LE-only controllers have LE implicitly enabled */ 394c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 395c73eee91SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 3962177bab5SJohan Hedberg } 3972177bab5SJohan Hedberg 3982177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 3992177bab5SJohan Hedberg { 4002177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 4012177bab5SJohan Hedberg return 0x02; 4022177bab5SJohan Hedberg 4032177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 4042177bab5SJohan Hedberg return 0x01; 4052177bab5SJohan Hedberg 4062177bab5SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 4072177bab5SJohan Hedberg hdev->lmp_subver == 0x0757) 4082177bab5SJohan Hedberg return 0x01; 4092177bab5SJohan Hedberg 4102177bab5SJohan Hedberg if (hdev->manufacturer == 15) { 4112177bab5SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 4122177bab5SJohan Hedberg return 0x01; 4132177bab5SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 4142177bab5SJohan Hedberg return 0x01; 4152177bab5SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 4162177bab5SJohan Hedberg return 0x01; 4172177bab5SJohan Hedberg } 4182177bab5SJohan Hedberg 4192177bab5SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 4202177bab5SJohan Hedberg hdev->lmp_subver == 0x1805) 4212177bab5SJohan Hedberg return 0x01; 4222177bab5SJohan Hedberg 4232177bab5SJohan Hedberg return 0x00; 4242177bab5SJohan Hedberg } 4252177bab5SJohan Hedberg 42642c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req) 4272177bab5SJohan Hedberg { 4282177bab5SJohan Hedberg u8 mode; 4292177bab5SJohan Hedberg 43042c6b129SJohan Hedberg mode = hci_get_inquiry_mode(req->hdev); 4312177bab5SJohan Hedberg 43242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 4332177bab5SJohan Hedberg } 4342177bab5SJohan Hedberg 43542c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req) 4362177bab5SJohan Hedberg { 43742c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 43842c6b129SJohan Hedberg 4392177bab5SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 4402177bab5SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 4412177bab5SJohan Hedberg * command otherwise. 4422177bab5SJohan Hedberg */ 4432177bab5SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 4442177bab5SJohan Hedberg 4452177bab5SJohan Hedberg /* CSR 1.1 dongles does not accept any bitfield so don't try to set 4462177bab5SJohan Hedberg * any event mask for pre 1.2 devices. 4472177bab5SJohan Hedberg */ 4482177bab5SJohan Hedberg if (hdev->hci_ver < BLUETOOTH_VER_1_2) 4492177bab5SJohan Hedberg return; 4502177bab5SJohan Hedberg 4512177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) { 4522177bab5SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 4532177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 4542177bab5SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 4552177bab5SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 4562177bab5SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 457c7882cbdSMarcel Holtmann } else { 458c7882cbdSMarcel Holtmann /* Use a different default for LE-only devices */ 459c7882cbdSMarcel Holtmann memset(events, 0, sizeof(events)); 460c7882cbdSMarcel Holtmann events[0] |= 0x10; /* Disconnection Complete */ 461c7882cbdSMarcel Holtmann events[0] |= 0x80; /* Encryption Change */ 462c7882cbdSMarcel Holtmann events[1] |= 0x08; /* Read Remote Version Information Complete */ 463c7882cbdSMarcel Holtmann events[1] |= 0x20; /* Command Complete */ 464c7882cbdSMarcel Holtmann events[1] |= 0x40; /* Command Status */ 465c7882cbdSMarcel Holtmann events[1] |= 0x80; /* Hardware Error */ 466c7882cbdSMarcel Holtmann events[2] |= 0x04; /* Number of Completed Packets */ 467c7882cbdSMarcel Holtmann events[3] |= 0x02; /* Data Buffer Overflow */ 468c7882cbdSMarcel Holtmann events[5] |= 0x80; /* Encryption Key Refresh Complete */ 4692177bab5SJohan Hedberg } 4702177bab5SJohan Hedberg 4712177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 4722177bab5SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 4732177bab5SJohan Hedberg 4742177bab5SJohan Hedberg if (lmp_sniffsubr_capable(hdev)) 4752177bab5SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 4762177bab5SJohan Hedberg 4772177bab5SJohan Hedberg if (lmp_pause_enc_capable(hdev)) 4782177bab5SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 4792177bab5SJohan Hedberg 4802177bab5SJohan Hedberg if (lmp_ext_inq_capable(hdev)) 4812177bab5SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 4822177bab5SJohan Hedberg 4832177bab5SJohan Hedberg if (lmp_no_flush_capable(hdev)) 4842177bab5SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 4852177bab5SJohan Hedberg 4862177bab5SJohan Hedberg if (lmp_lsto_capable(hdev)) 4872177bab5SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 4882177bab5SJohan Hedberg 4892177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 4902177bab5SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 4912177bab5SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 4922177bab5SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 4932177bab5SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 4942177bab5SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 4952177bab5SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 4962177bab5SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 4972177bab5SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 4982177bab5SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 4992177bab5SJohan Hedberg * Features Notification 5002177bab5SJohan Hedberg */ 5012177bab5SJohan Hedberg } 5022177bab5SJohan Hedberg 5032177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 5042177bab5SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 5052177bab5SJohan Hedberg 50642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 5072177bab5SJohan Hedberg 5082177bab5SJohan Hedberg if (lmp_le_capable(hdev)) { 5092177bab5SJohan Hedberg memset(events, 0, sizeof(events)); 5102177bab5SJohan Hedberg events[0] = 0x1f; 51142c6b129SJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, 5122177bab5SJohan Hedberg sizeof(events), events); 5132177bab5SJohan Hedberg } 5142177bab5SJohan Hedberg } 5152177bab5SJohan Hedberg 51642c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt) 5172177bab5SJohan Hedberg { 51842c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 51942c6b129SJohan Hedberg 5202177bab5SJohan Hedberg if (lmp_bredr_capable(hdev)) 52142c6b129SJohan Hedberg bredr_setup(req); 5222177bab5SJohan Hedberg 5232177bab5SJohan Hedberg if (lmp_le_capable(hdev)) 52442c6b129SJohan Hedberg le_setup(req); 5252177bab5SJohan Hedberg 52642c6b129SJohan Hedberg hci_setup_event_mask(req); 5272177bab5SJohan Hedberg 5283f8e2d75SJohan Hedberg /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read 5293f8e2d75SJohan Hedberg * local supported commands HCI command. 5303f8e2d75SJohan Hedberg */ 5313f8e2d75SJohan Hedberg if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) 53242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 5332177bab5SJohan Hedberg 5342177bab5SJohan Hedberg if (lmp_ssp_capable(hdev)) { 5352177bab5SJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 5362177bab5SJohan Hedberg u8 mode = 0x01; 53742c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SSP_MODE, 5382177bab5SJohan Hedberg sizeof(mode), &mode); 5392177bab5SJohan Hedberg } else { 5402177bab5SJohan Hedberg struct hci_cp_write_eir cp; 5412177bab5SJohan Hedberg 5422177bab5SJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 5432177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 5442177bab5SJohan Hedberg 54542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 5462177bab5SJohan Hedberg } 5472177bab5SJohan Hedberg } 5482177bab5SJohan Hedberg 5492177bab5SJohan Hedberg if (lmp_inq_rssi_capable(hdev)) 55042c6b129SJohan Hedberg hci_setup_inquiry_mode(req); 5512177bab5SJohan Hedberg 5522177bab5SJohan Hedberg if (lmp_inq_tx_pwr_capable(hdev)) 55342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 5542177bab5SJohan Hedberg 5552177bab5SJohan Hedberg if (lmp_ext_feat_capable(hdev)) { 5562177bab5SJohan Hedberg struct hci_cp_read_local_ext_features cp; 5572177bab5SJohan Hedberg 5582177bab5SJohan Hedberg cp.page = 0x01; 55942c6b129SJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 56042c6b129SJohan Hedberg sizeof(cp), &cp); 5612177bab5SJohan Hedberg } 5622177bab5SJohan Hedberg 5632177bab5SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 5642177bab5SJohan Hedberg u8 enable = 1; 56542c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 5662177bab5SJohan Hedberg &enable); 5672177bab5SJohan Hedberg } 5682177bab5SJohan Hedberg } 5692177bab5SJohan Hedberg 57042c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req) 5712177bab5SJohan Hedberg { 57242c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 5732177bab5SJohan Hedberg struct hci_cp_write_def_link_policy cp; 5742177bab5SJohan Hedberg u16 link_policy = 0; 5752177bab5SJohan Hedberg 5762177bab5SJohan Hedberg if (lmp_rswitch_capable(hdev)) 5772177bab5SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 5782177bab5SJohan Hedberg if (lmp_hold_capable(hdev)) 5792177bab5SJohan Hedberg link_policy |= HCI_LP_HOLD; 5802177bab5SJohan Hedberg if (lmp_sniff_capable(hdev)) 5812177bab5SJohan Hedberg link_policy |= HCI_LP_SNIFF; 5822177bab5SJohan Hedberg if (lmp_park_capable(hdev)) 5832177bab5SJohan Hedberg link_policy |= HCI_LP_PARK; 5842177bab5SJohan Hedberg 5852177bab5SJohan Hedberg cp.policy = cpu_to_le16(link_policy); 58642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); 5872177bab5SJohan Hedberg } 5882177bab5SJohan Hedberg 58942c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req) 5902177bab5SJohan Hedberg { 59142c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 5922177bab5SJohan Hedberg struct hci_cp_write_le_host_supported cp; 5932177bab5SJohan Hedberg 594c73eee91SJohan Hedberg /* LE-only devices do not support explicit enablement */ 595c73eee91SJohan Hedberg if (!lmp_bredr_capable(hdev)) 596c73eee91SJohan Hedberg return; 597c73eee91SJohan Hedberg 5982177bab5SJohan Hedberg memset(&cp, 0, sizeof(cp)); 5992177bab5SJohan Hedberg 6002177bab5SJohan Hedberg if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 6012177bab5SJohan Hedberg cp.le = 0x01; 6022177bab5SJohan Hedberg cp.simul = lmp_le_br_capable(hdev); 6032177bab5SJohan Hedberg } 6042177bab5SJohan Hedberg 6052177bab5SJohan Hedberg if (cp.le != lmp_host_le_capable(hdev)) 60642c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 6072177bab5SJohan Hedberg &cp); 6082177bab5SJohan Hedberg } 6092177bab5SJohan Hedberg 61042c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt) 6112177bab5SJohan Hedberg { 61242c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 613d2c5d77fSJohan Hedberg u8 p; 61442c6b129SJohan Hedberg 615b8f4e068SGustavo Padovan /* Some Broadcom based Bluetooth controllers do not support the 616b8f4e068SGustavo Padovan * Delete Stored Link Key command. They are clearly indicating its 617b8f4e068SGustavo Padovan * absence in the bit mask of supported commands. 618b8f4e068SGustavo Padovan * 619b8f4e068SGustavo Padovan * Check the supported commands and only if the the command is marked 620b8f4e068SGustavo Padovan * as supported send it. If not supported assume that the controller 621b8f4e068SGustavo Padovan * does not have actual support for stored link keys which makes this 622b8f4e068SGustavo Padovan * command redundant anyway. 623b8f4e068SGustavo Padovan */ 62459f45d57SJohan Hedberg if (hdev->commands[6] & 0x80) { 62559f45d57SJohan Hedberg struct hci_cp_delete_stored_link_key cp; 62659f45d57SJohan Hedberg 62759f45d57SJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 62859f45d57SJohan Hedberg cp.delete_all = 0x01; 62959f45d57SJohan Hedberg hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, 63059f45d57SJohan Hedberg sizeof(cp), &cp); 63159f45d57SJohan Hedberg } 63259f45d57SJohan Hedberg 6332177bab5SJohan Hedberg if (hdev->commands[5] & 0x10) 63442c6b129SJohan Hedberg hci_setup_link_policy(req); 6352177bab5SJohan Hedberg 63604b4edcbSJohan Hedberg if (lmp_le_capable(hdev)) { 63742c6b129SJohan Hedberg hci_set_le_support(req); 63804b4edcbSJohan Hedberg hci_update_ad(req); 63904b4edcbSJohan Hedberg } 640d2c5d77fSJohan Hedberg 641d2c5d77fSJohan Hedberg /* Read features beyond page 1 if available */ 642d2c5d77fSJohan Hedberg for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { 643d2c5d77fSJohan Hedberg struct hci_cp_read_local_ext_features cp; 644d2c5d77fSJohan Hedberg 645d2c5d77fSJohan Hedberg cp.page = p; 646d2c5d77fSJohan Hedberg hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, 647d2c5d77fSJohan Hedberg sizeof(cp), &cp); 648d2c5d77fSJohan Hedberg } 6492177bab5SJohan Hedberg } 6502177bab5SJohan Hedberg 6512177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev) 6522177bab5SJohan Hedberg { 6532177bab5SJohan Hedberg int err; 6542177bab5SJohan Hedberg 6552177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); 6562177bab5SJohan Hedberg if (err < 0) 6572177bab5SJohan Hedberg return err; 6582177bab5SJohan Hedberg 6592177bab5SJohan Hedberg /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 6602177bab5SJohan Hedberg * BR/EDR/LE type controllers. AMP controllers only need the 6612177bab5SJohan Hedberg * first stage init. 6622177bab5SJohan Hedberg */ 6632177bab5SJohan Hedberg if (hdev->dev_type != HCI_BREDR) 6642177bab5SJohan Hedberg return 0; 6652177bab5SJohan Hedberg 6662177bab5SJohan Hedberg err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); 6672177bab5SJohan Hedberg if (err < 0) 6682177bab5SJohan Hedberg return err; 6692177bab5SJohan Hedberg 6702177bab5SJohan Hedberg return __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 6712177bab5SJohan Hedberg } 6722177bab5SJohan Hedberg 67342c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt) 6741da177e4SLinus Torvalds { 6751da177e4SLinus Torvalds __u8 scan = opt; 6761da177e4SLinus Torvalds 67742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, scan); 6781da177e4SLinus Torvalds 6791da177e4SLinus Torvalds /* Inquiry and Page scans */ 68042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 6811da177e4SLinus Torvalds } 6821da177e4SLinus Torvalds 68342c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt) 6841da177e4SLinus Torvalds { 6851da177e4SLinus Torvalds __u8 auth = opt; 6861da177e4SLinus Torvalds 68742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, auth); 6881da177e4SLinus Torvalds 6891da177e4SLinus Torvalds /* Authentication */ 69042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth); 6911da177e4SLinus Torvalds } 6921da177e4SLinus Torvalds 69342c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt) 6941da177e4SLinus Torvalds { 6951da177e4SLinus Torvalds __u8 encrypt = opt; 6961da177e4SLinus Torvalds 69742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, encrypt); 6981da177e4SLinus Torvalds 699e4e8e37cSMarcel Holtmann /* Encryption */ 70042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 7011da177e4SLinus Torvalds } 7021da177e4SLinus Torvalds 70342c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt) 704e4e8e37cSMarcel Holtmann { 705e4e8e37cSMarcel Holtmann __le16 policy = cpu_to_le16(opt); 706e4e8e37cSMarcel Holtmann 70742c6b129SJohan Hedberg BT_DBG("%s %x", req->hdev->name, policy); 708e4e8e37cSMarcel Holtmann 709e4e8e37cSMarcel Holtmann /* Default link policy */ 71042c6b129SJohan Hedberg hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); 711e4e8e37cSMarcel Holtmann } 712e4e8e37cSMarcel Holtmann 7131da177e4SLinus Torvalds /* Get HCI device by index. 7141da177e4SLinus Torvalds * Device is held on return. */ 7151da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index) 7161da177e4SLinus Torvalds { 7178035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d; 7181da177e4SLinus Torvalds 7191da177e4SLinus Torvalds BT_DBG("%d", index); 7201da177e4SLinus Torvalds 7211da177e4SLinus Torvalds if (index < 0) 7221da177e4SLinus Torvalds return NULL; 7231da177e4SLinus Torvalds 7241da177e4SLinus Torvalds read_lock(&hci_dev_list_lock); 7258035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) { 7261da177e4SLinus Torvalds if (d->id == index) { 7271da177e4SLinus Torvalds hdev = hci_dev_hold(d); 7281da177e4SLinus Torvalds break; 7291da177e4SLinus Torvalds } 7301da177e4SLinus Torvalds } 7311da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock); 7321da177e4SLinus Torvalds return hdev; 7331da177e4SLinus Torvalds } 7341da177e4SLinus Torvalds 7351da177e4SLinus Torvalds /* ---- Inquiry support ---- */ 736ff9ef578SJohan Hedberg 73730dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev) 73830dc78e1SJohan Hedberg { 73930dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 74030dc78e1SJohan Hedberg 7416fbe195dSAndre Guedes switch (discov->state) { 742343f935bSAndre Guedes case DISCOVERY_FINDING: 7436fbe195dSAndre Guedes case DISCOVERY_RESOLVING: 74430dc78e1SJohan Hedberg return true; 74530dc78e1SJohan Hedberg 7466fbe195dSAndre Guedes default: 74730dc78e1SJohan Hedberg return false; 74830dc78e1SJohan Hedberg } 7496fbe195dSAndre Guedes } 75030dc78e1SJohan Hedberg 751ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state) 752ff9ef578SJohan Hedberg { 753ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state); 754ff9ef578SJohan Hedberg 755ff9ef578SJohan Hedberg if (hdev->discovery.state == state) 756ff9ef578SJohan Hedberg return; 757ff9ef578SJohan Hedberg 758ff9ef578SJohan Hedberg switch (state) { 759ff9ef578SJohan Hedberg case DISCOVERY_STOPPED: 7607b99b659SAndre Guedes if (hdev->discovery.state != DISCOVERY_STARTING) 761ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0); 762ff9ef578SJohan Hedberg break; 763ff9ef578SJohan Hedberg case DISCOVERY_STARTING: 764ff9ef578SJohan Hedberg break; 765343f935bSAndre Guedes case DISCOVERY_FINDING: 766ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1); 767ff9ef578SJohan Hedberg break; 76830dc78e1SJohan Hedberg case DISCOVERY_RESOLVING: 76930dc78e1SJohan Hedberg break; 770ff9ef578SJohan Hedberg case DISCOVERY_STOPPING: 771ff9ef578SJohan Hedberg break; 772ff9ef578SJohan Hedberg } 773ff9ef578SJohan Hedberg 774ff9ef578SJohan Hedberg hdev->discovery.state = state; 775ff9ef578SJohan Hedberg } 776ff9ef578SJohan Hedberg 7771f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev) 7781da177e4SLinus Torvalds { 77930883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 780b57c1a56SJohan Hedberg struct inquiry_entry *p, *n; 7811da177e4SLinus Torvalds 782561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) { 783561aafbcSJohan Hedberg list_del(&p->all); 784b57c1a56SJohan Hedberg kfree(p); 7851da177e4SLinus Torvalds } 786561aafbcSJohan Hedberg 787561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown); 788561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve); 7891da177e4SLinus Torvalds } 7901da177e4SLinus Torvalds 791a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 792a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr) 7931da177e4SLinus Torvalds { 79430883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 7951da177e4SLinus Torvalds struct inquiry_entry *e; 7961da177e4SLinus Torvalds 7976ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 7981da177e4SLinus Torvalds 799561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 8001da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr)) 8011da177e4SLinus Torvalds return e; 8021da177e4SLinus Torvalds } 8031da177e4SLinus Torvalds 804b57c1a56SJohan Hedberg return NULL; 805b57c1a56SJohan Hedberg } 806b57c1a56SJohan Hedberg 807561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 808561aafbcSJohan Hedberg bdaddr_t *bdaddr) 809561aafbcSJohan Hedberg { 81030883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 811561aafbcSJohan Hedberg struct inquiry_entry *e; 812561aafbcSJohan Hedberg 8136ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr); 814561aafbcSJohan Hedberg 815561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) { 816561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 817561aafbcSJohan Hedberg return e; 818561aafbcSJohan Hedberg } 819561aafbcSJohan Hedberg 820561aafbcSJohan Hedberg return NULL; 821561aafbcSJohan Hedberg } 822561aafbcSJohan Hedberg 82330dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 82430dc78e1SJohan Hedberg bdaddr_t *bdaddr, 82530dc78e1SJohan Hedberg int state) 82630dc78e1SJohan Hedberg { 82730dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 82830dc78e1SJohan Hedberg struct inquiry_entry *e; 82930dc78e1SJohan Hedberg 8306ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); 83130dc78e1SJohan Hedberg 83230dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) { 83330dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) 83430dc78e1SJohan Hedberg return e; 83530dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr)) 83630dc78e1SJohan Hedberg return e; 83730dc78e1SJohan Hedberg } 83830dc78e1SJohan Hedberg 83930dc78e1SJohan Hedberg return NULL; 84030dc78e1SJohan Hedberg } 84130dc78e1SJohan Hedberg 842a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 843a3d4e20aSJohan Hedberg struct inquiry_entry *ie) 844a3d4e20aSJohan Hedberg { 845a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery; 846a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve; 847a3d4e20aSJohan Hedberg struct inquiry_entry *p; 848a3d4e20aSJohan Hedberg 849a3d4e20aSJohan Hedberg list_del(&ie->list); 850a3d4e20aSJohan Hedberg 851a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) { 852a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING && 853a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi)) 854a3d4e20aSJohan Hedberg break; 855a3d4e20aSJohan Hedberg pos = &p->list; 856a3d4e20aSJohan Hedberg } 857a3d4e20aSJohan Hedberg 858a3d4e20aSJohan Hedberg list_add(&ie->list, pos); 859a3d4e20aSJohan Hedberg } 860a3d4e20aSJohan Hedberg 8613175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 862388fc8faSJohan Hedberg bool name_known, bool *ssp) 8631da177e4SLinus Torvalds { 86430883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 86570f23020SAndrei Emeltchenko struct inquiry_entry *ie; 8661da177e4SLinus Torvalds 8676ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 8681da177e4SLinus Torvalds 8692b2fec4dSSzymon Janc hci_remove_remote_oob_data(hdev, &data->bdaddr); 8702b2fec4dSSzymon Janc 871388fc8faSJohan Hedberg if (ssp) 872388fc8faSJohan Hedberg *ssp = data->ssp_mode; 873388fc8faSJohan Hedberg 87470f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr); 875a3d4e20aSJohan Hedberg if (ie) { 876388fc8faSJohan Hedberg if (ie->data.ssp_mode && ssp) 877388fc8faSJohan Hedberg *ssp = true; 878388fc8faSJohan Hedberg 879a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED && 880a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) { 881a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi; 882a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie); 883a3d4e20aSJohan Hedberg } 884a3d4e20aSJohan Hedberg 885561aafbcSJohan Hedberg goto update; 886a3d4e20aSJohan Hedberg } 887561aafbcSJohan Hedberg 8881da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */ 88970f23020SAndrei Emeltchenko ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC); 89070f23020SAndrei Emeltchenko if (!ie) 8913175405bSJohan Hedberg return false; 89270f23020SAndrei Emeltchenko 893561aafbcSJohan Hedberg list_add(&ie->all, &cache->all); 894561aafbcSJohan Hedberg 895561aafbcSJohan Hedberg if (name_known) { 896561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 897561aafbcSJohan Hedberg } else { 898561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN; 899561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown); 900561aafbcSJohan Hedberg } 901561aafbcSJohan Hedberg 902561aafbcSJohan Hedberg update: 903561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN && 904561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) { 905561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN; 906561aafbcSJohan Hedberg list_del(&ie->list); 9071da177e4SLinus Torvalds } 9081da177e4SLinus Torvalds 90970f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data)); 91070f23020SAndrei Emeltchenko ie->timestamp = jiffies; 9111da177e4SLinus Torvalds cache->timestamp = jiffies; 9123175405bSJohan Hedberg 9133175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN) 9143175405bSJohan Hedberg return false; 9153175405bSJohan Hedberg 9163175405bSJohan Hedberg return true; 9171da177e4SLinus Torvalds } 9181da177e4SLinus Torvalds 9191da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) 9201da177e4SLinus Torvalds { 92130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery; 9221da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf; 9231da177e4SLinus Torvalds struct inquiry_entry *e; 9241da177e4SLinus Torvalds int copied = 0; 9251da177e4SLinus Torvalds 926561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) { 9271da177e4SLinus Torvalds struct inquiry_data *data = &e->data; 928b57c1a56SJohan Hedberg 929b57c1a56SJohan Hedberg if (copied >= num) 930b57c1a56SJohan Hedberg break; 931b57c1a56SJohan Hedberg 9321da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr); 9331da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode; 9341da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode; 9351da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode; 9361da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3); 9371da177e4SLinus Torvalds info->clock_offset = data->clock_offset; 938b57c1a56SJohan Hedberg 9391da177e4SLinus Torvalds info++; 940b57c1a56SJohan Hedberg copied++; 9411da177e4SLinus Torvalds } 9421da177e4SLinus Torvalds 9431da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied); 9441da177e4SLinus Torvalds return copied; 9451da177e4SLinus Torvalds } 9461da177e4SLinus Torvalds 94742c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt) 9481da177e4SLinus Torvalds { 9491da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt; 95042c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev; 9511da177e4SLinus Torvalds struct hci_cp_inquiry cp; 9521da177e4SLinus Torvalds 9531da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 9541da177e4SLinus Torvalds 9551da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags)) 9561da177e4SLinus Torvalds return; 9571da177e4SLinus Torvalds 9581da177e4SLinus Torvalds /* Start Inquiry */ 9591da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3); 9601da177e4SLinus Torvalds cp.length = ir->length; 9611da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp; 96242c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 9631da177e4SLinus Torvalds } 9641da177e4SLinus Torvalds 9653e13fa1eSAndre Guedes static int wait_inquiry(void *word) 9663e13fa1eSAndre Guedes { 9673e13fa1eSAndre Guedes schedule(); 9683e13fa1eSAndre Guedes return signal_pending(current); 9693e13fa1eSAndre Guedes } 9703e13fa1eSAndre Guedes 9711da177e4SLinus Torvalds int hci_inquiry(void __user *arg) 9721da177e4SLinus Torvalds { 9731da177e4SLinus Torvalds __u8 __user *ptr = arg; 9741da177e4SLinus Torvalds struct hci_inquiry_req ir; 9751da177e4SLinus Torvalds struct hci_dev *hdev; 9761da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp; 9771da177e4SLinus Torvalds long timeo; 9781da177e4SLinus Torvalds __u8 *buf; 9791da177e4SLinus Torvalds 9801da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir))) 9811da177e4SLinus Torvalds return -EFAULT; 9821da177e4SLinus Torvalds 9835a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id); 9845a08ecceSAndrei Emeltchenko if (!hdev) 9851da177e4SLinus Torvalds return -ENODEV; 9861da177e4SLinus Torvalds 9870736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 9880736cfa8SMarcel Holtmann err = -EBUSY; 9890736cfa8SMarcel Holtmann goto done; 9900736cfa8SMarcel Holtmann } 9910736cfa8SMarcel Holtmann 99209fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 9931da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 994a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 9951f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 9961da177e4SLinus Torvalds do_inquiry = 1; 9971da177e4SLinus Torvalds } 99809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 9991da177e4SLinus Torvalds 100004837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000); 100170f23020SAndrei Emeltchenko 100270f23020SAndrei Emeltchenko if (do_inquiry) { 100301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir, 100401178cd4SJohan Hedberg timeo); 100570f23020SAndrei Emeltchenko if (err < 0) 10061da177e4SLinus Torvalds goto done; 10073e13fa1eSAndre Guedes 10083e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is 10093e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR. 10103e13fa1eSAndre Guedes */ 10113e13fa1eSAndre Guedes if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, 10123e13fa1eSAndre Guedes TASK_INTERRUPTIBLE)) 10133e13fa1eSAndre Guedes return -EINTR; 101470f23020SAndrei Emeltchenko } 10151da177e4SLinus Torvalds 10168fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with 10178fc9ced3SGustavo Padovan * 255 entries 10188fc9ced3SGustavo Padovan */ 10191da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; 10201da177e4SLinus Torvalds 10211da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then 10221da177e4SLinus Torvalds * copy it to the user space. 10231da177e4SLinus Torvalds */ 102470f23020SAndrei Emeltchenko buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); 102570f23020SAndrei Emeltchenko if (!buf) { 10261da177e4SLinus Torvalds err = -ENOMEM; 10271da177e4SLinus Torvalds goto done; 10281da177e4SLinus Torvalds } 10291da177e4SLinus Torvalds 103009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 10311da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); 103209fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 10331da177e4SLinus Torvalds 10341da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp); 10351da177e4SLinus Torvalds 10361da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) { 10371da177e4SLinus Torvalds ptr += sizeof(ir); 10381da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * 10391da177e4SLinus Torvalds ir.num_rsp)) 10401da177e4SLinus Torvalds err = -EFAULT; 10411da177e4SLinus Torvalds } else 10421da177e4SLinus Torvalds err = -EFAULT; 10431da177e4SLinus Torvalds 10441da177e4SLinus Torvalds kfree(buf); 10451da177e4SLinus Torvalds 10461da177e4SLinus Torvalds done: 10471da177e4SLinus Torvalds hci_dev_put(hdev); 10481da177e4SLinus Torvalds return err; 10491da177e4SLinus Torvalds } 10501da177e4SLinus Torvalds 10513f0f524bSJohan Hedberg static u8 create_ad(struct hci_dev *hdev, u8 *ptr) 10523f0f524bSJohan Hedberg { 10533f0f524bSJohan Hedberg u8 ad_len = 0, flags = 0; 10543f0f524bSJohan Hedberg size_t name_len; 10553f0f524bSJohan Hedberg 10563f0f524bSJohan Hedberg if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) 10573f0f524bSJohan Hedberg flags |= LE_AD_GENERAL; 10583f0f524bSJohan Hedberg 10593f0f524bSJohan Hedberg if (!lmp_bredr_capable(hdev)) 10603f0f524bSJohan Hedberg flags |= LE_AD_NO_BREDR; 10613f0f524bSJohan Hedberg 10623f0f524bSJohan Hedberg if (lmp_le_br_capable(hdev)) 10633f0f524bSJohan Hedberg flags |= LE_AD_SIM_LE_BREDR_CTRL; 10643f0f524bSJohan Hedberg 10653f0f524bSJohan Hedberg if (lmp_host_le_br_capable(hdev)) 10663f0f524bSJohan Hedberg flags |= LE_AD_SIM_LE_BREDR_HOST; 10673f0f524bSJohan Hedberg 10683f0f524bSJohan Hedberg if (flags) { 10693f0f524bSJohan Hedberg BT_DBG("adv flags 0x%02x", flags); 10703f0f524bSJohan Hedberg 10713f0f524bSJohan Hedberg ptr[0] = 2; 10723f0f524bSJohan Hedberg ptr[1] = EIR_FLAGS; 10733f0f524bSJohan Hedberg ptr[2] = flags; 10743f0f524bSJohan Hedberg 10753f0f524bSJohan Hedberg ad_len += 3; 10763f0f524bSJohan Hedberg ptr += 3; 10773f0f524bSJohan Hedberg } 10783f0f524bSJohan Hedberg 10793f0f524bSJohan Hedberg if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) { 10803f0f524bSJohan Hedberg ptr[0] = 2; 10813f0f524bSJohan Hedberg ptr[1] = EIR_TX_POWER; 10823f0f524bSJohan Hedberg ptr[2] = (u8) hdev->adv_tx_power; 10833f0f524bSJohan Hedberg 10843f0f524bSJohan Hedberg ad_len += 3; 10853f0f524bSJohan Hedberg ptr += 3; 10863f0f524bSJohan Hedberg } 10873f0f524bSJohan Hedberg 10883f0f524bSJohan Hedberg name_len = strlen(hdev->dev_name); 10893f0f524bSJohan Hedberg if (name_len > 0) { 10903f0f524bSJohan Hedberg size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2; 10913f0f524bSJohan Hedberg 10923f0f524bSJohan Hedberg if (name_len > max_len) { 10933f0f524bSJohan Hedberg name_len = max_len; 10943f0f524bSJohan Hedberg ptr[1] = EIR_NAME_SHORT; 10953f0f524bSJohan Hedberg } else 10963f0f524bSJohan Hedberg ptr[1] = EIR_NAME_COMPLETE; 10973f0f524bSJohan Hedberg 10983f0f524bSJohan Hedberg ptr[0] = name_len + 1; 10993f0f524bSJohan Hedberg 11003f0f524bSJohan Hedberg memcpy(ptr + 2, hdev->dev_name, name_len); 11013f0f524bSJohan Hedberg 11023f0f524bSJohan Hedberg ad_len += (name_len + 2); 11033f0f524bSJohan Hedberg ptr += (name_len + 2); 11043f0f524bSJohan Hedberg } 11053f0f524bSJohan Hedberg 11063f0f524bSJohan Hedberg return ad_len; 11073f0f524bSJohan Hedberg } 11083f0f524bSJohan Hedberg 110904b4edcbSJohan Hedberg void hci_update_ad(struct hci_request *req) 11103f0f524bSJohan Hedberg { 111104b4edcbSJohan Hedberg struct hci_dev *hdev = req->hdev; 11123f0f524bSJohan Hedberg struct hci_cp_le_set_adv_data cp; 11133f0f524bSJohan Hedberg u8 len; 11143f0f524bSJohan Hedberg 111504b4edcbSJohan Hedberg if (!lmp_le_capable(hdev)) 111604b4edcbSJohan Hedberg return; 11173f0f524bSJohan Hedberg 11183f0f524bSJohan Hedberg memset(&cp, 0, sizeof(cp)); 11193f0f524bSJohan Hedberg 11203f0f524bSJohan Hedberg len = create_ad(hdev, cp.data); 11213f0f524bSJohan Hedberg 11223f0f524bSJohan Hedberg if (hdev->adv_data_len == len && 112304b4edcbSJohan Hedberg memcmp(cp.data, hdev->adv_data, len) == 0) 112404b4edcbSJohan Hedberg return; 11253f0f524bSJohan Hedberg 11263f0f524bSJohan Hedberg memcpy(hdev->adv_data, cp.data, sizeof(cp.data)); 11273f0f524bSJohan Hedberg hdev->adv_data_len = len; 11283f0f524bSJohan Hedberg 11293f0f524bSJohan Hedberg cp.length = len; 11303f0f524bSJohan Hedberg 113104b4edcbSJohan Hedberg hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp); 11323f0f524bSJohan Hedberg } 11333f0f524bSJohan Hedberg 11341da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */ 11351da177e4SLinus Torvalds 11361da177e4SLinus Torvalds int hci_dev_open(__u16 dev) 11371da177e4SLinus Torvalds { 11381da177e4SLinus Torvalds struct hci_dev *hdev; 11391da177e4SLinus Torvalds int ret = 0; 11401da177e4SLinus Torvalds 11415a08ecceSAndrei Emeltchenko hdev = hci_dev_get(dev); 11425a08ecceSAndrei Emeltchenko if (!hdev) 11431da177e4SLinus Torvalds return -ENODEV; 11441da177e4SLinus Torvalds 11451da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 11461da177e4SLinus Torvalds 11471da177e4SLinus Torvalds hci_req_lock(hdev); 11481da177e4SLinus Torvalds 114994324962SJohan Hovold if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { 115094324962SJohan Hovold ret = -ENODEV; 115194324962SJohan Hovold goto done; 115294324962SJohan Hovold } 115394324962SJohan Hovold 1154611b30f7SMarcel Holtmann if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { 1155611b30f7SMarcel Holtmann ret = -ERFKILL; 1156611b30f7SMarcel Holtmann goto done; 1157611b30f7SMarcel Holtmann } 1158611b30f7SMarcel Holtmann 11591da177e4SLinus Torvalds if (test_bit(HCI_UP, &hdev->flags)) { 11601da177e4SLinus Torvalds ret = -EALREADY; 11611da177e4SLinus Torvalds goto done; 11621da177e4SLinus Torvalds } 11631da177e4SLinus Torvalds 11641da177e4SLinus Torvalds if (hdev->open(hdev)) { 11651da177e4SLinus Torvalds ret = -EIO; 11661da177e4SLinus Torvalds goto done; 11671da177e4SLinus Torvalds } 11681da177e4SLinus Torvalds 11691da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 11701da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 1171f41c70c4SMarcel Holtmann 1172f41c70c4SMarcel Holtmann if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags)) 1173f41c70c4SMarcel Holtmann ret = hdev->setup(hdev); 1174f41c70c4SMarcel Holtmann 1175f41c70c4SMarcel Holtmann if (!ret) { 1176f41c70c4SMarcel Holtmann /* Treat all non BR/EDR controllers as raw devices if 1177f41c70c4SMarcel Holtmann * enable_hs is not set. 1178f41c70c4SMarcel Holtmann */ 1179f41c70c4SMarcel Holtmann if (hdev->dev_type != HCI_BREDR && !enable_hs) 1180f41c70c4SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 1181f41c70c4SMarcel Holtmann 1182f41c70c4SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) 1183f41c70c4SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags); 1184f41c70c4SMarcel Holtmann 11850736cfa8SMarcel Holtmann if (!test_bit(HCI_RAW, &hdev->flags) && 11860736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 11872177bab5SJohan Hedberg ret = __hci_init(hdev); 11881da177e4SLinus Torvalds } 11891da177e4SLinus Torvalds 1190f41c70c4SMarcel Holtmann clear_bit(HCI_INIT, &hdev->flags); 1191f41c70c4SMarcel Holtmann 11921da177e4SLinus Torvalds if (!ret) { 11931da177e4SLinus Torvalds hci_dev_hold(hdev); 11941da177e4SLinus Torvalds set_bit(HCI_UP, &hdev->flags); 11951da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UP); 1196bb4b2a9aSAndrei Emeltchenko if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 11970736cfa8SMarcel Holtmann !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) && 1198bb4b2a9aSAndrei Emeltchenko mgmt_valid_hdev(hdev)) { 119909fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1200744cf19eSJohan Hedberg mgmt_powered(hdev, 1); 120109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 120256e5cb86SJohan Hedberg } 12031da177e4SLinus Torvalds } else { 12041da177e4SLinus Torvalds /* Init failed, cleanup */ 12053eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1206c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 1207b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 12081da177e4SLinus Torvalds 12091da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 12101da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 12111da177e4SLinus Torvalds 12121da177e4SLinus Torvalds if (hdev->flush) 12131da177e4SLinus Torvalds hdev->flush(hdev); 12141da177e4SLinus Torvalds 12151da177e4SLinus Torvalds if (hdev->sent_cmd) { 12161da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 12171da177e4SLinus Torvalds hdev->sent_cmd = NULL; 12181da177e4SLinus Torvalds } 12191da177e4SLinus Torvalds 12201da177e4SLinus Torvalds hdev->close(hdev); 12211da177e4SLinus Torvalds hdev->flags = 0; 12221da177e4SLinus Torvalds } 12231da177e4SLinus Torvalds 12241da177e4SLinus Torvalds done: 12251da177e4SLinus Torvalds hci_req_unlock(hdev); 12261da177e4SLinus Torvalds hci_dev_put(hdev); 12271da177e4SLinus Torvalds return ret; 12281da177e4SLinus Torvalds } 12291da177e4SLinus Torvalds 12301da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev) 12311da177e4SLinus Torvalds { 12321da177e4SLinus Torvalds BT_DBG("%s %p", hdev->name, hdev); 12331da177e4SLinus Torvalds 123478c04c0bSVinicius Costa Gomes cancel_delayed_work(&hdev->power_off); 123578c04c0bSVinicius Costa Gomes 12361da177e4SLinus Torvalds hci_req_cancel(hdev, ENODEV); 12371da177e4SLinus Torvalds hci_req_lock(hdev); 12381da177e4SLinus Torvalds 12391da177e4SLinus Torvalds if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { 1240b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 12411da177e4SLinus Torvalds hci_req_unlock(hdev); 12421da177e4SLinus Torvalds return 0; 12431da177e4SLinus Torvalds } 12441da177e4SLinus Torvalds 12453eff45eaSGustavo F. Padovan /* Flush RX and TX works */ 12463eff45eaSGustavo F. Padovan flush_work(&hdev->tx_work); 1247b78752ccSMarcel Holtmann flush_work(&hdev->rx_work); 12481da177e4SLinus Torvalds 124916ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 1250e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->discov_off); 125116ab91abSJohan Hedberg hdev->discov_timeout = 0; 12525e5282bbSJohan Hedberg clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); 125316ab91abSJohan Hedberg } 125416ab91abSJohan Hedberg 1255a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) 12567d78525dSJohan Hedberg cancel_delayed_work(&hdev->service_cache); 12577d78525dSJohan Hedberg 12587ba8b4beSAndre Guedes cancel_delayed_work_sync(&hdev->le_scan_disable); 12597ba8b4beSAndre Guedes 126009fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 12611f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 12621da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 126309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 12641da177e4SLinus Torvalds 12651da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_DOWN); 12661da177e4SLinus Torvalds 12671da177e4SLinus Torvalds if (hdev->flush) 12681da177e4SLinus Torvalds hdev->flush(hdev); 12691da177e4SLinus Torvalds 12701da177e4SLinus Torvalds /* Reset device */ 12711da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 12721da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 12738af59467SJohan Hedberg if (!test_bit(HCI_RAW, &hdev->flags) && 1274a6c511c6SSzymon Janc test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { 12751da177e4SLinus Torvalds set_bit(HCI_INIT, &hdev->flags); 127601178cd4SJohan Hedberg __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); 12771da177e4SLinus Torvalds clear_bit(HCI_INIT, &hdev->flags); 12781da177e4SLinus Torvalds } 12791da177e4SLinus Torvalds 1280c347b765SGustavo F. Padovan /* flush cmd work */ 1281c347b765SGustavo F. Padovan flush_work(&hdev->cmd_work); 12821da177e4SLinus Torvalds 12831da177e4SLinus Torvalds /* Drop queues */ 12841da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 12851da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 12861da177e4SLinus Torvalds skb_queue_purge(&hdev->raw_q); 12871da177e4SLinus Torvalds 12881da177e4SLinus Torvalds /* Drop last sent command */ 12891da177e4SLinus Torvalds if (hdev->sent_cmd) { 1290b79f44c1SVinicius Costa Gomes del_timer_sync(&hdev->cmd_timer); 12911da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 12921da177e4SLinus Torvalds hdev->sent_cmd = NULL; 12931da177e4SLinus Torvalds } 12941da177e4SLinus Torvalds 1295b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 1296b6ddb638SJohan Hedberg hdev->recv_evt = NULL; 1297b6ddb638SJohan Hedberg 12981da177e4SLinus Torvalds /* After this point our queues are empty 12991da177e4SLinus Torvalds * and no tasks are scheduled. */ 13001da177e4SLinus Torvalds hdev->close(hdev); 13011da177e4SLinus Torvalds 130235b973c9SJohan Hedberg /* Clear flags */ 130335b973c9SJohan Hedberg hdev->flags = 0; 130435b973c9SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 130535b973c9SJohan Hedberg 1306bb4b2a9aSAndrei Emeltchenko if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) && 1307bb4b2a9aSAndrei Emeltchenko mgmt_valid_hdev(hdev)) { 130809fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 1309744cf19eSJohan Hedberg mgmt_powered(hdev, 0); 131009fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13118ee56540SMarcel Holtmann } 13125add6af8SJohan Hedberg 1313ced5c338SAndrei Emeltchenko /* Controller radio is available but is currently powered down */ 1314ced5c338SAndrei Emeltchenko hdev->amp_status = 0; 1315ced5c338SAndrei Emeltchenko 1316e59fda8dSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 131709b3c3fbSJohan Hedberg memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 1318e59fda8dSJohan Hedberg 13191da177e4SLinus Torvalds hci_req_unlock(hdev); 13201da177e4SLinus Torvalds 13211da177e4SLinus Torvalds hci_dev_put(hdev); 13221da177e4SLinus Torvalds return 0; 13231da177e4SLinus Torvalds } 13241da177e4SLinus Torvalds 13251da177e4SLinus Torvalds int hci_dev_close(__u16 dev) 13261da177e4SLinus Torvalds { 13271da177e4SLinus Torvalds struct hci_dev *hdev; 13281da177e4SLinus Torvalds int err; 13291da177e4SLinus Torvalds 133070f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 133170f23020SAndrei Emeltchenko if (!hdev) 13321da177e4SLinus Torvalds return -ENODEV; 13338ee56540SMarcel Holtmann 13340736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 13350736cfa8SMarcel Holtmann err = -EBUSY; 13360736cfa8SMarcel Holtmann goto done; 13370736cfa8SMarcel Holtmann } 13380736cfa8SMarcel Holtmann 13398ee56540SMarcel Holtmann if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 13408ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off); 13418ee56540SMarcel Holtmann 13421da177e4SLinus Torvalds err = hci_dev_do_close(hdev); 13438ee56540SMarcel Holtmann 13440736cfa8SMarcel Holtmann done: 13451da177e4SLinus Torvalds hci_dev_put(hdev); 13461da177e4SLinus Torvalds return err; 13471da177e4SLinus Torvalds } 13481da177e4SLinus Torvalds 13491da177e4SLinus Torvalds int hci_dev_reset(__u16 dev) 13501da177e4SLinus Torvalds { 13511da177e4SLinus Torvalds struct hci_dev *hdev; 13521da177e4SLinus Torvalds int ret = 0; 13531da177e4SLinus Torvalds 135470f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 135570f23020SAndrei Emeltchenko if (!hdev) 13561da177e4SLinus Torvalds return -ENODEV; 13571da177e4SLinus Torvalds 13581da177e4SLinus Torvalds hci_req_lock(hdev); 13591da177e4SLinus Torvalds 1360808a049eSMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) { 1361808a049eSMarcel Holtmann ret = -ENETDOWN; 13621da177e4SLinus Torvalds goto done; 1363808a049eSMarcel Holtmann } 13641da177e4SLinus Torvalds 13650736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 13660736cfa8SMarcel Holtmann ret = -EBUSY; 13670736cfa8SMarcel Holtmann goto done; 13680736cfa8SMarcel Holtmann } 13690736cfa8SMarcel Holtmann 13701da177e4SLinus Torvalds /* Drop queues */ 13711da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q); 13721da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q); 13731da177e4SLinus Torvalds 137409fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 13751f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev); 13761da177e4SLinus Torvalds hci_conn_hash_flush(hdev); 137709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 13781da177e4SLinus Torvalds 13791da177e4SLinus Torvalds if (hdev->flush) 13801da177e4SLinus Torvalds hdev->flush(hdev); 13811da177e4SLinus Torvalds 13821da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1); 13836ed58ec5SVille Tervo hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; 13841da177e4SLinus Torvalds 13851da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) 138601178cd4SJohan Hedberg ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); 13871da177e4SLinus Torvalds 13881da177e4SLinus Torvalds done: 13891da177e4SLinus Torvalds hci_req_unlock(hdev); 13901da177e4SLinus Torvalds hci_dev_put(hdev); 13911da177e4SLinus Torvalds return ret; 13921da177e4SLinus Torvalds } 13931da177e4SLinus Torvalds 13941da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev) 13951da177e4SLinus Torvalds { 13961da177e4SLinus Torvalds struct hci_dev *hdev; 13971da177e4SLinus Torvalds int ret = 0; 13981da177e4SLinus Torvalds 139970f23020SAndrei Emeltchenko hdev = hci_dev_get(dev); 140070f23020SAndrei Emeltchenko if (!hdev) 14011da177e4SLinus Torvalds return -ENODEV; 14021da177e4SLinus Torvalds 14030736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 14040736cfa8SMarcel Holtmann ret = -EBUSY; 14050736cfa8SMarcel Holtmann goto done; 14060736cfa8SMarcel Holtmann } 14070736cfa8SMarcel Holtmann 14081da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 14091da177e4SLinus Torvalds 14100736cfa8SMarcel Holtmann done: 14111da177e4SLinus Torvalds hci_dev_put(hdev); 14121da177e4SLinus Torvalds return ret; 14131da177e4SLinus Torvalds } 14141da177e4SLinus Torvalds 14151da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg) 14161da177e4SLinus Torvalds { 14171da177e4SLinus Torvalds struct hci_dev *hdev; 14181da177e4SLinus Torvalds struct hci_dev_req dr; 14191da177e4SLinus Torvalds int err = 0; 14201da177e4SLinus Torvalds 14211da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr))) 14221da177e4SLinus Torvalds return -EFAULT; 14231da177e4SLinus Torvalds 142470f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id); 142570f23020SAndrei Emeltchenko if (!hdev) 14261da177e4SLinus Torvalds return -ENODEV; 14271da177e4SLinus Torvalds 14280736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 14290736cfa8SMarcel Holtmann err = -EBUSY; 14300736cfa8SMarcel Holtmann goto done; 14310736cfa8SMarcel Holtmann } 14320736cfa8SMarcel Holtmann 14331da177e4SLinus Torvalds switch (cmd) { 14341da177e4SLinus Torvalds case HCISETAUTH: 143501178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 14365f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 14371da177e4SLinus Torvalds break; 14381da177e4SLinus Torvalds 14391da177e4SLinus Torvalds case HCISETENCRYPT: 14401da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) { 14411da177e4SLinus Torvalds err = -EOPNOTSUPP; 14421da177e4SLinus Torvalds break; 14431da177e4SLinus Torvalds } 14441da177e4SLinus Torvalds 14451da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) { 14461da177e4SLinus Torvalds /* Auth must be enabled first */ 144701178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt, 14485f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 14491da177e4SLinus Torvalds if (err) 14501da177e4SLinus Torvalds break; 14511da177e4SLinus Torvalds } 14521da177e4SLinus Torvalds 145301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt, 14545f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 14551da177e4SLinus Torvalds break; 14561da177e4SLinus Torvalds 14571da177e4SLinus Torvalds case HCISETSCAN: 145801178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt, 14595f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 14601da177e4SLinus Torvalds break; 14611da177e4SLinus Torvalds 14621da177e4SLinus Torvalds case HCISETLINKPOL: 146301178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt, 14645f246e89SAndrei Emeltchenko HCI_INIT_TIMEOUT); 14651da177e4SLinus Torvalds break; 14661da177e4SLinus Torvalds 14671da177e4SLinus Torvalds case HCISETLINKMODE: 1468e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) & 1469e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT); 1470e4e8e37cSMarcel Holtmann break; 1471e4e8e37cSMarcel Holtmann 1472e4e8e37cSMarcel Holtmann case HCISETPTYPE: 1473e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt; 14741da177e4SLinus Torvalds break; 14751da177e4SLinus Torvalds 14761da177e4SLinus Torvalds case HCISETACLMTU: 14771da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); 14781da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); 14791da177e4SLinus Torvalds break; 14801da177e4SLinus Torvalds 14811da177e4SLinus Torvalds case HCISETSCOMTU: 14821da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); 14831da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); 14841da177e4SLinus Torvalds break; 14851da177e4SLinus Torvalds 14861da177e4SLinus Torvalds default: 14871da177e4SLinus Torvalds err = -EINVAL; 14881da177e4SLinus Torvalds break; 14891da177e4SLinus Torvalds } 1490e4e8e37cSMarcel Holtmann 14910736cfa8SMarcel Holtmann done: 14921da177e4SLinus Torvalds hci_dev_put(hdev); 14931da177e4SLinus Torvalds return err; 14941da177e4SLinus Torvalds } 14951da177e4SLinus Torvalds 14961da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg) 14971da177e4SLinus Torvalds { 14988035ded4SLuiz Augusto von Dentz struct hci_dev *hdev; 14991da177e4SLinus Torvalds struct hci_dev_list_req *dl; 15001da177e4SLinus Torvalds struct hci_dev_req *dr; 15011da177e4SLinus Torvalds int n = 0, size, err; 15021da177e4SLinus Torvalds __u16 dev_num; 15031da177e4SLinus Torvalds 15041da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg)) 15051da177e4SLinus Torvalds return -EFAULT; 15061da177e4SLinus Torvalds 15071da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) 15081da177e4SLinus Torvalds return -EINVAL; 15091da177e4SLinus Torvalds 15101da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr); 15111da177e4SLinus Torvalds 151270f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL); 151370f23020SAndrei Emeltchenko if (!dl) 15141da177e4SLinus Torvalds return -ENOMEM; 15151da177e4SLinus Torvalds 15161da177e4SLinus Torvalds dr = dl->dev_req; 15171da177e4SLinus Torvalds 1518f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock); 15198035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) { 1520a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1521e0f9309fSJohan Hedberg cancel_delayed_work(&hdev->power_off); 1522c542a06cSJohan Hedberg 1523a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1524a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1525c542a06cSJohan Hedberg 15261da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id; 15271da177e4SLinus Torvalds (dr + n)->dev_opt = hdev->flags; 1528c542a06cSJohan Hedberg 15291da177e4SLinus Torvalds if (++n >= dev_num) 15301da177e4SLinus Torvalds break; 15311da177e4SLinus Torvalds } 1532f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock); 15331da177e4SLinus Torvalds 15341da177e4SLinus Torvalds dl->dev_num = n; 15351da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr); 15361da177e4SLinus Torvalds 15371da177e4SLinus Torvalds err = copy_to_user(arg, dl, size); 15381da177e4SLinus Torvalds kfree(dl); 15391da177e4SLinus Torvalds 15401da177e4SLinus Torvalds return err ? -EFAULT : 0; 15411da177e4SLinus Torvalds } 15421da177e4SLinus Torvalds 15431da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg) 15441da177e4SLinus Torvalds { 15451da177e4SLinus Torvalds struct hci_dev *hdev; 15461da177e4SLinus Torvalds struct hci_dev_info di; 15471da177e4SLinus Torvalds int err = 0; 15481da177e4SLinus Torvalds 15491da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di))) 15501da177e4SLinus Torvalds return -EFAULT; 15511da177e4SLinus Torvalds 155270f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id); 155370f23020SAndrei Emeltchenko if (!hdev) 15541da177e4SLinus Torvalds return -ENODEV; 15551da177e4SLinus Torvalds 1556a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 15573243553fSJohan Hedberg cancel_delayed_work_sync(&hdev->power_off); 1558ab81cbf9SJohan Hedberg 1559a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1560a8b2d5c2SJohan Hedberg set_bit(HCI_PAIRABLE, &hdev->dev_flags); 1561c542a06cSJohan Hedberg 15621da177e4SLinus Torvalds strcpy(di.name, hdev->name); 15631da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr; 1564943da25dSMarcel Holtmann di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); 15651da177e4SLinus Torvalds di.flags = hdev->flags; 15661da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type; 1567572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) { 15681da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu; 15691da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts; 15701da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu; 15711da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts; 1572572c7f84SJohan Hedberg } else { 1573572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu; 1574572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts; 1575572c7f84SJohan Hedberg di.sco_mtu = 0; 1576572c7f84SJohan Hedberg di.sco_pkts = 0; 1577572c7f84SJohan Hedberg } 15781da177e4SLinus Torvalds di.link_policy = hdev->link_policy; 15791da177e4SLinus Torvalds di.link_mode = hdev->link_mode; 15801da177e4SLinus Torvalds 15811da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat)); 15821da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features)); 15831da177e4SLinus Torvalds 15841da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di))) 15851da177e4SLinus Torvalds err = -EFAULT; 15861da177e4SLinus Torvalds 15871da177e4SLinus Torvalds hci_dev_put(hdev); 15881da177e4SLinus Torvalds 15891da177e4SLinus Torvalds return err; 15901da177e4SLinus Torvalds } 15911da177e4SLinus Torvalds 15921da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */ 15931da177e4SLinus Torvalds 1594611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked) 1595611b30f7SMarcel Holtmann { 1596611b30f7SMarcel Holtmann struct hci_dev *hdev = data; 1597611b30f7SMarcel Holtmann 1598611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); 1599611b30f7SMarcel Holtmann 16000736cfa8SMarcel Holtmann if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) 16010736cfa8SMarcel Holtmann return -EBUSY; 16020736cfa8SMarcel Holtmann 1603611b30f7SMarcel Holtmann if (!blocked) 1604611b30f7SMarcel Holtmann return 0; 1605611b30f7SMarcel Holtmann 1606611b30f7SMarcel Holtmann hci_dev_do_close(hdev); 1607611b30f7SMarcel Holtmann 1608611b30f7SMarcel Holtmann return 0; 1609611b30f7SMarcel Holtmann } 1610611b30f7SMarcel Holtmann 1611611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = { 1612611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block, 1613611b30f7SMarcel Holtmann }; 1614611b30f7SMarcel Holtmann 1615ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work) 1616ab81cbf9SJohan Hedberg { 1617ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); 161896570ffcSJohan Hedberg int err; 1619ab81cbf9SJohan Hedberg 1620ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1621ab81cbf9SJohan Hedberg 162296570ffcSJohan Hedberg err = hci_dev_open(hdev->id); 162396570ffcSJohan Hedberg if (err < 0) { 162496570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err); 1625ab81cbf9SJohan Hedberg return; 162696570ffcSJohan Hedberg } 1627ab81cbf9SJohan Hedberg 1628a8b2d5c2SJohan Hedberg if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 162919202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off, 163019202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT); 1631ab81cbf9SJohan Hedberg 1632a8b2d5c2SJohan Hedberg if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 1633744cf19eSJohan Hedberg mgmt_index_added(hdev); 1634ab81cbf9SJohan Hedberg } 1635ab81cbf9SJohan Hedberg 1636ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work) 1637ab81cbf9SJohan Hedberg { 16383243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, 16393243553fSJohan Hedberg power_off.work); 1640ab81cbf9SJohan Hedberg 1641ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name); 1642ab81cbf9SJohan Hedberg 16438ee56540SMarcel Holtmann hci_dev_do_close(hdev); 1644ab81cbf9SJohan Hedberg } 1645ab81cbf9SJohan Hedberg 164616ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work) 164716ab91abSJohan Hedberg { 164816ab91abSJohan Hedberg struct hci_dev *hdev; 164916ab91abSJohan Hedberg u8 scan = SCAN_PAGE; 165016ab91abSJohan Hedberg 165116ab91abSJohan Hedberg hdev = container_of(work, struct hci_dev, discov_off.work); 165216ab91abSJohan Hedberg 165316ab91abSJohan Hedberg BT_DBG("%s", hdev->name); 165416ab91abSJohan Hedberg 165509fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 165616ab91abSJohan Hedberg 165716ab91abSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); 165816ab91abSJohan Hedberg 165916ab91abSJohan Hedberg hdev->discov_timeout = 0; 166016ab91abSJohan Hedberg 166109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 166216ab91abSJohan Hedberg } 166316ab91abSJohan Hedberg 16642aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev) 16652aeb9a1aSJohan Hedberg { 16664821002cSJohan Hedberg struct bt_uuid *uuid, *tmp; 16672aeb9a1aSJohan Hedberg 16684821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { 16694821002cSJohan Hedberg list_del(&uuid->list); 16702aeb9a1aSJohan Hedberg kfree(uuid); 16712aeb9a1aSJohan Hedberg } 16722aeb9a1aSJohan Hedberg 16732aeb9a1aSJohan Hedberg return 0; 16742aeb9a1aSJohan Hedberg } 16752aeb9a1aSJohan Hedberg 167655ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev) 167755ed8ca1SJohan Hedberg { 167855ed8ca1SJohan Hedberg struct list_head *p, *n; 167955ed8ca1SJohan Hedberg 168055ed8ca1SJohan Hedberg list_for_each_safe(p, n, &hdev->link_keys) { 168155ed8ca1SJohan Hedberg struct link_key *key; 168255ed8ca1SJohan Hedberg 168355ed8ca1SJohan Hedberg key = list_entry(p, struct link_key, list); 168455ed8ca1SJohan Hedberg 168555ed8ca1SJohan Hedberg list_del(p); 168655ed8ca1SJohan Hedberg kfree(key); 168755ed8ca1SJohan Hedberg } 168855ed8ca1SJohan Hedberg 168955ed8ca1SJohan Hedberg return 0; 169055ed8ca1SJohan Hedberg } 169155ed8ca1SJohan Hedberg 1692b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev) 1693b899efafSVinicius Costa Gomes { 1694b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1695b899efafSVinicius Costa Gomes 1696b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1697b899efafSVinicius Costa Gomes list_del(&k->list); 1698b899efafSVinicius Costa Gomes kfree(k); 1699b899efafSVinicius Costa Gomes } 1700b899efafSVinicius Costa Gomes 1701b899efafSVinicius Costa Gomes return 0; 1702b899efafSVinicius Costa Gomes } 1703b899efafSVinicius Costa Gomes 170455ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 170555ed8ca1SJohan Hedberg { 170655ed8ca1SJohan Hedberg struct link_key *k; 170755ed8ca1SJohan Hedberg 17088035ded4SLuiz Augusto von Dentz list_for_each_entry(k, &hdev->link_keys, list) 170955ed8ca1SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) 171055ed8ca1SJohan Hedberg return k; 171155ed8ca1SJohan Hedberg 171255ed8ca1SJohan Hedberg return NULL; 171355ed8ca1SJohan Hedberg } 171455ed8ca1SJohan Hedberg 1715745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, 1716d25e28abSJohan Hedberg u8 key_type, u8 old_key_type) 1717d25e28abSJohan Hedberg { 1718d25e28abSJohan Hedberg /* Legacy key */ 1719d25e28abSJohan Hedberg if (key_type < 0x03) 1720745c0ce3SVishal Agarwal return true; 1721d25e28abSJohan Hedberg 1722d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */ 1723d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION) 1724745c0ce3SVishal Agarwal return false; 1725d25e28abSJohan Hedberg 1726d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */ 1727d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) 1728745c0ce3SVishal Agarwal return false; 1729d25e28abSJohan Hedberg 1730d25e28abSJohan Hedberg /* Security mode 3 case */ 1731d25e28abSJohan Hedberg if (!conn) 1732745c0ce3SVishal Agarwal return true; 1733d25e28abSJohan Hedberg 1734d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */ 1735d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) 1736745c0ce3SVishal Agarwal return true; 1737d25e28abSJohan Hedberg 1738d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */ 1739d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03) 1740745c0ce3SVishal Agarwal return true; 1741d25e28abSJohan Hedberg 1742d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */ 1743d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) 1744745c0ce3SVishal Agarwal return true; 1745d25e28abSJohan Hedberg 1746d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key 1747d25e28abSJohan Hedberg * persistently */ 1748745c0ce3SVishal Agarwal return false; 1749d25e28abSJohan Hedberg } 1750d25e28abSJohan Hedberg 1751c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 175275d262c2SVinicius Costa Gomes { 1753c9839a11SVinicius Costa Gomes struct smp_ltk *k; 175475d262c2SVinicius Costa Gomes 1755c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) { 1756c9839a11SVinicius Costa Gomes if (k->ediv != ediv || 1757c9839a11SVinicius Costa Gomes memcmp(rand, k->rand, sizeof(k->rand))) 175875d262c2SVinicius Costa Gomes continue; 175975d262c2SVinicius Costa Gomes 176075d262c2SVinicius Costa Gomes return k; 176175d262c2SVinicius Costa Gomes } 176275d262c2SVinicius Costa Gomes 176375d262c2SVinicius Costa Gomes return NULL; 176475d262c2SVinicius Costa Gomes } 176575d262c2SVinicius Costa Gomes 1766c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1767c9839a11SVinicius Costa Gomes u8 addr_type) 176875d262c2SVinicius Costa Gomes { 1769c9839a11SVinicius Costa Gomes struct smp_ltk *k; 177075d262c2SVinicius Costa Gomes 1771c9839a11SVinicius Costa Gomes list_for_each_entry(k, &hdev->long_term_keys, list) 1772c9839a11SVinicius Costa Gomes if (addr_type == k->bdaddr_type && 1773c9839a11SVinicius Costa Gomes bacmp(bdaddr, &k->bdaddr) == 0) 177475d262c2SVinicius Costa Gomes return k; 177575d262c2SVinicius Costa Gomes 177675d262c2SVinicius Costa Gomes return NULL; 177775d262c2SVinicius Costa Gomes } 177875d262c2SVinicius Costa Gomes 1779d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 1780d25e28abSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) 178155ed8ca1SJohan Hedberg { 178255ed8ca1SJohan Hedberg struct link_key *key, *old_key; 1783745c0ce3SVishal Agarwal u8 old_key_type; 1784745c0ce3SVishal Agarwal bool persistent; 178555ed8ca1SJohan Hedberg 178655ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr); 178755ed8ca1SJohan Hedberg if (old_key) { 178855ed8ca1SJohan Hedberg old_key_type = old_key->type; 178955ed8ca1SJohan Hedberg key = old_key; 179055ed8ca1SJohan Hedberg } else { 179112adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff; 179255ed8ca1SJohan Hedberg key = kzalloc(sizeof(*key), GFP_ATOMIC); 179355ed8ca1SJohan Hedberg if (!key) 179455ed8ca1SJohan Hedberg return -ENOMEM; 179555ed8ca1SJohan Hedberg list_add(&key->list, &hdev->link_keys); 179655ed8ca1SJohan Hedberg } 179755ed8ca1SJohan Hedberg 17986ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); 179955ed8ca1SJohan Hedberg 1800d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed 1801d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no 1802d25e28abSJohan Hedberg * previous key */ 1803d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION && 1804a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { 1805d25e28abSJohan Hedberg type = HCI_LK_COMBINATION; 1806655fe6ecSJohan Hedberg if (conn) 1807655fe6ecSJohan Hedberg conn->key_type = type; 1808655fe6ecSJohan Hedberg } 1809d25e28abSJohan Hedberg 181055ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr); 18119b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE); 181255ed8ca1SJohan Hedberg key->pin_len = pin_len; 181355ed8ca1SJohan Hedberg 1814b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION) 181555ed8ca1SJohan Hedberg key->type = old_key_type; 18164748fed2SJohan Hedberg else 18174748fed2SJohan Hedberg key->type = type; 18184748fed2SJohan Hedberg 18194df378a1SJohan Hedberg if (!new_key) 18204df378a1SJohan Hedberg return 0; 18214df378a1SJohan Hedberg 18224df378a1SJohan Hedberg persistent = hci_persistent_key(hdev, conn, type, old_key_type); 18234df378a1SJohan Hedberg 1824744cf19eSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 18254df378a1SJohan Hedberg 18266ec5bcadSVishal Agarwal if (conn) 18276ec5bcadSVishal Agarwal conn->flush_key = !persistent; 182855ed8ca1SJohan Hedberg 182955ed8ca1SJohan Hedberg return 0; 183055ed8ca1SJohan Hedberg } 183155ed8ca1SJohan Hedberg 1832c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 18339a006657SAndrei Emeltchenko int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 183404124681SGustavo F. Padovan ediv, u8 rand[8]) 183575d262c2SVinicius Costa Gomes { 1836c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key; 183775d262c2SVinicius Costa Gomes 1838c9839a11SVinicius Costa Gomes if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK)) 1839c9839a11SVinicius Costa Gomes return 0; 184075d262c2SVinicius Costa Gomes 1841c9839a11SVinicius Costa Gomes old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 1842c9839a11SVinicius Costa Gomes if (old_key) 184375d262c2SVinicius Costa Gomes key = old_key; 1844c9839a11SVinicius Costa Gomes else { 1845c9839a11SVinicius Costa Gomes key = kzalloc(sizeof(*key), GFP_ATOMIC); 184675d262c2SVinicius Costa Gomes if (!key) 184775d262c2SVinicius Costa Gomes return -ENOMEM; 1848c9839a11SVinicius Costa Gomes list_add(&key->list, &hdev->long_term_keys); 184975d262c2SVinicius Costa Gomes } 185075d262c2SVinicius Costa Gomes 185175d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr); 1852c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type; 1853c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val)); 1854c9839a11SVinicius Costa Gomes key->authenticated = authenticated; 1855c9839a11SVinicius Costa Gomes key->ediv = ediv; 1856c9839a11SVinicius Costa Gomes key->enc_size = enc_size; 1857c9839a11SVinicius Costa Gomes key->type = type; 1858c9839a11SVinicius Costa Gomes memcpy(key->rand, rand, sizeof(key->rand)); 185975d262c2SVinicius Costa Gomes 1860c9839a11SVinicius Costa Gomes if (!new_key) 1861c9839a11SVinicius Costa Gomes return 0; 186275d262c2SVinicius Costa Gomes 1863261cc5aaSVinicius Costa Gomes if (type & HCI_SMP_LTK) 1864261cc5aaSVinicius Costa Gomes mgmt_new_ltk(hdev, key, 1); 1865261cc5aaSVinicius Costa Gomes 186675d262c2SVinicius Costa Gomes return 0; 186775d262c2SVinicius Costa Gomes } 186875d262c2SVinicius Costa Gomes 186955ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 187055ed8ca1SJohan Hedberg { 187155ed8ca1SJohan Hedberg struct link_key *key; 187255ed8ca1SJohan Hedberg 187355ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr); 187455ed8ca1SJohan Hedberg if (!key) 187555ed8ca1SJohan Hedberg return -ENOENT; 187655ed8ca1SJohan Hedberg 18776ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 187855ed8ca1SJohan Hedberg 187955ed8ca1SJohan Hedberg list_del(&key->list); 188055ed8ca1SJohan Hedberg kfree(key); 188155ed8ca1SJohan Hedberg 188255ed8ca1SJohan Hedberg return 0; 188355ed8ca1SJohan Hedberg } 188455ed8ca1SJohan Hedberg 1885b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) 1886b899efafSVinicius Costa Gomes { 1887b899efafSVinicius Costa Gomes struct smp_ltk *k, *tmp; 1888b899efafSVinicius Costa Gomes 1889b899efafSVinicius Costa Gomes list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { 1890b899efafSVinicius Costa Gomes if (bacmp(bdaddr, &k->bdaddr)) 1891b899efafSVinicius Costa Gomes continue; 1892b899efafSVinicius Costa Gomes 18936ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 1894b899efafSVinicius Costa Gomes 1895b899efafSVinicius Costa Gomes list_del(&k->list); 1896b899efafSVinicius Costa Gomes kfree(k); 1897b899efafSVinicius Costa Gomes } 1898b899efafSVinicius Costa Gomes 1899b899efafSVinicius Costa Gomes return 0; 1900b899efafSVinicius Costa Gomes } 1901b899efafSVinicius Costa Gomes 19026bd32326SVille Tervo /* HCI command timer function */ 1903bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg) 19046bd32326SVille Tervo { 19056bd32326SVille Tervo struct hci_dev *hdev = (void *) arg; 19066bd32326SVille Tervo 1907bda4f23aSAndrei Emeltchenko if (hdev->sent_cmd) { 1908bda4f23aSAndrei Emeltchenko struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; 1909bda4f23aSAndrei Emeltchenko u16 opcode = __le16_to_cpu(sent->opcode); 1910bda4f23aSAndrei Emeltchenko 1911bda4f23aSAndrei Emeltchenko BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); 1912bda4f23aSAndrei Emeltchenko } else { 19136bd32326SVille Tervo BT_ERR("%s command tx timeout", hdev->name); 1914bda4f23aSAndrei Emeltchenko } 1915bda4f23aSAndrei Emeltchenko 19166bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1); 1917c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 19186bd32326SVille Tervo } 19196bd32326SVille Tervo 19202763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 19212763eda6SSzymon Janc bdaddr_t *bdaddr) 19222763eda6SSzymon Janc { 19232763eda6SSzymon Janc struct oob_data *data; 19242763eda6SSzymon Janc 19252763eda6SSzymon Janc list_for_each_entry(data, &hdev->remote_oob_data, list) 19262763eda6SSzymon Janc if (bacmp(bdaddr, &data->bdaddr) == 0) 19272763eda6SSzymon Janc return data; 19282763eda6SSzymon Janc 19292763eda6SSzymon Janc return NULL; 19302763eda6SSzymon Janc } 19312763eda6SSzymon Janc 19322763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) 19332763eda6SSzymon Janc { 19342763eda6SSzymon Janc struct oob_data *data; 19352763eda6SSzymon Janc 19362763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 19372763eda6SSzymon Janc if (!data) 19382763eda6SSzymon Janc return -ENOENT; 19392763eda6SSzymon Janc 19406ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr); 19412763eda6SSzymon Janc 19422763eda6SSzymon Janc list_del(&data->list); 19432763eda6SSzymon Janc kfree(data); 19442763eda6SSzymon Janc 19452763eda6SSzymon Janc return 0; 19462763eda6SSzymon Janc } 19472763eda6SSzymon Janc 19482763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev) 19492763eda6SSzymon Janc { 19502763eda6SSzymon Janc struct oob_data *data, *n; 19512763eda6SSzymon Janc 19522763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { 19532763eda6SSzymon Janc list_del(&data->list); 19542763eda6SSzymon Janc kfree(data); 19552763eda6SSzymon Janc } 19562763eda6SSzymon Janc 19572763eda6SSzymon Janc return 0; 19582763eda6SSzymon Janc } 19592763eda6SSzymon Janc 19602763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, 19612763eda6SSzymon Janc u8 *randomizer) 19622763eda6SSzymon Janc { 19632763eda6SSzymon Janc struct oob_data *data; 19642763eda6SSzymon Janc 19652763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, bdaddr); 19662763eda6SSzymon Janc 19672763eda6SSzymon Janc if (!data) { 19682763eda6SSzymon Janc data = kmalloc(sizeof(*data), GFP_ATOMIC); 19692763eda6SSzymon Janc if (!data) 19702763eda6SSzymon Janc return -ENOMEM; 19712763eda6SSzymon Janc 19722763eda6SSzymon Janc bacpy(&data->bdaddr, bdaddr); 19732763eda6SSzymon Janc list_add(&data->list, &hdev->remote_oob_data); 19742763eda6SSzymon Janc } 19752763eda6SSzymon Janc 19762763eda6SSzymon Janc memcpy(data->hash, hash, sizeof(data->hash)); 19772763eda6SSzymon Janc memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); 19782763eda6SSzymon Janc 19796ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr); 19802763eda6SSzymon Janc 19812763eda6SSzymon Janc return 0; 19822763eda6SSzymon Janc } 19832763eda6SSzymon Janc 198404124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 1985b2a66aadSAntti Julku { 1986b2a66aadSAntti Julku struct bdaddr_list *b; 1987b2a66aadSAntti Julku 19888035ded4SLuiz Augusto von Dentz list_for_each_entry(b, &hdev->blacklist, list) 1989b2a66aadSAntti Julku if (bacmp(bdaddr, &b->bdaddr) == 0) 1990b2a66aadSAntti Julku return b; 1991b2a66aadSAntti Julku 1992b2a66aadSAntti Julku return NULL; 1993b2a66aadSAntti Julku } 1994b2a66aadSAntti Julku 1995b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev) 1996b2a66aadSAntti Julku { 1997b2a66aadSAntti Julku struct list_head *p, *n; 1998b2a66aadSAntti Julku 1999b2a66aadSAntti Julku list_for_each_safe(p, n, &hdev->blacklist) { 2000b2a66aadSAntti Julku struct bdaddr_list *b; 2001b2a66aadSAntti Julku 2002b2a66aadSAntti Julku b = list_entry(p, struct bdaddr_list, list); 2003b2a66aadSAntti Julku 2004b2a66aadSAntti Julku list_del(p); 2005b2a66aadSAntti Julku kfree(b); 2006b2a66aadSAntti Julku } 2007b2a66aadSAntti Julku 2008b2a66aadSAntti Julku return 0; 2009b2a66aadSAntti Julku } 2010b2a66aadSAntti Julku 201188c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2012b2a66aadSAntti Julku { 2013b2a66aadSAntti Julku struct bdaddr_list *entry; 2014b2a66aadSAntti Julku 2015b2a66aadSAntti Julku if (bacmp(bdaddr, BDADDR_ANY) == 0) 2016b2a66aadSAntti Julku return -EBADF; 2017b2a66aadSAntti Julku 20185e762444SAntti Julku if (hci_blacklist_lookup(hdev, bdaddr)) 20195e762444SAntti Julku return -EEXIST; 2020b2a66aadSAntti Julku 2021b2a66aadSAntti Julku entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); 20225e762444SAntti Julku if (!entry) 20235e762444SAntti Julku return -ENOMEM; 2024b2a66aadSAntti Julku 2025b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr); 2026b2a66aadSAntti Julku 2027b2a66aadSAntti Julku list_add(&entry->list, &hdev->blacklist); 2028b2a66aadSAntti Julku 202988c1fe4bSJohan Hedberg return mgmt_device_blocked(hdev, bdaddr, type); 2030b2a66aadSAntti Julku } 2031b2a66aadSAntti Julku 203288c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 2033b2a66aadSAntti Julku { 2034b2a66aadSAntti Julku struct bdaddr_list *entry; 2035b2a66aadSAntti Julku 20361ec918ceSSzymon Janc if (bacmp(bdaddr, BDADDR_ANY) == 0) 20375e762444SAntti Julku return hci_blacklist_clear(hdev); 2038b2a66aadSAntti Julku 2039b2a66aadSAntti Julku entry = hci_blacklist_lookup(hdev, bdaddr); 20401ec918ceSSzymon Janc if (!entry) 20415e762444SAntti Julku return -ENOENT; 2042b2a66aadSAntti Julku 2043b2a66aadSAntti Julku list_del(&entry->list); 2044b2a66aadSAntti Julku kfree(entry); 2045b2a66aadSAntti Julku 204688c1fe4bSJohan Hedberg return mgmt_device_unblocked(hdev, bdaddr, type); 2047b2a66aadSAntti Julku } 2048b2a66aadSAntti Julku 20494c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status) 20507ba8b4beSAndre Guedes { 20514c87eaabSAndre Guedes if (status) { 20524c87eaabSAndre Guedes BT_ERR("Failed to start inquiry: status %d", status); 20537ba8b4beSAndre Guedes 20544c87eaabSAndre Guedes hci_dev_lock(hdev); 20554c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 20564c87eaabSAndre Guedes hci_dev_unlock(hdev); 20574c87eaabSAndre Guedes return; 20584c87eaabSAndre Guedes } 20597ba8b4beSAndre Guedes } 20607ba8b4beSAndre Guedes 20614c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) 20627ba8b4beSAndre Guedes { 20634c87eaabSAndre Guedes /* General inquiry access code (GIAC) */ 20644c87eaabSAndre Guedes u8 lap[3] = { 0x33, 0x8b, 0x9e }; 20654c87eaabSAndre Guedes struct hci_request req; 20664c87eaabSAndre Guedes struct hci_cp_inquiry cp; 20677ba8b4beSAndre Guedes int err; 20687ba8b4beSAndre Guedes 20694c87eaabSAndre Guedes if (status) { 20704c87eaabSAndre Guedes BT_ERR("Failed to disable LE scanning: status %d", status); 20714c87eaabSAndre Guedes return; 20727ba8b4beSAndre Guedes } 20737ba8b4beSAndre Guedes 20744c87eaabSAndre Guedes switch (hdev->discovery.type) { 20754c87eaabSAndre Guedes case DISCOV_TYPE_LE: 20764c87eaabSAndre Guedes hci_dev_lock(hdev); 20774c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 20784c87eaabSAndre Guedes hci_dev_unlock(hdev); 20794c87eaabSAndre Guedes break; 20807dbfac1dSAndre Guedes 20814c87eaabSAndre Guedes case DISCOV_TYPE_INTERLEAVED: 20824c87eaabSAndre Guedes hci_req_init(&req, hdev); 20837dbfac1dSAndre Guedes 20847dbfac1dSAndre Guedes memset(&cp, 0, sizeof(cp)); 20854c87eaabSAndre Guedes memcpy(&cp.lap, lap, sizeof(cp.lap)); 20864c87eaabSAndre Guedes cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; 20874c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); 20884c87eaabSAndre Guedes 20894c87eaabSAndre Guedes hci_dev_lock(hdev); 20904c87eaabSAndre Guedes 20914c87eaabSAndre Guedes hci_inquiry_cache_flush(hdev); 20924c87eaabSAndre Guedes 20934c87eaabSAndre Guedes err = hci_req_run(&req, inquiry_complete); 20944c87eaabSAndre Guedes if (err) { 20954c87eaabSAndre Guedes BT_ERR("Inquiry request failed: err %d", err); 20964c87eaabSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 20977dbfac1dSAndre Guedes } 20987dbfac1dSAndre Guedes 20994c87eaabSAndre Guedes hci_dev_unlock(hdev); 21004c87eaabSAndre Guedes break; 21014c87eaabSAndre Guedes } 21027dbfac1dSAndre Guedes } 21037dbfac1dSAndre Guedes 21047ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work) 21057ba8b4beSAndre Guedes { 21067ba8b4beSAndre Guedes struct hci_dev *hdev = container_of(work, struct hci_dev, 21077ba8b4beSAndre Guedes le_scan_disable.work); 21087ba8b4beSAndre Guedes struct hci_cp_le_set_scan_enable cp; 21094c87eaabSAndre Guedes struct hci_request req; 21104c87eaabSAndre Guedes int err; 21117ba8b4beSAndre Guedes 21127ba8b4beSAndre Guedes BT_DBG("%s", hdev->name); 21137ba8b4beSAndre Guedes 21144c87eaabSAndre Guedes hci_req_init(&req, hdev); 21157ba8b4beSAndre Guedes 21167ba8b4beSAndre Guedes memset(&cp, 0, sizeof(cp)); 21174c87eaabSAndre Guedes cp.enable = LE_SCAN_DISABLE; 21184c87eaabSAndre Guedes hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 21197ba8b4beSAndre Guedes 21204c87eaabSAndre Guedes err = hci_req_run(&req, le_scan_disable_work_complete); 21214c87eaabSAndre Guedes if (err) 21224c87eaabSAndre Guedes BT_ERR("Disable LE scanning request failed: err %d", err); 212328b75a89SAndre Guedes } 212428b75a89SAndre Guedes 21259be0dab7SDavid Herrmann /* Alloc HCI device */ 21269be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void) 21279be0dab7SDavid Herrmann { 21289be0dab7SDavid Herrmann struct hci_dev *hdev; 21299be0dab7SDavid Herrmann 21309be0dab7SDavid Herrmann hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); 21319be0dab7SDavid Herrmann if (!hdev) 21329be0dab7SDavid Herrmann return NULL; 21339be0dab7SDavid Herrmann 2134b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 2135b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1); 2136b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT); 2137b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */ 2138bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 2139bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2140b1b813d4SDavid Herrmann 2141b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800; 2142b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80; 2143b1b813d4SDavid Herrmann 2144b1b813d4SDavid Herrmann mutex_init(&hdev->lock); 2145b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock); 2146b1b813d4SDavid Herrmann 2147b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending); 2148b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->blacklist); 2149b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids); 2150b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys); 2151b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys); 2152b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data); 21536b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list); 2154b1b813d4SDavid Herrmann 2155b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work); 2156b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work); 2157b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work); 2158b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on); 2159b1b813d4SDavid Herrmann 2160b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 2161b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 2162b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); 2163b1b813d4SDavid Herrmann 2164b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q); 2165b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q); 2166b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q); 2167b1b813d4SDavid Herrmann 2168b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q); 2169b1b813d4SDavid Herrmann 2170bda4f23aSAndrei Emeltchenko setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); 2171b1b813d4SDavid Herrmann 2172b1b813d4SDavid Herrmann hci_init_sysfs(hdev); 2173b1b813d4SDavid Herrmann discovery_init(hdev); 21749be0dab7SDavid Herrmann 21759be0dab7SDavid Herrmann return hdev; 21769be0dab7SDavid Herrmann } 21779be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev); 21789be0dab7SDavid Herrmann 21799be0dab7SDavid Herrmann /* Free HCI device */ 21809be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev) 21819be0dab7SDavid Herrmann { 21829be0dab7SDavid Herrmann /* will free via device release */ 21839be0dab7SDavid Herrmann put_device(&hdev->dev); 21849be0dab7SDavid Herrmann } 21859be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev); 21869be0dab7SDavid Herrmann 21871da177e4SLinus Torvalds /* Register HCI device */ 21881da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev) 21891da177e4SLinus Torvalds { 2190b1b813d4SDavid Herrmann int id, error; 21911da177e4SLinus Torvalds 2192010666a1SDavid Herrmann if (!hdev->open || !hdev->close) 21931da177e4SLinus Torvalds return -EINVAL; 21941da177e4SLinus Torvalds 219508add513SMat Martineau /* Do not allow HCI_AMP devices to register at index 0, 219608add513SMat Martineau * so the index can be used as the AMP controller ID. 219708add513SMat Martineau */ 21983df92b31SSasha Levin switch (hdev->dev_type) { 21993df92b31SSasha Levin case HCI_BREDR: 22003df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); 22011da177e4SLinus Torvalds break; 22023df92b31SSasha Levin case HCI_AMP: 22033df92b31SSasha Levin id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); 22043df92b31SSasha Levin break; 22053df92b31SSasha Levin default: 22063df92b31SSasha Levin return -EINVAL; 22071da177e4SLinus Torvalds } 22081da177e4SLinus Torvalds 22093df92b31SSasha Levin if (id < 0) 22103df92b31SSasha Levin return id; 22113df92b31SSasha Levin 22121da177e4SLinus Torvalds sprintf(hdev->name, "hci%d", id); 22131da177e4SLinus Torvalds hdev->id = id; 22142d8b3a11SAndrei Emeltchenko 22152d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 22162d8b3a11SAndrei Emeltchenko 2217d8537548SKees Cook hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 2218d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 221933ca954dSDavid Herrmann if (!hdev->workqueue) { 222033ca954dSDavid Herrmann error = -ENOMEM; 222133ca954dSDavid Herrmann goto err; 222233ca954dSDavid Herrmann } 2223f48fd9c8SMarcel Holtmann 2224d8537548SKees Cook hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | 2225d8537548SKees Cook WQ_MEM_RECLAIM, 1, hdev->name); 22266ead1bbcSJohan Hedberg if (!hdev->req_workqueue) { 22276ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue); 22286ead1bbcSJohan Hedberg error = -ENOMEM; 22296ead1bbcSJohan Hedberg goto err; 22306ead1bbcSJohan Hedberg } 22316ead1bbcSJohan Hedberg 223233ca954dSDavid Herrmann error = hci_add_sysfs(hdev); 223333ca954dSDavid Herrmann if (error < 0) 223433ca954dSDavid Herrmann goto err_wqueue; 22351da177e4SLinus Torvalds 2236611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 2237a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, 2238a8c5fb1aSGustavo Padovan hdev); 2239611b30f7SMarcel Holtmann if (hdev->rfkill) { 2240611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) { 2241611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2242611b30f7SMarcel Holtmann hdev->rfkill = NULL; 2243611b30f7SMarcel Holtmann } 2244611b30f7SMarcel Holtmann } 2245611b30f7SMarcel Holtmann 2246a8b2d5c2SJohan Hedberg set_bit(HCI_SETUP, &hdev->dev_flags); 2247ce2be9acSAndrei Emeltchenko 2248ce2be9acSAndrei Emeltchenko if (hdev->dev_type != HCI_AMP) 2249ce2be9acSAndrei Emeltchenko set_bit(HCI_AUTO_OFF, &hdev->dev_flags); 2250ce2be9acSAndrei Emeltchenko 2251fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock); 2252fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list); 2253fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock); 2254fcee3377SGustavo Padovan 22551da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_REG); 2256dc946bd8SDavid Herrmann hci_dev_hold(hdev); 22571da177e4SLinus Torvalds 225819202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on); 2259fbe96d6fSMarcel Holtmann 22601da177e4SLinus Torvalds return id; 2261f48fd9c8SMarcel Holtmann 226233ca954dSDavid Herrmann err_wqueue: 226333ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue); 22646ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 226533ca954dSDavid Herrmann err: 22663df92b31SSasha Levin ida_simple_remove(&hci_index_ida, hdev->id); 2267f48fd9c8SMarcel Holtmann 226833ca954dSDavid Herrmann return error; 22691da177e4SLinus Torvalds } 22701da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev); 22711da177e4SLinus Torvalds 22721da177e4SLinus Torvalds /* Unregister HCI device */ 227359735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev) 22741da177e4SLinus Torvalds { 22753df92b31SSasha Levin int i, id; 2276ef222013SMarcel Holtmann 2277c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); 22781da177e4SLinus Torvalds 227994324962SJohan Hovold set_bit(HCI_UNREGISTER, &hdev->dev_flags); 228094324962SJohan Hovold 22813df92b31SSasha Levin id = hdev->id; 22823df92b31SSasha Levin 2283f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock); 22841da177e4SLinus Torvalds list_del(&hdev->list); 2285f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock); 22861da177e4SLinus Torvalds 22871da177e4SLinus Torvalds hci_dev_do_close(hdev); 22881da177e4SLinus Torvalds 2289cd4c5391SSuraj Sumangala for (i = 0; i < NUM_REASSEMBLY; i++) 2290ef222013SMarcel Holtmann kfree_skb(hdev->reassembly[i]); 2291ef222013SMarcel Holtmann 2292b9b5ef18SGustavo Padovan cancel_work_sync(&hdev->power_on); 2293b9b5ef18SGustavo Padovan 2294ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) && 2295a8b2d5c2SJohan Hedberg !test_bit(HCI_SETUP, &hdev->dev_flags)) { 229609fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2297744cf19eSJohan Hedberg mgmt_index_removed(hdev); 229809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 229956e5cb86SJohan Hedberg } 2300ab81cbf9SJohan Hedberg 23012e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the 23022e58ef3eSJohan Hedberg * pending list */ 23032e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending)); 23042e58ef3eSJohan Hedberg 23051da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_UNREG); 23061da177e4SLinus Torvalds 2307611b30f7SMarcel Holtmann if (hdev->rfkill) { 2308611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill); 2309611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill); 2310611b30f7SMarcel Holtmann } 2311611b30f7SMarcel Holtmann 2312ce242970SDavid Herrmann hci_del_sysfs(hdev); 2313147e2d59SDave Young 2314f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue); 23156ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue); 2316f48fd9c8SMarcel Holtmann 231709fd0de5SGustavo F. Padovan hci_dev_lock(hdev); 2318e2e0cacbSJohan Hedberg hci_blacklist_clear(hdev); 23192aeb9a1aSJohan Hedberg hci_uuids_clear(hdev); 232055ed8ca1SJohan Hedberg hci_link_keys_clear(hdev); 2321b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev); 23222763eda6SSzymon Janc hci_remote_oob_data_clear(hdev); 232309fd0de5SGustavo F. Padovan hci_dev_unlock(hdev); 2324e2e0cacbSJohan Hedberg 2325dc946bd8SDavid Herrmann hci_dev_put(hdev); 23263df92b31SSasha Levin 23273df92b31SSasha Levin ida_simple_remove(&hci_index_ida, id); 23281da177e4SLinus Torvalds } 23291da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev); 23301da177e4SLinus Torvalds 23311da177e4SLinus Torvalds /* Suspend HCI device */ 23321da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev) 23331da177e4SLinus Torvalds { 23341da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_SUSPEND); 23351da177e4SLinus Torvalds return 0; 23361da177e4SLinus Torvalds } 23371da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev); 23381da177e4SLinus Torvalds 23391da177e4SLinus Torvalds /* Resume HCI device */ 23401da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev) 23411da177e4SLinus Torvalds { 23421da177e4SLinus Torvalds hci_notify(hdev, HCI_DEV_RESUME); 23431da177e4SLinus Torvalds return 0; 23441da177e4SLinus Torvalds } 23451da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev); 23461da177e4SLinus Torvalds 234776bca880SMarcel Holtmann /* Receive frame from HCI drivers */ 234876bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb) 234976bca880SMarcel Holtmann { 235076bca880SMarcel Holtmann struct hci_dev *hdev = (struct hci_dev *) skb->dev; 235176bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags) 235276bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) { 235376bca880SMarcel Holtmann kfree_skb(skb); 235476bca880SMarcel Holtmann return -ENXIO; 235576bca880SMarcel Holtmann } 235676bca880SMarcel Holtmann 2357d82603c6SJorrit Schippers /* Incoming skb */ 235876bca880SMarcel Holtmann bt_cb(skb)->incoming = 1; 235976bca880SMarcel Holtmann 236076bca880SMarcel Holtmann /* Time stamp */ 236176bca880SMarcel Holtmann __net_timestamp(skb); 236276bca880SMarcel Holtmann 236376bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb); 2364b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work); 2365c78ae283SMarcel Holtmann 236676bca880SMarcel Holtmann return 0; 236776bca880SMarcel Holtmann } 236876bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame); 236976bca880SMarcel Holtmann 237033e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 23711e429f38SGustavo F. Padovan int count, __u8 index) 237233e882a5SSuraj Sumangala { 237333e882a5SSuraj Sumangala int len = 0; 237433e882a5SSuraj Sumangala int hlen = 0; 237533e882a5SSuraj Sumangala int remain = count; 237633e882a5SSuraj Sumangala struct sk_buff *skb; 237733e882a5SSuraj Sumangala struct bt_skb_cb *scb; 237833e882a5SSuraj Sumangala 237933e882a5SSuraj Sumangala if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || 238033e882a5SSuraj Sumangala index >= NUM_REASSEMBLY) 238133e882a5SSuraj Sumangala return -EILSEQ; 238233e882a5SSuraj Sumangala 238333e882a5SSuraj Sumangala skb = hdev->reassembly[index]; 238433e882a5SSuraj Sumangala 238533e882a5SSuraj Sumangala if (!skb) { 238633e882a5SSuraj Sumangala switch (type) { 238733e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 238833e882a5SSuraj Sumangala len = HCI_MAX_FRAME_SIZE; 238933e882a5SSuraj Sumangala hlen = HCI_ACL_HDR_SIZE; 239033e882a5SSuraj Sumangala break; 239133e882a5SSuraj Sumangala case HCI_EVENT_PKT: 239233e882a5SSuraj Sumangala len = HCI_MAX_EVENT_SIZE; 239333e882a5SSuraj Sumangala hlen = HCI_EVENT_HDR_SIZE; 239433e882a5SSuraj Sumangala break; 239533e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 239633e882a5SSuraj Sumangala len = HCI_MAX_SCO_SIZE; 239733e882a5SSuraj Sumangala hlen = HCI_SCO_HDR_SIZE; 239833e882a5SSuraj Sumangala break; 239933e882a5SSuraj Sumangala } 240033e882a5SSuraj Sumangala 24011e429f38SGustavo F. Padovan skb = bt_skb_alloc(len, GFP_ATOMIC); 240233e882a5SSuraj Sumangala if (!skb) 240333e882a5SSuraj Sumangala return -ENOMEM; 240433e882a5SSuraj Sumangala 240533e882a5SSuraj Sumangala scb = (void *) skb->cb; 240633e882a5SSuraj Sumangala scb->expect = hlen; 240733e882a5SSuraj Sumangala scb->pkt_type = type; 240833e882a5SSuraj Sumangala 240933e882a5SSuraj Sumangala skb->dev = (void *) hdev; 241033e882a5SSuraj Sumangala hdev->reassembly[index] = skb; 241133e882a5SSuraj Sumangala } 241233e882a5SSuraj Sumangala 241333e882a5SSuraj Sumangala while (count) { 241433e882a5SSuraj Sumangala scb = (void *) skb->cb; 241589bb46d0SDan Carpenter len = min_t(uint, scb->expect, count); 241633e882a5SSuraj Sumangala 241733e882a5SSuraj Sumangala memcpy(skb_put(skb, len), data, len); 241833e882a5SSuraj Sumangala 241933e882a5SSuraj Sumangala count -= len; 242033e882a5SSuraj Sumangala data += len; 242133e882a5SSuraj Sumangala scb->expect -= len; 242233e882a5SSuraj Sumangala remain = count; 242333e882a5SSuraj Sumangala 242433e882a5SSuraj Sumangala switch (type) { 242533e882a5SSuraj Sumangala case HCI_EVENT_PKT: 242633e882a5SSuraj Sumangala if (skb->len == HCI_EVENT_HDR_SIZE) { 242733e882a5SSuraj Sumangala struct hci_event_hdr *h = hci_event_hdr(skb); 242833e882a5SSuraj Sumangala scb->expect = h->plen; 242933e882a5SSuraj Sumangala 243033e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 243133e882a5SSuraj Sumangala kfree_skb(skb); 243233e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 243333e882a5SSuraj Sumangala return -ENOMEM; 243433e882a5SSuraj Sumangala } 243533e882a5SSuraj Sumangala } 243633e882a5SSuraj Sumangala break; 243733e882a5SSuraj Sumangala 243833e882a5SSuraj Sumangala case HCI_ACLDATA_PKT: 243933e882a5SSuraj Sumangala if (skb->len == HCI_ACL_HDR_SIZE) { 244033e882a5SSuraj Sumangala struct hci_acl_hdr *h = hci_acl_hdr(skb); 244133e882a5SSuraj Sumangala scb->expect = __le16_to_cpu(h->dlen); 244233e882a5SSuraj Sumangala 244333e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 244433e882a5SSuraj Sumangala kfree_skb(skb); 244533e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 244633e882a5SSuraj Sumangala return -ENOMEM; 244733e882a5SSuraj Sumangala } 244833e882a5SSuraj Sumangala } 244933e882a5SSuraj Sumangala break; 245033e882a5SSuraj Sumangala 245133e882a5SSuraj Sumangala case HCI_SCODATA_PKT: 245233e882a5SSuraj Sumangala if (skb->len == HCI_SCO_HDR_SIZE) { 245333e882a5SSuraj Sumangala struct hci_sco_hdr *h = hci_sco_hdr(skb); 245433e882a5SSuraj Sumangala scb->expect = h->dlen; 245533e882a5SSuraj Sumangala 245633e882a5SSuraj Sumangala if (skb_tailroom(skb) < scb->expect) { 245733e882a5SSuraj Sumangala kfree_skb(skb); 245833e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 245933e882a5SSuraj Sumangala return -ENOMEM; 246033e882a5SSuraj Sumangala } 246133e882a5SSuraj Sumangala } 246233e882a5SSuraj Sumangala break; 246333e882a5SSuraj Sumangala } 246433e882a5SSuraj Sumangala 246533e882a5SSuraj Sumangala if (scb->expect == 0) { 246633e882a5SSuraj Sumangala /* Complete frame */ 246733e882a5SSuraj Sumangala 246833e882a5SSuraj Sumangala bt_cb(skb)->pkt_type = type; 246933e882a5SSuraj Sumangala hci_recv_frame(skb); 247033e882a5SSuraj Sumangala 247133e882a5SSuraj Sumangala hdev->reassembly[index] = NULL; 247233e882a5SSuraj Sumangala return remain; 247333e882a5SSuraj Sumangala } 247433e882a5SSuraj Sumangala } 247533e882a5SSuraj Sumangala 247633e882a5SSuraj Sumangala return remain; 247733e882a5SSuraj Sumangala } 247833e882a5SSuraj Sumangala 2479ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) 2480ef222013SMarcel Holtmann { 2481f39a3c06SSuraj Sumangala int rem = 0; 2482f39a3c06SSuraj Sumangala 2483ef222013SMarcel Holtmann if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) 2484ef222013SMarcel Holtmann return -EILSEQ; 2485ef222013SMarcel Holtmann 2486da5f6c37SGustavo F. Padovan while (count) { 24871e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, type - 1); 2488f39a3c06SSuraj Sumangala if (rem < 0) 2489f39a3c06SSuraj Sumangala return rem; 2490ef222013SMarcel Holtmann 2491f39a3c06SSuraj Sumangala data += (count - rem); 2492f39a3c06SSuraj Sumangala count = rem; 2493f81c6224SJoe Perches } 2494ef222013SMarcel Holtmann 2495f39a3c06SSuraj Sumangala return rem; 2496ef222013SMarcel Holtmann } 2497ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment); 2498ef222013SMarcel Holtmann 249999811510SSuraj Sumangala #define STREAM_REASSEMBLY 0 250099811510SSuraj Sumangala 250199811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) 250299811510SSuraj Sumangala { 250399811510SSuraj Sumangala int type; 250499811510SSuraj Sumangala int rem = 0; 250599811510SSuraj Sumangala 2506da5f6c37SGustavo F. Padovan while (count) { 250799811510SSuraj Sumangala struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; 250899811510SSuraj Sumangala 250999811510SSuraj Sumangala if (!skb) { 251099811510SSuraj Sumangala struct { char type; } *pkt; 251199811510SSuraj Sumangala 251299811510SSuraj Sumangala /* Start of the frame */ 251399811510SSuraj Sumangala pkt = data; 251499811510SSuraj Sumangala type = pkt->type; 251599811510SSuraj Sumangala 251699811510SSuraj Sumangala data++; 251799811510SSuraj Sumangala count--; 251899811510SSuraj Sumangala } else 251999811510SSuraj Sumangala type = bt_cb(skb)->pkt_type; 252099811510SSuraj Sumangala 25211e429f38SGustavo F. Padovan rem = hci_reassembly(hdev, type, data, count, 25221e429f38SGustavo F. Padovan STREAM_REASSEMBLY); 252399811510SSuraj Sumangala if (rem < 0) 252499811510SSuraj Sumangala return rem; 252599811510SSuraj Sumangala 252699811510SSuraj Sumangala data += (count - rem); 252799811510SSuraj Sumangala count = rem; 2528f81c6224SJoe Perches } 252999811510SSuraj Sumangala 253099811510SSuraj Sumangala return rem; 253199811510SSuraj Sumangala } 253299811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment); 253399811510SSuraj Sumangala 25341da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */ 25351da177e4SLinus Torvalds 25361da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb) 25371da177e4SLinus Torvalds { 25381da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 25391da177e4SLinus Torvalds 2540f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 25411da177e4SLinus Torvalds list_add(&cb->list, &hci_cb_list); 2542f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 25431da177e4SLinus Torvalds 25441da177e4SLinus Torvalds return 0; 25451da177e4SLinus Torvalds } 25461da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb); 25471da177e4SLinus Torvalds 25481da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb) 25491da177e4SLinus Torvalds { 25501da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name); 25511da177e4SLinus Torvalds 2552f20d09d5SGustavo F. Padovan write_lock(&hci_cb_list_lock); 25531da177e4SLinus Torvalds list_del(&cb->list); 2554f20d09d5SGustavo F. Padovan write_unlock(&hci_cb_list_lock); 25551da177e4SLinus Torvalds 25561da177e4SLinus Torvalds return 0; 25571da177e4SLinus Torvalds } 25581da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb); 25591da177e4SLinus Torvalds 25601da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb) 25611da177e4SLinus Torvalds { 25621da177e4SLinus Torvalds struct hci_dev *hdev = (struct hci_dev *) skb->dev; 25631da177e4SLinus Torvalds 25641da177e4SLinus Torvalds if (!hdev) { 25651da177e4SLinus Torvalds kfree_skb(skb); 25661da177e4SLinus Torvalds return -ENODEV; 25671da177e4SLinus Torvalds } 25681da177e4SLinus Torvalds 25690d48d939SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); 25701da177e4SLinus Torvalds 25711da177e4SLinus Torvalds /* Time stamp */ 2572a61bbcf2SPatrick McHardy __net_timestamp(skb); 25731da177e4SLinus Torvalds 2574cd82e61cSMarcel Holtmann /* Send copy to monitor */ 2575cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 2576cd82e61cSMarcel Holtmann 2577cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) { 2578cd82e61cSMarcel Holtmann /* Send copy to the sockets */ 2579470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 25801da177e4SLinus Torvalds } 25811da177e4SLinus Torvalds 25821da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */ 25831da177e4SLinus Torvalds skb_orphan(skb); 25841da177e4SLinus Torvalds 25851da177e4SLinus Torvalds return hdev->send(skb); 25861da177e4SLinus Torvalds } 25871da177e4SLinus Torvalds 25883119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev) 25893119ae95SJohan Hedberg { 25903119ae95SJohan Hedberg skb_queue_head_init(&req->cmd_q); 25913119ae95SJohan Hedberg req->hdev = hdev; 25925d73e034SAndre Guedes req->err = 0; 25933119ae95SJohan Hedberg } 25943119ae95SJohan Hedberg 25953119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 25963119ae95SJohan Hedberg { 25973119ae95SJohan Hedberg struct hci_dev *hdev = req->hdev; 25983119ae95SJohan Hedberg struct sk_buff *skb; 25993119ae95SJohan Hedberg unsigned long flags; 26003119ae95SJohan Hedberg 26013119ae95SJohan Hedberg BT_DBG("length %u", skb_queue_len(&req->cmd_q)); 26023119ae95SJohan Hedberg 26035d73e034SAndre Guedes /* If an error occured during request building, remove all HCI 26045d73e034SAndre Guedes * commands queued on the HCI request queue. 26055d73e034SAndre Guedes */ 26065d73e034SAndre Guedes if (req->err) { 26075d73e034SAndre Guedes skb_queue_purge(&req->cmd_q); 26085d73e034SAndre Guedes return req->err; 26095d73e034SAndre Guedes } 26105d73e034SAndre Guedes 26113119ae95SJohan Hedberg /* Do not allow empty requests */ 26123119ae95SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 2613382b0c39SAndre Guedes return -ENODATA; 26143119ae95SJohan Hedberg 26153119ae95SJohan Hedberg skb = skb_peek_tail(&req->cmd_q); 26163119ae95SJohan Hedberg bt_cb(skb)->req.complete = complete; 26173119ae95SJohan Hedberg 26183119ae95SJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 26193119ae95SJohan Hedberg skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 26203119ae95SJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 26213119ae95SJohan Hedberg 26223119ae95SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 26233119ae95SJohan Hedberg 26243119ae95SJohan Hedberg return 0; 26253119ae95SJohan Hedberg } 26263119ae95SJohan Hedberg 26271ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, 262807dc93ddSJohan Hedberg u32 plen, const void *param) 26291da177e4SLinus Torvalds { 26301da177e4SLinus Torvalds int len = HCI_COMMAND_HDR_SIZE + plen; 26311da177e4SLinus Torvalds struct hci_command_hdr *hdr; 26321da177e4SLinus Torvalds struct sk_buff *skb; 26331da177e4SLinus Torvalds 26341da177e4SLinus Torvalds skb = bt_skb_alloc(len, GFP_ATOMIC); 26351ca3a9d0SJohan Hedberg if (!skb) 26361ca3a9d0SJohan Hedberg return NULL; 26371da177e4SLinus Torvalds 26381da177e4SLinus Torvalds hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE); 2639a9de9248SMarcel Holtmann hdr->opcode = cpu_to_le16(opcode); 26401da177e4SLinus Torvalds hdr->plen = plen; 26411da177e4SLinus Torvalds 26421da177e4SLinus Torvalds if (plen) 26431da177e4SLinus Torvalds memcpy(skb_put(skb, plen), param, plen); 26441da177e4SLinus Torvalds 26451da177e4SLinus Torvalds BT_DBG("skb len %d", skb->len); 26461da177e4SLinus Torvalds 26470d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 26481da177e4SLinus Torvalds skb->dev = (void *) hdev; 2649c78ae283SMarcel Holtmann 26501ca3a9d0SJohan Hedberg return skb; 26511ca3a9d0SJohan Hedberg } 26521ca3a9d0SJohan Hedberg 26531ca3a9d0SJohan Hedberg /* Send HCI command */ 265407dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 265507dc93ddSJohan Hedberg const void *param) 26561ca3a9d0SJohan Hedberg { 26571ca3a9d0SJohan Hedberg struct sk_buff *skb; 26581ca3a9d0SJohan Hedberg 26591ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 26601ca3a9d0SJohan Hedberg 26611ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 26621ca3a9d0SJohan Hedberg if (!skb) { 26631ca3a9d0SJohan Hedberg BT_ERR("%s no memory for command", hdev->name); 26641ca3a9d0SJohan Hedberg return -ENOMEM; 26651ca3a9d0SJohan Hedberg } 26661ca3a9d0SJohan Hedberg 266711714b3dSJohan Hedberg /* Stand-alone HCI commands must be flaged as 266811714b3dSJohan Hedberg * single-command requests. 266911714b3dSJohan Hedberg */ 267011714b3dSJohan Hedberg bt_cb(skb)->req.start = true; 267111714b3dSJohan Hedberg 26721da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb); 2673c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 26741da177e4SLinus Torvalds 26751da177e4SLinus Torvalds return 0; 26761da177e4SLinus Torvalds } 26771da177e4SLinus Torvalds 267871c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */ 267907dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 268007dc93ddSJohan Hedberg const void *param, u8 event) 268171c76a17SJohan Hedberg { 268271c76a17SJohan Hedberg struct hci_dev *hdev = req->hdev; 268371c76a17SJohan Hedberg struct sk_buff *skb; 268471c76a17SJohan Hedberg 268571c76a17SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); 268671c76a17SJohan Hedberg 268734739c1eSAndre Guedes /* If an error occured during request building, there is no point in 268834739c1eSAndre Guedes * queueing the HCI command. We can simply return. 268934739c1eSAndre Guedes */ 269034739c1eSAndre Guedes if (req->err) 269134739c1eSAndre Guedes return; 269234739c1eSAndre Guedes 269371c76a17SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param); 269471c76a17SJohan Hedberg if (!skb) { 26955d73e034SAndre Guedes BT_ERR("%s no memory for command (opcode 0x%4.4x)", 26965d73e034SAndre Guedes hdev->name, opcode); 26975d73e034SAndre Guedes req->err = -ENOMEM; 2698e348fe6bSAndre Guedes return; 269971c76a17SJohan Hedberg } 270071c76a17SJohan Hedberg 270171c76a17SJohan Hedberg if (skb_queue_empty(&req->cmd_q)) 270271c76a17SJohan Hedberg bt_cb(skb)->req.start = true; 270371c76a17SJohan Hedberg 270402350a72SJohan Hedberg bt_cb(skb)->req.event = event; 270502350a72SJohan Hedberg 270671c76a17SJohan Hedberg skb_queue_tail(&req->cmd_q, skb); 270771c76a17SJohan Hedberg } 270871c76a17SJohan Hedberg 270907dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 271007dc93ddSJohan Hedberg const void *param) 271102350a72SJohan Hedberg { 271202350a72SJohan Hedberg hci_req_add_ev(req, opcode, plen, param, 0); 271302350a72SJohan Hedberg } 271402350a72SJohan Hedberg 27151da177e4SLinus Torvalds /* Get data from the previously sent command */ 2716a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 27171da177e4SLinus Torvalds { 27181da177e4SLinus Torvalds struct hci_command_hdr *hdr; 27191da177e4SLinus Torvalds 27201da177e4SLinus Torvalds if (!hdev->sent_cmd) 27211da177e4SLinus Torvalds return NULL; 27221da177e4SLinus Torvalds 27231da177e4SLinus Torvalds hdr = (void *) hdev->sent_cmd->data; 27241da177e4SLinus Torvalds 2725a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode)) 27261da177e4SLinus Torvalds return NULL; 27271da177e4SLinus Torvalds 2728f0e09510SAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 27291da177e4SLinus Torvalds 27301da177e4SLinus Torvalds return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; 27311da177e4SLinus Torvalds } 27321da177e4SLinus Torvalds 27331da177e4SLinus Torvalds /* Send ACL data */ 27341da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) 27351da177e4SLinus Torvalds { 27361da177e4SLinus Torvalds struct hci_acl_hdr *hdr; 27371da177e4SLinus Torvalds int len = skb->len; 27381da177e4SLinus Torvalds 2739badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE); 2740badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 27419c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb); 2742aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags)); 2743aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len); 27441da177e4SLinus Torvalds } 27451da177e4SLinus Torvalds 2746ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, 274773d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags) 27481da177e4SLinus Torvalds { 2749ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn; 27501da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 27511da177e4SLinus Torvalds struct sk_buff *list; 27521da177e4SLinus Torvalds 2753087bfd99SGustavo Padovan skb->len = skb_headlen(skb); 2754087bfd99SGustavo Padovan skb->data_len = 0; 2755087bfd99SGustavo Padovan 2756087bfd99SGustavo Padovan bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2757204a6e54SAndrei Emeltchenko 2758204a6e54SAndrei Emeltchenko switch (hdev->dev_type) { 2759204a6e54SAndrei Emeltchenko case HCI_BREDR: 2760087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags); 2761204a6e54SAndrei Emeltchenko break; 2762204a6e54SAndrei Emeltchenko case HCI_AMP: 2763204a6e54SAndrei Emeltchenko hci_add_acl_hdr(skb, chan->handle, flags); 2764204a6e54SAndrei Emeltchenko break; 2765204a6e54SAndrei Emeltchenko default: 2766204a6e54SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 2767204a6e54SAndrei Emeltchenko return; 2768204a6e54SAndrei Emeltchenko } 2769087bfd99SGustavo Padovan 277070f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list; 277170f23020SAndrei Emeltchenko if (!list) { 27721da177e4SLinus Torvalds /* Non fragmented */ 27731da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); 27741da177e4SLinus Torvalds 277573d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb); 27761da177e4SLinus Torvalds } else { 27771da177e4SLinus Torvalds /* Fragmented */ 27781da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 27791da177e4SLinus Torvalds 27801da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL; 27811da177e4SLinus Torvalds 27821da177e4SLinus Torvalds /* Queue all fragments atomically */ 2783af3e6359SGustavo F. Padovan spin_lock(&queue->lock); 27841da177e4SLinus Torvalds 278573d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 2786e702112fSAndrei Emeltchenko 2787e702112fSAndrei Emeltchenko flags &= ~ACL_START; 2788e702112fSAndrei Emeltchenko flags |= ACL_CONT; 27891da177e4SLinus Torvalds do { 27901da177e4SLinus Torvalds skb = list; list = list->next; 27911da177e4SLinus Torvalds 27921da177e4SLinus Torvalds skb->dev = (void *) hdev; 27930d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 2794e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags); 27951da177e4SLinus Torvalds 27961da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 27971da177e4SLinus Torvalds 279873d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb); 27991da177e4SLinus Torvalds } while (list); 28001da177e4SLinus Torvalds 2801af3e6359SGustavo F. Padovan spin_unlock(&queue->lock); 28021da177e4SLinus Torvalds } 280373d80debSLuiz Augusto von Dentz } 280473d80debSLuiz Augusto von Dentz 280573d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) 280673d80debSLuiz Augusto von Dentz { 2807ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev; 280873d80debSLuiz Augusto von Dentz 2809f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); 281073d80debSLuiz Augusto von Dentz 281173d80debSLuiz Augusto von Dentz skb->dev = (void *) hdev; 281273d80debSLuiz Augusto von Dentz 2813ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags); 28141da177e4SLinus Torvalds 28153eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 28161da177e4SLinus Torvalds } 28171da177e4SLinus Torvalds 28181da177e4SLinus Torvalds /* Send SCO data */ 28190d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 28201da177e4SLinus Torvalds { 28211da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev; 28221da177e4SLinus Torvalds struct hci_sco_hdr hdr; 28231da177e4SLinus Torvalds 28241da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len); 28251da177e4SLinus Torvalds 2826aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle); 28271da177e4SLinus Torvalds hdr.dlen = skb->len; 28281da177e4SLinus Torvalds 2829badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE); 2830badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb); 28319c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE); 28321da177e4SLinus Torvalds 28331da177e4SLinus Torvalds skb->dev = (void *) hdev; 28340d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; 2835c78ae283SMarcel Holtmann 28361da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb); 28373eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 28381da177e4SLinus Torvalds } 28391da177e4SLinus Torvalds 28401da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */ 28411da177e4SLinus Torvalds 28421da177e4SLinus Torvalds /* HCI Connection scheduler */ 28436039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, 2844a8c5fb1aSGustavo Padovan int *quote) 28451da177e4SLinus Torvalds { 28461da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 28478035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c; 2848abc5de8fSMikel Astiz unsigned int num = 0, min = ~0; 28491da177e4SLinus Torvalds 28501da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always 28511da177e4SLinus Torvalds * added and removed with TX task disabled. */ 2852bf4c6325SGustavo F. Padovan 2853bf4c6325SGustavo F. Padovan rcu_read_lock(); 2854bf4c6325SGustavo F. Padovan 2855bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2856769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q)) 28571da177e4SLinus Torvalds continue; 2858769be974SMarcel Holtmann 2859769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG) 2860769be974SMarcel Holtmann continue; 2861769be974SMarcel Holtmann 28621da177e4SLinus Torvalds num++; 28631da177e4SLinus Torvalds 28641da177e4SLinus Torvalds if (c->sent < min) { 28651da177e4SLinus Torvalds min = c->sent; 28661da177e4SLinus Torvalds conn = c; 28671da177e4SLinus Torvalds } 286852087a79SLuiz Augusto von Dentz 286952087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 287052087a79SLuiz Augusto von Dentz break; 28711da177e4SLinus Torvalds } 28721da177e4SLinus Torvalds 2873bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2874bf4c6325SGustavo F. Padovan 28751da177e4SLinus Torvalds if (conn) { 28766ed58ec5SVille Tervo int cnt, q; 28776ed58ec5SVille Tervo 28786ed58ec5SVille Tervo switch (conn->type) { 28796ed58ec5SVille Tervo case ACL_LINK: 28806ed58ec5SVille Tervo cnt = hdev->acl_cnt; 28816ed58ec5SVille Tervo break; 28826ed58ec5SVille Tervo case SCO_LINK: 28836ed58ec5SVille Tervo case ESCO_LINK: 28846ed58ec5SVille Tervo cnt = hdev->sco_cnt; 28856ed58ec5SVille Tervo break; 28866ed58ec5SVille Tervo case LE_LINK: 28876ed58ec5SVille Tervo cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 28886ed58ec5SVille Tervo break; 28896ed58ec5SVille Tervo default: 28906ed58ec5SVille Tervo cnt = 0; 28916ed58ec5SVille Tervo BT_ERR("Unknown link type"); 28926ed58ec5SVille Tervo } 28936ed58ec5SVille Tervo 28946ed58ec5SVille Tervo q = cnt / num; 28951da177e4SLinus Torvalds *quote = q ? q : 1; 28961da177e4SLinus Torvalds } else 28971da177e4SLinus Torvalds *quote = 0; 28981da177e4SLinus Torvalds 28991da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote); 29001da177e4SLinus Torvalds return conn; 29011da177e4SLinus Torvalds } 29021da177e4SLinus Torvalds 29036039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) 29041da177e4SLinus Torvalds { 29051da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 29061da177e4SLinus Torvalds struct hci_conn *c; 29071da177e4SLinus Torvalds 2908bae1f5d9SVille Tervo BT_ERR("%s link tx timeout", hdev->name); 29091da177e4SLinus Torvalds 2910bf4c6325SGustavo F. Padovan rcu_read_lock(); 2911bf4c6325SGustavo F. Padovan 29121da177e4SLinus Torvalds /* Kill stalled connections */ 2913bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 2914bae1f5d9SVille Tervo if (c->type == type && c->sent) { 29156ed93dc6SAndrei Emeltchenko BT_ERR("%s killing stalled connection %pMR", 29166ed93dc6SAndrei Emeltchenko hdev->name, &c->dst); 2917bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); 29181da177e4SLinus Torvalds } 29191da177e4SLinus Torvalds } 2920bf4c6325SGustavo F. Padovan 2921bf4c6325SGustavo F. Padovan rcu_read_unlock(); 29221da177e4SLinus Torvalds } 29231da177e4SLinus Torvalds 29246039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, 292573d80debSLuiz Augusto von Dentz int *quote) 292673d80debSLuiz Augusto von Dentz { 292773d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 292873d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL; 2929abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0; 293073d80debSLuiz Augusto von Dentz struct hci_conn *conn; 293173d80debSLuiz Augusto von Dentz int cnt, q, conn_num = 0; 293273d80debSLuiz Augusto von Dentz 293373d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 293473d80debSLuiz Augusto von Dentz 2935bf4c6325SGustavo F. Padovan rcu_read_lock(); 2936bf4c6325SGustavo F. Padovan 2937bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 293873d80debSLuiz Augusto von Dentz struct hci_chan *tmp; 293973d80debSLuiz Augusto von Dentz 294073d80debSLuiz Augusto von Dentz if (conn->type != type) 294173d80debSLuiz Augusto von Dentz continue; 294273d80debSLuiz Augusto von Dentz 294373d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 294473d80debSLuiz Augusto von Dentz continue; 294573d80debSLuiz Augusto von Dentz 294673d80debSLuiz Augusto von Dentz conn_num++; 294773d80debSLuiz Augusto von Dentz 29488192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) { 294973d80debSLuiz Augusto von Dentz struct sk_buff *skb; 295073d80debSLuiz Augusto von Dentz 295173d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q)) 295273d80debSLuiz Augusto von Dentz continue; 295373d80debSLuiz Augusto von Dentz 295473d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q); 295573d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio) 295673d80debSLuiz Augusto von Dentz continue; 295773d80debSLuiz Augusto von Dentz 295873d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) { 295973d80debSLuiz Augusto von Dentz num = 0; 296073d80debSLuiz Augusto von Dentz min = ~0; 296173d80debSLuiz Augusto von Dentz cur_prio = skb->priority; 296273d80debSLuiz Augusto von Dentz } 296373d80debSLuiz Augusto von Dentz 296473d80debSLuiz Augusto von Dentz num++; 296573d80debSLuiz Augusto von Dentz 296673d80debSLuiz Augusto von Dentz if (conn->sent < min) { 296773d80debSLuiz Augusto von Dentz min = conn->sent; 296873d80debSLuiz Augusto von Dentz chan = tmp; 296973d80debSLuiz Augusto von Dentz } 297073d80debSLuiz Augusto von Dentz } 297173d80debSLuiz Augusto von Dentz 297273d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num) 297373d80debSLuiz Augusto von Dentz break; 297473d80debSLuiz Augusto von Dentz } 297573d80debSLuiz Augusto von Dentz 2976bf4c6325SGustavo F. Padovan rcu_read_unlock(); 2977bf4c6325SGustavo F. Padovan 297873d80debSLuiz Augusto von Dentz if (!chan) 297973d80debSLuiz Augusto von Dentz return NULL; 298073d80debSLuiz Augusto von Dentz 298173d80debSLuiz Augusto von Dentz switch (chan->conn->type) { 298273d80debSLuiz Augusto von Dentz case ACL_LINK: 298373d80debSLuiz Augusto von Dentz cnt = hdev->acl_cnt; 298473d80debSLuiz Augusto von Dentz break; 2985bd1eb66bSAndrei Emeltchenko case AMP_LINK: 2986bd1eb66bSAndrei Emeltchenko cnt = hdev->block_cnt; 2987bd1eb66bSAndrei Emeltchenko break; 298873d80debSLuiz Augusto von Dentz case SCO_LINK: 298973d80debSLuiz Augusto von Dentz case ESCO_LINK: 299073d80debSLuiz Augusto von Dentz cnt = hdev->sco_cnt; 299173d80debSLuiz Augusto von Dentz break; 299273d80debSLuiz Augusto von Dentz case LE_LINK: 299373d80debSLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; 299473d80debSLuiz Augusto von Dentz break; 299573d80debSLuiz Augusto von Dentz default: 299673d80debSLuiz Augusto von Dentz cnt = 0; 299773d80debSLuiz Augusto von Dentz BT_ERR("Unknown link type"); 299873d80debSLuiz Augusto von Dentz } 299973d80debSLuiz Augusto von Dentz 300073d80debSLuiz Augusto von Dentz q = cnt / num; 300173d80debSLuiz Augusto von Dentz *quote = q ? q : 1; 300273d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote); 300373d80debSLuiz Augusto von Dentz return chan; 300473d80debSLuiz Augusto von Dentz } 300573d80debSLuiz Augusto von Dentz 300602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) 300702b20f0bSLuiz Augusto von Dentz { 300802b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 300902b20f0bSLuiz Augusto von Dentz struct hci_conn *conn; 301002b20f0bSLuiz Augusto von Dentz int num = 0; 301102b20f0bSLuiz Augusto von Dentz 301202b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name); 301302b20f0bSLuiz Augusto von Dentz 3014bf4c6325SGustavo F. Padovan rcu_read_lock(); 3015bf4c6325SGustavo F. Padovan 3016bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) { 301702b20f0bSLuiz Augusto von Dentz struct hci_chan *chan; 301802b20f0bSLuiz Augusto von Dentz 301902b20f0bSLuiz Augusto von Dentz if (conn->type != type) 302002b20f0bSLuiz Augusto von Dentz continue; 302102b20f0bSLuiz Augusto von Dentz 302202b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) 302302b20f0bSLuiz Augusto von Dentz continue; 302402b20f0bSLuiz Augusto von Dentz 302502b20f0bSLuiz Augusto von Dentz num++; 302602b20f0bSLuiz Augusto von Dentz 30278192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) { 302802b20f0bSLuiz Augusto von Dentz struct sk_buff *skb; 302902b20f0bSLuiz Augusto von Dentz 303002b20f0bSLuiz Augusto von Dentz if (chan->sent) { 303102b20f0bSLuiz Augusto von Dentz chan->sent = 0; 303202b20f0bSLuiz Augusto von Dentz continue; 303302b20f0bSLuiz Augusto von Dentz } 303402b20f0bSLuiz Augusto von Dentz 303502b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q)) 303602b20f0bSLuiz Augusto von Dentz continue; 303702b20f0bSLuiz Augusto von Dentz 303802b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q); 303902b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1) 304002b20f0bSLuiz Augusto von Dentz continue; 304102b20f0bSLuiz Augusto von Dentz 304202b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1; 304302b20f0bSLuiz Augusto von Dentz 304402b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb, 304502b20f0bSLuiz Augusto von Dentz skb->priority); 304602b20f0bSLuiz Augusto von Dentz } 304702b20f0bSLuiz Augusto von Dentz 304802b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num) 304902b20f0bSLuiz Augusto von Dentz break; 305002b20f0bSLuiz Augusto von Dentz } 3051bf4c6325SGustavo F. Padovan 3052bf4c6325SGustavo F. Padovan rcu_read_unlock(); 3053bf4c6325SGustavo F. Padovan 305402b20f0bSLuiz Augusto von Dentz } 305502b20f0bSLuiz Augusto von Dentz 3056b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) 3057b71d385aSAndrei Emeltchenko { 3058b71d385aSAndrei Emeltchenko /* Calculate count of blocks used by this packet */ 3059b71d385aSAndrei Emeltchenko return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); 3060b71d385aSAndrei Emeltchenko } 3061b71d385aSAndrei Emeltchenko 30626039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) 30631da177e4SLinus Torvalds { 30641da177e4SLinus Torvalds if (!test_bit(HCI_RAW, &hdev->flags)) { 30651da177e4SLinus Torvalds /* ACL tx timeout must be longer than maximum 30661da177e4SLinus Torvalds * link supervision timeout (40.9 seconds) */ 306763d2bc1bSAndrei Emeltchenko if (!cnt && time_after(jiffies, hdev->acl_last_tx + 30685f246e89SAndrei Emeltchenko HCI_ACL_TX_TIMEOUT)) 3069bae1f5d9SVille Tervo hci_link_tx_to(hdev, ACL_LINK); 30701da177e4SLinus Torvalds } 307163d2bc1bSAndrei Emeltchenko } 30721da177e4SLinus Torvalds 30736039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev) 307463d2bc1bSAndrei Emeltchenko { 307563d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt; 307663d2bc1bSAndrei Emeltchenko struct hci_chan *chan; 307763d2bc1bSAndrei Emeltchenko struct sk_buff *skb; 307863d2bc1bSAndrei Emeltchenko int quote; 307963d2bc1bSAndrei Emeltchenko 308063d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 308104837f64SMarcel Holtmann 308273d80debSLuiz Augusto von Dentz while (hdev->acl_cnt && 308373d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { 3084ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3085ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 308673d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 308773d80debSLuiz Augusto von Dentz skb->len, skb->priority); 308873d80debSLuiz Augusto von Dentz 3089ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3090ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3091ec1cce24SLuiz Augusto von Dentz break; 3092ec1cce24SLuiz Augusto von Dentz 3093ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3094ec1cce24SLuiz Augusto von Dentz 309573d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn, 309673d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active); 309704837f64SMarcel Holtmann 30981da177e4SLinus Torvalds hci_send_frame(skb); 30991da177e4SLinus Torvalds hdev->acl_last_tx = jiffies; 31001da177e4SLinus Torvalds 31011da177e4SLinus Torvalds hdev->acl_cnt--; 310273d80debSLuiz Augusto von Dentz chan->sent++; 310373d80debSLuiz Augusto von Dentz chan->conn->sent++; 31041da177e4SLinus Torvalds } 31051da177e4SLinus Torvalds } 310602b20f0bSLuiz Augusto von Dentz 310702b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt) 310802b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK); 31091da177e4SLinus Torvalds } 31101da177e4SLinus Torvalds 31116039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev) 3112b71d385aSAndrei Emeltchenko { 311363d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->block_cnt; 3114b71d385aSAndrei Emeltchenko struct hci_chan *chan; 3115b71d385aSAndrei Emeltchenko struct sk_buff *skb; 3116b71d385aSAndrei Emeltchenko int quote; 3117bd1eb66bSAndrei Emeltchenko u8 type; 3118b71d385aSAndrei Emeltchenko 311963d2bc1bSAndrei Emeltchenko __check_timeout(hdev, cnt); 3120b71d385aSAndrei Emeltchenko 3121bd1eb66bSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3122bd1eb66bSAndrei Emeltchenko 3123bd1eb66bSAndrei Emeltchenko if (hdev->dev_type == HCI_AMP) 3124bd1eb66bSAndrei Emeltchenko type = AMP_LINK; 3125bd1eb66bSAndrei Emeltchenko else 3126bd1eb66bSAndrei Emeltchenko type = ACL_LINK; 3127bd1eb66bSAndrei Emeltchenko 3128b71d385aSAndrei Emeltchenko while (hdev->block_cnt > 0 && 3129bd1eb66bSAndrei Emeltchenko (chan = hci_chan_sent(hdev, type, "e))) { 3130b71d385aSAndrei Emeltchenko u32 priority = (skb_peek(&chan->data_q))->priority; 3131b71d385aSAndrei Emeltchenko while (quote > 0 && (skb = skb_peek(&chan->data_q))) { 3132b71d385aSAndrei Emeltchenko int blocks; 3133b71d385aSAndrei Emeltchenko 3134b71d385aSAndrei Emeltchenko BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 3135b71d385aSAndrei Emeltchenko skb->len, skb->priority); 3136b71d385aSAndrei Emeltchenko 3137b71d385aSAndrei Emeltchenko /* Stop if priority has changed */ 3138b71d385aSAndrei Emeltchenko if (skb->priority < priority) 3139b71d385aSAndrei Emeltchenko break; 3140b71d385aSAndrei Emeltchenko 3141b71d385aSAndrei Emeltchenko skb = skb_dequeue(&chan->data_q); 3142b71d385aSAndrei Emeltchenko 3143b71d385aSAndrei Emeltchenko blocks = __get_blocks(hdev, skb); 3144b71d385aSAndrei Emeltchenko if (blocks > hdev->block_cnt) 3145b71d385aSAndrei Emeltchenko return; 3146b71d385aSAndrei Emeltchenko 3147b71d385aSAndrei Emeltchenko hci_conn_enter_active_mode(chan->conn, 3148b71d385aSAndrei Emeltchenko bt_cb(skb)->force_active); 3149b71d385aSAndrei Emeltchenko 3150b71d385aSAndrei Emeltchenko hci_send_frame(skb); 3151b71d385aSAndrei Emeltchenko hdev->acl_last_tx = jiffies; 3152b71d385aSAndrei Emeltchenko 3153b71d385aSAndrei Emeltchenko hdev->block_cnt -= blocks; 3154b71d385aSAndrei Emeltchenko quote -= blocks; 3155b71d385aSAndrei Emeltchenko 3156b71d385aSAndrei Emeltchenko chan->sent += blocks; 3157b71d385aSAndrei Emeltchenko chan->conn->sent += blocks; 3158b71d385aSAndrei Emeltchenko } 3159b71d385aSAndrei Emeltchenko } 3160b71d385aSAndrei Emeltchenko 3161b71d385aSAndrei Emeltchenko if (cnt != hdev->block_cnt) 3162bd1eb66bSAndrei Emeltchenko hci_prio_recalculate(hdev, type); 3163b71d385aSAndrei Emeltchenko } 3164b71d385aSAndrei Emeltchenko 31656039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev) 3166b71d385aSAndrei Emeltchenko { 3167b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name); 3168b71d385aSAndrei Emeltchenko 3169bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */ 3170bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) 3171bd1eb66bSAndrei Emeltchenko return; 3172bd1eb66bSAndrei Emeltchenko 3173bd1eb66bSAndrei Emeltchenko /* No AMP link over AMP controller */ 3174bd1eb66bSAndrei Emeltchenko if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) 3175b71d385aSAndrei Emeltchenko return; 3176b71d385aSAndrei Emeltchenko 3177b71d385aSAndrei Emeltchenko switch (hdev->flow_ctl_mode) { 3178b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_PACKET_BASED: 3179b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev); 3180b71d385aSAndrei Emeltchenko break; 3181b71d385aSAndrei Emeltchenko 3182b71d385aSAndrei Emeltchenko case HCI_FLOW_CTL_MODE_BLOCK_BASED: 3183b71d385aSAndrei Emeltchenko hci_sched_acl_blk(hdev); 3184b71d385aSAndrei Emeltchenko break; 3185b71d385aSAndrei Emeltchenko } 3186b71d385aSAndrei Emeltchenko } 3187b71d385aSAndrei Emeltchenko 31881da177e4SLinus Torvalds /* Schedule SCO */ 31896039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev) 31901da177e4SLinus Torvalds { 31911da177e4SLinus Torvalds struct hci_conn *conn; 31921da177e4SLinus Torvalds struct sk_buff *skb; 31931da177e4SLinus Torvalds int quote; 31941da177e4SLinus Torvalds 31951da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 31961da177e4SLinus Torvalds 319752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, SCO_LINK)) 319852087a79SLuiz Augusto von Dentz return; 319952087a79SLuiz Augusto von Dentz 32001da177e4SLinus Torvalds while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { 32011da177e4SLinus Torvalds while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 32021da177e4SLinus Torvalds BT_DBG("skb %p len %d", skb, skb->len); 32031da177e4SLinus Torvalds hci_send_frame(skb); 32041da177e4SLinus Torvalds 32051da177e4SLinus Torvalds conn->sent++; 32061da177e4SLinus Torvalds if (conn->sent == ~0) 32071da177e4SLinus Torvalds conn->sent = 0; 32081da177e4SLinus Torvalds } 32091da177e4SLinus Torvalds } 32101da177e4SLinus Torvalds } 32111da177e4SLinus Torvalds 32126039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev) 3213b6a0dc82SMarcel Holtmann { 3214b6a0dc82SMarcel Holtmann struct hci_conn *conn; 3215b6a0dc82SMarcel Holtmann struct sk_buff *skb; 3216b6a0dc82SMarcel Holtmann int quote; 3217b6a0dc82SMarcel Holtmann 3218b6a0dc82SMarcel Holtmann BT_DBG("%s", hdev->name); 3219b6a0dc82SMarcel Holtmann 322052087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ESCO_LINK)) 322152087a79SLuiz Augusto von Dentz return; 322252087a79SLuiz Augusto von Dentz 32238fc9ced3SGustavo Padovan while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, 32248fc9ced3SGustavo Padovan "e))) { 3225b6a0dc82SMarcel Holtmann while (quote-- && (skb = skb_dequeue(&conn->data_q))) { 3226b6a0dc82SMarcel Holtmann BT_DBG("skb %p len %d", skb, skb->len); 3227b6a0dc82SMarcel Holtmann hci_send_frame(skb); 3228b6a0dc82SMarcel Holtmann 3229b6a0dc82SMarcel Holtmann conn->sent++; 3230b6a0dc82SMarcel Holtmann if (conn->sent == ~0) 3231b6a0dc82SMarcel Holtmann conn->sent = 0; 3232b6a0dc82SMarcel Holtmann } 3233b6a0dc82SMarcel Holtmann } 3234b6a0dc82SMarcel Holtmann } 3235b6a0dc82SMarcel Holtmann 32366039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev) 32376ed58ec5SVille Tervo { 323873d80debSLuiz Augusto von Dentz struct hci_chan *chan; 32396ed58ec5SVille Tervo struct sk_buff *skb; 324002b20f0bSLuiz Augusto von Dentz int quote, cnt, tmp; 32416ed58ec5SVille Tervo 32426ed58ec5SVille Tervo BT_DBG("%s", hdev->name); 32436ed58ec5SVille Tervo 324452087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK)) 324552087a79SLuiz Augusto von Dentz return; 324652087a79SLuiz Augusto von Dentz 32476ed58ec5SVille Tervo if (!test_bit(HCI_RAW, &hdev->flags)) { 32486ed58ec5SVille Tervo /* LE tx timeout must be longer than maximum 32496ed58ec5SVille Tervo * link supervision timeout (40.9 seconds) */ 3250bae1f5d9SVille Tervo if (!hdev->le_cnt && hdev->le_pkts && 32516ed58ec5SVille Tervo time_after(jiffies, hdev->le_last_tx + HZ * 45)) 3252bae1f5d9SVille Tervo hci_link_tx_to(hdev, LE_LINK); 32536ed58ec5SVille Tervo } 32546ed58ec5SVille Tervo 32556ed58ec5SVille Tervo cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; 325602b20f0bSLuiz Augusto von Dentz tmp = cnt; 325773d80debSLuiz Augusto von Dentz while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { 3258ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority; 3259ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) { 326073d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb, 326173d80debSLuiz Augusto von Dentz skb->len, skb->priority); 32626ed58ec5SVille Tervo 3263ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */ 3264ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority) 3265ec1cce24SLuiz Augusto von Dentz break; 3266ec1cce24SLuiz Augusto von Dentz 3267ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q); 3268ec1cce24SLuiz Augusto von Dentz 32696ed58ec5SVille Tervo hci_send_frame(skb); 32706ed58ec5SVille Tervo hdev->le_last_tx = jiffies; 32716ed58ec5SVille Tervo 32726ed58ec5SVille Tervo cnt--; 327373d80debSLuiz Augusto von Dentz chan->sent++; 327473d80debSLuiz Augusto von Dentz chan->conn->sent++; 32756ed58ec5SVille Tervo } 32766ed58ec5SVille Tervo } 327773d80debSLuiz Augusto von Dentz 32786ed58ec5SVille Tervo if (hdev->le_pkts) 32796ed58ec5SVille Tervo hdev->le_cnt = cnt; 32806ed58ec5SVille Tervo else 32816ed58ec5SVille Tervo hdev->acl_cnt = cnt; 328202b20f0bSLuiz Augusto von Dentz 328302b20f0bSLuiz Augusto von Dentz if (cnt != tmp) 328402b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK); 32856ed58ec5SVille Tervo } 32866ed58ec5SVille Tervo 32873eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work) 32881da177e4SLinus Torvalds { 32893eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); 32901da177e4SLinus Torvalds struct sk_buff *skb; 32911da177e4SLinus Torvalds 32926ed58ec5SVille Tervo BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, 32936ed58ec5SVille Tervo hdev->sco_cnt, hdev->le_cnt); 32941da177e4SLinus Torvalds 3295*52de599eSMarcel Holtmann if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 32961da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */ 32971da177e4SLinus Torvalds hci_sched_acl(hdev); 32981da177e4SLinus Torvalds hci_sched_sco(hdev); 3299b6a0dc82SMarcel Holtmann hci_sched_esco(hdev); 33006ed58ec5SVille Tervo hci_sched_le(hdev); 3301*52de599eSMarcel Holtmann } 33026ed58ec5SVille Tervo 33031da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */ 33041da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q))) 33051da177e4SLinus Torvalds hci_send_frame(skb); 33061da177e4SLinus Torvalds } 33071da177e4SLinus Torvalds 330825985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */ 33091da177e4SLinus Torvalds 33101da177e4SLinus Torvalds /* ACL data packet */ 33116039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) 33121da177e4SLinus Torvalds { 33131da177e4SLinus Torvalds struct hci_acl_hdr *hdr = (void *) skb->data; 33141da177e4SLinus Torvalds struct hci_conn *conn; 33151da177e4SLinus Torvalds __u16 handle, flags; 33161da177e4SLinus Torvalds 33171da177e4SLinus Torvalds skb_pull(skb, HCI_ACL_HDR_SIZE); 33181da177e4SLinus Torvalds 33191da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 33201da177e4SLinus Torvalds flags = hci_flags(handle); 33211da177e4SLinus Torvalds handle = hci_handle(handle); 33221da177e4SLinus Torvalds 3323f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, 3324a8c5fb1aSGustavo Padovan handle, flags); 33251da177e4SLinus Torvalds 33261da177e4SLinus Torvalds hdev->stat.acl_rx++; 33271da177e4SLinus Torvalds 33281da177e4SLinus Torvalds hci_dev_lock(hdev); 33291da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 33301da177e4SLinus Torvalds hci_dev_unlock(hdev); 33311da177e4SLinus Torvalds 33321da177e4SLinus Torvalds if (conn) { 333365983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); 333404837f64SMarcel Holtmann 33351da177e4SLinus Torvalds /* Send to upper protocol */ 3336686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags); 33371da177e4SLinus Torvalds return; 33381da177e4SLinus Torvalds } else { 33391da177e4SLinus Torvalds BT_ERR("%s ACL packet for unknown connection handle %d", 33401da177e4SLinus Torvalds hdev->name, handle); 33411da177e4SLinus Torvalds } 33421da177e4SLinus Torvalds 33431da177e4SLinus Torvalds kfree_skb(skb); 33441da177e4SLinus Torvalds } 33451da177e4SLinus Torvalds 33461da177e4SLinus Torvalds /* SCO data packet */ 33476039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) 33481da177e4SLinus Torvalds { 33491da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data; 33501da177e4SLinus Torvalds struct hci_conn *conn; 33511da177e4SLinus Torvalds __u16 handle; 33521da177e4SLinus Torvalds 33531da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE); 33541da177e4SLinus Torvalds 33551da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle); 33561da177e4SLinus Torvalds 3357f0e09510SAndrei Emeltchenko BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); 33581da177e4SLinus Torvalds 33591da177e4SLinus Torvalds hdev->stat.sco_rx++; 33601da177e4SLinus Torvalds 33611da177e4SLinus Torvalds hci_dev_lock(hdev); 33621da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 33631da177e4SLinus Torvalds hci_dev_unlock(hdev); 33641da177e4SLinus Torvalds 33651da177e4SLinus Torvalds if (conn) { 33661da177e4SLinus Torvalds /* Send to upper protocol */ 3367686ebf28SUlisses Furquim sco_recv_scodata(conn, skb); 33681da177e4SLinus Torvalds return; 33691da177e4SLinus Torvalds } else { 33701da177e4SLinus Torvalds BT_ERR("%s SCO packet for unknown connection handle %d", 33711da177e4SLinus Torvalds hdev->name, handle); 33721da177e4SLinus Torvalds } 33731da177e4SLinus Torvalds 33741da177e4SLinus Torvalds kfree_skb(skb); 33751da177e4SLinus Torvalds } 33761da177e4SLinus Torvalds 33779238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev) 33789238f36aSJohan Hedberg { 33799238f36aSJohan Hedberg struct sk_buff *skb; 33809238f36aSJohan Hedberg 33819238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q); 33829238f36aSJohan Hedberg if (!skb) 33839238f36aSJohan Hedberg return true; 33849238f36aSJohan Hedberg 33859238f36aSJohan Hedberg return bt_cb(skb)->req.start; 33869238f36aSJohan Hedberg } 33879238f36aSJohan Hedberg 338842c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev) 338942c6b129SJohan Hedberg { 339042c6b129SJohan Hedberg struct hci_command_hdr *sent; 339142c6b129SJohan Hedberg struct sk_buff *skb; 339242c6b129SJohan Hedberg u16 opcode; 339342c6b129SJohan Hedberg 339442c6b129SJohan Hedberg if (!hdev->sent_cmd) 339542c6b129SJohan Hedberg return; 339642c6b129SJohan Hedberg 339742c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data; 339842c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode); 339942c6b129SJohan Hedberg if (opcode == HCI_OP_RESET) 340042c6b129SJohan Hedberg return; 340142c6b129SJohan Hedberg 340242c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); 340342c6b129SJohan Hedberg if (!skb) 340442c6b129SJohan Hedberg return; 340542c6b129SJohan Hedberg 340642c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb); 340742c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work); 340842c6b129SJohan Hedberg } 340942c6b129SJohan Hedberg 34109238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 34119238f36aSJohan Hedberg { 34129238f36aSJohan Hedberg hci_req_complete_t req_complete = NULL; 34139238f36aSJohan Hedberg struct sk_buff *skb; 34149238f36aSJohan Hedberg unsigned long flags; 34159238f36aSJohan Hedberg 34169238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); 34179238f36aSJohan Hedberg 341842c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was 341942c6b129SJohan Hedberg * sent we need to do special handling of it. 34209238f36aSJohan Hedberg */ 342142c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) { 342242c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous 342342c6b129SJohan Hedberg * reset complete event during init and any pending 342442c6b129SJohan Hedberg * command will never be completed. In such a case we 342542c6b129SJohan Hedberg * need to resend whatever was the last sent 342642c6b129SJohan Hedberg * command. 342742c6b129SJohan Hedberg */ 342842c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET) 342942c6b129SJohan Hedberg hci_resend_last(hdev); 343042c6b129SJohan Hedberg 34319238f36aSJohan Hedberg return; 343242c6b129SJohan Hedberg } 34339238f36aSJohan Hedberg 34349238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in 34359238f36aSJohan Hedberg * this request the request is not yet complete. 34369238f36aSJohan Hedberg */ 34379238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev)) 34389238f36aSJohan Hedberg return; 34399238f36aSJohan Hedberg 34409238f36aSJohan Hedberg /* If this was the last command in a request the complete 34419238f36aSJohan Hedberg * callback would be found in hdev->sent_cmd instead of the 34429238f36aSJohan Hedberg * command queue (hdev->cmd_q). 34439238f36aSJohan Hedberg */ 34449238f36aSJohan Hedberg if (hdev->sent_cmd) { 34459238f36aSJohan Hedberg req_complete = bt_cb(hdev->sent_cmd)->req.complete; 344653e21fbcSJohan Hedberg 344753e21fbcSJohan Hedberg if (req_complete) { 344853e21fbcSJohan Hedberg /* We must set the complete callback to NULL to 344953e21fbcSJohan Hedberg * avoid calling the callback more than once if 345053e21fbcSJohan Hedberg * this function gets called again. 345153e21fbcSJohan Hedberg */ 345253e21fbcSJohan Hedberg bt_cb(hdev->sent_cmd)->req.complete = NULL; 345353e21fbcSJohan Hedberg 34549238f36aSJohan Hedberg goto call_complete; 34559238f36aSJohan Hedberg } 345653e21fbcSJohan Hedberg } 34579238f36aSJohan Hedberg 34589238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */ 34599238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags); 34609238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) { 34619238f36aSJohan Hedberg if (bt_cb(skb)->req.start) { 34629238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb); 34639238f36aSJohan Hedberg break; 34649238f36aSJohan Hedberg } 34659238f36aSJohan Hedberg 34669238f36aSJohan Hedberg req_complete = bt_cb(skb)->req.complete; 34679238f36aSJohan Hedberg kfree_skb(skb); 34689238f36aSJohan Hedberg } 34699238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 34709238f36aSJohan Hedberg 34719238f36aSJohan Hedberg call_complete: 34729238f36aSJohan Hedberg if (req_complete) 34739238f36aSJohan Hedberg req_complete(hdev, status); 34749238f36aSJohan Hedberg } 34759238f36aSJohan Hedberg 3476b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work) 34771da177e4SLinus Torvalds { 3478b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); 34791da177e4SLinus Torvalds struct sk_buff *skb; 34801da177e4SLinus Torvalds 34811da177e4SLinus Torvalds BT_DBG("%s", hdev->name); 34821da177e4SLinus Torvalds 34831da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->rx_q))) { 3484cd82e61cSMarcel Holtmann /* Send copy to monitor */ 3485cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb); 3486cd82e61cSMarcel Holtmann 34871da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) { 34881da177e4SLinus Torvalds /* Send copy to the sockets */ 3489470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb); 34901da177e4SLinus Torvalds } 34911da177e4SLinus Torvalds 34920736cfa8SMarcel Holtmann if (test_bit(HCI_RAW, &hdev->flags) || 34930736cfa8SMarcel Holtmann test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { 34941da177e4SLinus Torvalds kfree_skb(skb); 34951da177e4SLinus Torvalds continue; 34961da177e4SLinus Torvalds } 34971da177e4SLinus Torvalds 34981da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) { 34991da177e4SLinus Torvalds /* Don't process data packets in this states. */ 35000d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 35011da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 35021da177e4SLinus Torvalds case HCI_SCODATA_PKT: 35031da177e4SLinus Torvalds kfree_skb(skb); 35041da177e4SLinus Torvalds continue; 35053ff50b79SStephen Hemminger } 35061da177e4SLinus Torvalds } 35071da177e4SLinus Torvalds 35081da177e4SLinus Torvalds /* Process frame */ 35090d48d939SMarcel Holtmann switch (bt_cb(skb)->pkt_type) { 35101da177e4SLinus Torvalds case HCI_EVENT_PKT: 3511b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name); 35121da177e4SLinus Torvalds hci_event_packet(hdev, skb); 35131da177e4SLinus Torvalds break; 35141da177e4SLinus Torvalds 35151da177e4SLinus Torvalds case HCI_ACLDATA_PKT: 35161da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name); 35171da177e4SLinus Torvalds hci_acldata_packet(hdev, skb); 35181da177e4SLinus Torvalds break; 35191da177e4SLinus Torvalds 35201da177e4SLinus Torvalds case HCI_SCODATA_PKT: 35211da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name); 35221da177e4SLinus Torvalds hci_scodata_packet(hdev, skb); 35231da177e4SLinus Torvalds break; 35241da177e4SLinus Torvalds 35251da177e4SLinus Torvalds default: 35261da177e4SLinus Torvalds kfree_skb(skb); 35271da177e4SLinus Torvalds break; 35281da177e4SLinus Torvalds } 35291da177e4SLinus Torvalds } 35301da177e4SLinus Torvalds } 35311da177e4SLinus Torvalds 3532c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work) 35331da177e4SLinus Torvalds { 3534c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); 35351da177e4SLinus Torvalds struct sk_buff *skb; 35361da177e4SLinus Torvalds 35372104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, 35382104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); 35391da177e4SLinus Torvalds 35401da177e4SLinus Torvalds /* Send queued commands */ 35415a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) { 35425a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q); 35435a08ecceSAndrei Emeltchenko if (!skb) 35445a08ecceSAndrei Emeltchenko return; 35455a08ecceSAndrei Emeltchenko 35461da177e4SLinus Torvalds kfree_skb(hdev->sent_cmd); 35471da177e4SLinus Torvalds 3548a675d7f1SMarcel Holtmann hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); 354970f23020SAndrei Emeltchenko if (hdev->sent_cmd) { 35501da177e4SLinus Torvalds atomic_dec(&hdev->cmd_cnt); 35511da177e4SLinus Torvalds hci_send_frame(skb); 35527bdb8a5cSSzymon Janc if (test_bit(HCI_RESET, &hdev->flags)) 35537bdb8a5cSSzymon Janc del_timer(&hdev->cmd_timer); 35547bdb8a5cSSzymon Janc else 35556bd32326SVille Tervo mod_timer(&hdev->cmd_timer, 35565f246e89SAndrei Emeltchenko jiffies + HCI_CMD_TIMEOUT); 35571da177e4SLinus Torvalds } else { 35581da177e4SLinus Torvalds skb_queue_head(&hdev->cmd_q, skb); 3559c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 35601da177e4SLinus Torvalds } 35611da177e4SLinus Torvalds } 35621da177e4SLinus Torvalds } 35632519a1fcSAndre Guedes 356431f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type) 356531f7956cSAndre Guedes { 356631f7956cSAndre Guedes switch (bdaddr_type) { 356731f7956cSAndre Guedes case BDADDR_LE_PUBLIC: 356831f7956cSAndre Guedes return ADDR_LE_DEV_PUBLIC; 356931f7956cSAndre Guedes 357031f7956cSAndre Guedes default: 357131f7956cSAndre Guedes /* Fallback to LE Random address type */ 357231f7956cSAndre Guedes return ADDR_LE_DEV_RANDOM; 357331f7956cSAndre Guedes } 357431f7956cSAndre Guedes } 3575