11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 32d0a0346SRon Shaffer Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. 41da177e4SLinus Torvalds 51da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 61da177e4SLinus Torvalds 71da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 81da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 91da177e4SLinus Torvalds published by the Free Software Foundation; 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 121da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 131da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 141da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 151da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 161da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 171da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 181da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 211da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 221da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 231da177e4SLinus Torvalds */ 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds /* Bluetooth HCI event handling. */ 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds #include <linux/module.h> 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds #include <linux/types.h> 301da177e4SLinus Torvalds #include <linux/errno.h> 311da177e4SLinus Torvalds #include <linux/kernel.h> 321da177e4SLinus Torvalds #include <linux/slab.h> 331da177e4SLinus Torvalds #include <linux/poll.h> 341da177e4SLinus Torvalds #include <linux/fcntl.h> 351da177e4SLinus Torvalds #include <linux/init.h> 361da177e4SLinus Torvalds #include <linux/skbuff.h> 371da177e4SLinus Torvalds #include <linux/interrupt.h> 381da177e4SLinus Torvalds #include <linux/notifier.h> 391da177e4SLinus Torvalds #include <net/sock.h> 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds #include <asm/system.h> 4270f23020SAndrei Emeltchenko #include <linux/uaccess.h> 431da177e4SLinus Torvalds #include <asm/unaligned.h> 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 461da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 471da177e4SLinus Torvalds 48eb939922SRusty Russell static bool enable_le; 49e6100a25SAndre Guedes 501da177e4SLinus Torvalds /* Handle HCI Event packets */ 511da177e4SLinus Torvalds 52a9de9248SMarcel Holtmann static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) 531da177e4SLinus Torvalds { 54a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 551da177e4SLinus Torvalds 56a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 571da177e4SLinus Torvalds 58e6d465cbSAndre Guedes if (status) { 59e6d465cbSAndre Guedes hci_dev_lock(hdev); 60e6d465cbSAndre Guedes mgmt_stop_discovery_failed(hdev, status); 61e6d465cbSAndre Guedes hci_dev_unlock(hdev); 62a9de9248SMarcel Holtmann return; 63e6d465cbSAndre Guedes } 641da177e4SLinus Torvalds 6589352e7dSAndre Guedes clear_bit(HCI_INQUIRY, &hdev->flags); 6689352e7dSAndre Guedes 6756e5cb86SJohan Hedberg hci_dev_lock(hdev); 68ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 6956e5cb86SJohan Hedberg hci_dev_unlock(hdev); 70a9de9248SMarcel Holtmann 7123bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); 72a9de9248SMarcel Holtmann 73a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 741da177e4SLinus Torvalds } 756bd57416SMarcel Holtmann 76a9de9248SMarcel Holtmann static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) 771da177e4SLinus Torvalds { 78a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 79a9de9248SMarcel Holtmann 80a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 81a9de9248SMarcel Holtmann 82a9de9248SMarcel Holtmann if (status) 83a9de9248SMarcel Holtmann return; 84a9de9248SMarcel Holtmann 85a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 86a9de9248SMarcel Holtmann } 87a9de9248SMarcel Holtmann 88a9de9248SMarcel Holtmann static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb) 89a9de9248SMarcel Holtmann { 90a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 91a9de9248SMarcel Holtmann } 92a9de9248SMarcel Holtmann 93a9de9248SMarcel Holtmann static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb) 94a9de9248SMarcel Holtmann { 95a9de9248SMarcel Holtmann struct hci_rp_role_discovery *rp = (void *) skb->data; 961da177e4SLinus Torvalds struct hci_conn *conn; 971da177e4SLinus Torvalds 98a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 991da177e4SLinus Torvalds 100a9de9248SMarcel Holtmann if (rp->status) 101a9de9248SMarcel Holtmann return; 1021da177e4SLinus Torvalds 1031da177e4SLinus Torvalds hci_dev_lock(hdev); 1041da177e4SLinus Torvalds 105a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 1061da177e4SLinus Torvalds if (conn) { 107a9de9248SMarcel Holtmann if (rp->role) 1081da177e4SLinus Torvalds conn->link_mode &= ~HCI_LM_MASTER; 1091da177e4SLinus Torvalds else 1101da177e4SLinus Torvalds conn->link_mode |= HCI_LM_MASTER; 1111da177e4SLinus Torvalds } 1121da177e4SLinus Torvalds 1131da177e4SLinus Torvalds hci_dev_unlock(hdev); 114a9de9248SMarcel Holtmann } 1151da177e4SLinus Torvalds 116e4e8e37cSMarcel Holtmann static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 117e4e8e37cSMarcel Holtmann { 118e4e8e37cSMarcel Holtmann struct hci_rp_read_link_policy *rp = (void *) skb->data; 119e4e8e37cSMarcel Holtmann struct hci_conn *conn; 120e4e8e37cSMarcel Holtmann 121e4e8e37cSMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 122e4e8e37cSMarcel Holtmann 123e4e8e37cSMarcel Holtmann if (rp->status) 124e4e8e37cSMarcel Holtmann return; 125e4e8e37cSMarcel Holtmann 126e4e8e37cSMarcel Holtmann hci_dev_lock(hdev); 127e4e8e37cSMarcel Holtmann 128e4e8e37cSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 129e4e8e37cSMarcel Holtmann if (conn) 130e4e8e37cSMarcel Holtmann conn->link_policy = __le16_to_cpu(rp->policy); 131e4e8e37cSMarcel Holtmann 132e4e8e37cSMarcel Holtmann hci_dev_unlock(hdev); 133e4e8e37cSMarcel Holtmann } 134e4e8e37cSMarcel Holtmann 135a9de9248SMarcel Holtmann static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 136a9de9248SMarcel Holtmann { 137a9de9248SMarcel Holtmann struct hci_rp_write_link_policy *rp = (void *) skb->data; 138a9de9248SMarcel Holtmann struct hci_conn *conn; 139a9de9248SMarcel Holtmann void *sent; 140a9de9248SMarcel Holtmann 141a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 142a9de9248SMarcel Holtmann 143a9de9248SMarcel Holtmann if (rp->status) 144a9de9248SMarcel Holtmann return; 145a9de9248SMarcel Holtmann 146a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY); 14704837f64SMarcel Holtmann if (!sent) 148a9de9248SMarcel Holtmann return; 14904837f64SMarcel Holtmann 15004837f64SMarcel Holtmann hci_dev_lock(hdev); 15104837f64SMarcel Holtmann 152a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 153e4e8e37cSMarcel Holtmann if (conn) 15483985319SHarvey Harrison conn->link_policy = get_unaligned_le16(sent + 2); 15504837f64SMarcel Holtmann 15604837f64SMarcel Holtmann hci_dev_unlock(hdev); 1571da177e4SLinus Torvalds } 1581da177e4SLinus Torvalds 159e4e8e37cSMarcel Holtmann static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 160e4e8e37cSMarcel Holtmann { 161e4e8e37cSMarcel Holtmann struct hci_rp_read_def_link_policy *rp = (void *) skb->data; 162e4e8e37cSMarcel Holtmann 163e4e8e37cSMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 164e4e8e37cSMarcel Holtmann 165e4e8e37cSMarcel Holtmann if (rp->status) 166e4e8e37cSMarcel Holtmann return; 167e4e8e37cSMarcel Holtmann 168e4e8e37cSMarcel Holtmann hdev->link_policy = __le16_to_cpu(rp->policy); 169e4e8e37cSMarcel Holtmann } 170e4e8e37cSMarcel Holtmann 171e4e8e37cSMarcel Holtmann static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 172e4e8e37cSMarcel Holtmann { 173e4e8e37cSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 174e4e8e37cSMarcel Holtmann void *sent; 175e4e8e37cSMarcel Holtmann 176e4e8e37cSMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 177e4e8e37cSMarcel Holtmann 178e4e8e37cSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); 179e4e8e37cSMarcel Holtmann if (!sent) 180e4e8e37cSMarcel Holtmann return; 181e4e8e37cSMarcel Holtmann 182e4e8e37cSMarcel Holtmann if (!status) 183e4e8e37cSMarcel Holtmann hdev->link_policy = get_unaligned_le16(sent); 184e4e8e37cSMarcel Holtmann 18523bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status); 186e4e8e37cSMarcel Holtmann } 187e4e8e37cSMarcel Holtmann 188a9de9248SMarcel Holtmann static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) 1891da177e4SLinus Torvalds { 190a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 191a9de9248SMarcel Holtmann 192a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 193a9de9248SMarcel Holtmann 19410572132SGustavo F. Padovan clear_bit(HCI_RESET, &hdev->flags); 19510572132SGustavo F. Padovan 19623bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_RESET, status); 197d23264a8SAndre Guedes 1987005ff17SJohan Hedberg /* Reset all flags, except persistent ones */ 19995947a39SHemant Gupta hdev->dev_flags &= BIT(HCI_MGMT) | BIT(HCI_SETUP) | BIT(HCI_AUTO_OFF) | 20095947a39SHemant Gupta BIT(HCI_LINK_KEYS) | BIT(HCI_DEBUG_KEYS); 201a9de9248SMarcel Holtmann } 202a9de9248SMarcel Holtmann 203a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 204a9de9248SMarcel Holtmann { 205a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 2061da177e4SLinus Torvalds void *sent; 2071da177e4SLinus Torvalds 208a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 2091da177e4SLinus Torvalds 210a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); 2111da177e4SLinus Torvalds if (!sent) 212a9de9248SMarcel Holtmann return; 2131da177e4SLinus Torvalds 21456e5cb86SJohan Hedberg hci_dev_lock(hdev); 21556e5cb86SJohan Hedberg 216a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 217744cf19eSJohan Hedberg mgmt_set_local_name_complete(hdev, sent, status); 218b312b161SJohan Hedberg 21956e5cb86SJohan Hedberg if (status == 0) 2201f6c6378SJohan Hedberg memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 22156e5cb86SJohan Hedberg 22256e5cb86SJohan Hedberg hci_dev_unlock(hdev); 223a9de9248SMarcel Holtmann } 224a9de9248SMarcel Holtmann 225a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) 226a9de9248SMarcel Holtmann { 227a9de9248SMarcel Holtmann struct hci_rp_read_local_name *rp = (void *) skb->data; 228a9de9248SMarcel Holtmann 229a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 230a9de9248SMarcel Holtmann 231a9de9248SMarcel Holtmann if (rp->status) 232a9de9248SMarcel Holtmann return; 233a9de9248SMarcel Holtmann 2341f6c6378SJohan Hedberg memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); 235a9de9248SMarcel Holtmann } 236a9de9248SMarcel Holtmann 237a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) 238a9de9248SMarcel Holtmann { 239a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 240a9de9248SMarcel Holtmann void *sent; 241a9de9248SMarcel Holtmann 242a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 243a9de9248SMarcel Holtmann 244a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); 245a9de9248SMarcel Holtmann if (!sent) 246a9de9248SMarcel Holtmann return; 2471da177e4SLinus Torvalds 2481da177e4SLinus Torvalds if (!status) { 249a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 250a9de9248SMarcel Holtmann 2511da177e4SLinus Torvalds if (param == AUTH_ENABLED) 2521da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags); 2531da177e4SLinus Torvalds else 2541da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags); 2551da177e4SLinus Torvalds } 256a9de9248SMarcel Holtmann 25723bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status); 258a9de9248SMarcel Holtmann } 2591da177e4SLinus Torvalds 260a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) 261a9de9248SMarcel Holtmann { 262a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 263a9de9248SMarcel Holtmann void *sent; 264a9de9248SMarcel Holtmann 265a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 266a9de9248SMarcel Holtmann 267a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); 2681da177e4SLinus Torvalds if (!sent) 269a9de9248SMarcel Holtmann return; 2701da177e4SLinus Torvalds 2711da177e4SLinus Torvalds if (!status) { 272a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 273a9de9248SMarcel Holtmann 2741da177e4SLinus Torvalds if (param) 2751da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags); 2761da177e4SLinus Torvalds else 2771da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags); 2781da177e4SLinus Torvalds } 279a9de9248SMarcel Holtmann 28023bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status); 2811da177e4SLinus Torvalds } 2821da177e4SLinus Torvalds 283a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) 284a9de9248SMarcel Holtmann { 28536f7fc7eSJohan Hedberg __u8 param, status = *((__u8 *) skb->data); 28636f7fc7eSJohan Hedberg int old_pscan, old_iscan; 287a9de9248SMarcel Holtmann void *sent; 2881da177e4SLinus Torvalds 289a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 290a9de9248SMarcel Holtmann 291a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); 2921da177e4SLinus Torvalds if (!sent) 293a9de9248SMarcel Holtmann return; 2941da177e4SLinus Torvalds 29536f7fc7eSJohan Hedberg param = *((__u8 *) sent); 296a9de9248SMarcel Holtmann 29756e5cb86SJohan Hedberg hci_dev_lock(hdev); 29856e5cb86SJohan Hedberg 2992d7cee58SJohan Hedberg if (status != 0) { 300744cf19eSJohan Hedberg mgmt_write_scan_failed(hdev, param, status); 3012d7cee58SJohan Hedberg hdev->discov_timeout = 0; 3022d7cee58SJohan Hedberg goto done; 3032d7cee58SJohan Hedberg } 3042d7cee58SJohan Hedberg 3059fbcbb45SJohan Hedberg old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags); 3069fbcbb45SJohan Hedberg old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags); 307a9de9248SMarcel Holtmann 30873f22f62SJohan Hedberg if (param & SCAN_INQUIRY) { 3091da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags); 3109fbcbb45SJohan Hedberg if (!old_iscan) 311744cf19eSJohan Hedberg mgmt_discoverable(hdev, 1); 31216ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 31316ab91abSJohan Hedberg int to = msecs_to_jiffies(hdev->discov_timeout * 1000); 31416ab91abSJohan Hedberg queue_delayed_work(hdev->workqueue, &hdev->discov_off, 31516ab91abSJohan Hedberg to); 31616ab91abSJohan Hedberg } 3179fbcbb45SJohan Hedberg } else if (old_iscan) 318744cf19eSJohan Hedberg mgmt_discoverable(hdev, 0); 3191da177e4SLinus Torvalds 3209fbcbb45SJohan Hedberg if (param & SCAN_PAGE) { 3211da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags); 3229fbcbb45SJohan Hedberg if (!old_pscan) 323744cf19eSJohan Hedberg mgmt_connectable(hdev, 1); 3249fbcbb45SJohan Hedberg } else if (old_pscan) 325744cf19eSJohan Hedberg mgmt_connectable(hdev, 0); 326a9de9248SMarcel Holtmann 32736f7fc7eSJohan Hedberg done: 32856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 32923bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); 3301da177e4SLinus Torvalds } 3311da177e4SLinus Torvalds 332a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 333a9de9248SMarcel Holtmann { 334a9de9248SMarcel Holtmann struct hci_rp_read_class_of_dev *rp = (void *) skb->data; 335a9de9248SMarcel Holtmann 336a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 337a9de9248SMarcel Holtmann 338a9de9248SMarcel Holtmann if (rp->status) 339a9de9248SMarcel Holtmann return; 340a9de9248SMarcel Holtmann 341a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3); 342a9de9248SMarcel Holtmann 343a9de9248SMarcel Holtmann BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name, 344a9de9248SMarcel Holtmann hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); 345a9de9248SMarcel Holtmann } 346a9de9248SMarcel Holtmann 347a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 348a9de9248SMarcel Holtmann { 349a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 350a9de9248SMarcel Holtmann void *sent; 351a9de9248SMarcel Holtmann 352a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 353a9de9248SMarcel Holtmann 354f383f275SMarcel Holtmann if (status) 355f383f275SMarcel Holtmann return; 356f383f275SMarcel Holtmann 357a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); 358a9de9248SMarcel Holtmann if (!sent) 359a9de9248SMarcel Holtmann return; 360a9de9248SMarcel Holtmann 361a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3); 362a9de9248SMarcel Holtmann } 363a9de9248SMarcel Holtmann 364a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 365a9de9248SMarcel Holtmann { 366a9de9248SMarcel Holtmann struct hci_rp_read_voice_setting *rp = (void *) skb->data; 367a9de9248SMarcel Holtmann __u16 setting; 368a9de9248SMarcel Holtmann 369a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 370a9de9248SMarcel Holtmann 371a9de9248SMarcel Holtmann if (rp->status) 372a9de9248SMarcel Holtmann return; 373a9de9248SMarcel Holtmann 374a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting); 375a9de9248SMarcel Holtmann 376a9de9248SMarcel Holtmann if (hdev->voice_setting == setting) 377a9de9248SMarcel Holtmann return; 378a9de9248SMarcel Holtmann 379a9de9248SMarcel Holtmann hdev->voice_setting = setting; 380a9de9248SMarcel Holtmann 381a9de9248SMarcel Holtmann BT_DBG("%s voice setting 0x%04x", hdev->name, setting); 382a9de9248SMarcel Holtmann 3833c54711cSGustavo F. Padovan if (hdev->notify) 384a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 385a9de9248SMarcel Holtmann } 386a9de9248SMarcel Holtmann 387a9de9248SMarcel Holtmann static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 388a9de9248SMarcel Holtmann { 389a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 390f383f275SMarcel Holtmann __u16 setting; 391a9de9248SMarcel Holtmann void *sent; 392a9de9248SMarcel Holtmann 393a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 394a9de9248SMarcel Holtmann 395f383f275SMarcel Holtmann if (status) 396f383f275SMarcel Holtmann return; 397f383f275SMarcel Holtmann 398a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); 399a9de9248SMarcel Holtmann if (!sent) 400a9de9248SMarcel Holtmann return; 401a9de9248SMarcel Holtmann 402f383f275SMarcel Holtmann setting = get_unaligned_le16(sent); 4031da177e4SLinus Torvalds 404f383f275SMarcel Holtmann if (hdev->voice_setting == setting) 405f383f275SMarcel Holtmann return; 406f383f275SMarcel Holtmann 4071da177e4SLinus Torvalds hdev->voice_setting = setting; 4081da177e4SLinus Torvalds 409a9de9248SMarcel Holtmann BT_DBG("%s voice setting 0x%04x", hdev->name, setting); 4101da177e4SLinus Torvalds 4113c54711cSGustavo F. Padovan if (hdev->notify) 4121da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 4131da177e4SLinus Torvalds } 4141da177e4SLinus Torvalds 415a9de9248SMarcel Holtmann static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 4161da177e4SLinus Torvalds { 417a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 4181da177e4SLinus Torvalds 419a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 4201da177e4SLinus Torvalds 42123bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status); 4221143e5a6SMarcel Holtmann } 4231143e5a6SMarcel Holtmann 424333140b5SMarcel Holtmann static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 425333140b5SMarcel Holtmann { 426333140b5SMarcel Holtmann struct hci_rp_read_ssp_mode *rp = (void *) skb->data; 427333140b5SMarcel Holtmann 428333140b5SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 429333140b5SMarcel Holtmann 430333140b5SMarcel Holtmann if (rp->status) 431333140b5SMarcel Holtmann return; 432333140b5SMarcel Holtmann 43384bde9d6SJohan Hedberg if (rp->mode) 43484bde9d6SJohan Hedberg set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 43584bde9d6SJohan Hedberg else 43684bde9d6SJohan Hedberg clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 437333140b5SMarcel Holtmann } 438333140b5SMarcel Holtmann 439333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 440333140b5SMarcel Holtmann { 441333140b5SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 442333140b5SMarcel Holtmann void *sent; 443333140b5SMarcel Holtmann 444333140b5SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 445333140b5SMarcel Holtmann 446333140b5SMarcel Holtmann if (status) 447333140b5SMarcel Holtmann return; 448333140b5SMarcel Holtmann 449333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); 450333140b5SMarcel Holtmann if (!sent) 451333140b5SMarcel Holtmann return; 452333140b5SMarcel Holtmann 45384bde9d6SJohan Hedberg if (*((u8 *) sent)) 45484bde9d6SJohan Hedberg set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 45584bde9d6SJohan Hedberg else 45684bde9d6SJohan Hedberg clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 457333140b5SMarcel Holtmann } 458333140b5SMarcel Holtmann 459d5859e22SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 460d5859e22SJohan Hedberg { 461d5859e22SJohan Hedberg if (hdev->features[6] & LMP_EXT_INQ) 462d5859e22SJohan Hedberg return 2; 463d5859e22SJohan Hedberg 464d5859e22SJohan Hedberg if (hdev->features[3] & LMP_RSSI_INQ) 465d5859e22SJohan Hedberg return 1; 466d5859e22SJohan Hedberg 467d5859e22SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 468d5859e22SJohan Hedberg hdev->lmp_subver == 0x0757) 469d5859e22SJohan Hedberg return 1; 470d5859e22SJohan Hedberg 471d5859e22SJohan Hedberg if (hdev->manufacturer == 15) { 472d5859e22SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 473d5859e22SJohan Hedberg return 1; 474d5859e22SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 475d5859e22SJohan Hedberg return 1; 476d5859e22SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 477d5859e22SJohan Hedberg return 1; 478d5859e22SJohan Hedberg } 479d5859e22SJohan Hedberg 480d5859e22SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 481d5859e22SJohan Hedberg hdev->lmp_subver == 0x1805) 482d5859e22SJohan Hedberg return 1; 483d5859e22SJohan Hedberg 484d5859e22SJohan Hedberg return 0; 485d5859e22SJohan Hedberg } 486d5859e22SJohan Hedberg 487d5859e22SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_dev *hdev) 488d5859e22SJohan Hedberg { 489d5859e22SJohan Hedberg u8 mode; 490d5859e22SJohan Hedberg 491d5859e22SJohan Hedberg mode = hci_get_inquiry_mode(hdev); 492d5859e22SJohan Hedberg 493d5859e22SJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 494d5859e22SJohan Hedberg } 495d5859e22SJohan Hedberg 496d5859e22SJohan Hedberg static void hci_setup_event_mask(struct hci_dev *hdev) 497d5859e22SJohan Hedberg { 498d5859e22SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 499d5859e22SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 500d5859e22SJohan Hedberg * command otherwise */ 501d5859e22SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 502d5859e22SJohan Hedberg 5036de6c18dSVille Tervo /* CSR 1.1 dongles does not accept any bitfield so don't try to set 5046de6c18dSVille Tervo * any event mask for pre 1.2 devices */ 5055a13b095SAndrei Emeltchenko if (hdev->hci_ver < BLUETOOTH_VER_1_2) 5066de6c18dSVille Tervo return; 5076de6c18dSVille Tervo 508d5859e22SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 509d5859e22SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 510d5859e22SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 511d5859e22SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 512d5859e22SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 513d5859e22SJohan Hedberg 514d5859e22SJohan Hedberg if (hdev->features[3] & LMP_RSSI_INQ) 515d5859e22SJohan Hedberg events[4] |= 0x04; /* Inquiry Result with RSSI */ 516d5859e22SJohan Hedberg 517d5859e22SJohan Hedberg if (hdev->features[5] & LMP_SNIFF_SUBR) 518d5859e22SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 519d5859e22SJohan Hedberg 520d5859e22SJohan Hedberg if (hdev->features[5] & LMP_PAUSE_ENC) 521d5859e22SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 522d5859e22SJohan Hedberg 523d5859e22SJohan Hedberg if (hdev->features[6] & LMP_EXT_INQ) 524d5859e22SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 525d5859e22SJohan Hedberg 526d5859e22SJohan Hedberg if (hdev->features[6] & LMP_NO_FLUSH) 527d5859e22SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 528d5859e22SJohan Hedberg 529d5859e22SJohan Hedberg if (hdev->features[7] & LMP_LSTO) 530d5859e22SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 531d5859e22SJohan Hedberg 532d5859e22SJohan Hedberg if (hdev->features[6] & LMP_SIMPLE_PAIR) { 533d5859e22SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 534d5859e22SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 535d5859e22SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 536d5859e22SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 537d5859e22SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 538d5859e22SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 539d5859e22SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 540d5859e22SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 541d5859e22SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 542d5859e22SJohan Hedberg * Features Notification */ 543d5859e22SJohan Hedberg } 544d5859e22SJohan Hedberg 545d5859e22SJohan Hedberg if (hdev->features[4] & LMP_LE) 546d5859e22SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 547d5859e22SJohan Hedberg 548d5859e22SJohan Hedberg hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 549d5859e22SJohan Hedberg } 550d5859e22SJohan Hedberg 551e6100a25SAndre Guedes static void hci_set_le_support(struct hci_dev *hdev) 552e6100a25SAndre Guedes { 553e6100a25SAndre Guedes struct hci_cp_write_le_host_supported cp; 554e6100a25SAndre Guedes 555e6100a25SAndre Guedes memset(&cp, 0, sizeof(cp)); 556e6100a25SAndre Guedes 557e6100a25SAndre Guedes if (enable_le) { 558e6100a25SAndre Guedes cp.le = 1; 559e6100a25SAndre Guedes cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); 560e6100a25SAndre Guedes } 561e6100a25SAndre Guedes 562e6100a25SAndre Guedes hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp); 563e6100a25SAndre Guedes } 564e6100a25SAndre Guedes 565d5859e22SJohan Hedberg static void hci_setup(struct hci_dev *hdev) 566d5859e22SJohan Hedberg { 567e61ef499SAndrei Emeltchenko if (hdev->dev_type != HCI_BREDR) 568e61ef499SAndrei Emeltchenko return; 569e61ef499SAndrei Emeltchenko 570d5859e22SJohan Hedberg hci_setup_event_mask(hdev); 571d5859e22SJohan Hedberg 572d095c1ebSAndrei Emeltchenko if (hdev->hci_ver > BLUETOOTH_VER_1_1) 573d5859e22SJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 574d5859e22SJohan Hedberg 575d5859e22SJohan Hedberg if (hdev->features[6] & LMP_SIMPLE_PAIR) { 576d5859e22SJohan Hedberg u8 mode = 0x01; 577d5859e22SJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode); 578d5859e22SJohan Hedberg } 579d5859e22SJohan Hedberg 580d5859e22SJohan Hedberg if (hdev->features[3] & LMP_RSSI_INQ) 581d5859e22SJohan Hedberg hci_setup_inquiry_mode(hdev); 582d5859e22SJohan Hedberg 583d5859e22SJohan Hedberg if (hdev->features[7] & LMP_INQ_TX_PWR) 584d5859e22SJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 585971e3a4bSAndre Guedes 586971e3a4bSAndre Guedes if (hdev->features[7] & LMP_EXTFEATURES) { 587971e3a4bSAndre Guedes struct hci_cp_read_local_ext_features cp; 588971e3a4bSAndre Guedes 589971e3a4bSAndre Guedes cp.page = 0x01; 590971e3a4bSAndre Guedes hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, 591971e3a4bSAndre Guedes sizeof(cp), &cp); 592971e3a4bSAndre Guedes } 593e6100a25SAndre Guedes 594e6100a25SAndre Guedes if (hdev->features[4] & LMP_LE) 595e6100a25SAndre Guedes hci_set_le_support(hdev); 596d5859e22SJohan Hedberg } 597d5859e22SJohan Hedberg 598a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) 599a9de9248SMarcel Holtmann { 600a9de9248SMarcel Holtmann struct hci_rp_read_local_version *rp = (void *) skb->data; 6011143e5a6SMarcel Holtmann 602a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 6031143e5a6SMarcel Holtmann 604a9de9248SMarcel Holtmann if (rp->status) 605a9de9248SMarcel Holtmann return; 6061143e5a6SMarcel Holtmann 607a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver; 608e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 609d5859e22SJohan Hedberg hdev->lmp_ver = rp->lmp_ver; 610e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer); 611d5859e22SJohan Hedberg hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); 6121da177e4SLinus Torvalds 613a9de9248SMarcel Holtmann BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name, 614a9de9248SMarcel Holtmann hdev->manufacturer, 615a9de9248SMarcel Holtmann hdev->hci_ver, hdev->hci_rev); 616d5859e22SJohan Hedberg 617d5859e22SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags)) 618d5859e22SJohan Hedberg hci_setup(hdev); 619d5859e22SJohan Hedberg } 620d5859e22SJohan Hedberg 621d5859e22SJohan Hedberg static void hci_setup_link_policy(struct hci_dev *hdev) 622d5859e22SJohan Hedberg { 623d5859e22SJohan Hedberg u16 link_policy = 0; 624d5859e22SJohan Hedberg 625d5859e22SJohan Hedberg if (hdev->features[0] & LMP_RSWITCH) 626d5859e22SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 627d5859e22SJohan Hedberg if (hdev->features[0] & LMP_HOLD) 628d5859e22SJohan Hedberg link_policy |= HCI_LP_HOLD; 629d5859e22SJohan Hedberg if (hdev->features[0] & LMP_SNIFF) 630d5859e22SJohan Hedberg link_policy |= HCI_LP_SNIFF; 631d5859e22SJohan Hedberg if (hdev->features[1] & LMP_PARK) 632d5859e22SJohan Hedberg link_policy |= HCI_LP_PARK; 633d5859e22SJohan Hedberg 634d5859e22SJohan Hedberg link_policy = cpu_to_le16(link_policy); 635d5859e22SJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 636d5859e22SJohan Hedberg sizeof(link_policy), &link_policy); 6371da177e4SLinus Torvalds } 6381da177e4SLinus Torvalds 639a9de9248SMarcel Holtmann static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb) 640a9de9248SMarcel Holtmann { 641a9de9248SMarcel Holtmann struct hci_rp_read_local_commands *rp = (void *) skb->data; 642a9de9248SMarcel Holtmann 643a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 644a9de9248SMarcel Holtmann 645a9de9248SMarcel Holtmann if (rp->status) 646d5859e22SJohan Hedberg goto done; 647a9de9248SMarcel Holtmann 648a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 649d5859e22SJohan Hedberg 650d5859e22SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10)) 651d5859e22SJohan Hedberg hci_setup_link_policy(hdev); 652d5859e22SJohan Hedberg 653d5859e22SJohan Hedberg done: 654d5859e22SJohan Hedberg hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status); 655a9de9248SMarcel Holtmann } 656a9de9248SMarcel Holtmann 657a9de9248SMarcel Holtmann static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb) 658a9de9248SMarcel Holtmann { 659a9de9248SMarcel Holtmann struct hci_rp_read_local_features *rp = (void *) skb->data; 660a9de9248SMarcel Holtmann 661a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 662a9de9248SMarcel Holtmann 663a9de9248SMarcel Holtmann if (rp->status) 664a9de9248SMarcel Holtmann return; 665a9de9248SMarcel Holtmann 666a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8); 6671da177e4SLinus Torvalds 6681da177e4SLinus Torvalds /* Adjust default settings according to features 6691da177e4SLinus Torvalds * supported by device. */ 670a9de9248SMarcel Holtmann 6711da177e4SLinus Torvalds if (hdev->features[0] & LMP_3SLOT) 6721da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 6731da177e4SLinus Torvalds 6741da177e4SLinus Torvalds if (hdev->features[0] & LMP_5SLOT) 6751da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 6761da177e4SLinus Torvalds 6775b7f9909SMarcel Holtmann if (hdev->features[1] & LMP_HV2) { 6781da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2); 6795b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2); 6805b7f9909SMarcel Holtmann } 6811da177e4SLinus Torvalds 6825b7f9909SMarcel Holtmann if (hdev->features[1] & LMP_HV3) { 6831da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3); 6845b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3); 6855b7f9909SMarcel Holtmann } 6865b7f9909SMarcel Holtmann 6875b7f9909SMarcel Holtmann if (hdev->features[3] & LMP_ESCO) 6885b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3); 6895b7f9909SMarcel Holtmann 6905b7f9909SMarcel Holtmann if (hdev->features[4] & LMP_EV4) 6915b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4); 6925b7f9909SMarcel Holtmann 6935b7f9909SMarcel Holtmann if (hdev->features[4] & LMP_EV5) 6945b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5); 6951da177e4SLinus Torvalds 696efc7688bSMarcel Holtmann if (hdev->features[5] & LMP_EDR_ESCO_2M) 697efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3); 698efc7688bSMarcel Holtmann 699efc7688bSMarcel Holtmann if (hdev->features[5] & LMP_EDR_ESCO_3M) 700efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3); 701efc7688bSMarcel Holtmann 702efc7688bSMarcel Holtmann if (hdev->features[5] & LMP_EDR_3S_ESCO) 703efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 704efc7688bSMarcel Holtmann 705a9de9248SMarcel Holtmann BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name, 706a9de9248SMarcel Holtmann hdev->features[0], hdev->features[1], 707a9de9248SMarcel Holtmann hdev->features[2], hdev->features[3], 708a9de9248SMarcel Holtmann hdev->features[4], hdev->features[5], 709a9de9248SMarcel Holtmann hdev->features[6], hdev->features[7]); 7101da177e4SLinus Torvalds } 7111da177e4SLinus Torvalds 712971e3a4bSAndre Guedes static void hci_cc_read_local_ext_features(struct hci_dev *hdev, 713971e3a4bSAndre Guedes struct sk_buff *skb) 714971e3a4bSAndre Guedes { 715971e3a4bSAndre Guedes struct hci_rp_read_local_ext_features *rp = (void *) skb->data; 716971e3a4bSAndre Guedes 717971e3a4bSAndre Guedes BT_DBG("%s status 0x%x", hdev->name, rp->status); 718971e3a4bSAndre Guedes 719971e3a4bSAndre Guedes if (rp->status) 720971e3a4bSAndre Guedes return; 721971e3a4bSAndre Guedes 722b5b32b65SAndre Guedes switch (rp->page) { 723b5b32b65SAndre Guedes case 0: 724b5b32b65SAndre Guedes memcpy(hdev->features, rp->features, 8); 725b5b32b65SAndre Guedes break; 726b5b32b65SAndre Guedes case 1: 72759e29406SAndre Guedes memcpy(hdev->host_features, rp->features, 8); 728b5b32b65SAndre Guedes break; 729b5b32b65SAndre Guedes } 730971e3a4bSAndre Guedes 731971e3a4bSAndre Guedes hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status); 732971e3a4bSAndre Guedes } 733971e3a4bSAndre Guedes 7341e89cffbSAndrei Emeltchenko static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, 7351e89cffbSAndrei Emeltchenko struct sk_buff *skb) 7361e89cffbSAndrei Emeltchenko { 7371e89cffbSAndrei Emeltchenko struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; 7381e89cffbSAndrei Emeltchenko 7391e89cffbSAndrei Emeltchenko BT_DBG("%s status 0x%x", hdev->name, rp->status); 7401e89cffbSAndrei Emeltchenko 7411e89cffbSAndrei Emeltchenko if (rp->status) 7421e89cffbSAndrei Emeltchenko return; 7431e89cffbSAndrei Emeltchenko 7441e89cffbSAndrei Emeltchenko hdev->flow_ctl_mode = rp->mode; 7451e89cffbSAndrei Emeltchenko 7461e89cffbSAndrei Emeltchenko hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status); 7471e89cffbSAndrei Emeltchenko } 7481e89cffbSAndrei Emeltchenko 749a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 750a9de9248SMarcel Holtmann { 751a9de9248SMarcel Holtmann struct hci_rp_read_buffer_size *rp = (void *) skb->data; 752a9de9248SMarcel Holtmann 753a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 754a9de9248SMarcel Holtmann 755a9de9248SMarcel Holtmann if (rp->status) 756a9de9248SMarcel Holtmann return; 757a9de9248SMarcel Holtmann 758a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu); 759a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu; 760a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt); 761a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt); 762da1f5198SMarcel Holtmann 763da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { 764da1f5198SMarcel Holtmann hdev->sco_mtu = 64; 765da1f5198SMarcel Holtmann hdev->sco_pkts = 8; 766da1f5198SMarcel Holtmann } 767da1f5198SMarcel Holtmann 768da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts; 769da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 7701da177e4SLinus Torvalds 771a9de9248SMarcel Holtmann BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, 772a9de9248SMarcel Holtmann hdev->acl_mtu, hdev->acl_pkts, 773a9de9248SMarcel Holtmann hdev->sco_mtu, hdev->sco_pkts); 7741da177e4SLinus Torvalds } 7751da177e4SLinus Torvalds 776a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) 777a9de9248SMarcel Holtmann { 778a9de9248SMarcel Holtmann struct hci_rp_read_bd_addr *rp = (void *) skb->data; 7791da177e4SLinus Torvalds 780a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 781a9de9248SMarcel Holtmann 782a9de9248SMarcel Holtmann if (!rp->status) 783a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr); 784a9de9248SMarcel Holtmann 78523bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status); 78623bb5763SJohan Hedberg } 78723bb5763SJohan Hedberg 788350ee4cfSAndrei Emeltchenko static void hci_cc_read_data_block_size(struct hci_dev *hdev, 789350ee4cfSAndrei Emeltchenko struct sk_buff *skb) 790350ee4cfSAndrei Emeltchenko { 791350ee4cfSAndrei Emeltchenko struct hci_rp_read_data_block_size *rp = (void *) skb->data; 792350ee4cfSAndrei Emeltchenko 793350ee4cfSAndrei Emeltchenko BT_DBG("%s status 0x%x", hdev->name, rp->status); 794350ee4cfSAndrei Emeltchenko 795350ee4cfSAndrei Emeltchenko if (rp->status) 796350ee4cfSAndrei Emeltchenko return; 797350ee4cfSAndrei Emeltchenko 798350ee4cfSAndrei Emeltchenko hdev->block_mtu = __le16_to_cpu(rp->max_acl_len); 799350ee4cfSAndrei Emeltchenko hdev->block_len = __le16_to_cpu(rp->block_len); 800350ee4cfSAndrei Emeltchenko hdev->num_blocks = __le16_to_cpu(rp->num_blocks); 801350ee4cfSAndrei Emeltchenko 802350ee4cfSAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 803350ee4cfSAndrei Emeltchenko 804350ee4cfSAndrei Emeltchenko BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, 805350ee4cfSAndrei Emeltchenko hdev->block_cnt, hdev->block_len); 806350ee4cfSAndrei Emeltchenko 807350ee4cfSAndrei Emeltchenko hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status); 808350ee4cfSAndrei Emeltchenko } 809350ee4cfSAndrei Emeltchenko 81023bb5763SJohan Hedberg static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) 81123bb5763SJohan Hedberg { 81223bb5763SJohan Hedberg __u8 status = *((__u8 *) skb->data); 81323bb5763SJohan Hedberg 81423bb5763SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 81523bb5763SJohan Hedberg 81623bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); 8171da177e4SLinus Torvalds } 8181da177e4SLinus Torvalds 819928abaa7SAndrei Emeltchenko static void hci_cc_read_local_amp_info(struct hci_dev *hdev, 820928abaa7SAndrei Emeltchenko struct sk_buff *skb) 821928abaa7SAndrei Emeltchenko { 822928abaa7SAndrei Emeltchenko struct hci_rp_read_local_amp_info *rp = (void *) skb->data; 823928abaa7SAndrei Emeltchenko 824928abaa7SAndrei Emeltchenko BT_DBG("%s status 0x%x", hdev->name, rp->status); 825928abaa7SAndrei Emeltchenko 826928abaa7SAndrei Emeltchenko if (rp->status) 827928abaa7SAndrei Emeltchenko return; 828928abaa7SAndrei Emeltchenko 829928abaa7SAndrei Emeltchenko hdev->amp_status = rp->amp_status; 830928abaa7SAndrei Emeltchenko hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); 831928abaa7SAndrei Emeltchenko hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); 832928abaa7SAndrei Emeltchenko hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); 833928abaa7SAndrei Emeltchenko hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); 834928abaa7SAndrei Emeltchenko hdev->amp_type = rp->amp_type; 835928abaa7SAndrei Emeltchenko hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); 836928abaa7SAndrei Emeltchenko hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); 837928abaa7SAndrei Emeltchenko hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); 838928abaa7SAndrei Emeltchenko hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); 839928abaa7SAndrei Emeltchenko 840928abaa7SAndrei Emeltchenko hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status); 841928abaa7SAndrei Emeltchenko } 842928abaa7SAndrei Emeltchenko 843b0916ea0SJohan Hedberg static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, 844b0916ea0SJohan Hedberg struct sk_buff *skb) 845b0916ea0SJohan Hedberg { 846b0916ea0SJohan Hedberg __u8 status = *((__u8 *) skb->data); 847b0916ea0SJohan Hedberg 848b0916ea0SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 849b0916ea0SJohan Hedberg 850b0916ea0SJohan Hedberg hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status); 851b0916ea0SJohan Hedberg } 852b0916ea0SJohan Hedberg 853d5859e22SJohan Hedberg static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb) 854d5859e22SJohan Hedberg { 855d5859e22SJohan Hedberg __u8 status = *((__u8 *) skb->data); 856d5859e22SJohan Hedberg 857d5859e22SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 858d5859e22SJohan Hedberg 859d5859e22SJohan Hedberg hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status); 860d5859e22SJohan Hedberg } 861d5859e22SJohan Hedberg 862d5859e22SJohan Hedberg static void hci_cc_write_inquiry_mode(struct hci_dev *hdev, 863d5859e22SJohan Hedberg struct sk_buff *skb) 864d5859e22SJohan Hedberg { 865d5859e22SJohan Hedberg __u8 status = *((__u8 *) skb->data); 866d5859e22SJohan Hedberg 867d5859e22SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 868d5859e22SJohan Hedberg 869d5859e22SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status); 870d5859e22SJohan Hedberg } 871d5859e22SJohan Hedberg 872d5859e22SJohan Hedberg static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, 873d5859e22SJohan Hedberg struct sk_buff *skb) 874d5859e22SJohan Hedberg { 875d5859e22SJohan Hedberg __u8 status = *((__u8 *) skb->data); 876d5859e22SJohan Hedberg 877d5859e22SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 878d5859e22SJohan Hedberg 879d5859e22SJohan Hedberg hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status); 880d5859e22SJohan Hedberg } 881d5859e22SJohan Hedberg 882d5859e22SJohan Hedberg static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb) 883d5859e22SJohan Hedberg { 884d5859e22SJohan Hedberg __u8 status = *((__u8 *) skb->data); 885d5859e22SJohan Hedberg 886d5859e22SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 887d5859e22SJohan Hedberg 888d5859e22SJohan Hedberg hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status); 889d5859e22SJohan Hedberg } 890d5859e22SJohan Hedberg 891980e1a53SJohan Hedberg static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) 892980e1a53SJohan Hedberg { 893980e1a53SJohan Hedberg struct hci_rp_pin_code_reply *rp = (void *) skb->data; 894980e1a53SJohan Hedberg struct hci_cp_pin_code_reply *cp; 895980e1a53SJohan Hedberg struct hci_conn *conn; 896980e1a53SJohan Hedberg 897980e1a53SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, rp->status); 898980e1a53SJohan Hedberg 89956e5cb86SJohan Hedberg hci_dev_lock(hdev); 90056e5cb86SJohan Hedberg 901a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 902744cf19eSJohan Hedberg mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); 903980e1a53SJohan Hedberg 904980e1a53SJohan Hedberg if (rp->status != 0) 90556e5cb86SJohan Hedberg goto unlock; 906980e1a53SJohan Hedberg 907980e1a53SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); 908980e1a53SJohan Hedberg if (!cp) 90956e5cb86SJohan Hedberg goto unlock; 910980e1a53SJohan Hedberg 911980e1a53SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 912980e1a53SJohan Hedberg if (conn) 913980e1a53SJohan Hedberg conn->pin_length = cp->pin_len; 91456e5cb86SJohan Hedberg 91556e5cb86SJohan Hedberg unlock: 91656e5cb86SJohan Hedberg hci_dev_unlock(hdev); 917980e1a53SJohan Hedberg } 918980e1a53SJohan Hedberg 919980e1a53SJohan Hedberg static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) 920980e1a53SJohan Hedberg { 921980e1a53SJohan Hedberg struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data; 922980e1a53SJohan Hedberg 923980e1a53SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, rp->status); 924980e1a53SJohan Hedberg 92556e5cb86SJohan Hedberg hci_dev_lock(hdev); 92656e5cb86SJohan Hedberg 927a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 928744cf19eSJohan Hedberg mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, 929980e1a53SJohan Hedberg rp->status); 93056e5cb86SJohan Hedberg 93156e5cb86SJohan Hedberg hci_dev_unlock(hdev); 932980e1a53SJohan Hedberg } 93356e5cb86SJohan Hedberg 9346ed58ec5SVille Tervo static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, 9356ed58ec5SVille Tervo struct sk_buff *skb) 9366ed58ec5SVille Tervo { 9376ed58ec5SVille Tervo struct hci_rp_le_read_buffer_size *rp = (void *) skb->data; 9386ed58ec5SVille Tervo 9396ed58ec5SVille Tervo BT_DBG("%s status 0x%x", hdev->name, rp->status); 9406ed58ec5SVille Tervo 9416ed58ec5SVille Tervo if (rp->status) 9426ed58ec5SVille Tervo return; 9436ed58ec5SVille Tervo 9446ed58ec5SVille Tervo hdev->le_mtu = __le16_to_cpu(rp->le_mtu); 9456ed58ec5SVille Tervo hdev->le_pkts = rp->le_max_pkt; 9466ed58ec5SVille Tervo 9476ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 9486ed58ec5SVille Tervo 9496ed58ec5SVille Tervo BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); 9506ed58ec5SVille Tervo 9516ed58ec5SVille Tervo hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); 9526ed58ec5SVille Tervo } 953980e1a53SJohan Hedberg 954a5c29683SJohan Hedberg static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) 955a5c29683SJohan Hedberg { 956a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 957a5c29683SJohan Hedberg 958a5c29683SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, rp->status); 959a5c29683SJohan Hedberg 96056e5cb86SJohan Hedberg hci_dev_lock(hdev); 96156e5cb86SJohan Hedberg 962a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 963744cf19eSJohan Hedberg mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, 964a5c29683SJohan Hedberg rp->status); 96556e5cb86SJohan Hedberg 96656e5cb86SJohan Hedberg hci_dev_unlock(hdev); 967a5c29683SJohan Hedberg } 968a5c29683SJohan Hedberg 969a5c29683SJohan Hedberg static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, 970a5c29683SJohan Hedberg struct sk_buff *skb) 971a5c29683SJohan Hedberg { 972a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 973a5c29683SJohan Hedberg 974a5c29683SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, rp->status); 975a5c29683SJohan Hedberg 97656e5cb86SJohan Hedberg hci_dev_lock(hdev); 97756e5cb86SJohan Hedberg 978a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 979744cf19eSJohan Hedberg mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, 980a5c29683SJohan Hedberg rp->status); 98156e5cb86SJohan Hedberg 98256e5cb86SJohan Hedberg hci_dev_unlock(hdev); 983a5c29683SJohan Hedberg } 984a5c29683SJohan Hedberg 9851143d458SBrian Gix static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) 9861143d458SBrian Gix { 9871143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 9881143d458SBrian Gix 9891143d458SBrian Gix BT_DBG("%s status 0x%x", hdev->name, rp->status); 9901143d458SBrian Gix 9911143d458SBrian Gix hci_dev_lock(hdev); 9921143d458SBrian Gix 993a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 9941143d458SBrian Gix mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, 9951143d458SBrian Gix rp->status); 9961143d458SBrian Gix 9971143d458SBrian Gix hci_dev_unlock(hdev); 9981143d458SBrian Gix } 9991143d458SBrian Gix 10001143d458SBrian Gix static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, 10011143d458SBrian Gix struct sk_buff *skb) 10021143d458SBrian Gix { 10031143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 10041143d458SBrian Gix 10051143d458SBrian Gix BT_DBG("%s status 0x%x", hdev->name, rp->status); 10061143d458SBrian Gix 10071143d458SBrian Gix hci_dev_lock(hdev); 10081143d458SBrian Gix 1009a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 10101143d458SBrian Gix mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, 10111143d458SBrian Gix rp->status); 10121143d458SBrian Gix 10131143d458SBrian Gix hci_dev_unlock(hdev); 10141143d458SBrian Gix } 10151143d458SBrian Gix 1016c35938b2SSzymon Janc static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, 1017c35938b2SSzymon Janc struct sk_buff *skb) 1018c35938b2SSzymon Janc { 1019c35938b2SSzymon Janc struct hci_rp_read_local_oob_data *rp = (void *) skb->data; 1020c35938b2SSzymon Janc 1021c35938b2SSzymon Janc BT_DBG("%s status 0x%x", hdev->name, rp->status); 1022c35938b2SSzymon Janc 102356e5cb86SJohan Hedberg hci_dev_lock(hdev); 1024744cf19eSJohan Hedberg mgmt_read_local_oob_data_reply_complete(hdev, rp->hash, 1025c35938b2SSzymon Janc rp->randomizer, rp->status); 102656e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1027c35938b2SSzymon Janc } 1028c35938b2SSzymon Janc 102907f7fa5dSAndre Guedes static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) 103007f7fa5dSAndre Guedes { 103107f7fa5dSAndre Guedes __u8 status = *((__u8 *) skb->data); 103207f7fa5dSAndre Guedes 103307f7fa5dSAndre Guedes BT_DBG("%s status 0x%x", hdev->name, status); 10347ba8b4beSAndre Guedes 10357ba8b4beSAndre Guedes hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status); 10363fd24153SAndre Guedes 10373fd24153SAndre Guedes if (status) { 10383fd24153SAndre Guedes hci_dev_lock(hdev); 10393fd24153SAndre Guedes mgmt_start_discovery_failed(hdev, status); 10403fd24153SAndre Guedes hci_dev_unlock(hdev); 10413fd24153SAndre Guedes return; 10423fd24153SAndre Guedes } 104307f7fa5dSAndre Guedes } 104407f7fa5dSAndre Guedes 1045eb9d91f5SAndre Guedes static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, 1046eb9d91f5SAndre Guedes struct sk_buff *skb) 1047eb9d91f5SAndre Guedes { 1048eb9d91f5SAndre Guedes struct hci_cp_le_set_scan_enable *cp; 1049eb9d91f5SAndre Guedes __u8 status = *((__u8 *) skb->data); 1050eb9d91f5SAndre Guedes 1051eb9d91f5SAndre Guedes BT_DBG("%s status 0x%x", hdev->name, status); 1052eb9d91f5SAndre Guedes 1053eb9d91f5SAndre Guedes cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); 1054eb9d91f5SAndre Guedes if (!cp) 1055eb9d91f5SAndre Guedes return; 1056eb9d91f5SAndre Guedes 105768a8aea4SAndrei Emeltchenko switch (cp->enable) { 105868a8aea4SAndrei Emeltchenko case LE_SCANNING_ENABLED: 10597ba8b4beSAndre Guedes hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status); 10607ba8b4beSAndre Guedes 10613fd24153SAndre Guedes if (status) { 10623fd24153SAndre Guedes hci_dev_lock(hdev); 10633fd24153SAndre Guedes mgmt_start_discovery_failed(hdev, status); 10643fd24153SAndre Guedes hci_dev_unlock(hdev); 10657ba8b4beSAndre Guedes return; 10663fd24153SAndre Guedes } 10677ba8b4beSAndre Guedes 1068d23264a8SAndre Guedes set_bit(HCI_LE_SCAN, &hdev->dev_flags); 1069d23264a8SAndre Guedes 1070db323f2fSGustavo F. Padovan cancel_delayed_work_sync(&hdev->adv_work); 1071a8f13c8cSAndre Guedes 1072a8f13c8cSAndre Guedes hci_dev_lock(hdev); 1073eb9d91f5SAndre Guedes hci_adv_entries_clear(hdev); 1074c599008fSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_LE_SCAN); 1075a8f13c8cSAndre Guedes hci_dev_unlock(hdev); 107668a8aea4SAndrei Emeltchenko break; 107768a8aea4SAndrei Emeltchenko 107868a8aea4SAndrei Emeltchenko case LE_SCANNING_DISABLED: 10797ba8b4beSAndre Guedes if (status) 10807ba8b4beSAndre Guedes return; 10817ba8b4beSAndre Guedes 1082d23264a8SAndre Guedes clear_bit(HCI_LE_SCAN, &hdev->dev_flags); 1083d23264a8SAndre Guedes 1084c599008fSAndre Guedes hci_dev_lock(hdev); 1085c599008fSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 1086c599008fSAndre Guedes hci_dev_unlock(hdev); 1087c599008fSAndre Guedes 1088d084329eSAndre Guedes schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT); 108968a8aea4SAndrei Emeltchenko break; 109068a8aea4SAndrei Emeltchenko 109168a8aea4SAndrei Emeltchenko default: 109268a8aea4SAndrei Emeltchenko BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable); 109368a8aea4SAndrei Emeltchenko break; 109435815085SAndre Guedes } 1095eb9d91f5SAndre Guedes } 1096eb9d91f5SAndre Guedes 1097a7a595f6SVinicius Costa Gomes static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb) 1098a7a595f6SVinicius Costa Gomes { 1099a7a595f6SVinicius Costa Gomes struct hci_rp_le_ltk_reply *rp = (void *) skb->data; 1100a7a595f6SVinicius Costa Gomes 1101a7a595f6SVinicius Costa Gomes BT_DBG("%s status 0x%x", hdev->name, rp->status); 1102a7a595f6SVinicius Costa Gomes 1103a7a595f6SVinicius Costa Gomes if (rp->status) 1104a7a595f6SVinicius Costa Gomes return; 1105a7a595f6SVinicius Costa Gomes 1106a7a595f6SVinicius Costa Gomes hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status); 1107a7a595f6SVinicius Costa Gomes } 1108a7a595f6SVinicius Costa Gomes 1109a7a595f6SVinicius Costa Gomes static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) 1110a7a595f6SVinicius Costa Gomes { 1111a7a595f6SVinicius Costa Gomes struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data; 1112a7a595f6SVinicius Costa Gomes 1113a7a595f6SVinicius Costa Gomes BT_DBG("%s status 0x%x", hdev->name, rp->status); 1114a7a595f6SVinicius Costa Gomes 1115a7a595f6SVinicius Costa Gomes if (rp->status) 1116a7a595f6SVinicius Costa Gomes return; 1117a7a595f6SVinicius Costa Gomes 1118a7a595f6SVinicius Costa Gomes hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status); 1119a7a595f6SVinicius Costa Gomes } 1120a7a595f6SVinicius Costa Gomes 1121f9b49306SAndre Guedes static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev, 1122f9b49306SAndre Guedes struct sk_buff *skb) 1123f9b49306SAndre Guedes { 1124f9b49306SAndre Guedes struct hci_cp_read_local_ext_features cp; 1125f9b49306SAndre Guedes __u8 status = *((__u8 *) skb->data); 1126f9b49306SAndre Guedes 1127f9b49306SAndre Guedes BT_DBG("%s status 0x%x", hdev->name, status); 1128f9b49306SAndre Guedes 1129f9b49306SAndre Guedes if (status) 1130f9b49306SAndre Guedes return; 1131f9b49306SAndre Guedes 1132f9b49306SAndre Guedes cp.page = 0x01; 1133f9b49306SAndre Guedes hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp); 1134f9b49306SAndre Guedes } 1135f9b49306SAndre Guedes 1136a9de9248SMarcel Holtmann static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) 1137a9de9248SMarcel Holtmann { 1138a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1139a9de9248SMarcel Holtmann 1140a9de9248SMarcel Holtmann if (status) { 114123bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_INQUIRY, status); 1142a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 114356e5cb86SJohan Hedberg hci_dev_lock(hdev); 1144a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 11457a135109SAndre Guedes mgmt_start_discovery_failed(hdev, status); 114656e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1147314b2381SJohan Hedberg return; 1148314b2381SJohan Hedberg } 1149314b2381SJohan Hedberg 115089352e7dSAndre Guedes set_bit(HCI_INQUIRY, &hdev->flags); 115189352e7dSAndre Guedes 115256e5cb86SJohan Hedberg hci_dev_lock(hdev); 115330dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_INQUIRY); 115456e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1155a9de9248SMarcel Holtmann } 1156a9de9248SMarcel Holtmann 11571da177e4SLinus Torvalds static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 11581da177e4SLinus Torvalds { 1159a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp; 11601da177e4SLinus Torvalds struct hci_conn *conn; 11611da177e4SLinus Torvalds 1162a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1163a9de9248SMarcel Holtmann 1164a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); 11651da177e4SLinus Torvalds if (!cp) 11661da177e4SLinus Torvalds return; 11671da177e4SLinus Torvalds 11681da177e4SLinus Torvalds hci_dev_lock(hdev); 11691da177e4SLinus Torvalds 11701da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 11711da177e4SLinus Torvalds 1172a9de9248SMarcel Holtmann BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn); 11731da177e4SLinus Torvalds 11741da177e4SLinus Torvalds if (status) { 11751da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) { 11764c67bc74SMarcel Holtmann if (status != 0x0c || conn->attempt > 2) { 11771da177e4SLinus Torvalds conn->state = BT_CLOSED; 11781da177e4SLinus Torvalds hci_proto_connect_cfm(conn, status); 11791da177e4SLinus Torvalds hci_conn_del(conn); 11804c67bc74SMarcel Holtmann } else 11814c67bc74SMarcel Holtmann conn->state = BT_CONNECT2; 11821da177e4SLinus Torvalds } 11831da177e4SLinus Torvalds } else { 11841da177e4SLinus Torvalds if (!conn) { 11851da177e4SLinus Torvalds conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr); 11861da177e4SLinus Torvalds if (conn) { 1187a0c808b3SJohan Hedberg conn->out = true; 11881da177e4SLinus Torvalds conn->link_mode |= HCI_LM_MASTER; 11891da177e4SLinus Torvalds } else 1190893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 11911da177e4SLinus Torvalds } 11921da177e4SLinus Torvalds } 11931da177e4SLinus Torvalds 11941da177e4SLinus Torvalds hci_dev_unlock(hdev); 11951da177e4SLinus Torvalds } 11961da177e4SLinus Torvalds 1197a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) 11981da177e4SLinus Torvalds { 1199a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp; 12001da177e4SLinus Torvalds struct hci_conn *acl, *sco; 12011da177e4SLinus Torvalds __u16 handle; 12021da177e4SLinus Torvalds 1203b6a0dc82SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1204b6a0dc82SMarcel Holtmann 1205a9de9248SMarcel Holtmann if (!status) 1206a9de9248SMarcel Holtmann return; 1207a9de9248SMarcel Holtmann 1208a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 12091da177e4SLinus Torvalds if (!cp) 1210a9de9248SMarcel Holtmann return; 12111da177e4SLinus Torvalds 12121da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle); 12131da177e4SLinus Torvalds 1214a9de9248SMarcel Holtmann BT_DBG("%s handle %d", hdev->name, handle); 12151da177e4SLinus Torvalds 12161da177e4SLinus Torvalds hci_dev_lock(hdev); 12171da177e4SLinus Torvalds 12181da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle); 12195a08ecceSAndrei Emeltchenko if (acl) { 12205a08ecceSAndrei Emeltchenko sco = acl->link; 12215a08ecceSAndrei Emeltchenko if (sco) { 12221da177e4SLinus Torvalds sco->state = BT_CLOSED; 12231da177e4SLinus Torvalds 12241da177e4SLinus Torvalds hci_proto_connect_cfm(sco, status); 12251da177e4SLinus Torvalds hci_conn_del(sco); 12261da177e4SLinus Torvalds } 12275a08ecceSAndrei Emeltchenko } 12281da177e4SLinus Torvalds 12291da177e4SLinus Torvalds hci_dev_unlock(hdev); 12301da177e4SLinus Torvalds } 12311da177e4SLinus Torvalds 1232f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) 1233f8558555SMarcel Holtmann { 1234f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp; 1235f8558555SMarcel Holtmann struct hci_conn *conn; 1236f8558555SMarcel Holtmann 1237f8558555SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1238f8558555SMarcel Holtmann 1239f8558555SMarcel Holtmann if (!status) 1240f8558555SMarcel Holtmann return; 1241f8558555SMarcel Holtmann 1242f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); 1243f8558555SMarcel Holtmann if (!cp) 1244f8558555SMarcel Holtmann return; 1245f8558555SMarcel Holtmann 1246f8558555SMarcel Holtmann hci_dev_lock(hdev); 1247f8558555SMarcel Holtmann 1248f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1249f8558555SMarcel Holtmann if (conn) { 1250f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1251f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 1252f8558555SMarcel Holtmann hci_conn_put(conn); 1253f8558555SMarcel Holtmann } 1254f8558555SMarcel Holtmann } 1255f8558555SMarcel Holtmann 1256f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1257f8558555SMarcel Holtmann } 1258f8558555SMarcel Holtmann 1259f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) 1260f8558555SMarcel Holtmann { 1261f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp; 1262f8558555SMarcel Holtmann struct hci_conn *conn; 1263f8558555SMarcel Holtmann 1264f8558555SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1265f8558555SMarcel Holtmann 1266f8558555SMarcel Holtmann if (!status) 1267f8558555SMarcel Holtmann return; 1268f8558555SMarcel Holtmann 1269f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); 1270f8558555SMarcel Holtmann if (!cp) 1271f8558555SMarcel Holtmann return; 1272f8558555SMarcel Holtmann 1273f8558555SMarcel Holtmann hci_dev_lock(hdev); 1274f8558555SMarcel Holtmann 1275f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1276f8558555SMarcel Holtmann if (conn) { 1277f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1278f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 1279f8558555SMarcel Holtmann hci_conn_put(conn); 1280f8558555SMarcel Holtmann } 1281f8558555SMarcel Holtmann } 1282f8558555SMarcel Holtmann 1283f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1284f8558555SMarcel Holtmann } 1285f8558555SMarcel Holtmann 1286127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev, 1287392599b9SJohan Hedberg struct hci_conn *conn) 1288392599b9SJohan Hedberg { 1289392599b9SJohan Hedberg if (conn->state != BT_CONFIG || !conn->out) 1290392599b9SJohan Hedberg return 0; 1291392599b9SJohan Hedberg 1292765c2a96SJohan Hedberg if (conn->pending_sec_level == BT_SECURITY_SDP) 1293392599b9SJohan Hedberg return 0; 1294392599b9SJohan Hedberg 1295392599b9SJohan Hedberg /* Only request authentication for SSP connections or non-SSP 1296e9bf2bf0SVinicius Costa Gomes * devices with sec_level HIGH or if MITM protection is requested */ 1297aa64a8b5SJohan Hedberg if (!hci_conn_ssp_enabled(conn) && 1298e9bf2bf0SVinicius Costa Gomes conn->pending_sec_level != BT_SECURITY_HIGH && 1299e9bf2bf0SVinicius Costa Gomes !(conn->auth_type & 0x01)) 1300392599b9SJohan Hedberg return 0; 1301392599b9SJohan Hedberg 1302392599b9SJohan Hedberg return 1; 1303392599b9SJohan Hedberg } 1304392599b9SJohan Hedberg 130530dc78e1SJohan Hedberg static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e) 130630dc78e1SJohan Hedberg { 130730dc78e1SJohan Hedberg struct hci_cp_remote_name_req cp; 130830dc78e1SJohan Hedberg 130930dc78e1SJohan Hedberg memset(&cp, 0, sizeof(cp)); 131030dc78e1SJohan Hedberg 131130dc78e1SJohan Hedberg bacpy(&cp.bdaddr, &e->data.bdaddr); 131230dc78e1SJohan Hedberg cp.pscan_rep_mode = e->data.pscan_rep_mode; 131330dc78e1SJohan Hedberg cp.pscan_mode = e->data.pscan_mode; 131430dc78e1SJohan Hedberg cp.clock_offset = e->data.clock_offset; 131530dc78e1SJohan Hedberg 131630dc78e1SJohan Hedberg return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 131730dc78e1SJohan Hedberg } 131830dc78e1SJohan Hedberg 1319b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev) 132030dc78e1SJohan Hedberg { 132130dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 132230dc78e1SJohan Hedberg struct inquiry_entry *e; 132330dc78e1SJohan Hedberg 1324b644ba33SJohan Hedberg if (list_empty(&discov->resolve)) 1325b644ba33SJohan Hedberg return false; 1326b644ba33SJohan Hedberg 1327b644ba33SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 1328b644ba33SJohan Hedberg if (hci_resolve_name(hdev, e) == 0) { 1329b644ba33SJohan Hedberg e->name_state = NAME_PENDING; 1330b644ba33SJohan Hedberg return true; 1331b644ba33SJohan Hedberg } 1332b644ba33SJohan Hedberg 1333b644ba33SJohan Hedberg return false; 1334b644ba33SJohan Hedberg } 1335b644ba33SJohan Hedberg 1336b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, 1337b644ba33SJohan Hedberg bdaddr_t *bdaddr, u8 *name, u8 name_len) 1338b644ba33SJohan Hedberg { 1339b644ba33SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 1340b644ba33SJohan Hedberg struct inquiry_entry *e; 1341b644ba33SJohan Hedberg 1342b644ba33SJohan Hedberg if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 1343b644ba33SJohan Hedberg mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 1344b644ba33SJohan Hedberg name, name_len, conn->dev_class); 1345b644ba33SJohan Hedberg 1346b644ba33SJohan Hedberg if (discov->state == DISCOVERY_STOPPED) 1347b644ba33SJohan Hedberg return; 1348b644ba33SJohan Hedberg 134930dc78e1SJohan Hedberg if (discov->state == DISCOVERY_STOPPING) 135030dc78e1SJohan Hedberg goto discov_complete; 135130dc78e1SJohan Hedberg 135230dc78e1SJohan Hedberg if (discov->state != DISCOVERY_RESOLVING) 135330dc78e1SJohan Hedberg return; 135430dc78e1SJohan Hedberg 135530dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); 135630dc78e1SJohan Hedberg if (e) { 135730dc78e1SJohan Hedberg e->name_state = NAME_KNOWN; 135830dc78e1SJohan Hedberg list_del(&e->list); 1359b644ba33SJohan Hedberg if (name) 1360b644ba33SJohan Hedberg mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, 1361b644ba33SJohan Hedberg e->data.rssi, name, name_len); 136230dc78e1SJohan Hedberg } 136330dc78e1SJohan Hedberg 1364b644ba33SJohan Hedberg if (hci_resolve_next_name(hdev)) 136530dc78e1SJohan Hedberg return; 136630dc78e1SJohan Hedberg 136730dc78e1SJohan Hedberg discov_complete: 136830dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 136930dc78e1SJohan Hedberg } 137030dc78e1SJohan Hedberg 1371a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 13721da177e4SLinus Torvalds { 1373127178d2SJohan Hedberg struct hci_cp_remote_name_req *cp; 1374127178d2SJohan Hedberg struct hci_conn *conn; 1375127178d2SJohan Hedberg 1376a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1377127178d2SJohan Hedberg 1378127178d2SJohan Hedberg /* If successful wait for the name req complete event before 1379127178d2SJohan Hedberg * checking for the need to do authentication */ 1380127178d2SJohan Hedberg if (!status) 1381127178d2SJohan Hedberg return; 1382127178d2SJohan Hedberg 1383127178d2SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); 1384127178d2SJohan Hedberg if (!cp) 1385127178d2SJohan Hedberg return; 1386127178d2SJohan Hedberg 1387127178d2SJohan Hedberg hci_dev_lock(hdev); 1388127178d2SJohan Hedberg 1389127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1390b644ba33SJohan Hedberg 1391b644ba33SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 1392b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); 1393b644ba33SJohan Hedberg 139479c6c70cSJohan Hedberg if (!conn) 139579c6c70cSJohan Hedberg goto unlock; 139679c6c70cSJohan Hedberg 139779c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 139879c6c70cSJohan Hedberg goto unlock; 139979c6c70cSJohan Hedberg 140051a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 1401127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 1402127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 1403127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 1404127178d2SJohan Hedberg } 1405127178d2SJohan Hedberg 140679c6c70cSJohan Hedberg unlock: 1407127178d2SJohan Hedberg hci_dev_unlock(hdev); 1408a9de9248SMarcel Holtmann } 14091da177e4SLinus Torvalds 1410769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 1411769be974SMarcel Holtmann { 1412769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp; 1413769be974SMarcel Holtmann struct hci_conn *conn; 1414769be974SMarcel Holtmann 1415769be974SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1416769be974SMarcel Holtmann 1417769be974SMarcel Holtmann if (!status) 1418769be974SMarcel Holtmann return; 1419769be974SMarcel Holtmann 1420769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); 1421769be974SMarcel Holtmann if (!cp) 1422769be974SMarcel Holtmann return; 1423769be974SMarcel Holtmann 1424769be974SMarcel Holtmann hci_dev_lock(hdev); 1425769be974SMarcel Holtmann 1426769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1427769be974SMarcel Holtmann if (conn) { 1428769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1429769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 1430769be974SMarcel Holtmann hci_conn_put(conn); 1431769be974SMarcel Holtmann } 1432769be974SMarcel Holtmann } 1433769be974SMarcel Holtmann 1434769be974SMarcel Holtmann hci_dev_unlock(hdev); 1435769be974SMarcel Holtmann } 1436769be974SMarcel Holtmann 1437769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) 1438769be974SMarcel Holtmann { 1439769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp; 1440769be974SMarcel Holtmann struct hci_conn *conn; 1441769be974SMarcel Holtmann 1442769be974SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1443769be974SMarcel Holtmann 1444769be974SMarcel Holtmann if (!status) 1445769be974SMarcel Holtmann return; 1446769be974SMarcel Holtmann 1447769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); 1448769be974SMarcel Holtmann if (!cp) 1449769be974SMarcel Holtmann return; 1450769be974SMarcel Holtmann 1451769be974SMarcel Holtmann hci_dev_lock(hdev); 1452769be974SMarcel Holtmann 1453769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1454769be974SMarcel Holtmann if (conn) { 1455769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1456769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 1457769be974SMarcel Holtmann hci_conn_put(conn); 1458769be974SMarcel Holtmann } 1459769be974SMarcel Holtmann } 1460769be974SMarcel Holtmann 1461769be974SMarcel Holtmann hci_dev_unlock(hdev); 1462769be974SMarcel Holtmann } 1463769be974SMarcel Holtmann 1464a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 1465a9de9248SMarcel Holtmann { 1466b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp; 1467b6a0dc82SMarcel Holtmann struct hci_conn *acl, *sco; 1468b6a0dc82SMarcel Holtmann __u16 handle; 1469b6a0dc82SMarcel Holtmann 1470a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1471b6a0dc82SMarcel Holtmann 1472b6a0dc82SMarcel Holtmann if (!status) 1473b6a0dc82SMarcel Holtmann return; 1474b6a0dc82SMarcel Holtmann 1475b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN); 1476b6a0dc82SMarcel Holtmann if (!cp) 1477b6a0dc82SMarcel Holtmann return; 1478b6a0dc82SMarcel Holtmann 1479b6a0dc82SMarcel Holtmann handle = __le16_to_cpu(cp->handle); 1480b6a0dc82SMarcel Holtmann 1481b6a0dc82SMarcel Holtmann BT_DBG("%s handle %d", hdev->name, handle); 1482b6a0dc82SMarcel Holtmann 1483b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 1484b6a0dc82SMarcel Holtmann 1485b6a0dc82SMarcel Holtmann acl = hci_conn_hash_lookup_handle(hdev, handle); 14865a08ecceSAndrei Emeltchenko if (acl) { 14875a08ecceSAndrei Emeltchenko sco = acl->link; 14885a08ecceSAndrei Emeltchenko if (sco) { 1489b6a0dc82SMarcel Holtmann sco->state = BT_CLOSED; 1490b6a0dc82SMarcel Holtmann 1491b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(sco, status); 1492b6a0dc82SMarcel Holtmann hci_conn_del(sco); 1493b6a0dc82SMarcel Holtmann } 14945a08ecceSAndrei Emeltchenko } 1495b6a0dc82SMarcel Holtmann 1496b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 1497a9de9248SMarcel Holtmann } 1498a9de9248SMarcel Holtmann 1499a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 1500a9de9248SMarcel Holtmann { 1501a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp; 150204837f64SMarcel Holtmann struct hci_conn *conn; 150304837f64SMarcel Holtmann 1504a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1505a9de9248SMarcel Holtmann 1506a9de9248SMarcel Holtmann if (!status) 1507a9de9248SMarcel Holtmann return; 1508a9de9248SMarcel Holtmann 1509a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE); 151004837f64SMarcel Holtmann if (!cp) 1511a9de9248SMarcel Holtmann return; 151204837f64SMarcel Holtmann 151304837f64SMarcel Holtmann hci_dev_lock(hdev); 151404837f64SMarcel Holtmann 151504837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1516e73439d8SMarcel Holtmann if (conn) { 151751a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 151804837f64SMarcel Holtmann 151951a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1520e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1521e73439d8SMarcel Holtmann } 1522e73439d8SMarcel Holtmann 152304837f64SMarcel Holtmann hci_dev_unlock(hdev); 152404837f64SMarcel Holtmann } 152504837f64SMarcel Holtmann 1526a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) 1527a9de9248SMarcel Holtmann { 1528a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp; 152904837f64SMarcel Holtmann struct hci_conn *conn; 153004837f64SMarcel Holtmann 1531a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1532a9de9248SMarcel Holtmann 1533a9de9248SMarcel Holtmann if (!status) 1534a9de9248SMarcel Holtmann return; 1535a9de9248SMarcel Holtmann 1536a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE); 153704837f64SMarcel Holtmann if (!cp) 1538a9de9248SMarcel Holtmann return; 153904837f64SMarcel Holtmann 154004837f64SMarcel Holtmann hci_dev_lock(hdev); 154104837f64SMarcel Holtmann 154204837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1543e73439d8SMarcel Holtmann if (conn) { 154451a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 154504837f64SMarcel Holtmann 154651a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1547e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1548e73439d8SMarcel Holtmann } 1549e73439d8SMarcel Holtmann 155004837f64SMarcel Holtmann hci_dev_unlock(hdev); 155104837f64SMarcel Holtmann } 155204837f64SMarcel Holtmann 1553fcd89c09SVille Tervo static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) 1554fcd89c09SVille Tervo { 1555fcd89c09SVille Tervo struct hci_cp_le_create_conn *cp; 1556fcd89c09SVille Tervo struct hci_conn *conn; 1557fcd89c09SVille Tervo 1558fcd89c09SVille Tervo BT_DBG("%s status 0x%x", hdev->name, status); 1559fcd89c09SVille Tervo 1560fcd89c09SVille Tervo cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); 1561fcd89c09SVille Tervo if (!cp) 1562fcd89c09SVille Tervo return; 1563fcd89c09SVille Tervo 1564fcd89c09SVille Tervo hci_dev_lock(hdev); 1565fcd89c09SVille Tervo 1566fcd89c09SVille Tervo conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr); 1567fcd89c09SVille Tervo 1568fcd89c09SVille Tervo BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr), 1569fcd89c09SVille Tervo conn); 1570fcd89c09SVille Tervo 1571fcd89c09SVille Tervo if (status) { 1572fcd89c09SVille Tervo if (conn && conn->state == BT_CONNECT) { 1573fcd89c09SVille Tervo conn->state = BT_CLOSED; 1574fcd89c09SVille Tervo hci_proto_connect_cfm(conn, status); 1575fcd89c09SVille Tervo hci_conn_del(conn); 1576fcd89c09SVille Tervo } 1577fcd89c09SVille Tervo } else { 1578fcd89c09SVille Tervo if (!conn) { 1579fcd89c09SVille Tervo conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr); 158029b7988aSAndre Guedes if (conn) { 158129b7988aSAndre Guedes conn->dst_type = cp->peer_addr_type; 1582a0c808b3SJohan Hedberg conn->out = true; 158329b7988aSAndre Guedes } else { 1584fcd89c09SVille Tervo BT_ERR("No memory for new connection"); 1585fcd89c09SVille Tervo } 1586fcd89c09SVille Tervo } 158729b7988aSAndre Guedes } 1588fcd89c09SVille Tervo 1589fcd89c09SVille Tervo hci_dev_unlock(hdev); 1590fcd89c09SVille Tervo } 1591fcd89c09SVille Tervo 1592a7a595f6SVinicius Costa Gomes static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) 1593a7a595f6SVinicius Costa Gomes { 1594a7a595f6SVinicius Costa Gomes BT_DBG("%s status 0x%x", hdev->name, status); 1595a7a595f6SVinicius Costa Gomes } 1596a7a595f6SVinicius Costa Gomes 15971da177e4SLinus Torvalds static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 15981da177e4SLinus Torvalds { 15991da177e4SLinus Torvalds __u8 status = *((__u8 *) skb->data); 160030dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 160130dc78e1SJohan Hedberg struct inquiry_entry *e; 16021da177e4SLinus Torvalds 16031da177e4SLinus Torvalds BT_DBG("%s status %d", hdev->name, status); 16041da177e4SLinus Torvalds 160523bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_INQUIRY, status); 16066bd57416SMarcel Holtmann 1607a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 160889352e7dSAndre Guedes 160989352e7dSAndre Guedes if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 161089352e7dSAndre Guedes return; 161189352e7dSAndre Guedes 1612a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 161330dc78e1SJohan Hedberg return; 161430dc78e1SJohan Hedberg 161556e5cb86SJohan Hedberg hci_dev_lock(hdev); 161630dc78e1SJohan Hedberg 161730dc78e1SJohan Hedberg if (discov->state != DISCOVERY_INQUIRY) 161830dc78e1SJohan Hedberg goto unlock; 161930dc78e1SJohan Hedberg 162030dc78e1SJohan Hedberg if (list_empty(&discov->resolve)) { 1621ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 162230dc78e1SJohan Hedberg goto unlock; 162330dc78e1SJohan Hedberg } 162430dc78e1SJohan Hedberg 162530dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 162630dc78e1SJohan Hedberg if (e && hci_resolve_name(hdev, e) == 0) { 162730dc78e1SJohan Hedberg e->name_state = NAME_PENDING; 162830dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); 162930dc78e1SJohan Hedberg } else { 163030dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 163130dc78e1SJohan Hedberg } 163230dc78e1SJohan Hedberg 163330dc78e1SJohan Hedberg unlock: 163456e5cb86SJohan Hedberg hci_dev_unlock(hdev); 16351da177e4SLinus Torvalds } 16361da177e4SLinus Torvalds 16371da177e4SLinus Torvalds static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 16381da177e4SLinus Torvalds { 163945bb4bf0SMarcel Holtmann struct inquiry_data data; 1640a9de9248SMarcel Holtmann struct inquiry_info *info = (void *) (skb->data + 1); 16411da177e4SLinus Torvalds int num_rsp = *((__u8 *) skb->data); 16421da177e4SLinus Torvalds 16431da177e4SLinus Torvalds BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 16441da177e4SLinus Torvalds 164545bb4bf0SMarcel Holtmann if (!num_rsp) 164645bb4bf0SMarcel Holtmann return; 164745bb4bf0SMarcel Holtmann 16481da177e4SLinus Torvalds hci_dev_lock(hdev); 164945bb4bf0SMarcel Holtmann 1650e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 16513175405bSJohan Hedberg bool name_known; 16523175405bSJohan Hedberg 16531da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr); 16541da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode; 16551da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode; 16561da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode; 16571da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3); 16581da177e4SLinus Torvalds data.clock_offset = info->clock_offset; 16591da177e4SLinus Torvalds data.rssi = 0x00; 166041a96212SMarcel Holtmann data.ssp_mode = 0x00; 16613175405bSJohan Hedberg 16623175405bSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, false); 166348264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 16647d262f86SAndre Guedes info->dev_class, 0, !name_known, 16657d262f86SAndre Guedes NULL, 0); 16661da177e4SLinus Torvalds } 166745bb4bf0SMarcel Holtmann 16681da177e4SLinus Torvalds hci_dev_unlock(hdev); 16691da177e4SLinus Torvalds } 16701da177e4SLinus Torvalds 1671a9de9248SMarcel Holtmann static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 16721da177e4SLinus Torvalds { 1673a9de9248SMarcel Holtmann struct hci_ev_conn_complete *ev = (void *) skb->data; 1674a9de9248SMarcel Holtmann struct hci_conn *conn; 16751da177e4SLinus Torvalds 1676a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 167745bb4bf0SMarcel Holtmann 16781da177e4SLinus Torvalds hci_dev_lock(hdev); 167945bb4bf0SMarcel Holtmann 1680a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 16819499237aSMarcel Holtmann if (!conn) { 16829499237aSMarcel Holtmann if (ev->link_type != SCO_LINK) 16839499237aSMarcel Holtmann goto unlock; 16849499237aSMarcel Holtmann 16859499237aSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 1686a9de9248SMarcel Holtmann if (!conn) 1687a9de9248SMarcel Holtmann goto unlock; 168845bb4bf0SMarcel Holtmann 16899499237aSMarcel Holtmann conn->type = SCO_LINK; 16909499237aSMarcel Holtmann } 16919499237aSMarcel Holtmann 1692a9de9248SMarcel Holtmann if (!ev->status) { 1693a9de9248SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 1694769be974SMarcel Holtmann 1695769be974SMarcel Holtmann if (conn->type == ACL_LINK) { 1696769be974SMarcel Holtmann conn->state = BT_CONFIG; 1697769be974SMarcel Holtmann hci_conn_hold(conn); 1698052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 1699769be974SMarcel Holtmann } else 1700a9de9248SMarcel Holtmann conn->state = BT_CONNECTED; 1701a9de9248SMarcel Holtmann 17029eba32b8SMarcel Holtmann hci_conn_hold_device(conn); 17037d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 17047d0db0a3SMarcel Holtmann 1705a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags)) 1706a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 1707a9de9248SMarcel Holtmann 1708a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags)) 1709a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_ENCRYPT; 1710a9de9248SMarcel Holtmann 1711a9de9248SMarcel Holtmann /* Get remote features */ 1712a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 1713a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp; 1714a9de9248SMarcel Holtmann cp.handle = ev->handle; 1715769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, 1716769be974SMarcel Holtmann sizeof(cp), &cp); 171745bb4bf0SMarcel Holtmann } 1718a9de9248SMarcel Holtmann 1719a9de9248SMarcel Holtmann /* Set packet type for incoming connection */ 1720d095c1ebSAndrei Emeltchenko if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) { 1721a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp; 1722a9de9248SMarcel Holtmann cp.handle = ev->handle; 1723a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 1724a8746417SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, 1725a8746417SMarcel Holtmann sizeof(cp), &cp); 1726a9de9248SMarcel Holtmann } 172717d5c04cSJohan Hedberg } else { 1728a9de9248SMarcel Holtmann conn->state = BT_CLOSED; 172917d5c04cSJohan Hedberg if (conn->type == ACL_LINK) 1730744cf19eSJohan Hedberg mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, 173148264f06SJohan Hedberg conn->dst_type, ev->status); 173217d5c04cSJohan Hedberg } 173345bb4bf0SMarcel Holtmann 1734e73439d8SMarcel Holtmann if (conn->type == ACL_LINK) 1735e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 173645bb4bf0SMarcel Holtmann 1737769be974SMarcel Holtmann if (ev->status) { 1738a9de9248SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1739a9de9248SMarcel Holtmann hci_conn_del(conn); 1740c89b6e6bSMarcel Holtmann } else if (ev->link_type != ACL_LINK) 1741c89b6e6bSMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1742a9de9248SMarcel Holtmann 1743a9de9248SMarcel Holtmann unlock: 17441da177e4SLinus Torvalds hci_dev_unlock(hdev); 1745a9de9248SMarcel Holtmann 1746a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 17471da177e4SLinus Torvalds } 17481da177e4SLinus Torvalds 17491da177e4SLinus Torvalds static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 17501da177e4SLinus Torvalds { 1751a9de9248SMarcel Holtmann struct hci_ev_conn_request *ev = (void *) skb->data; 17521da177e4SLinus Torvalds int mask = hdev->link_mode; 17531da177e4SLinus Torvalds 1754a9de9248SMarcel Holtmann BT_DBG("%s bdaddr %s type 0x%x", hdev->name, 17551da177e4SLinus Torvalds batostr(&ev->bdaddr), ev->link_type); 17561da177e4SLinus Torvalds 17571da177e4SLinus Torvalds mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); 17581da177e4SLinus Torvalds 1759138d22efSSzymon Janc if ((mask & HCI_LM_ACCEPT) && 1760138d22efSSzymon Janc !hci_blacklist_lookup(hdev, &ev->bdaddr)) { 17611da177e4SLinus Torvalds /* Connection accepted */ 1762c7bdd502SMarcel Holtmann struct inquiry_entry *ie; 17631da177e4SLinus Torvalds struct hci_conn *conn; 17641da177e4SLinus Torvalds 17651da177e4SLinus Torvalds hci_dev_lock(hdev); 1766b6a0dc82SMarcel Holtmann 1767cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 1768cc11b9c1SAndrei Emeltchenko if (ie) 1769c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3); 1770c7bdd502SMarcel Holtmann 17711da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 17721da177e4SLinus Torvalds if (!conn) { 1773cc11b9c1SAndrei Emeltchenko conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr); 1774cc11b9c1SAndrei Emeltchenko if (!conn) { 1775893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 17761da177e4SLinus Torvalds hci_dev_unlock(hdev); 17771da177e4SLinus Torvalds return; 17781da177e4SLinus Torvalds } 17791da177e4SLinus Torvalds } 1780b6a0dc82SMarcel Holtmann 17811da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3); 17821da177e4SLinus Torvalds conn->state = BT_CONNECT; 1783b6a0dc82SMarcel Holtmann 17841da177e4SLinus Torvalds hci_dev_unlock(hdev); 17851da177e4SLinus Torvalds 1786b6a0dc82SMarcel Holtmann if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) { 1787b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp; 1788b6a0dc82SMarcel Holtmann 17891da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 17901da177e4SLinus Torvalds 17911da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 17921da177e4SLinus Torvalds cp.role = 0x00; /* Become master */ 17931da177e4SLinus Torvalds else 17941da177e4SLinus Torvalds cp.role = 0x01; /* Remain slave */ 17951da177e4SLinus Torvalds 1796b6a0dc82SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, 1797b6a0dc82SMarcel Holtmann sizeof(cp), &cp); 1798b6a0dc82SMarcel Holtmann } else { 1799b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp; 1800b6a0dc82SMarcel Holtmann 1801b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 1802a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 1803b6a0dc82SMarcel Holtmann 1804b6a0dc82SMarcel Holtmann cp.tx_bandwidth = cpu_to_le32(0x00001f40); 1805b6a0dc82SMarcel Holtmann cp.rx_bandwidth = cpu_to_le32(0x00001f40); 1806b6a0dc82SMarcel Holtmann cp.max_latency = cpu_to_le16(0xffff); 1807b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting); 1808b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff; 1809b6a0dc82SMarcel Holtmann 1810b6a0dc82SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, 1811b6a0dc82SMarcel Holtmann sizeof(cp), &cp); 1812b6a0dc82SMarcel Holtmann } 18131da177e4SLinus Torvalds } else { 18141da177e4SLinus Torvalds /* Connection rejected */ 18151da177e4SLinus Torvalds struct hci_cp_reject_conn_req cp; 18161da177e4SLinus Torvalds 18171da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 18189f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_REJ_BAD_ADDR; 1819a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); 18201da177e4SLinus Torvalds } 18211da177e4SLinus Torvalds } 18221da177e4SLinus Torvalds 18231da177e4SLinus Torvalds static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 18241da177e4SLinus Torvalds { 1825a9de9248SMarcel Holtmann struct hci_ev_disconn_complete *ev = (void *) skb->data; 182604837f64SMarcel Holtmann struct hci_conn *conn; 18271da177e4SLinus Torvalds 18281da177e4SLinus Torvalds BT_DBG("%s status %d", hdev->name, ev->status); 18291da177e4SLinus Torvalds 18301da177e4SLinus Torvalds hci_dev_lock(hdev); 18311da177e4SLinus Torvalds 183204837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1833f7520543SJohan Hedberg if (!conn) 1834f7520543SJohan Hedberg goto unlock; 1835f7520543SJohan Hedberg 183637d9ef76SJohan Hedberg if (ev->status == 0) 18371da177e4SLinus Torvalds conn->state = BT_CLOSED; 18387d0db0a3SMarcel Holtmann 1839b644ba33SJohan Hedberg if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && 1840b644ba33SJohan Hedberg (conn->type == ACL_LINK || conn->type == LE_LINK)) { 184137d9ef76SJohan Hedberg if (ev->status != 0) 184237d9ef76SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, ev->status); 184337d9ef76SJohan Hedberg else 1844afc747a6SJohan Hedberg mgmt_device_disconnected(hdev, &conn->dst, conn->type, 184548264f06SJohan Hedberg conn->dst_type); 184637d9ef76SJohan Hedberg } 1847f7520543SJohan Hedberg 184837d9ef76SJohan Hedberg if (ev->status == 0) { 18492950f21aSMarcel Holtmann hci_proto_disconn_cfm(conn, ev->reason); 18501da177e4SLinus Torvalds hci_conn_del(conn); 185137d9ef76SJohan Hedberg } 18521da177e4SLinus Torvalds 1853f7520543SJohan Hedberg unlock: 18541da177e4SLinus Torvalds hci_dev_unlock(hdev); 18551da177e4SLinus Torvalds } 18561da177e4SLinus Torvalds 1857a9de9248SMarcel Holtmann static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1858a9de9248SMarcel Holtmann { 1859a9de9248SMarcel Holtmann struct hci_ev_auth_complete *ev = (void *) skb->data; 1860a9de9248SMarcel Holtmann struct hci_conn *conn; 1861a9de9248SMarcel Holtmann 1862a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 1863a9de9248SMarcel Holtmann 1864a9de9248SMarcel Holtmann hci_dev_lock(hdev); 1865a9de9248SMarcel Holtmann 1866a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1867d7556e20SWaldemar Rymarkiewicz if (!conn) 1868d7556e20SWaldemar Rymarkiewicz goto unlock; 1869d7556e20SWaldemar Rymarkiewicz 1870765c2a96SJohan Hedberg if (!ev->status) { 1871aa64a8b5SJohan Hedberg if (!hci_conn_ssp_enabled(conn) && 187251a8efd7SJohan Hedberg test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { 1873d7556e20SWaldemar Rymarkiewicz BT_INFO("re-auth of legacy device is not possible."); 187419f8def0SWaldemar Rymarkiewicz } else { 1875a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 1876765c2a96SJohan Hedberg conn->sec_level = conn->pending_sec_level; 187719f8def0SWaldemar Rymarkiewicz } 18782a611692SJohan Hedberg } else { 1879744cf19eSJohan Hedberg mgmt_auth_failed(hdev, &conn->dst, ev->status); 18802a611692SJohan Hedberg } 1881a9de9248SMarcel Holtmann 188251a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 188351a8efd7SJohan Hedberg clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); 1884a9de9248SMarcel Holtmann 1885f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1886aa64a8b5SJohan Hedberg if (!ev->status && hci_conn_ssp_enabled(conn)) { 1887f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 1888f8558555SMarcel Holtmann cp.handle = ev->handle; 1889f8558555SMarcel Holtmann cp.encrypt = 0x01; 1890d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 1891d7556e20SWaldemar Rymarkiewicz &cp); 1892f8558555SMarcel Holtmann } else { 1893f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 1894f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1895f8558555SMarcel Holtmann hci_conn_put(conn); 1896f8558555SMarcel Holtmann } 1897052b30b0SMarcel Holtmann } else { 1898a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status); 1899a9de9248SMarcel Holtmann 1900052b30b0SMarcel Holtmann hci_conn_hold(conn); 1901052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 1902052b30b0SMarcel Holtmann hci_conn_put(conn); 1903052b30b0SMarcel Holtmann } 1904052b30b0SMarcel Holtmann 190551a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { 1906a9de9248SMarcel Holtmann if (!ev->status) { 1907a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 1908f8558555SMarcel Holtmann cp.handle = ev->handle; 1909f8558555SMarcel Holtmann cp.encrypt = 0x01; 1910d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 1911d7556e20SWaldemar Rymarkiewicz &cp); 1912a9de9248SMarcel Holtmann } else { 191351a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 1914a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, 0x00); 1915a9de9248SMarcel Holtmann } 1916a9de9248SMarcel Holtmann } 1917a9de9248SMarcel Holtmann 1918d7556e20SWaldemar Rymarkiewicz unlock: 1919a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 1920a9de9248SMarcel Holtmann } 1921a9de9248SMarcel Holtmann 1922a9de9248SMarcel Holtmann static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) 1923a9de9248SMarcel Holtmann { 1924127178d2SJohan Hedberg struct hci_ev_remote_name *ev = (void *) skb->data; 1925127178d2SJohan Hedberg struct hci_conn *conn; 1926127178d2SJohan Hedberg 1927a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 1928a9de9248SMarcel Holtmann 1929a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 1930127178d2SJohan Hedberg 1931127178d2SJohan Hedberg hci_dev_lock(hdev); 1932127178d2SJohan Hedberg 1933127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 1934b644ba33SJohan Hedberg 1935b644ba33SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1936b644ba33SJohan Hedberg goto check_auth; 1937b644ba33SJohan Hedberg 1938b644ba33SJohan Hedberg if (ev->status == 0) 1939b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, 1940b644ba33SJohan Hedberg strnlen(ev->name, HCI_MAX_NAME_LENGTH)); 1941b644ba33SJohan Hedberg else 1942b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); 1943b644ba33SJohan Hedberg 1944b644ba33SJohan Hedberg check_auth: 194579c6c70cSJohan Hedberg if (!conn) 194679c6c70cSJohan Hedberg goto unlock; 194779c6c70cSJohan Hedberg 194879c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 194979c6c70cSJohan Hedberg goto unlock; 195079c6c70cSJohan Hedberg 195151a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 1952127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 1953127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 1954127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 1955127178d2SJohan Hedberg } 1956127178d2SJohan Hedberg 195779c6c70cSJohan Hedberg unlock: 1958127178d2SJohan Hedberg hci_dev_unlock(hdev); 1959a9de9248SMarcel Holtmann } 1960a9de9248SMarcel Holtmann 1961a9de9248SMarcel Holtmann static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 1962a9de9248SMarcel Holtmann { 1963a9de9248SMarcel Holtmann struct hci_ev_encrypt_change *ev = (void *) skb->data; 1964a9de9248SMarcel Holtmann struct hci_conn *conn; 1965a9de9248SMarcel Holtmann 1966a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 1967a9de9248SMarcel Holtmann 1968a9de9248SMarcel Holtmann hci_dev_lock(hdev); 1969a9de9248SMarcel Holtmann 1970a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1971a9de9248SMarcel Holtmann if (conn) { 1972a9de9248SMarcel Holtmann if (!ev->status) { 1973ae293196SMarcel Holtmann if (ev->encrypt) { 1974ae293196SMarcel Holtmann /* Encryption implies authentication */ 1975ae293196SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 1976a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_ENCRYPT; 1977da85e5e5SVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 1978ae293196SMarcel Holtmann } else 1979a9de9248SMarcel Holtmann conn->link_mode &= ~HCI_LM_ENCRYPT; 1980a9de9248SMarcel Holtmann } 1981a9de9248SMarcel Holtmann 198251a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 1983a9de9248SMarcel Holtmann 1984f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1985f8558555SMarcel Holtmann if (!ev->status) 1986f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 1987f8558555SMarcel Holtmann 1988f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1989f8558555SMarcel Holtmann hci_conn_put(conn); 1990f8558555SMarcel Holtmann } else 1991a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, ev->encrypt); 1992a9de9248SMarcel Holtmann } 1993a9de9248SMarcel Holtmann 1994a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 1995a9de9248SMarcel Holtmann } 1996a9de9248SMarcel Holtmann 1997a9de9248SMarcel Holtmann static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1998a9de9248SMarcel Holtmann { 1999a9de9248SMarcel Holtmann struct hci_ev_change_link_key_complete *ev = (void *) skb->data; 2000a9de9248SMarcel Holtmann struct hci_conn *conn; 2001a9de9248SMarcel Holtmann 2002a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 2003a9de9248SMarcel Holtmann 2004a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2005a9de9248SMarcel Holtmann 2006a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2007a9de9248SMarcel Holtmann if (conn) { 2008a9de9248SMarcel Holtmann if (!ev->status) 2009a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_SECURE; 2010a9de9248SMarcel Holtmann 201151a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 2012a9de9248SMarcel Holtmann 2013a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status); 2014a9de9248SMarcel Holtmann } 2015a9de9248SMarcel Holtmann 2016a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2017a9de9248SMarcel Holtmann } 2018a9de9248SMarcel Holtmann 2019a9de9248SMarcel Holtmann static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb) 2020a9de9248SMarcel Holtmann { 2021a9de9248SMarcel Holtmann struct hci_ev_remote_features *ev = (void *) skb->data; 2022a9de9248SMarcel Holtmann struct hci_conn *conn; 2023a9de9248SMarcel Holtmann 2024a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 2025a9de9248SMarcel Holtmann 2026a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2027a9de9248SMarcel Holtmann 2028a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2029ccd556feSJohan Hedberg if (!conn) 2030ccd556feSJohan Hedberg goto unlock; 2031ccd556feSJohan Hedberg 2032769be974SMarcel Holtmann if (!ev->status) 2033a9de9248SMarcel Holtmann memcpy(conn->features, ev->features, 8); 2034a9de9248SMarcel Holtmann 2035ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 2036ccd556feSJohan Hedberg goto unlock; 2037ccd556feSJohan Hedberg 2038ccd556feSJohan Hedberg if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) { 2039769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp; 2040769be974SMarcel Holtmann cp.handle = ev->handle; 2041769be974SMarcel Holtmann cp.page = 0x01; 2042ccd556feSJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, 2043769be974SMarcel Holtmann sizeof(cp), &cp); 2044392599b9SJohan Hedberg goto unlock; 2045392599b9SJohan Hedberg } 2046392599b9SJohan Hedberg 2047127178d2SJohan Hedberg if (!ev->status) { 2048127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 2049127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 2050127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 2051127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 2052127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 2053b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 2054b644ba33SJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 2055b644ba33SJohan Hedberg conn->dst_type, NULL, 0, 2056b644ba33SJohan Hedberg conn->dev_class); 2057392599b9SJohan Hedberg 2058127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 2059769be974SMarcel Holtmann conn->state = BT_CONNECTED; 2060769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 2061769be974SMarcel Holtmann hci_conn_put(conn); 2062769be974SMarcel Holtmann } 2063769be974SMarcel Holtmann 2064ccd556feSJohan Hedberg unlock: 2065a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2066a9de9248SMarcel Holtmann } 2067a9de9248SMarcel Holtmann 2068a9de9248SMarcel Holtmann static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb) 2069a9de9248SMarcel Holtmann { 2070a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2071a9de9248SMarcel Holtmann } 2072a9de9248SMarcel Holtmann 2073a9de9248SMarcel Holtmann static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2074a9de9248SMarcel Holtmann { 2075a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2076a9de9248SMarcel Holtmann } 2077a9de9248SMarcel Holtmann 2078a9de9248SMarcel Holtmann static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2079a9de9248SMarcel Holtmann { 2080a9de9248SMarcel Holtmann struct hci_ev_cmd_complete *ev = (void *) skb->data; 2081a9de9248SMarcel Holtmann __u16 opcode; 2082a9de9248SMarcel Holtmann 2083a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2084a9de9248SMarcel Holtmann 2085a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 2086a9de9248SMarcel Holtmann 2087a9de9248SMarcel Holtmann switch (opcode) { 2088a9de9248SMarcel Holtmann case HCI_OP_INQUIRY_CANCEL: 2089a9de9248SMarcel Holtmann hci_cc_inquiry_cancel(hdev, skb); 2090a9de9248SMarcel Holtmann break; 2091a9de9248SMarcel Holtmann 2092a9de9248SMarcel Holtmann case HCI_OP_EXIT_PERIODIC_INQ: 2093a9de9248SMarcel Holtmann hci_cc_exit_periodic_inq(hdev, skb); 2094a9de9248SMarcel Holtmann break; 2095a9de9248SMarcel Holtmann 2096a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ_CANCEL: 2097a9de9248SMarcel Holtmann hci_cc_remote_name_req_cancel(hdev, skb); 2098a9de9248SMarcel Holtmann break; 2099a9de9248SMarcel Holtmann 2100a9de9248SMarcel Holtmann case HCI_OP_ROLE_DISCOVERY: 2101a9de9248SMarcel Holtmann hci_cc_role_discovery(hdev, skb); 2102a9de9248SMarcel Holtmann break; 2103a9de9248SMarcel Holtmann 2104e4e8e37cSMarcel Holtmann case HCI_OP_READ_LINK_POLICY: 2105e4e8e37cSMarcel Holtmann hci_cc_read_link_policy(hdev, skb); 2106e4e8e37cSMarcel Holtmann break; 2107e4e8e37cSMarcel Holtmann 2108a9de9248SMarcel Holtmann case HCI_OP_WRITE_LINK_POLICY: 2109a9de9248SMarcel Holtmann hci_cc_write_link_policy(hdev, skb); 2110a9de9248SMarcel Holtmann break; 2111a9de9248SMarcel Holtmann 2112e4e8e37cSMarcel Holtmann case HCI_OP_READ_DEF_LINK_POLICY: 2113e4e8e37cSMarcel Holtmann hci_cc_read_def_link_policy(hdev, skb); 2114e4e8e37cSMarcel Holtmann break; 2115e4e8e37cSMarcel Holtmann 2116e4e8e37cSMarcel Holtmann case HCI_OP_WRITE_DEF_LINK_POLICY: 2117e4e8e37cSMarcel Holtmann hci_cc_write_def_link_policy(hdev, skb); 2118e4e8e37cSMarcel Holtmann break; 2119e4e8e37cSMarcel Holtmann 2120a9de9248SMarcel Holtmann case HCI_OP_RESET: 2121a9de9248SMarcel Holtmann hci_cc_reset(hdev, skb); 2122a9de9248SMarcel Holtmann break; 2123a9de9248SMarcel Holtmann 2124a9de9248SMarcel Holtmann case HCI_OP_WRITE_LOCAL_NAME: 2125a9de9248SMarcel Holtmann hci_cc_write_local_name(hdev, skb); 2126a9de9248SMarcel Holtmann break; 2127a9de9248SMarcel Holtmann 2128a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_NAME: 2129a9de9248SMarcel Holtmann hci_cc_read_local_name(hdev, skb); 2130a9de9248SMarcel Holtmann break; 2131a9de9248SMarcel Holtmann 2132a9de9248SMarcel Holtmann case HCI_OP_WRITE_AUTH_ENABLE: 2133a9de9248SMarcel Holtmann hci_cc_write_auth_enable(hdev, skb); 2134a9de9248SMarcel Holtmann break; 2135a9de9248SMarcel Holtmann 2136a9de9248SMarcel Holtmann case HCI_OP_WRITE_ENCRYPT_MODE: 2137a9de9248SMarcel Holtmann hci_cc_write_encrypt_mode(hdev, skb); 2138a9de9248SMarcel Holtmann break; 2139a9de9248SMarcel Holtmann 2140a9de9248SMarcel Holtmann case HCI_OP_WRITE_SCAN_ENABLE: 2141a9de9248SMarcel Holtmann hci_cc_write_scan_enable(hdev, skb); 2142a9de9248SMarcel Holtmann break; 2143a9de9248SMarcel Holtmann 2144a9de9248SMarcel Holtmann case HCI_OP_READ_CLASS_OF_DEV: 2145a9de9248SMarcel Holtmann hci_cc_read_class_of_dev(hdev, skb); 2146a9de9248SMarcel Holtmann break; 2147a9de9248SMarcel Holtmann 2148a9de9248SMarcel Holtmann case HCI_OP_WRITE_CLASS_OF_DEV: 2149a9de9248SMarcel Holtmann hci_cc_write_class_of_dev(hdev, skb); 2150a9de9248SMarcel Holtmann break; 2151a9de9248SMarcel Holtmann 2152a9de9248SMarcel Holtmann case HCI_OP_READ_VOICE_SETTING: 2153a9de9248SMarcel Holtmann hci_cc_read_voice_setting(hdev, skb); 2154a9de9248SMarcel Holtmann break; 2155a9de9248SMarcel Holtmann 2156a9de9248SMarcel Holtmann case HCI_OP_WRITE_VOICE_SETTING: 2157a9de9248SMarcel Holtmann hci_cc_write_voice_setting(hdev, skb); 2158a9de9248SMarcel Holtmann break; 2159a9de9248SMarcel Holtmann 2160a9de9248SMarcel Holtmann case HCI_OP_HOST_BUFFER_SIZE: 2161a9de9248SMarcel Holtmann hci_cc_host_buffer_size(hdev, skb); 2162a9de9248SMarcel Holtmann break; 2163a9de9248SMarcel Holtmann 2164333140b5SMarcel Holtmann case HCI_OP_READ_SSP_MODE: 2165333140b5SMarcel Holtmann hci_cc_read_ssp_mode(hdev, skb); 2166333140b5SMarcel Holtmann break; 2167333140b5SMarcel Holtmann 2168333140b5SMarcel Holtmann case HCI_OP_WRITE_SSP_MODE: 2169333140b5SMarcel Holtmann hci_cc_write_ssp_mode(hdev, skb); 2170333140b5SMarcel Holtmann break; 2171333140b5SMarcel Holtmann 2172a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_VERSION: 2173a9de9248SMarcel Holtmann hci_cc_read_local_version(hdev, skb); 2174a9de9248SMarcel Holtmann break; 2175a9de9248SMarcel Holtmann 2176a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_COMMANDS: 2177a9de9248SMarcel Holtmann hci_cc_read_local_commands(hdev, skb); 2178a9de9248SMarcel Holtmann break; 2179a9de9248SMarcel Holtmann 2180a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_FEATURES: 2181a9de9248SMarcel Holtmann hci_cc_read_local_features(hdev, skb); 2182a9de9248SMarcel Holtmann break; 2183a9de9248SMarcel Holtmann 2184971e3a4bSAndre Guedes case HCI_OP_READ_LOCAL_EXT_FEATURES: 2185971e3a4bSAndre Guedes hci_cc_read_local_ext_features(hdev, skb); 2186971e3a4bSAndre Guedes break; 2187971e3a4bSAndre Guedes 2188a9de9248SMarcel Holtmann case HCI_OP_READ_BUFFER_SIZE: 2189a9de9248SMarcel Holtmann hci_cc_read_buffer_size(hdev, skb); 2190a9de9248SMarcel Holtmann break; 2191a9de9248SMarcel Holtmann 2192a9de9248SMarcel Holtmann case HCI_OP_READ_BD_ADDR: 2193a9de9248SMarcel Holtmann hci_cc_read_bd_addr(hdev, skb); 2194a9de9248SMarcel Holtmann break; 2195a9de9248SMarcel Holtmann 2196350ee4cfSAndrei Emeltchenko case HCI_OP_READ_DATA_BLOCK_SIZE: 2197350ee4cfSAndrei Emeltchenko hci_cc_read_data_block_size(hdev, skb); 2198350ee4cfSAndrei Emeltchenko break; 2199350ee4cfSAndrei Emeltchenko 220023bb5763SJohan Hedberg case HCI_OP_WRITE_CA_TIMEOUT: 220123bb5763SJohan Hedberg hci_cc_write_ca_timeout(hdev, skb); 220223bb5763SJohan Hedberg break; 220323bb5763SJohan Hedberg 22041e89cffbSAndrei Emeltchenko case HCI_OP_READ_FLOW_CONTROL_MODE: 22051e89cffbSAndrei Emeltchenko hci_cc_read_flow_control_mode(hdev, skb); 22061e89cffbSAndrei Emeltchenko break; 22071e89cffbSAndrei Emeltchenko 2208928abaa7SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_INFO: 2209928abaa7SAndrei Emeltchenko hci_cc_read_local_amp_info(hdev, skb); 2210928abaa7SAndrei Emeltchenko break; 2211928abaa7SAndrei Emeltchenko 2212b0916ea0SJohan Hedberg case HCI_OP_DELETE_STORED_LINK_KEY: 2213b0916ea0SJohan Hedberg hci_cc_delete_stored_link_key(hdev, skb); 2214b0916ea0SJohan Hedberg break; 2215b0916ea0SJohan Hedberg 2216d5859e22SJohan Hedberg case HCI_OP_SET_EVENT_MASK: 2217d5859e22SJohan Hedberg hci_cc_set_event_mask(hdev, skb); 2218d5859e22SJohan Hedberg break; 2219d5859e22SJohan Hedberg 2220d5859e22SJohan Hedberg case HCI_OP_WRITE_INQUIRY_MODE: 2221d5859e22SJohan Hedberg hci_cc_write_inquiry_mode(hdev, skb); 2222d5859e22SJohan Hedberg break; 2223d5859e22SJohan Hedberg 2224d5859e22SJohan Hedberg case HCI_OP_READ_INQ_RSP_TX_POWER: 2225d5859e22SJohan Hedberg hci_cc_read_inq_rsp_tx_power(hdev, skb); 2226d5859e22SJohan Hedberg break; 2227d5859e22SJohan Hedberg 2228d5859e22SJohan Hedberg case HCI_OP_SET_EVENT_FLT: 2229d5859e22SJohan Hedberg hci_cc_set_event_flt(hdev, skb); 2230d5859e22SJohan Hedberg break; 2231d5859e22SJohan Hedberg 2232980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_REPLY: 2233980e1a53SJohan Hedberg hci_cc_pin_code_reply(hdev, skb); 2234980e1a53SJohan Hedberg break; 2235980e1a53SJohan Hedberg 2236980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_NEG_REPLY: 2237980e1a53SJohan Hedberg hci_cc_pin_code_neg_reply(hdev, skb); 2238980e1a53SJohan Hedberg break; 2239980e1a53SJohan Hedberg 2240c35938b2SSzymon Janc case HCI_OP_READ_LOCAL_OOB_DATA: 2241c35938b2SSzymon Janc hci_cc_read_local_oob_data_reply(hdev, skb); 2242c35938b2SSzymon Janc break; 2243c35938b2SSzymon Janc 22446ed58ec5SVille Tervo case HCI_OP_LE_READ_BUFFER_SIZE: 22456ed58ec5SVille Tervo hci_cc_le_read_buffer_size(hdev, skb); 22466ed58ec5SVille Tervo break; 22476ed58ec5SVille Tervo 2248a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_REPLY: 2249a5c29683SJohan Hedberg hci_cc_user_confirm_reply(hdev, skb); 2250a5c29683SJohan Hedberg break; 2251a5c29683SJohan Hedberg 2252a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_NEG_REPLY: 2253a5c29683SJohan Hedberg hci_cc_user_confirm_neg_reply(hdev, skb); 2254a5c29683SJohan Hedberg break; 2255a5c29683SJohan Hedberg 22561143d458SBrian Gix case HCI_OP_USER_PASSKEY_REPLY: 22571143d458SBrian Gix hci_cc_user_passkey_reply(hdev, skb); 22581143d458SBrian Gix break; 22591143d458SBrian Gix 22601143d458SBrian Gix case HCI_OP_USER_PASSKEY_NEG_REPLY: 22611143d458SBrian Gix hci_cc_user_passkey_neg_reply(hdev, skb); 226207f7fa5dSAndre Guedes 226307f7fa5dSAndre Guedes case HCI_OP_LE_SET_SCAN_PARAM: 226407f7fa5dSAndre Guedes hci_cc_le_set_scan_param(hdev, skb); 22651143d458SBrian Gix break; 22661143d458SBrian Gix 2267eb9d91f5SAndre Guedes case HCI_OP_LE_SET_SCAN_ENABLE: 2268eb9d91f5SAndre Guedes hci_cc_le_set_scan_enable(hdev, skb); 2269eb9d91f5SAndre Guedes break; 2270eb9d91f5SAndre Guedes 2271a7a595f6SVinicius Costa Gomes case HCI_OP_LE_LTK_REPLY: 2272a7a595f6SVinicius Costa Gomes hci_cc_le_ltk_reply(hdev, skb); 2273a7a595f6SVinicius Costa Gomes break; 2274a7a595f6SVinicius Costa Gomes 2275a7a595f6SVinicius Costa Gomes case HCI_OP_LE_LTK_NEG_REPLY: 2276a7a595f6SVinicius Costa Gomes hci_cc_le_ltk_neg_reply(hdev, skb); 2277a7a595f6SVinicius Costa Gomes break; 2278a7a595f6SVinicius Costa Gomes 2279f9b49306SAndre Guedes case HCI_OP_WRITE_LE_HOST_SUPPORTED: 2280f9b49306SAndre Guedes hci_cc_write_le_host_supported(hdev, skb); 2281f9b49306SAndre Guedes break; 2282f9b49306SAndre Guedes 2283a9de9248SMarcel Holtmann default: 2284a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 2285a9de9248SMarcel Holtmann break; 2286a9de9248SMarcel Holtmann } 2287a9de9248SMarcel Holtmann 22886bd32326SVille Tervo if (ev->opcode != HCI_OP_NOP) 22896bd32326SVille Tervo del_timer(&hdev->cmd_timer); 22906bd32326SVille Tervo 2291a9de9248SMarcel Holtmann if (ev->ncmd) { 2292a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 2293a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 2294c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 2295a9de9248SMarcel Holtmann } 2296a9de9248SMarcel Holtmann } 2297a9de9248SMarcel Holtmann 2298a9de9248SMarcel Holtmann static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) 2299a9de9248SMarcel Holtmann { 2300a9de9248SMarcel Holtmann struct hci_ev_cmd_status *ev = (void *) skb->data; 2301a9de9248SMarcel Holtmann __u16 opcode; 2302a9de9248SMarcel Holtmann 2303a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2304a9de9248SMarcel Holtmann 2305a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 2306a9de9248SMarcel Holtmann 2307a9de9248SMarcel Holtmann switch (opcode) { 2308a9de9248SMarcel Holtmann case HCI_OP_INQUIRY: 2309a9de9248SMarcel Holtmann hci_cs_inquiry(hdev, ev->status); 2310a9de9248SMarcel Holtmann break; 2311a9de9248SMarcel Holtmann 2312a9de9248SMarcel Holtmann case HCI_OP_CREATE_CONN: 2313a9de9248SMarcel Holtmann hci_cs_create_conn(hdev, ev->status); 2314a9de9248SMarcel Holtmann break; 2315a9de9248SMarcel Holtmann 2316a9de9248SMarcel Holtmann case HCI_OP_ADD_SCO: 2317a9de9248SMarcel Holtmann hci_cs_add_sco(hdev, ev->status); 2318a9de9248SMarcel Holtmann break; 2319a9de9248SMarcel Holtmann 2320f8558555SMarcel Holtmann case HCI_OP_AUTH_REQUESTED: 2321f8558555SMarcel Holtmann hci_cs_auth_requested(hdev, ev->status); 2322f8558555SMarcel Holtmann break; 2323f8558555SMarcel Holtmann 2324f8558555SMarcel Holtmann case HCI_OP_SET_CONN_ENCRYPT: 2325f8558555SMarcel Holtmann hci_cs_set_conn_encrypt(hdev, ev->status); 2326f8558555SMarcel Holtmann break; 2327f8558555SMarcel Holtmann 2328a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ: 2329a9de9248SMarcel Holtmann hci_cs_remote_name_req(hdev, ev->status); 2330a9de9248SMarcel Holtmann break; 2331a9de9248SMarcel Holtmann 2332769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_FEATURES: 2333769be974SMarcel Holtmann hci_cs_read_remote_features(hdev, ev->status); 2334769be974SMarcel Holtmann break; 2335769be974SMarcel Holtmann 2336769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_EXT_FEATURES: 2337769be974SMarcel Holtmann hci_cs_read_remote_ext_features(hdev, ev->status); 2338769be974SMarcel Holtmann break; 2339769be974SMarcel Holtmann 2340a9de9248SMarcel Holtmann case HCI_OP_SETUP_SYNC_CONN: 2341a9de9248SMarcel Holtmann hci_cs_setup_sync_conn(hdev, ev->status); 2342a9de9248SMarcel Holtmann break; 2343a9de9248SMarcel Holtmann 2344a9de9248SMarcel Holtmann case HCI_OP_SNIFF_MODE: 2345a9de9248SMarcel Holtmann hci_cs_sniff_mode(hdev, ev->status); 2346a9de9248SMarcel Holtmann break; 2347a9de9248SMarcel Holtmann 2348a9de9248SMarcel Holtmann case HCI_OP_EXIT_SNIFF_MODE: 2349a9de9248SMarcel Holtmann hci_cs_exit_sniff_mode(hdev, ev->status); 2350a9de9248SMarcel Holtmann break; 2351a9de9248SMarcel Holtmann 23528962ee74SJohan Hedberg case HCI_OP_DISCONNECT: 23538962ee74SJohan Hedberg if (ev->status != 0) 235437d9ef76SJohan Hedberg mgmt_disconnect_failed(hdev, NULL, ev->status); 23558962ee74SJohan Hedberg break; 23568962ee74SJohan Hedberg 2357fcd89c09SVille Tervo case HCI_OP_LE_CREATE_CONN: 2358fcd89c09SVille Tervo hci_cs_le_create_conn(hdev, ev->status); 2359fcd89c09SVille Tervo break; 2360fcd89c09SVille Tervo 2361a7a595f6SVinicius Costa Gomes case HCI_OP_LE_START_ENC: 2362a7a595f6SVinicius Costa Gomes hci_cs_le_start_enc(hdev, ev->status); 2363a7a595f6SVinicius Costa Gomes break; 2364a7a595f6SVinicius Costa Gomes 2365a9de9248SMarcel Holtmann default: 2366a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 2367a9de9248SMarcel Holtmann break; 2368a9de9248SMarcel Holtmann } 2369a9de9248SMarcel Holtmann 23706bd32326SVille Tervo if (ev->opcode != HCI_OP_NOP) 23716bd32326SVille Tervo del_timer(&hdev->cmd_timer); 23726bd32326SVille Tervo 237310572132SGustavo F. Padovan if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { 2374a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 2375a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 2376c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 2377a9de9248SMarcel Holtmann } 2378a9de9248SMarcel Holtmann } 2379a9de9248SMarcel Holtmann 2380a9de9248SMarcel Holtmann static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2381a9de9248SMarcel Holtmann { 2382a9de9248SMarcel Holtmann struct hci_ev_role_change *ev = (void *) skb->data; 2383a9de9248SMarcel Holtmann struct hci_conn *conn; 2384a9de9248SMarcel Holtmann 2385a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 2386a9de9248SMarcel Holtmann 2387a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2388a9de9248SMarcel Holtmann 2389a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2390a9de9248SMarcel Holtmann if (conn) { 2391a9de9248SMarcel Holtmann if (!ev->status) { 2392a9de9248SMarcel Holtmann if (ev->role) 2393a9de9248SMarcel Holtmann conn->link_mode &= ~HCI_LM_MASTER; 2394a9de9248SMarcel Holtmann else 2395a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_MASTER; 2396a9de9248SMarcel Holtmann } 2397a9de9248SMarcel Holtmann 239851a8efd7SJohan Hedberg clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 2399a9de9248SMarcel Holtmann 2400a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role); 2401a9de9248SMarcel Holtmann } 2402a9de9248SMarcel Holtmann 2403a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2404a9de9248SMarcel Holtmann } 2405a9de9248SMarcel Holtmann 24061da177e4SLinus Torvalds static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) 24071da177e4SLinus Torvalds { 2408a9de9248SMarcel Holtmann struct hci_ev_num_comp_pkts *ev = (void *) skb->data; 24091da177e4SLinus Torvalds int i; 24101da177e4SLinus Torvalds 241132ac5b9bSAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) { 241232ac5b9bSAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 241332ac5b9bSAndrei Emeltchenko return; 241432ac5b9bSAndrei Emeltchenko } 241532ac5b9bSAndrei Emeltchenko 2416c5993de8SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 2417c5993de8SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_pkts_info)) { 24181da177e4SLinus Torvalds BT_DBG("%s bad parameters", hdev->name); 24191da177e4SLinus Torvalds return; 24201da177e4SLinus Torvalds } 24211da177e4SLinus Torvalds 2422c5993de8SAndrei Emeltchenko BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl); 2423c5993de8SAndrei Emeltchenko 2424613a1c0cSAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 2425613a1c0cSAndrei Emeltchenko struct hci_comp_pkts_info *info = &ev->handles[i]; 24261da177e4SLinus Torvalds struct hci_conn *conn; 24271da177e4SLinus Torvalds __u16 handle, count; 24281da177e4SLinus Torvalds 2429613a1c0cSAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 2430613a1c0cSAndrei Emeltchenko count = __le16_to_cpu(info->count); 24311da177e4SLinus Torvalds 24321da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 2433f4280918SAndrei Emeltchenko if (!conn) 2434f4280918SAndrei Emeltchenko continue; 2435f4280918SAndrei Emeltchenko 24361da177e4SLinus Torvalds conn->sent -= count; 24371da177e4SLinus Torvalds 2438f4280918SAndrei Emeltchenko switch (conn->type) { 2439f4280918SAndrei Emeltchenko case ACL_LINK: 244070f23020SAndrei Emeltchenko hdev->acl_cnt += count; 244170f23020SAndrei Emeltchenko if (hdev->acl_cnt > hdev->acl_pkts) 24421da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts; 2443f4280918SAndrei Emeltchenko break; 2444f4280918SAndrei Emeltchenko 2445f4280918SAndrei Emeltchenko case LE_LINK: 24466ed58ec5SVille Tervo if (hdev->le_pkts) { 24476ed58ec5SVille Tervo hdev->le_cnt += count; 24486ed58ec5SVille Tervo if (hdev->le_cnt > hdev->le_pkts) 24496ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 24506ed58ec5SVille Tervo } else { 24516ed58ec5SVille Tervo hdev->acl_cnt += count; 24526ed58ec5SVille Tervo if (hdev->acl_cnt > hdev->acl_pkts) 24536ed58ec5SVille Tervo hdev->acl_cnt = hdev->acl_pkts; 24546ed58ec5SVille Tervo } 2455f4280918SAndrei Emeltchenko break; 2456f4280918SAndrei Emeltchenko 2457f4280918SAndrei Emeltchenko case SCO_LINK: 245870f23020SAndrei Emeltchenko hdev->sco_cnt += count; 245970f23020SAndrei Emeltchenko if (hdev->sco_cnt > hdev->sco_pkts) 24605b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 2461f4280918SAndrei Emeltchenko break; 2462f4280918SAndrei Emeltchenko 2463f4280918SAndrei Emeltchenko default: 2464f4280918SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 2465f4280918SAndrei Emeltchenko break; 24661da177e4SLinus Torvalds } 24671da177e4SLinus Torvalds } 2468a9de9248SMarcel Holtmann 24693eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 24701da177e4SLinus Torvalds } 24711da177e4SLinus Torvalds 247225e89e99SAndrei Emeltchenko static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev, 247325e89e99SAndrei Emeltchenko struct sk_buff *skb) 247425e89e99SAndrei Emeltchenko { 247525e89e99SAndrei Emeltchenko struct hci_ev_num_comp_blocks *ev = (void *) skb->data; 247625e89e99SAndrei Emeltchenko int i; 247725e89e99SAndrei Emeltchenko 247825e89e99SAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) { 247925e89e99SAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 248025e89e99SAndrei Emeltchenko return; 248125e89e99SAndrei Emeltchenko } 248225e89e99SAndrei Emeltchenko 248325e89e99SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 248425e89e99SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { 248525e89e99SAndrei Emeltchenko BT_DBG("%s bad parameters", hdev->name); 248625e89e99SAndrei Emeltchenko return; 248725e89e99SAndrei Emeltchenko } 248825e89e99SAndrei Emeltchenko 248925e89e99SAndrei Emeltchenko BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks, 249025e89e99SAndrei Emeltchenko ev->num_hndl); 249125e89e99SAndrei Emeltchenko 249225e89e99SAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 249325e89e99SAndrei Emeltchenko struct hci_comp_blocks_info *info = &ev->handles[i]; 249425e89e99SAndrei Emeltchenko struct hci_conn *conn; 249525e89e99SAndrei Emeltchenko __u16 handle, block_count; 249625e89e99SAndrei Emeltchenko 249725e89e99SAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 249825e89e99SAndrei Emeltchenko block_count = __le16_to_cpu(info->blocks); 249925e89e99SAndrei Emeltchenko 250025e89e99SAndrei Emeltchenko conn = hci_conn_hash_lookup_handle(hdev, handle); 250125e89e99SAndrei Emeltchenko if (!conn) 250225e89e99SAndrei Emeltchenko continue; 250325e89e99SAndrei Emeltchenko 250425e89e99SAndrei Emeltchenko conn->sent -= block_count; 250525e89e99SAndrei Emeltchenko 250625e89e99SAndrei Emeltchenko switch (conn->type) { 250725e89e99SAndrei Emeltchenko case ACL_LINK: 250825e89e99SAndrei Emeltchenko hdev->block_cnt += block_count; 250925e89e99SAndrei Emeltchenko if (hdev->block_cnt > hdev->num_blocks) 251025e89e99SAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 251125e89e99SAndrei Emeltchenko break; 251225e89e99SAndrei Emeltchenko 251325e89e99SAndrei Emeltchenko default: 251425e89e99SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 251525e89e99SAndrei Emeltchenko break; 251625e89e99SAndrei Emeltchenko } 251725e89e99SAndrei Emeltchenko } 251825e89e99SAndrei Emeltchenko 251925e89e99SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->tx_work); 252025e89e99SAndrei Emeltchenko } 252125e89e99SAndrei Emeltchenko 252204837f64SMarcel Holtmann static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 25231da177e4SLinus Torvalds { 2524a9de9248SMarcel Holtmann struct hci_ev_mode_change *ev = (void *) skb->data; 252504837f64SMarcel Holtmann struct hci_conn *conn; 25261da177e4SLinus Torvalds 25271da177e4SLinus Torvalds BT_DBG("%s status %d", hdev->name, ev->status); 25281da177e4SLinus Torvalds 25291da177e4SLinus Torvalds hci_dev_lock(hdev); 25301da177e4SLinus Torvalds 253104837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 253204837f64SMarcel Holtmann if (conn) { 253304837f64SMarcel Holtmann conn->mode = ev->mode; 253404837f64SMarcel Holtmann conn->interval = __le16_to_cpu(ev->interval); 253504837f64SMarcel Holtmann 253651a8efd7SJohan Hedberg if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) { 253704837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE) 253858a681efSJohan Hedberg set_bit(HCI_CONN_POWER_SAVE, &conn->flags); 253904837f64SMarcel Holtmann else 254058a681efSJohan Hedberg clear_bit(HCI_CONN_POWER_SAVE, &conn->flags); 254104837f64SMarcel Holtmann } 2542e73439d8SMarcel Holtmann 254351a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 2544e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 254504837f64SMarcel Holtmann } 254604837f64SMarcel Holtmann 254704837f64SMarcel Holtmann hci_dev_unlock(hdev); 254804837f64SMarcel Holtmann } 254904837f64SMarcel Holtmann 25501da177e4SLinus Torvalds static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 25511da177e4SLinus Torvalds { 2552052b30b0SMarcel Holtmann struct hci_ev_pin_code_req *ev = (void *) skb->data; 2553052b30b0SMarcel Holtmann struct hci_conn *conn; 2554052b30b0SMarcel Holtmann 2555a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2556052b30b0SMarcel Holtmann 2557052b30b0SMarcel Holtmann hci_dev_lock(hdev); 2558052b30b0SMarcel Holtmann 2559052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2560b6f98044SWaldemar Rymarkiewicz if (!conn) 2561b6f98044SWaldemar Rymarkiewicz goto unlock; 2562b6f98044SWaldemar Rymarkiewicz 2563b6f98044SWaldemar Rymarkiewicz if (conn->state == BT_CONNECTED) { 2564052b30b0SMarcel Holtmann hci_conn_hold(conn); 2565052b30b0SMarcel Holtmann conn->disc_timeout = HCI_PAIRING_TIMEOUT; 2566052b30b0SMarcel Holtmann hci_conn_put(conn); 2567052b30b0SMarcel Holtmann } 2568052b30b0SMarcel Holtmann 2569a8b2d5c2SJohan Hedberg if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags)) 257003b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, 257103b555e1SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 2572a8b2d5c2SJohan Hedberg else if (test_bit(HCI_MGMT, &hdev->dev_flags)) { 2573a770bb5aSWaldemar Rymarkiewicz u8 secure; 2574a770bb5aSWaldemar Rymarkiewicz 2575a770bb5aSWaldemar Rymarkiewicz if (conn->pending_sec_level == BT_SECURITY_HIGH) 2576a770bb5aSWaldemar Rymarkiewicz secure = 1; 2577a770bb5aSWaldemar Rymarkiewicz else 2578a770bb5aSWaldemar Rymarkiewicz secure = 0; 2579a770bb5aSWaldemar Rymarkiewicz 2580744cf19eSJohan Hedberg mgmt_pin_code_request(hdev, &ev->bdaddr, secure); 2581a770bb5aSWaldemar Rymarkiewicz } 2582980e1a53SJohan Hedberg 2583b6f98044SWaldemar Rymarkiewicz unlock: 2584052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 25851da177e4SLinus Torvalds } 25861da177e4SLinus Torvalds 25871da177e4SLinus Torvalds static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 25881da177e4SLinus Torvalds { 258955ed8ca1SJohan Hedberg struct hci_ev_link_key_req *ev = (void *) skb->data; 259055ed8ca1SJohan Hedberg struct hci_cp_link_key_reply cp; 259155ed8ca1SJohan Hedberg struct hci_conn *conn; 259255ed8ca1SJohan Hedberg struct link_key *key; 259355ed8ca1SJohan Hedberg 2594a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 259555ed8ca1SJohan Hedberg 2596a8b2d5c2SJohan Hedberg if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) 259755ed8ca1SJohan Hedberg return; 259855ed8ca1SJohan Hedberg 259955ed8ca1SJohan Hedberg hci_dev_lock(hdev); 260055ed8ca1SJohan Hedberg 260155ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, &ev->bdaddr); 260255ed8ca1SJohan Hedberg if (!key) { 260355ed8ca1SJohan Hedberg BT_DBG("%s link key not found for %s", hdev->name, 260455ed8ca1SJohan Hedberg batostr(&ev->bdaddr)); 260555ed8ca1SJohan Hedberg goto not_found; 260655ed8ca1SJohan Hedberg } 260755ed8ca1SJohan Hedberg 260855ed8ca1SJohan Hedberg BT_DBG("%s found key type %u for %s", hdev->name, key->type, 260955ed8ca1SJohan Hedberg batostr(&ev->bdaddr)); 261055ed8ca1SJohan Hedberg 2611a8b2d5c2SJohan Hedberg if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) && 2612b6020ba0SWaldemar Rymarkiewicz key->type == HCI_LK_DEBUG_COMBINATION) { 261355ed8ca1SJohan Hedberg BT_DBG("%s ignoring debug key", hdev->name); 261455ed8ca1SJohan Hedberg goto not_found; 261555ed8ca1SJohan Hedberg } 261655ed8ca1SJohan Hedberg 261755ed8ca1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 261860b83f57SWaldemar Rymarkiewicz if (conn) { 261960b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_UNAUTH_COMBINATION && 262060b83f57SWaldemar Rymarkiewicz conn->auth_type != 0xff && 262160b83f57SWaldemar Rymarkiewicz (conn->auth_type & 0x01)) { 262255ed8ca1SJohan Hedberg BT_DBG("%s ignoring unauthenticated key", hdev->name); 262355ed8ca1SJohan Hedberg goto not_found; 262455ed8ca1SJohan Hedberg } 262555ed8ca1SJohan Hedberg 262660b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && 262760b83f57SWaldemar Rymarkiewicz conn->pending_sec_level == BT_SECURITY_HIGH) { 262860b83f57SWaldemar Rymarkiewicz BT_DBG("%s ignoring key unauthenticated for high \ 262960b83f57SWaldemar Rymarkiewicz security", hdev->name); 263060b83f57SWaldemar Rymarkiewicz goto not_found; 263160b83f57SWaldemar Rymarkiewicz } 263260b83f57SWaldemar Rymarkiewicz 263360b83f57SWaldemar Rymarkiewicz conn->key_type = key->type; 263460b83f57SWaldemar Rymarkiewicz conn->pin_length = key->pin_len; 263560b83f57SWaldemar Rymarkiewicz } 263660b83f57SWaldemar Rymarkiewicz 263755ed8ca1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 263855ed8ca1SJohan Hedberg memcpy(cp.link_key, key->val, 16); 263955ed8ca1SJohan Hedberg 264055ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); 264155ed8ca1SJohan Hedberg 264255ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 264355ed8ca1SJohan Hedberg 264455ed8ca1SJohan Hedberg return; 264555ed8ca1SJohan Hedberg 264655ed8ca1SJohan Hedberg not_found: 264755ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); 264855ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 26491da177e4SLinus Torvalds } 26501da177e4SLinus Torvalds 26511da177e4SLinus Torvalds static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 26521da177e4SLinus Torvalds { 2653052b30b0SMarcel Holtmann struct hci_ev_link_key_notify *ev = (void *) skb->data; 2654052b30b0SMarcel Holtmann struct hci_conn *conn; 265555ed8ca1SJohan Hedberg u8 pin_len = 0; 2656052b30b0SMarcel Holtmann 2657a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2658052b30b0SMarcel Holtmann 2659052b30b0SMarcel Holtmann hci_dev_lock(hdev); 2660052b30b0SMarcel Holtmann 2661052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2662052b30b0SMarcel Holtmann if (conn) { 2663052b30b0SMarcel Holtmann hci_conn_hold(conn); 2664052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 2665980e1a53SJohan Hedberg pin_len = conn->pin_length; 266613d39315SWaldemar Rymarkiewicz 266713d39315SWaldemar Rymarkiewicz if (ev->key_type != HCI_LK_CHANGED_COMBINATION) 266813d39315SWaldemar Rymarkiewicz conn->key_type = ev->key_type; 266913d39315SWaldemar Rymarkiewicz 2670052b30b0SMarcel Holtmann hci_conn_put(conn); 2671052b30b0SMarcel Holtmann } 2672052b30b0SMarcel Holtmann 2673a8b2d5c2SJohan Hedberg if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) 2674d25e28abSJohan Hedberg hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, 267555ed8ca1SJohan Hedberg ev->key_type, pin_len); 267655ed8ca1SJohan Hedberg 2677052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 26781da177e4SLinus Torvalds } 26791da177e4SLinus Torvalds 268004837f64SMarcel Holtmann static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) 268104837f64SMarcel Holtmann { 2682a9de9248SMarcel Holtmann struct hci_ev_clock_offset *ev = (void *) skb->data; 268304837f64SMarcel Holtmann struct hci_conn *conn; 268404837f64SMarcel Holtmann 268504837f64SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 268604837f64SMarcel Holtmann 268704837f64SMarcel Holtmann hci_dev_lock(hdev); 268804837f64SMarcel Holtmann 268904837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 26901da177e4SLinus Torvalds if (conn && !ev->status) { 26911da177e4SLinus Torvalds struct inquiry_entry *ie; 26921da177e4SLinus Torvalds 2693cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 2694cc11b9c1SAndrei Emeltchenko if (ie) { 26951da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset; 26961da177e4SLinus Torvalds ie->timestamp = jiffies; 26971da177e4SLinus Torvalds } 26981da177e4SLinus Torvalds } 26991da177e4SLinus Torvalds 27001da177e4SLinus Torvalds hci_dev_unlock(hdev); 27011da177e4SLinus Torvalds } 27021da177e4SLinus Torvalds 2703a8746417SMarcel Holtmann static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2704a8746417SMarcel Holtmann { 2705a8746417SMarcel Holtmann struct hci_ev_pkt_type_change *ev = (void *) skb->data; 2706a8746417SMarcel Holtmann struct hci_conn *conn; 2707a8746417SMarcel Holtmann 2708a8746417SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 2709a8746417SMarcel Holtmann 2710a8746417SMarcel Holtmann hci_dev_lock(hdev); 2711a8746417SMarcel Holtmann 2712a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2713a8746417SMarcel Holtmann if (conn && !ev->status) 2714a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type); 2715a8746417SMarcel Holtmann 2716a8746417SMarcel Holtmann hci_dev_unlock(hdev); 2717a8746417SMarcel Holtmann } 2718a8746417SMarcel Holtmann 271985a1e930SMarcel Holtmann static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) 272085a1e930SMarcel Holtmann { 2721a9de9248SMarcel Holtmann struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; 272285a1e930SMarcel Holtmann struct inquiry_entry *ie; 272385a1e930SMarcel Holtmann 272485a1e930SMarcel Holtmann BT_DBG("%s", hdev->name); 272585a1e930SMarcel Holtmann 272685a1e930SMarcel Holtmann hci_dev_lock(hdev); 272785a1e930SMarcel Holtmann 2728cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 2729cc11b9c1SAndrei Emeltchenko if (ie) { 273085a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode; 273185a1e930SMarcel Holtmann ie->timestamp = jiffies; 273285a1e930SMarcel Holtmann } 273385a1e930SMarcel Holtmann 273485a1e930SMarcel Holtmann hci_dev_unlock(hdev); 273585a1e930SMarcel Holtmann } 273685a1e930SMarcel Holtmann 2737a9de9248SMarcel Holtmann static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb) 2738a9de9248SMarcel Holtmann { 2739a9de9248SMarcel Holtmann struct inquiry_data data; 2740a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 27413175405bSJohan Hedberg bool name_known; 2742a9de9248SMarcel Holtmann 2743a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 2744a9de9248SMarcel Holtmann 2745a9de9248SMarcel Holtmann if (!num_rsp) 2746a9de9248SMarcel Holtmann return; 2747a9de9248SMarcel Holtmann 2748a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2749a9de9248SMarcel Holtmann 2750a9de9248SMarcel Holtmann if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { 2751138d22efSSzymon Janc struct inquiry_info_with_rssi_and_pscan_mode *info; 2752138d22efSSzymon Janc info = (void *) (skb->data + 1); 2753a9de9248SMarcel Holtmann 2754e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 2755a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 2756a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 2757a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 2758a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode; 2759a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 2760a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 2761a9de9248SMarcel Holtmann data.rssi = info->rssi; 276241a96212SMarcel Holtmann data.ssp_mode = 0x00; 27633175405bSJohan Hedberg 27643175405bSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, 27653175405bSJohan Hedberg false); 276648264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 2767e17acd40SJohan Hedberg info->dev_class, info->rssi, 27687d262f86SAndre Guedes !name_known, NULL, 0); 2769a9de9248SMarcel Holtmann } 2770a9de9248SMarcel Holtmann } else { 2771a9de9248SMarcel Holtmann struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); 2772a9de9248SMarcel Holtmann 2773e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 2774a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 2775a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 2776a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 2777a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 2778a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 2779a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 2780a9de9248SMarcel Holtmann data.rssi = info->rssi; 278141a96212SMarcel Holtmann data.ssp_mode = 0x00; 27823175405bSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, 27833175405bSJohan Hedberg false); 278448264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 2785e17acd40SJohan Hedberg info->dev_class, info->rssi, 27867d262f86SAndre Guedes !name_known, NULL, 0); 2787a9de9248SMarcel Holtmann } 2788a9de9248SMarcel Holtmann } 2789a9de9248SMarcel Holtmann 2790a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2791a9de9248SMarcel Holtmann } 2792a9de9248SMarcel Holtmann 2793a9de9248SMarcel Holtmann static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb) 2794a9de9248SMarcel Holtmann { 279541a96212SMarcel Holtmann struct hci_ev_remote_ext_features *ev = (void *) skb->data; 279641a96212SMarcel Holtmann struct hci_conn *conn; 279741a96212SMarcel Holtmann 2798a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 279941a96212SMarcel Holtmann 280041a96212SMarcel Holtmann hci_dev_lock(hdev); 280141a96212SMarcel Holtmann 280241a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2803ccd556feSJohan Hedberg if (!conn) 2804ccd556feSJohan Hedberg goto unlock; 2805ccd556feSJohan Hedberg 2806769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) { 280741a96212SMarcel Holtmann struct inquiry_entry *ie; 280841a96212SMarcel Holtmann 2809cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 2810cc11b9c1SAndrei Emeltchenko if (ie) 281141a96212SMarcel Holtmann ie->data.ssp_mode = (ev->features[0] & 0x01); 281241a96212SMarcel Holtmann 281358a681efSJohan Hedberg if (ev->features[0] & 0x01) 281458a681efSJohan Hedberg set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 281541a96212SMarcel Holtmann } 281641a96212SMarcel Holtmann 2817ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 2818ccd556feSJohan Hedberg goto unlock; 2819ccd556feSJohan Hedberg 2820127178d2SJohan Hedberg if (!ev->status) { 2821127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 2822127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 2823127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 2824127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 2825127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 2826b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 2827b644ba33SJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 2828b644ba33SJohan Hedberg conn->dst_type, NULL, 0, 2829b644ba33SJohan Hedberg conn->dev_class); 2830392599b9SJohan Hedberg 2831127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 2832769be974SMarcel Holtmann conn->state = BT_CONNECTED; 2833769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 2834769be974SMarcel Holtmann hci_conn_put(conn); 2835769be974SMarcel Holtmann } 2836769be974SMarcel Holtmann 2837ccd556feSJohan Hedberg unlock: 283841a96212SMarcel Holtmann hci_dev_unlock(hdev); 2839a9de9248SMarcel Holtmann } 2840a9de9248SMarcel Holtmann 2841a9de9248SMarcel Holtmann static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2842a9de9248SMarcel Holtmann { 2843b6a0dc82SMarcel Holtmann struct hci_ev_sync_conn_complete *ev = (void *) skb->data; 2844b6a0dc82SMarcel Holtmann struct hci_conn *conn; 2845b6a0dc82SMarcel Holtmann 2846b6a0dc82SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 2847b6a0dc82SMarcel Holtmann 2848b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 2849b6a0dc82SMarcel Holtmann 2850b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 28519dc0a3afSMarcel Holtmann if (!conn) { 28529dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK) 28539dc0a3afSMarcel Holtmann goto unlock; 28549dc0a3afSMarcel Holtmann 28559dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 2856b6a0dc82SMarcel Holtmann if (!conn) 2857b6a0dc82SMarcel Holtmann goto unlock; 2858b6a0dc82SMarcel Holtmann 28599dc0a3afSMarcel Holtmann conn->type = SCO_LINK; 28609dc0a3afSMarcel Holtmann } 28619dc0a3afSMarcel Holtmann 2862732547f9SMarcel Holtmann switch (ev->status) { 2863732547f9SMarcel Holtmann case 0x00: 2864732547f9SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 2865732547f9SMarcel Holtmann conn->state = BT_CONNECTED; 2866732547f9SMarcel Holtmann 28679eba32b8SMarcel Holtmann hci_conn_hold_device(conn); 2868732547f9SMarcel Holtmann hci_conn_add_sysfs(conn); 2869732547f9SMarcel Holtmann break; 2870732547f9SMarcel Holtmann 2871705e5711SStephen Coe case 0x11: /* Unsupported Feature or Parameter Value */ 2872732547f9SMarcel Holtmann case 0x1c: /* SCO interval rejected */ 28731038a00bSNick Pelly case 0x1a: /* Unsupported Remote Feature */ 2874732547f9SMarcel Holtmann case 0x1f: /* Unspecified error */ 2875732547f9SMarcel Holtmann if (conn->out && conn->attempt < 2) { 2876efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 2877efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK); 2878efc7688bSMarcel Holtmann hci_setup_sync(conn, conn->link->handle); 2879efc7688bSMarcel Holtmann goto unlock; 2880efc7688bSMarcel Holtmann } 2881732547f9SMarcel Holtmann /* fall through */ 2882efc7688bSMarcel Holtmann 2883732547f9SMarcel Holtmann default: 2884b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED; 2885732547f9SMarcel Holtmann break; 2886732547f9SMarcel Holtmann } 2887b6a0dc82SMarcel Holtmann 2888b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 2889b6a0dc82SMarcel Holtmann if (ev->status) 2890b6a0dc82SMarcel Holtmann hci_conn_del(conn); 2891b6a0dc82SMarcel Holtmann 2892b6a0dc82SMarcel Holtmann unlock: 2893b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 2894a9de9248SMarcel Holtmann } 2895a9de9248SMarcel Holtmann 2896a9de9248SMarcel Holtmann static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb) 2897a9de9248SMarcel Holtmann { 2898a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2899a9de9248SMarcel Holtmann } 2900a9de9248SMarcel Holtmann 290104837f64SMarcel Holtmann static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) 290204837f64SMarcel Holtmann { 2903a9de9248SMarcel Holtmann struct hci_ev_sniff_subrate *ev = (void *) skb->data; 290404837f64SMarcel Holtmann 290504837f64SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 290604837f64SMarcel Holtmann } 290704837f64SMarcel Holtmann 2908a9de9248SMarcel Holtmann static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 2909a9de9248SMarcel Holtmann { 2910a9de9248SMarcel Holtmann struct inquiry_data data; 2911a9de9248SMarcel Holtmann struct extended_inquiry_info *info = (void *) (skb->data + 1); 2912a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 2913a9de9248SMarcel Holtmann 2914a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 2915a9de9248SMarcel Holtmann 2916a9de9248SMarcel Holtmann if (!num_rsp) 2917a9de9248SMarcel Holtmann return; 2918a9de9248SMarcel Holtmann 2919a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2920a9de9248SMarcel Holtmann 2921e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 2922561aafbcSJohan Hedberg bool name_known; 2923561aafbcSJohan Hedberg 2924a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 2925a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 2926a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 2927a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 2928a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 2929a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 2930a9de9248SMarcel Holtmann data.rssi = info->rssi; 293141a96212SMarcel Holtmann data.ssp_mode = 0x01; 2932561aafbcSJohan Hedberg 2933a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 29344ddb1930SJohan Hedberg name_known = eir_has_data_type(info->data, 29354ddb1930SJohan Hedberg sizeof(info->data), 29364ddb1930SJohan Hedberg EIR_NAME_COMPLETE); 2937561aafbcSJohan Hedberg else 2938561aafbcSJohan Hedberg name_known = true; 2939561aafbcSJohan Hedberg 29403175405bSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, name_known); 294148264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 2942561aafbcSJohan Hedberg info->dev_class, info->rssi, 29437d262f86SAndre Guedes !name_known, info->data, 29447d262f86SAndre Guedes sizeof(info->data)); 2945a9de9248SMarcel Holtmann } 2946a9de9248SMarcel Holtmann 2947a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2948a9de9248SMarcel Holtmann } 2949a9de9248SMarcel Holtmann 295017fa4b9dSJohan Hedberg static inline u8 hci_get_auth_req(struct hci_conn *conn) 295117fa4b9dSJohan Hedberg { 295217fa4b9dSJohan Hedberg /* If remote requests dedicated bonding follow that lead */ 295317fa4b9dSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) { 295417fa4b9dSJohan Hedberg /* If both remote and local IO capabilities allow MITM 295517fa4b9dSJohan Hedberg * protection then require it, otherwise don't */ 295617fa4b9dSJohan Hedberg if (conn->remote_cap == 0x03 || conn->io_capability == 0x03) 295717fa4b9dSJohan Hedberg return 0x02; 295817fa4b9dSJohan Hedberg else 295917fa4b9dSJohan Hedberg return 0x03; 296017fa4b9dSJohan Hedberg } 296117fa4b9dSJohan Hedberg 296217fa4b9dSJohan Hedberg /* If remote requests no-bonding follow that lead */ 296317fa4b9dSJohan Hedberg if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01) 296458797bf7SWaldemar Rymarkiewicz return conn->remote_auth | (conn->auth_type & 0x01); 296517fa4b9dSJohan Hedberg 296617fa4b9dSJohan Hedberg return conn->auth_type; 296717fa4b9dSJohan Hedberg } 296817fa4b9dSJohan Hedberg 29690493684eSMarcel Holtmann static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 29700493684eSMarcel Holtmann { 29710493684eSMarcel Holtmann struct hci_ev_io_capa_request *ev = (void *) skb->data; 29720493684eSMarcel Holtmann struct hci_conn *conn; 29730493684eSMarcel Holtmann 29740493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 29750493684eSMarcel Holtmann 29760493684eSMarcel Holtmann hci_dev_lock(hdev); 29770493684eSMarcel Holtmann 29780493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 297903b555e1SJohan Hedberg if (!conn) 298003b555e1SJohan Hedberg goto unlock; 298103b555e1SJohan Hedberg 29820493684eSMarcel Holtmann hci_conn_hold(conn); 29830493684eSMarcel Holtmann 2984a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 298503b555e1SJohan Hedberg goto unlock; 298603b555e1SJohan Hedberg 2987a8b2d5c2SJohan Hedberg if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) || 298803b555e1SJohan Hedberg (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { 298917fa4b9dSJohan Hedberg struct hci_cp_io_capability_reply cp; 299017fa4b9dSJohan Hedberg 299117fa4b9dSJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 29927a7f1e7cSHemant Gupta /* Change the IO capability from KeyboardDisplay 29937a7f1e7cSHemant Gupta * to DisplayYesNo as it is not supported by BT spec. */ 29947a7f1e7cSHemant Gupta cp.capability = (conn->io_capability == 0x04) ? 29957a7f1e7cSHemant Gupta 0x01 : conn->io_capability; 29967cbc9bd9SJohan Hedberg conn->auth_type = hci_get_auth_req(conn); 29977cbc9bd9SJohan Hedberg cp.authentication = conn->auth_type; 299817fa4b9dSJohan Hedberg 299958a681efSJohan Hedberg if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) && 3000ce85ee13SSzymon Janc hci_find_remote_oob_data(hdev, &conn->dst)) 3001ce85ee13SSzymon Janc cp.oob_data = 0x01; 3002ce85ee13SSzymon Janc else 3003ce85ee13SSzymon Janc cp.oob_data = 0x00; 3004ce85ee13SSzymon Janc 300517fa4b9dSJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, 300617fa4b9dSJohan Hedberg sizeof(cp), &cp); 300703b555e1SJohan Hedberg } else { 300803b555e1SJohan Hedberg struct hci_cp_io_capability_neg_reply cp; 300903b555e1SJohan Hedberg 301003b555e1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 30119f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; 301203b555e1SJohan Hedberg 301303b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, 301403b555e1SJohan Hedberg sizeof(cp), &cp); 301503b555e1SJohan Hedberg } 301603b555e1SJohan Hedberg 301703b555e1SJohan Hedberg unlock: 301803b555e1SJohan Hedberg hci_dev_unlock(hdev); 301903b555e1SJohan Hedberg } 302003b555e1SJohan Hedberg 302103b555e1SJohan Hedberg static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) 302203b555e1SJohan Hedberg { 302303b555e1SJohan Hedberg struct hci_ev_io_capa_reply *ev = (void *) skb->data; 302403b555e1SJohan Hedberg struct hci_conn *conn; 302503b555e1SJohan Hedberg 302603b555e1SJohan Hedberg BT_DBG("%s", hdev->name); 302703b555e1SJohan Hedberg 302803b555e1SJohan Hedberg hci_dev_lock(hdev); 302903b555e1SJohan Hedberg 303003b555e1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 303103b555e1SJohan Hedberg if (!conn) 303203b555e1SJohan Hedberg goto unlock; 303303b555e1SJohan Hedberg 303403b555e1SJohan Hedberg conn->remote_cap = ev->capability; 303503b555e1SJohan Hedberg conn->remote_auth = ev->authentication; 303658a681efSJohan Hedberg if (ev->oob_data) 303758a681efSJohan Hedberg set_bit(HCI_CONN_REMOTE_OOB, &conn->flags); 303803b555e1SJohan Hedberg 303903b555e1SJohan Hedberg unlock: 30400493684eSMarcel Holtmann hci_dev_unlock(hdev); 30410493684eSMarcel Holtmann } 30420493684eSMarcel Holtmann 3043a5c29683SJohan Hedberg static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, 3044a5c29683SJohan Hedberg struct sk_buff *skb) 3045a5c29683SJohan Hedberg { 3046a5c29683SJohan Hedberg struct hci_ev_user_confirm_req *ev = (void *) skb->data; 304755bc1a37SJohan Hedberg int loc_mitm, rem_mitm, confirm_hint = 0; 30487a828908SJohan Hedberg struct hci_conn *conn; 3049a5c29683SJohan Hedberg 3050a5c29683SJohan Hedberg BT_DBG("%s", hdev->name); 3051a5c29683SJohan Hedberg 3052a5c29683SJohan Hedberg hci_dev_lock(hdev); 3053a5c29683SJohan Hedberg 3054a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 30557a828908SJohan Hedberg goto unlock; 30567a828908SJohan Hedberg 30577a828908SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 30587a828908SJohan Hedberg if (!conn) 30597a828908SJohan Hedberg goto unlock; 30607a828908SJohan Hedberg 30617a828908SJohan Hedberg loc_mitm = (conn->auth_type & 0x01); 30627a828908SJohan Hedberg rem_mitm = (conn->remote_auth & 0x01); 30637a828908SJohan Hedberg 30647a828908SJohan Hedberg /* If we require MITM but the remote device can't provide that 30657a828908SJohan Hedberg * (it has NoInputNoOutput) then reject the confirmation 30667a828908SJohan Hedberg * request. The only exception is when we're dedicated bonding 30677a828908SJohan Hedberg * initiators (connect_cfm_cb set) since then we always have the MITM 30687a828908SJohan Hedberg * bit set. */ 30697a828908SJohan Hedberg if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) { 30707a828908SJohan Hedberg BT_DBG("Rejecting request: remote device can't provide MITM"); 30717a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, 30727a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 30737a828908SJohan Hedberg goto unlock; 30747a828908SJohan Hedberg } 30757a828908SJohan Hedberg 30767a828908SJohan Hedberg /* If no side requires MITM protection; auto-accept */ 30777a828908SJohan Hedberg if ((!loc_mitm || conn->remote_cap == 0x03) && 30787a828908SJohan Hedberg (!rem_mitm || conn->io_capability == 0x03)) { 307955bc1a37SJohan Hedberg 308055bc1a37SJohan Hedberg /* If we're not the initiators request authorization to 308155bc1a37SJohan Hedberg * proceed from user space (mgmt_user_confirm with 308255bc1a37SJohan Hedberg * confirm_hint set to 1). */ 308351a8efd7SJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 308455bc1a37SJohan Hedberg BT_DBG("Confirming auto-accept as acceptor"); 308555bc1a37SJohan Hedberg confirm_hint = 1; 308655bc1a37SJohan Hedberg goto confirm; 308755bc1a37SJohan Hedberg } 308855bc1a37SJohan Hedberg 30899f61656aSJohan Hedberg BT_DBG("Auto-accept of user confirmation with %ums delay", 30909f61656aSJohan Hedberg hdev->auto_accept_delay); 30919f61656aSJohan Hedberg 30929f61656aSJohan Hedberg if (hdev->auto_accept_delay > 0) { 30939f61656aSJohan Hedberg int delay = msecs_to_jiffies(hdev->auto_accept_delay); 30949f61656aSJohan Hedberg mod_timer(&conn->auto_accept_timer, jiffies + delay); 30959f61656aSJohan Hedberg goto unlock; 30969f61656aSJohan Hedberg } 30979f61656aSJohan Hedberg 30987a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, 30997a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 31007a828908SJohan Hedberg goto unlock; 31017a828908SJohan Hedberg } 31027a828908SJohan Hedberg 310355bc1a37SJohan Hedberg confirm: 3104744cf19eSJohan Hedberg mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey, 310555bc1a37SJohan Hedberg confirm_hint); 3106a5c29683SJohan Hedberg 31077a828908SJohan Hedberg unlock: 3108a5c29683SJohan Hedberg hci_dev_unlock(hdev); 3109a5c29683SJohan Hedberg } 3110a5c29683SJohan Hedberg 31111143d458SBrian Gix static inline void hci_user_passkey_request_evt(struct hci_dev *hdev, 31121143d458SBrian Gix struct sk_buff *skb) 31131143d458SBrian Gix { 31141143d458SBrian Gix struct hci_ev_user_passkey_req *ev = (void *) skb->data; 31151143d458SBrian Gix 31161143d458SBrian Gix BT_DBG("%s", hdev->name); 31171143d458SBrian Gix 31181143d458SBrian Gix hci_dev_lock(hdev); 31191143d458SBrian Gix 3120a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 31211143d458SBrian Gix mgmt_user_passkey_request(hdev, &ev->bdaddr); 31221143d458SBrian Gix 31231143d458SBrian Gix hci_dev_unlock(hdev); 31241143d458SBrian Gix } 31251143d458SBrian Gix 31260493684eSMarcel Holtmann static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 31270493684eSMarcel Holtmann { 31280493684eSMarcel Holtmann struct hci_ev_simple_pair_complete *ev = (void *) skb->data; 31290493684eSMarcel Holtmann struct hci_conn *conn; 31300493684eSMarcel Holtmann 31310493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 31320493684eSMarcel Holtmann 31330493684eSMarcel Holtmann hci_dev_lock(hdev); 31340493684eSMarcel Holtmann 31350493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 31362a611692SJohan Hedberg if (!conn) 31372a611692SJohan Hedberg goto unlock; 31382a611692SJohan Hedberg 31392a611692SJohan Hedberg /* To avoid duplicate auth_failed events to user space we check 31402a611692SJohan Hedberg * the HCI_CONN_AUTH_PEND flag which will be set if we 31412a611692SJohan Hedberg * initiated the authentication. A traditional auth_complete 31422a611692SJohan Hedberg * event gets always produced as initiator and is also mapped to 31432a611692SJohan Hedberg * the mgmt_auth_failed event */ 314451a8efd7SJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0) 3145744cf19eSJohan Hedberg mgmt_auth_failed(hdev, &conn->dst, ev->status); 31462a611692SJohan Hedberg 31470493684eSMarcel Holtmann hci_conn_put(conn); 31480493684eSMarcel Holtmann 31492a611692SJohan Hedberg unlock: 31500493684eSMarcel Holtmann hci_dev_unlock(hdev); 31510493684eSMarcel Holtmann } 31520493684eSMarcel Holtmann 315341a96212SMarcel Holtmann static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb) 315441a96212SMarcel Holtmann { 315541a96212SMarcel Holtmann struct hci_ev_remote_host_features *ev = (void *) skb->data; 315641a96212SMarcel Holtmann struct inquiry_entry *ie; 315741a96212SMarcel Holtmann 315841a96212SMarcel Holtmann BT_DBG("%s", hdev->name); 315941a96212SMarcel Holtmann 316041a96212SMarcel Holtmann hci_dev_lock(hdev); 316141a96212SMarcel Holtmann 3162cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3163cc11b9c1SAndrei Emeltchenko if (ie) 316441a96212SMarcel Holtmann ie->data.ssp_mode = (ev->features[0] & 0x01); 316541a96212SMarcel Holtmann 316641a96212SMarcel Holtmann hci_dev_unlock(hdev); 316741a96212SMarcel Holtmann } 316841a96212SMarcel Holtmann 31692763eda6SSzymon Janc static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, 31702763eda6SSzymon Janc struct sk_buff *skb) 31712763eda6SSzymon Janc { 31722763eda6SSzymon Janc struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; 31732763eda6SSzymon Janc struct oob_data *data; 31742763eda6SSzymon Janc 31752763eda6SSzymon Janc BT_DBG("%s", hdev->name); 31762763eda6SSzymon Janc 31772763eda6SSzymon Janc hci_dev_lock(hdev); 31782763eda6SSzymon Janc 3179a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 3180e1ba1f15SSzymon Janc goto unlock; 3181e1ba1f15SSzymon Janc 31822763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, &ev->bdaddr); 31832763eda6SSzymon Janc if (data) { 31842763eda6SSzymon Janc struct hci_cp_remote_oob_data_reply cp; 31852763eda6SSzymon Janc 31862763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 31872763eda6SSzymon Janc memcpy(cp.hash, data->hash, sizeof(cp.hash)); 31882763eda6SSzymon Janc memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer)); 31892763eda6SSzymon Janc 31902763eda6SSzymon Janc hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp), 31912763eda6SSzymon Janc &cp); 31922763eda6SSzymon Janc } else { 31932763eda6SSzymon Janc struct hci_cp_remote_oob_data_neg_reply cp; 31942763eda6SSzymon Janc 31952763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 31962763eda6SSzymon Janc hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp), 31972763eda6SSzymon Janc &cp); 31982763eda6SSzymon Janc } 31992763eda6SSzymon Janc 3200e1ba1f15SSzymon Janc unlock: 32012763eda6SSzymon Janc hci_dev_unlock(hdev); 32022763eda6SSzymon Janc } 32032763eda6SSzymon Janc 3204fcd89c09SVille Tervo static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 3205fcd89c09SVille Tervo { 3206fcd89c09SVille Tervo struct hci_ev_le_conn_complete *ev = (void *) skb->data; 3207fcd89c09SVille Tervo struct hci_conn *conn; 3208fcd89c09SVille Tervo 3209fcd89c09SVille Tervo BT_DBG("%s status %d", hdev->name, ev->status); 3210fcd89c09SVille Tervo 3211fcd89c09SVille Tervo hci_dev_lock(hdev); 3212fcd89c09SVille Tervo 3213fcd89c09SVille Tervo conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr); 3214b62f328bSVille Tervo if (!conn) { 3215b62f328bSVille Tervo conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr); 3216b62f328bSVille Tervo if (!conn) { 3217b62f328bSVille Tervo BT_ERR("No memory for new connection"); 3218b62f328bSVille Tervo hci_dev_unlock(hdev); 3219b62f328bSVille Tervo return; 3220b62f328bSVille Tervo } 322129b7988aSAndre Guedes 322229b7988aSAndre Guedes conn->dst_type = ev->bdaddr_type; 3223b62f328bSVille Tervo } 3224fcd89c09SVille Tervo 3225fcd89c09SVille Tervo if (ev->status) { 322648264f06SJohan Hedberg mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, 322748264f06SJohan Hedberg conn->dst_type, ev->status); 3228fcd89c09SVille Tervo hci_proto_connect_cfm(conn, ev->status); 3229fcd89c09SVille Tervo conn->state = BT_CLOSED; 3230fcd89c09SVille Tervo hci_conn_del(conn); 3231fcd89c09SVille Tervo goto unlock; 3232fcd89c09SVille Tervo } 3233fcd89c09SVille Tervo 3234b644ba33SJohan Hedberg if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 3235b644ba33SJohan Hedberg mgmt_device_connected(hdev, &ev->bdaddr, conn->type, 3236b644ba33SJohan Hedberg conn->dst_type, NULL, 0, 0); 323783bc71b4SVinicius Costa Gomes 32387b5c0d52SVinicius Costa Gomes conn->sec_level = BT_SECURITY_LOW; 3239fcd89c09SVille Tervo conn->handle = __le16_to_cpu(ev->handle); 3240fcd89c09SVille Tervo conn->state = BT_CONNECTED; 3241fcd89c09SVille Tervo 3242fcd89c09SVille Tervo hci_conn_hold_device(conn); 3243fcd89c09SVille Tervo hci_conn_add_sysfs(conn); 3244fcd89c09SVille Tervo 3245fcd89c09SVille Tervo hci_proto_connect_cfm(conn, ev->status); 3246fcd89c09SVille Tervo 3247fcd89c09SVille Tervo unlock: 3248fcd89c09SVille Tervo hci_dev_unlock(hdev); 3249fcd89c09SVille Tervo } 3250fcd89c09SVille Tervo 32519aa04c91SAndre Guedes static inline void hci_le_adv_report_evt(struct hci_dev *hdev, 32529aa04c91SAndre Guedes struct sk_buff *skb) 32539aa04c91SAndre Guedes { 3254e95beb41SAndre Guedes u8 num_reports = skb->data[0]; 3255e95beb41SAndre Guedes void *ptr = &skb->data[1]; 32563c9e9195SAndre Guedes s8 rssi; 32579aa04c91SAndre Guedes 32589aa04c91SAndre Guedes hci_dev_lock(hdev); 32599aa04c91SAndre Guedes 3260e95beb41SAndre Guedes while (num_reports--) { 3261e95beb41SAndre Guedes struct hci_ev_le_advertising_info *ev = ptr; 3262e95beb41SAndre Guedes 32639aa04c91SAndre Guedes hci_add_adv_entry(hdev, ev); 32649aa04c91SAndre Guedes 32653c9e9195SAndre Guedes rssi = ev->data[ev->length]; 32663c9e9195SAndre Guedes mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type, 32673c9e9195SAndre Guedes NULL, rssi, 0, ev->data, ev->length); 32683c9e9195SAndre Guedes 3269e95beb41SAndre Guedes ptr += sizeof(*ev) + ev->length + 1; 32709aa04c91SAndre Guedes } 32719aa04c91SAndre Guedes 32729aa04c91SAndre Guedes hci_dev_unlock(hdev); 32739aa04c91SAndre Guedes } 32749aa04c91SAndre Guedes 3275a7a595f6SVinicius Costa Gomes static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, 3276a7a595f6SVinicius Costa Gomes struct sk_buff *skb) 3277a7a595f6SVinicius Costa Gomes { 3278a7a595f6SVinicius Costa Gomes struct hci_ev_le_ltk_req *ev = (void *) skb->data; 3279a7a595f6SVinicius Costa Gomes struct hci_cp_le_ltk_reply cp; 3280bea710feSVinicius Costa Gomes struct hci_cp_le_ltk_neg_reply neg; 3281a7a595f6SVinicius Costa Gomes struct hci_conn *conn; 3282c9839a11SVinicius Costa Gomes struct smp_ltk *ltk; 3283a7a595f6SVinicius Costa Gomes 3284a7a595f6SVinicius Costa Gomes BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle)); 3285a7a595f6SVinicius Costa Gomes 3286a7a595f6SVinicius Costa Gomes hci_dev_lock(hdev); 3287a7a595f6SVinicius Costa Gomes 3288a7a595f6SVinicius Costa Gomes conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3289bea710feSVinicius Costa Gomes if (conn == NULL) 3290bea710feSVinicius Costa Gomes goto not_found; 3291a7a595f6SVinicius Costa Gomes 3292bea710feSVinicius Costa Gomes ltk = hci_find_ltk(hdev, ev->ediv, ev->random); 3293bea710feSVinicius Costa Gomes if (ltk == NULL) 3294bea710feSVinicius Costa Gomes goto not_found; 3295bea710feSVinicius Costa Gomes 3296bea710feSVinicius Costa Gomes memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); 3297a7a595f6SVinicius Costa Gomes cp.handle = cpu_to_le16(conn->handle); 3298c9839a11SVinicius Costa Gomes 3299c9839a11SVinicius Costa Gomes if (ltk->authenticated) 3300c9839a11SVinicius Costa Gomes conn->sec_level = BT_SECURITY_HIGH; 3301a7a595f6SVinicius Costa Gomes 3302a7a595f6SVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); 3303a7a595f6SVinicius Costa Gomes 3304c9839a11SVinicius Costa Gomes if (ltk->type & HCI_SMP_STK) { 3305c9839a11SVinicius Costa Gomes list_del(<k->list); 3306c9839a11SVinicius Costa Gomes kfree(ltk); 3307c9839a11SVinicius Costa Gomes } 3308c9839a11SVinicius Costa Gomes 3309a7a595f6SVinicius Costa Gomes hci_dev_unlock(hdev); 3310bea710feSVinicius Costa Gomes 3311bea710feSVinicius Costa Gomes return; 3312bea710feSVinicius Costa Gomes 3313bea710feSVinicius Costa Gomes not_found: 3314bea710feSVinicius Costa Gomes neg.handle = ev->handle; 3315bea710feSVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); 3316bea710feSVinicius Costa Gomes hci_dev_unlock(hdev); 3317a7a595f6SVinicius Costa Gomes } 3318a7a595f6SVinicius Costa Gomes 3319fcd89c09SVille Tervo static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) 3320fcd89c09SVille Tervo { 3321fcd89c09SVille Tervo struct hci_ev_le_meta *le_ev = (void *) skb->data; 3322fcd89c09SVille Tervo 3323fcd89c09SVille Tervo skb_pull(skb, sizeof(*le_ev)); 3324fcd89c09SVille Tervo 3325fcd89c09SVille Tervo switch (le_ev->subevent) { 3326fcd89c09SVille Tervo case HCI_EV_LE_CONN_COMPLETE: 3327fcd89c09SVille Tervo hci_le_conn_complete_evt(hdev, skb); 3328fcd89c09SVille Tervo break; 3329fcd89c09SVille Tervo 33309aa04c91SAndre Guedes case HCI_EV_LE_ADVERTISING_REPORT: 33319aa04c91SAndre Guedes hci_le_adv_report_evt(hdev, skb); 33329aa04c91SAndre Guedes break; 33339aa04c91SAndre Guedes 3334a7a595f6SVinicius Costa Gomes case HCI_EV_LE_LTK_REQ: 3335a7a595f6SVinicius Costa Gomes hci_le_ltk_request_evt(hdev, skb); 3336a7a595f6SVinicius Costa Gomes break; 3337a7a595f6SVinicius Costa Gomes 3338fcd89c09SVille Tervo default: 3339fcd89c09SVille Tervo break; 3340fcd89c09SVille Tervo } 3341fcd89c09SVille Tervo } 3342fcd89c09SVille Tervo 33431da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 33441da177e4SLinus Torvalds { 3345a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data; 3346a9de9248SMarcel Holtmann __u8 event = hdr->evt; 33471da177e4SLinus Torvalds 33481da177e4SLinus Torvalds skb_pull(skb, HCI_EVENT_HDR_SIZE); 33491da177e4SLinus Torvalds 3350a9de9248SMarcel Holtmann switch (event) { 33511da177e4SLinus Torvalds case HCI_EV_INQUIRY_COMPLETE: 33521da177e4SLinus Torvalds hci_inquiry_complete_evt(hdev, skb); 33531da177e4SLinus Torvalds break; 33541da177e4SLinus Torvalds 33551da177e4SLinus Torvalds case HCI_EV_INQUIRY_RESULT: 33561da177e4SLinus Torvalds hci_inquiry_result_evt(hdev, skb); 33571da177e4SLinus Torvalds break; 33581da177e4SLinus Torvalds 3359a9de9248SMarcel Holtmann case HCI_EV_CONN_COMPLETE: 3360a9de9248SMarcel Holtmann hci_conn_complete_evt(hdev, skb); 336121d9e30eSMarcel Holtmann break; 336221d9e30eSMarcel Holtmann 33631da177e4SLinus Torvalds case HCI_EV_CONN_REQUEST: 33641da177e4SLinus Torvalds hci_conn_request_evt(hdev, skb); 33651da177e4SLinus Torvalds break; 33661da177e4SLinus Torvalds 33671da177e4SLinus Torvalds case HCI_EV_DISCONN_COMPLETE: 33681da177e4SLinus Torvalds hci_disconn_complete_evt(hdev, skb); 33691da177e4SLinus Torvalds break; 33701da177e4SLinus Torvalds 33711da177e4SLinus Torvalds case HCI_EV_AUTH_COMPLETE: 33721da177e4SLinus Torvalds hci_auth_complete_evt(hdev, skb); 33731da177e4SLinus Torvalds break; 33741da177e4SLinus Torvalds 3375a9de9248SMarcel Holtmann case HCI_EV_REMOTE_NAME: 3376a9de9248SMarcel Holtmann hci_remote_name_evt(hdev, skb); 3377a9de9248SMarcel Holtmann break; 3378a9de9248SMarcel Holtmann 33791da177e4SLinus Torvalds case HCI_EV_ENCRYPT_CHANGE: 33801da177e4SLinus Torvalds hci_encrypt_change_evt(hdev, skb); 33811da177e4SLinus Torvalds break; 33821da177e4SLinus Torvalds 3383a9de9248SMarcel Holtmann case HCI_EV_CHANGE_LINK_KEY_COMPLETE: 3384a9de9248SMarcel Holtmann hci_change_link_key_complete_evt(hdev, skb); 3385a9de9248SMarcel Holtmann break; 3386a9de9248SMarcel Holtmann 3387a9de9248SMarcel Holtmann case HCI_EV_REMOTE_FEATURES: 3388a9de9248SMarcel Holtmann hci_remote_features_evt(hdev, skb); 3389a9de9248SMarcel Holtmann break; 3390a9de9248SMarcel Holtmann 3391a9de9248SMarcel Holtmann case HCI_EV_REMOTE_VERSION: 3392a9de9248SMarcel Holtmann hci_remote_version_evt(hdev, skb); 3393a9de9248SMarcel Holtmann break; 3394a9de9248SMarcel Holtmann 3395a9de9248SMarcel Holtmann case HCI_EV_QOS_SETUP_COMPLETE: 3396a9de9248SMarcel Holtmann hci_qos_setup_complete_evt(hdev, skb); 3397a9de9248SMarcel Holtmann break; 3398a9de9248SMarcel Holtmann 3399a9de9248SMarcel Holtmann case HCI_EV_CMD_COMPLETE: 3400a9de9248SMarcel Holtmann hci_cmd_complete_evt(hdev, skb); 3401a9de9248SMarcel Holtmann break; 3402a9de9248SMarcel Holtmann 3403a9de9248SMarcel Holtmann case HCI_EV_CMD_STATUS: 3404a9de9248SMarcel Holtmann hci_cmd_status_evt(hdev, skb); 3405a9de9248SMarcel Holtmann break; 3406a9de9248SMarcel Holtmann 3407a9de9248SMarcel Holtmann case HCI_EV_ROLE_CHANGE: 3408a9de9248SMarcel Holtmann hci_role_change_evt(hdev, skb); 3409a9de9248SMarcel Holtmann break; 3410a9de9248SMarcel Holtmann 3411a9de9248SMarcel Holtmann case HCI_EV_NUM_COMP_PKTS: 3412a9de9248SMarcel Holtmann hci_num_comp_pkts_evt(hdev, skb); 3413a9de9248SMarcel Holtmann break; 3414a9de9248SMarcel Holtmann 3415a9de9248SMarcel Holtmann case HCI_EV_MODE_CHANGE: 3416a9de9248SMarcel Holtmann hci_mode_change_evt(hdev, skb); 34171da177e4SLinus Torvalds break; 34181da177e4SLinus Torvalds 34191da177e4SLinus Torvalds case HCI_EV_PIN_CODE_REQ: 34201da177e4SLinus Torvalds hci_pin_code_request_evt(hdev, skb); 34211da177e4SLinus Torvalds break; 34221da177e4SLinus Torvalds 34231da177e4SLinus Torvalds case HCI_EV_LINK_KEY_REQ: 34241da177e4SLinus Torvalds hci_link_key_request_evt(hdev, skb); 34251da177e4SLinus Torvalds break; 34261da177e4SLinus Torvalds 34271da177e4SLinus Torvalds case HCI_EV_LINK_KEY_NOTIFY: 34281da177e4SLinus Torvalds hci_link_key_notify_evt(hdev, skb); 34291da177e4SLinus Torvalds break; 34301da177e4SLinus Torvalds 34311da177e4SLinus Torvalds case HCI_EV_CLOCK_OFFSET: 34321da177e4SLinus Torvalds hci_clock_offset_evt(hdev, skb); 34331da177e4SLinus Torvalds break; 34341da177e4SLinus Torvalds 3435a8746417SMarcel Holtmann case HCI_EV_PKT_TYPE_CHANGE: 3436a8746417SMarcel Holtmann hci_pkt_type_change_evt(hdev, skb); 3437a8746417SMarcel Holtmann break; 3438a8746417SMarcel Holtmann 343985a1e930SMarcel Holtmann case HCI_EV_PSCAN_REP_MODE: 344085a1e930SMarcel Holtmann hci_pscan_rep_mode_evt(hdev, skb); 344185a1e930SMarcel Holtmann break; 344285a1e930SMarcel Holtmann 3443a9de9248SMarcel Holtmann case HCI_EV_INQUIRY_RESULT_WITH_RSSI: 3444a9de9248SMarcel Holtmann hci_inquiry_result_with_rssi_evt(hdev, skb); 3445a9de9248SMarcel Holtmann break; 3446a9de9248SMarcel Holtmann 3447a9de9248SMarcel Holtmann case HCI_EV_REMOTE_EXT_FEATURES: 3448a9de9248SMarcel Holtmann hci_remote_ext_features_evt(hdev, skb); 3449a9de9248SMarcel Holtmann break; 3450a9de9248SMarcel Holtmann 3451a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_COMPLETE: 3452a9de9248SMarcel Holtmann hci_sync_conn_complete_evt(hdev, skb); 3453a9de9248SMarcel Holtmann break; 3454a9de9248SMarcel Holtmann 3455a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_CHANGED: 3456a9de9248SMarcel Holtmann hci_sync_conn_changed_evt(hdev, skb); 3457a9de9248SMarcel Holtmann break; 3458a9de9248SMarcel Holtmann 345904837f64SMarcel Holtmann case HCI_EV_SNIFF_SUBRATE: 346004837f64SMarcel Holtmann hci_sniff_subrate_evt(hdev, skb); 346104837f64SMarcel Holtmann break; 346204837f64SMarcel Holtmann 3463a9de9248SMarcel Holtmann case HCI_EV_EXTENDED_INQUIRY_RESULT: 3464a9de9248SMarcel Holtmann hci_extended_inquiry_result_evt(hdev, skb); 34651da177e4SLinus Torvalds break; 34661da177e4SLinus Torvalds 34670493684eSMarcel Holtmann case HCI_EV_IO_CAPA_REQUEST: 34680493684eSMarcel Holtmann hci_io_capa_request_evt(hdev, skb); 34690493684eSMarcel Holtmann break; 34700493684eSMarcel Holtmann 347103b555e1SJohan Hedberg case HCI_EV_IO_CAPA_REPLY: 347203b555e1SJohan Hedberg hci_io_capa_reply_evt(hdev, skb); 347303b555e1SJohan Hedberg break; 347403b555e1SJohan Hedberg 3475a5c29683SJohan Hedberg case HCI_EV_USER_CONFIRM_REQUEST: 3476a5c29683SJohan Hedberg hci_user_confirm_request_evt(hdev, skb); 3477a5c29683SJohan Hedberg break; 3478a5c29683SJohan Hedberg 34791143d458SBrian Gix case HCI_EV_USER_PASSKEY_REQUEST: 34801143d458SBrian Gix hci_user_passkey_request_evt(hdev, skb); 34811143d458SBrian Gix break; 34821143d458SBrian Gix 34830493684eSMarcel Holtmann case HCI_EV_SIMPLE_PAIR_COMPLETE: 34840493684eSMarcel Holtmann hci_simple_pair_complete_evt(hdev, skb); 34850493684eSMarcel Holtmann break; 34860493684eSMarcel Holtmann 348741a96212SMarcel Holtmann case HCI_EV_REMOTE_HOST_FEATURES: 348841a96212SMarcel Holtmann hci_remote_host_features_evt(hdev, skb); 348941a96212SMarcel Holtmann break; 349041a96212SMarcel Holtmann 3491fcd89c09SVille Tervo case HCI_EV_LE_META: 3492fcd89c09SVille Tervo hci_le_meta_evt(hdev, skb); 3493fcd89c09SVille Tervo break; 3494fcd89c09SVille Tervo 34952763eda6SSzymon Janc case HCI_EV_REMOTE_OOB_DATA_REQUEST: 34962763eda6SSzymon Janc hci_remote_oob_data_request_evt(hdev, skb); 34972763eda6SSzymon Janc break; 34982763eda6SSzymon Janc 349925e89e99SAndrei Emeltchenko case HCI_EV_NUM_COMP_BLOCKS: 350025e89e99SAndrei Emeltchenko hci_num_comp_blocks_evt(hdev, skb); 350125e89e99SAndrei Emeltchenko break; 350225e89e99SAndrei Emeltchenko 35031da177e4SLinus Torvalds default: 3504a9de9248SMarcel Holtmann BT_DBG("%s event 0x%x", hdev->name, event); 35051da177e4SLinus Torvalds break; 35061da177e4SLinus Torvalds } 35071da177e4SLinus Torvalds 35081da177e4SLinus Torvalds kfree_skb(skb); 35091da177e4SLinus Torvalds hdev->stat.evt_rx++; 35101da177e4SLinus Torvalds } 35111da177e4SLinus Torvalds 35121da177e4SLinus Torvalds /* Generate internal stack event */ 35131da177e4SLinus Torvalds void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) 35141da177e4SLinus Torvalds { 35151da177e4SLinus Torvalds struct hci_event_hdr *hdr; 35161da177e4SLinus Torvalds struct hci_ev_stack_internal *ev; 35171da177e4SLinus Torvalds struct sk_buff *skb; 35181da177e4SLinus Torvalds 35191da177e4SLinus Torvalds skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC); 35201da177e4SLinus Torvalds if (!skb) 35211da177e4SLinus Torvalds return; 35221da177e4SLinus Torvalds 35231da177e4SLinus Torvalds hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE); 35241da177e4SLinus Torvalds hdr->evt = HCI_EV_STACK_INTERNAL; 35251da177e4SLinus Torvalds hdr->plen = sizeof(*ev) + dlen; 35261da177e4SLinus Torvalds 35271da177e4SLinus Torvalds ev = (void *) skb_put(skb, sizeof(*ev) + dlen); 35281da177e4SLinus Torvalds ev->type = type; 35291da177e4SLinus Torvalds memcpy(ev->data, data, dlen); 35301da177e4SLinus Torvalds 3531576c7d85SMarcel Holtmann bt_cb(skb)->incoming = 1; 3532a61bbcf2SPatrick McHardy __net_timestamp(skb); 3533576c7d85SMarcel Holtmann 35340d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_EVENT_PKT; 35351da177e4SLinus Torvalds skb->dev = (void *) hdev; 3536eec8d2bcSJohan Hedberg hci_send_to_sock(hdev, skb, NULL); 35371da177e4SLinus Torvalds kfree_skb(skb); 35381da177e4SLinus Torvalds } 3539e6100a25SAndre Guedes 3540669bb396SGustavo F. Padovan module_param(enable_le, bool, 0644); 3541e6100a25SAndre Guedes MODULE_PARM_DESC(enable_le, "Enable LE support"); 3542