11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 31da177e4SLinus Torvalds Copyright (C) 2000-2001 Qualcomm Incorporated 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> 421da177e4SLinus Torvalds #include <asm/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 481da177e4SLinus Torvalds /* Handle HCI Event packets */ 491da177e4SLinus Torvalds 50a9de9248SMarcel Holtmann static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) 511da177e4SLinus Torvalds { 52a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 531da177e4SLinus Torvalds 54a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 551da177e4SLinus Torvalds 56a9de9248SMarcel Holtmann if (status) 57a9de9248SMarcel Holtmann return; 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds clear_bit(HCI_INQUIRY, &hdev->flags); 60a9de9248SMarcel Holtmann 611da177e4SLinus Torvalds hci_req_complete(hdev, status); 62a9de9248SMarcel Holtmann 63a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 641da177e4SLinus Torvalds } 656bd57416SMarcel Holtmann 66a9de9248SMarcel Holtmann static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) 671da177e4SLinus Torvalds { 68a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 69a9de9248SMarcel Holtmann 70a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 71a9de9248SMarcel Holtmann 72a9de9248SMarcel Holtmann if (status) 73a9de9248SMarcel Holtmann return; 74a9de9248SMarcel Holtmann 75a9de9248SMarcel Holtmann clear_bit(HCI_INQUIRY, &hdev->flags); 76a9de9248SMarcel Holtmann 77a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 78a9de9248SMarcel Holtmann } 79a9de9248SMarcel Holtmann 80a9de9248SMarcel Holtmann static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb) 81a9de9248SMarcel Holtmann { 82a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 83a9de9248SMarcel Holtmann } 84a9de9248SMarcel Holtmann 85a9de9248SMarcel Holtmann static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb) 86a9de9248SMarcel Holtmann { 87a9de9248SMarcel Holtmann struct hci_rp_role_discovery *rp = (void *) skb->data; 881da177e4SLinus Torvalds struct hci_conn *conn; 891da177e4SLinus Torvalds 90a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 911da177e4SLinus Torvalds 92a9de9248SMarcel Holtmann if (rp->status) 93a9de9248SMarcel Holtmann return; 941da177e4SLinus Torvalds 951da177e4SLinus Torvalds hci_dev_lock(hdev); 961da177e4SLinus Torvalds 97a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 981da177e4SLinus Torvalds if (conn) { 99a9de9248SMarcel Holtmann if (rp->role) 1001da177e4SLinus Torvalds conn->link_mode &= ~HCI_LM_MASTER; 1011da177e4SLinus Torvalds else 1021da177e4SLinus Torvalds conn->link_mode |= HCI_LM_MASTER; 1031da177e4SLinus Torvalds } 1041da177e4SLinus Torvalds 1051da177e4SLinus Torvalds hci_dev_unlock(hdev); 106a9de9248SMarcel Holtmann } 1071da177e4SLinus Torvalds 108e4e8e37cSMarcel Holtmann static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 109e4e8e37cSMarcel Holtmann { 110e4e8e37cSMarcel Holtmann struct hci_rp_read_link_policy *rp = (void *) skb->data; 111e4e8e37cSMarcel Holtmann struct hci_conn *conn; 112e4e8e37cSMarcel Holtmann 113e4e8e37cSMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 114e4e8e37cSMarcel Holtmann 115e4e8e37cSMarcel Holtmann if (rp->status) 116e4e8e37cSMarcel Holtmann return; 117e4e8e37cSMarcel Holtmann 118e4e8e37cSMarcel Holtmann hci_dev_lock(hdev); 119e4e8e37cSMarcel Holtmann 120e4e8e37cSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 121e4e8e37cSMarcel Holtmann if (conn) 122e4e8e37cSMarcel Holtmann conn->link_policy = __le16_to_cpu(rp->policy); 123e4e8e37cSMarcel Holtmann 124e4e8e37cSMarcel Holtmann hci_dev_unlock(hdev); 125e4e8e37cSMarcel Holtmann } 126e4e8e37cSMarcel Holtmann 127a9de9248SMarcel Holtmann static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 128a9de9248SMarcel Holtmann { 129a9de9248SMarcel Holtmann struct hci_rp_write_link_policy *rp = (void *) skb->data; 130a9de9248SMarcel Holtmann struct hci_conn *conn; 131a9de9248SMarcel Holtmann void *sent; 132a9de9248SMarcel Holtmann 133a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 134a9de9248SMarcel Holtmann 135a9de9248SMarcel Holtmann if (rp->status) 136a9de9248SMarcel Holtmann return; 137a9de9248SMarcel Holtmann 138a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY); 13904837f64SMarcel Holtmann if (!sent) 140a9de9248SMarcel Holtmann return; 14104837f64SMarcel Holtmann 14204837f64SMarcel Holtmann hci_dev_lock(hdev); 14304837f64SMarcel Holtmann 144a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 145e4e8e37cSMarcel Holtmann if (conn) 14683985319SHarvey Harrison conn->link_policy = get_unaligned_le16(sent + 2); 14704837f64SMarcel Holtmann 14804837f64SMarcel Holtmann hci_dev_unlock(hdev); 1491da177e4SLinus Torvalds } 1501da177e4SLinus Torvalds 151e4e8e37cSMarcel Holtmann static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 152e4e8e37cSMarcel Holtmann { 153e4e8e37cSMarcel Holtmann struct hci_rp_read_def_link_policy *rp = (void *) skb->data; 154e4e8e37cSMarcel Holtmann 155e4e8e37cSMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 156e4e8e37cSMarcel Holtmann 157e4e8e37cSMarcel Holtmann if (rp->status) 158e4e8e37cSMarcel Holtmann return; 159e4e8e37cSMarcel Holtmann 160e4e8e37cSMarcel Holtmann hdev->link_policy = __le16_to_cpu(rp->policy); 161e4e8e37cSMarcel Holtmann } 162e4e8e37cSMarcel Holtmann 163e4e8e37cSMarcel Holtmann static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 164e4e8e37cSMarcel Holtmann { 165e4e8e37cSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 166e4e8e37cSMarcel Holtmann void *sent; 167e4e8e37cSMarcel Holtmann 168e4e8e37cSMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 169e4e8e37cSMarcel Holtmann 170e4e8e37cSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); 171e4e8e37cSMarcel Holtmann if (!sent) 172e4e8e37cSMarcel Holtmann return; 173e4e8e37cSMarcel Holtmann 174e4e8e37cSMarcel Holtmann if (!status) 175e4e8e37cSMarcel Holtmann hdev->link_policy = get_unaligned_le16(sent); 176e4e8e37cSMarcel Holtmann 177e4e8e37cSMarcel Holtmann hci_req_complete(hdev, status); 178e4e8e37cSMarcel Holtmann } 179e4e8e37cSMarcel Holtmann 180a9de9248SMarcel Holtmann static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) 1811da177e4SLinus Torvalds { 182a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 183a9de9248SMarcel Holtmann 184a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 185a9de9248SMarcel Holtmann 186a9de9248SMarcel Holtmann hci_req_complete(hdev, status); 187a9de9248SMarcel Holtmann } 188a9de9248SMarcel Holtmann 189a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 190a9de9248SMarcel Holtmann { 191a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 1921da177e4SLinus Torvalds void *sent; 1931da177e4SLinus Torvalds 194a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1951da177e4SLinus Torvalds 196f383f275SMarcel Holtmann if (status) 197f383f275SMarcel Holtmann return; 198f383f275SMarcel Holtmann 199a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); 2001da177e4SLinus Torvalds if (!sent) 201a9de9248SMarcel Holtmann return; 2021da177e4SLinus Torvalds 203a9de9248SMarcel Holtmann memcpy(hdev->dev_name, sent, 248); 204a9de9248SMarcel Holtmann } 205a9de9248SMarcel Holtmann 206a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) 207a9de9248SMarcel Holtmann { 208a9de9248SMarcel Holtmann struct hci_rp_read_local_name *rp = (void *) skb->data; 209a9de9248SMarcel Holtmann 210a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 211a9de9248SMarcel Holtmann 212a9de9248SMarcel Holtmann if (rp->status) 213a9de9248SMarcel Holtmann return; 214a9de9248SMarcel Holtmann 215a9de9248SMarcel Holtmann memcpy(hdev->dev_name, rp->name, 248); 216a9de9248SMarcel Holtmann } 217a9de9248SMarcel Holtmann 218a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) 219a9de9248SMarcel Holtmann { 220a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 221a9de9248SMarcel Holtmann void *sent; 222a9de9248SMarcel Holtmann 223a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 224a9de9248SMarcel Holtmann 225a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); 226a9de9248SMarcel Holtmann if (!sent) 227a9de9248SMarcel Holtmann return; 2281da177e4SLinus Torvalds 2291da177e4SLinus Torvalds if (!status) { 230a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 231a9de9248SMarcel Holtmann 2321da177e4SLinus Torvalds if (param == AUTH_ENABLED) 2331da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags); 2341da177e4SLinus Torvalds else 2351da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags); 2361da177e4SLinus Torvalds } 237a9de9248SMarcel Holtmann 2381da177e4SLinus Torvalds hci_req_complete(hdev, status); 239a9de9248SMarcel Holtmann } 2401da177e4SLinus Torvalds 241a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) 242a9de9248SMarcel Holtmann { 243a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 244a9de9248SMarcel Holtmann void *sent; 245a9de9248SMarcel Holtmann 246a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 247a9de9248SMarcel Holtmann 248a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); 2491da177e4SLinus Torvalds if (!sent) 250a9de9248SMarcel Holtmann return; 2511da177e4SLinus Torvalds 2521da177e4SLinus Torvalds if (!status) { 253a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 254a9de9248SMarcel Holtmann 2551da177e4SLinus Torvalds if (param) 2561da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags); 2571da177e4SLinus Torvalds else 2581da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags); 2591da177e4SLinus Torvalds } 260a9de9248SMarcel Holtmann 2611da177e4SLinus Torvalds hci_req_complete(hdev, status); 2621da177e4SLinus Torvalds } 2631da177e4SLinus Torvalds 264a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) 265a9de9248SMarcel Holtmann { 266a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 267a9de9248SMarcel Holtmann void *sent; 2681da177e4SLinus Torvalds 269a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 270a9de9248SMarcel Holtmann 271a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); 2721da177e4SLinus Torvalds if (!sent) 273a9de9248SMarcel Holtmann return; 2741da177e4SLinus Torvalds 2751da177e4SLinus Torvalds if (!status) { 276a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 277a9de9248SMarcel Holtmann 2781da177e4SLinus Torvalds clear_bit(HCI_PSCAN, &hdev->flags); 2791da177e4SLinus Torvalds clear_bit(HCI_ISCAN, &hdev->flags); 280a9de9248SMarcel Holtmann 2811da177e4SLinus Torvalds if (param & SCAN_INQUIRY) 2821da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags); 2831da177e4SLinus Torvalds 2841da177e4SLinus Torvalds if (param & SCAN_PAGE) 2851da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags); 2861da177e4SLinus Torvalds } 287a9de9248SMarcel Holtmann 2881da177e4SLinus Torvalds hci_req_complete(hdev, status); 2891da177e4SLinus Torvalds } 2901da177e4SLinus Torvalds 291a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 292a9de9248SMarcel Holtmann { 293a9de9248SMarcel Holtmann struct hci_rp_read_class_of_dev *rp = (void *) skb->data; 294a9de9248SMarcel Holtmann 295a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 296a9de9248SMarcel Holtmann 297a9de9248SMarcel Holtmann if (rp->status) 298a9de9248SMarcel Holtmann return; 299a9de9248SMarcel Holtmann 300a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3); 301a9de9248SMarcel Holtmann 302a9de9248SMarcel Holtmann BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name, 303a9de9248SMarcel Holtmann hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); 304a9de9248SMarcel Holtmann } 305a9de9248SMarcel Holtmann 306a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 307a9de9248SMarcel Holtmann { 308a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 309a9de9248SMarcel Holtmann void *sent; 310a9de9248SMarcel Holtmann 311a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 312a9de9248SMarcel Holtmann 313f383f275SMarcel Holtmann if (status) 314f383f275SMarcel Holtmann return; 315f383f275SMarcel Holtmann 316a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); 317a9de9248SMarcel Holtmann if (!sent) 318a9de9248SMarcel Holtmann return; 319a9de9248SMarcel Holtmann 320a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3); 321a9de9248SMarcel Holtmann } 322a9de9248SMarcel Holtmann 323a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 324a9de9248SMarcel Holtmann { 325a9de9248SMarcel Holtmann struct hci_rp_read_voice_setting *rp = (void *) skb->data; 326a9de9248SMarcel Holtmann __u16 setting; 327a9de9248SMarcel Holtmann 328a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 329a9de9248SMarcel Holtmann 330a9de9248SMarcel Holtmann if (rp->status) 331a9de9248SMarcel Holtmann return; 332a9de9248SMarcel Holtmann 333a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting); 334a9de9248SMarcel Holtmann 335a9de9248SMarcel Holtmann if (hdev->voice_setting == setting) 336a9de9248SMarcel Holtmann return; 337a9de9248SMarcel Holtmann 338a9de9248SMarcel Holtmann hdev->voice_setting = setting; 339a9de9248SMarcel Holtmann 340a9de9248SMarcel Holtmann BT_DBG("%s voice setting 0x%04x", hdev->name, setting); 341a9de9248SMarcel Holtmann 342a9de9248SMarcel Holtmann if (hdev->notify) { 343a9de9248SMarcel Holtmann tasklet_disable(&hdev->tx_task); 344a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 345a9de9248SMarcel Holtmann tasklet_enable(&hdev->tx_task); 346a9de9248SMarcel Holtmann } 347a9de9248SMarcel Holtmann } 348a9de9248SMarcel Holtmann 349a9de9248SMarcel Holtmann static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 350a9de9248SMarcel Holtmann { 351a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 352f383f275SMarcel Holtmann __u16 setting; 353a9de9248SMarcel Holtmann void *sent; 354a9de9248SMarcel Holtmann 355a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 356a9de9248SMarcel Holtmann 357f383f275SMarcel Holtmann if (status) 358f383f275SMarcel Holtmann return; 359f383f275SMarcel Holtmann 360a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); 361a9de9248SMarcel Holtmann if (!sent) 362a9de9248SMarcel Holtmann return; 363a9de9248SMarcel Holtmann 364f383f275SMarcel Holtmann setting = get_unaligned_le16(sent); 3651da177e4SLinus Torvalds 366f383f275SMarcel Holtmann if (hdev->voice_setting == setting) 367f383f275SMarcel Holtmann return; 368f383f275SMarcel Holtmann 3691da177e4SLinus Torvalds hdev->voice_setting = setting; 3701da177e4SLinus Torvalds 371a9de9248SMarcel Holtmann BT_DBG("%s voice setting 0x%04x", hdev->name, setting); 3721da177e4SLinus Torvalds 3731da177e4SLinus Torvalds if (hdev->notify) { 3741da177e4SLinus Torvalds tasklet_disable(&hdev->tx_task); 3751da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 3761da177e4SLinus Torvalds tasklet_enable(&hdev->tx_task); 3771da177e4SLinus Torvalds } 3781da177e4SLinus Torvalds } 3791da177e4SLinus Torvalds 380a9de9248SMarcel Holtmann static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 3811da177e4SLinus Torvalds { 382a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 3831da177e4SLinus Torvalds 384a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 3851da177e4SLinus Torvalds 386a9de9248SMarcel Holtmann hci_req_complete(hdev, status); 3871143e5a6SMarcel Holtmann } 3881143e5a6SMarcel Holtmann 389333140b5SMarcel Holtmann static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 390333140b5SMarcel Holtmann { 391333140b5SMarcel Holtmann struct hci_rp_read_ssp_mode *rp = (void *) skb->data; 392333140b5SMarcel Holtmann 393333140b5SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 394333140b5SMarcel Holtmann 395333140b5SMarcel Holtmann if (rp->status) 396333140b5SMarcel Holtmann return; 397333140b5SMarcel Holtmann 398333140b5SMarcel Holtmann hdev->ssp_mode = rp->mode; 399333140b5SMarcel Holtmann } 400333140b5SMarcel Holtmann 401333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 402333140b5SMarcel Holtmann { 403333140b5SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 404333140b5SMarcel Holtmann void *sent; 405333140b5SMarcel Holtmann 406333140b5SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 407333140b5SMarcel Holtmann 408333140b5SMarcel Holtmann if (status) 409333140b5SMarcel Holtmann return; 410333140b5SMarcel Holtmann 411333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); 412333140b5SMarcel Holtmann if (!sent) 413333140b5SMarcel Holtmann return; 414333140b5SMarcel Holtmann 415333140b5SMarcel Holtmann hdev->ssp_mode = *((__u8 *) sent); 416333140b5SMarcel Holtmann } 417333140b5SMarcel Holtmann 418a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) 419a9de9248SMarcel Holtmann { 420a9de9248SMarcel Holtmann struct hci_rp_read_local_version *rp = (void *) skb->data; 4211143e5a6SMarcel Holtmann 422a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 4231143e5a6SMarcel Holtmann 424a9de9248SMarcel Holtmann if (rp->status) 425a9de9248SMarcel Holtmann return; 4261143e5a6SMarcel Holtmann 427a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver; 428e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 429e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer); 4301da177e4SLinus Torvalds 431a9de9248SMarcel Holtmann BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name, 432a9de9248SMarcel Holtmann hdev->manufacturer, 433a9de9248SMarcel Holtmann hdev->hci_ver, hdev->hci_rev); 4341da177e4SLinus Torvalds } 4351da177e4SLinus Torvalds 436a9de9248SMarcel Holtmann static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb) 437a9de9248SMarcel Holtmann { 438a9de9248SMarcel Holtmann struct hci_rp_read_local_commands *rp = (void *) skb->data; 439a9de9248SMarcel Holtmann 440a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 441a9de9248SMarcel Holtmann 442a9de9248SMarcel Holtmann if (rp->status) 443a9de9248SMarcel Holtmann return; 444a9de9248SMarcel Holtmann 445a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 446a9de9248SMarcel Holtmann } 447a9de9248SMarcel Holtmann 448a9de9248SMarcel Holtmann static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb) 449a9de9248SMarcel Holtmann { 450a9de9248SMarcel Holtmann struct hci_rp_read_local_features *rp = (void *) skb->data; 451a9de9248SMarcel Holtmann 452a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 453a9de9248SMarcel Holtmann 454a9de9248SMarcel Holtmann if (rp->status) 455a9de9248SMarcel Holtmann return; 456a9de9248SMarcel Holtmann 457a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8); 4581da177e4SLinus Torvalds 4591da177e4SLinus Torvalds /* Adjust default settings according to features 4601da177e4SLinus Torvalds * supported by device. */ 461a9de9248SMarcel Holtmann 4621da177e4SLinus Torvalds if (hdev->features[0] & LMP_3SLOT) 4631da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 4641da177e4SLinus Torvalds 4651da177e4SLinus Torvalds if (hdev->features[0] & LMP_5SLOT) 4661da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 4671da177e4SLinus Torvalds 4685b7f9909SMarcel Holtmann if (hdev->features[1] & LMP_HV2) { 4691da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2); 4705b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2); 4715b7f9909SMarcel Holtmann } 4721da177e4SLinus Torvalds 4735b7f9909SMarcel Holtmann if (hdev->features[1] & LMP_HV3) { 4741da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3); 4755b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3); 4765b7f9909SMarcel Holtmann } 4775b7f9909SMarcel Holtmann 4785b7f9909SMarcel Holtmann if (hdev->features[3] & LMP_ESCO) 4795b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3); 4805b7f9909SMarcel Holtmann 4815b7f9909SMarcel Holtmann if (hdev->features[4] & LMP_EV4) 4825b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4); 4835b7f9909SMarcel Holtmann 4845b7f9909SMarcel Holtmann if (hdev->features[4] & LMP_EV5) 4855b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5); 4861da177e4SLinus Torvalds 487efc7688bSMarcel Holtmann if (hdev->features[5] & LMP_EDR_ESCO_2M) 488efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3); 489efc7688bSMarcel Holtmann 490efc7688bSMarcel Holtmann if (hdev->features[5] & LMP_EDR_ESCO_3M) 491efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3); 492efc7688bSMarcel Holtmann 493efc7688bSMarcel Holtmann if (hdev->features[5] & LMP_EDR_3S_ESCO) 494efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 495efc7688bSMarcel Holtmann 496a9de9248SMarcel Holtmann BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name, 497a9de9248SMarcel Holtmann hdev->features[0], hdev->features[1], 498a9de9248SMarcel Holtmann hdev->features[2], hdev->features[3], 499a9de9248SMarcel Holtmann hdev->features[4], hdev->features[5], 500a9de9248SMarcel Holtmann hdev->features[6], hdev->features[7]); 5011da177e4SLinus Torvalds } 5021da177e4SLinus Torvalds 503a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 504a9de9248SMarcel Holtmann { 505a9de9248SMarcel Holtmann struct hci_rp_read_buffer_size *rp = (void *) skb->data; 506a9de9248SMarcel Holtmann 507a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 508a9de9248SMarcel Holtmann 509a9de9248SMarcel Holtmann if (rp->status) 510a9de9248SMarcel Holtmann return; 511a9de9248SMarcel Holtmann 512a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu); 513a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu; 514a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt); 515a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt); 516da1f5198SMarcel Holtmann 517da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { 518da1f5198SMarcel Holtmann hdev->sco_mtu = 64; 519da1f5198SMarcel Holtmann hdev->sco_pkts = 8; 520da1f5198SMarcel Holtmann } 521da1f5198SMarcel Holtmann 522da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts; 523da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 5241da177e4SLinus Torvalds 525a9de9248SMarcel Holtmann BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, 526a9de9248SMarcel Holtmann hdev->acl_mtu, hdev->acl_pkts, 527a9de9248SMarcel Holtmann hdev->sco_mtu, hdev->sco_pkts); 5281da177e4SLinus Torvalds } 5291da177e4SLinus Torvalds 530a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) 531a9de9248SMarcel Holtmann { 532a9de9248SMarcel Holtmann struct hci_rp_read_bd_addr *rp = (void *) skb->data; 5331da177e4SLinus Torvalds 534a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 535a9de9248SMarcel Holtmann 536a9de9248SMarcel Holtmann if (!rp->status) 537a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr); 538a9de9248SMarcel Holtmann 539a9de9248SMarcel Holtmann hci_req_complete(hdev, rp->status); 5401da177e4SLinus Torvalds } 5411da177e4SLinus Torvalds 542a9de9248SMarcel Holtmann static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) 543a9de9248SMarcel Holtmann { 544a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 545a9de9248SMarcel Holtmann 546a9de9248SMarcel Holtmann if (status) { 547a9de9248SMarcel Holtmann hci_req_complete(hdev, status); 548a9de9248SMarcel Holtmann 549a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 550a9de9248SMarcel Holtmann } else 551a9de9248SMarcel Holtmann set_bit(HCI_INQUIRY, &hdev->flags); 552a9de9248SMarcel Holtmann } 553a9de9248SMarcel Holtmann 5541da177e4SLinus Torvalds static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 5551da177e4SLinus Torvalds { 556a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp; 5571da177e4SLinus Torvalds struct hci_conn *conn; 5581da177e4SLinus Torvalds 559a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 560a9de9248SMarcel Holtmann 561a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); 5621da177e4SLinus Torvalds if (!cp) 5631da177e4SLinus Torvalds return; 5641da177e4SLinus Torvalds 5651da177e4SLinus Torvalds hci_dev_lock(hdev); 5661da177e4SLinus Torvalds 5671da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 5681da177e4SLinus Torvalds 569a9de9248SMarcel Holtmann BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn); 5701da177e4SLinus Torvalds 5711da177e4SLinus Torvalds if (status) { 5721da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) { 5734c67bc74SMarcel Holtmann if (status != 0x0c || conn->attempt > 2) { 5741da177e4SLinus Torvalds conn->state = BT_CLOSED; 5751da177e4SLinus Torvalds hci_proto_connect_cfm(conn, status); 5761da177e4SLinus Torvalds hci_conn_del(conn); 5774c67bc74SMarcel Holtmann } else 5784c67bc74SMarcel Holtmann conn->state = BT_CONNECT2; 5791da177e4SLinus Torvalds } 5801da177e4SLinus Torvalds } else { 5811da177e4SLinus Torvalds if (!conn) { 5821da177e4SLinus Torvalds conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr); 5831da177e4SLinus Torvalds if (conn) { 5841da177e4SLinus Torvalds conn->out = 1; 5851da177e4SLinus Torvalds conn->link_mode |= HCI_LM_MASTER; 5861da177e4SLinus Torvalds } else 5871da177e4SLinus Torvalds BT_ERR("No memmory for new connection"); 5881da177e4SLinus Torvalds } 5891da177e4SLinus Torvalds } 5901da177e4SLinus Torvalds 5911da177e4SLinus Torvalds hci_dev_unlock(hdev); 5921da177e4SLinus Torvalds } 5931da177e4SLinus Torvalds 594a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) 5951da177e4SLinus Torvalds { 596a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp; 5971da177e4SLinus Torvalds struct hci_conn *acl, *sco; 5981da177e4SLinus Torvalds __u16 handle; 5991da177e4SLinus Torvalds 600b6a0dc82SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 601b6a0dc82SMarcel Holtmann 602a9de9248SMarcel Holtmann if (!status) 603a9de9248SMarcel Holtmann return; 604a9de9248SMarcel Holtmann 605a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 6061da177e4SLinus Torvalds if (!cp) 607a9de9248SMarcel Holtmann return; 6081da177e4SLinus Torvalds 6091da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle); 6101da177e4SLinus Torvalds 611a9de9248SMarcel Holtmann BT_DBG("%s handle %d", hdev->name, handle); 6121da177e4SLinus Torvalds 6131da177e4SLinus Torvalds hci_dev_lock(hdev); 6141da177e4SLinus Torvalds 6151da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle); 6161da177e4SLinus Torvalds if (acl && (sco = acl->link)) { 6171da177e4SLinus Torvalds sco->state = BT_CLOSED; 6181da177e4SLinus Torvalds 6191da177e4SLinus Torvalds hci_proto_connect_cfm(sco, status); 6201da177e4SLinus Torvalds hci_conn_del(sco); 6211da177e4SLinus Torvalds } 6221da177e4SLinus Torvalds 6231da177e4SLinus Torvalds hci_dev_unlock(hdev); 6241da177e4SLinus Torvalds } 6251da177e4SLinus Torvalds 626f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) 627f8558555SMarcel Holtmann { 628f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp; 629f8558555SMarcel Holtmann struct hci_conn *conn; 630f8558555SMarcel Holtmann 631f8558555SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 632f8558555SMarcel Holtmann 633f8558555SMarcel Holtmann if (!status) 634f8558555SMarcel Holtmann return; 635f8558555SMarcel Holtmann 636f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); 637f8558555SMarcel Holtmann if (!cp) 638f8558555SMarcel Holtmann return; 639f8558555SMarcel Holtmann 640f8558555SMarcel Holtmann hci_dev_lock(hdev); 641f8558555SMarcel Holtmann 642f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 643f8558555SMarcel Holtmann if (conn) { 644f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 645f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 646f8558555SMarcel Holtmann hci_conn_put(conn); 647f8558555SMarcel Holtmann } 648f8558555SMarcel Holtmann } 649f8558555SMarcel Holtmann 650f8558555SMarcel Holtmann hci_dev_unlock(hdev); 651f8558555SMarcel Holtmann } 652f8558555SMarcel Holtmann 653f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) 654f8558555SMarcel Holtmann { 655f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp; 656f8558555SMarcel Holtmann struct hci_conn *conn; 657f8558555SMarcel Holtmann 658f8558555SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 659f8558555SMarcel Holtmann 660f8558555SMarcel Holtmann if (!status) 661f8558555SMarcel Holtmann return; 662f8558555SMarcel Holtmann 663f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); 664f8558555SMarcel Holtmann if (!cp) 665f8558555SMarcel Holtmann return; 666f8558555SMarcel Holtmann 667f8558555SMarcel Holtmann hci_dev_lock(hdev); 668f8558555SMarcel Holtmann 669f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 670f8558555SMarcel Holtmann if (conn) { 671f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 672f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 673f8558555SMarcel Holtmann hci_conn_put(conn); 674f8558555SMarcel Holtmann } 675f8558555SMarcel Holtmann } 676f8558555SMarcel Holtmann 677f8558555SMarcel Holtmann hci_dev_unlock(hdev); 678f8558555SMarcel Holtmann } 679f8558555SMarcel Holtmann 680a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 6811da177e4SLinus Torvalds { 682a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 683a9de9248SMarcel Holtmann } 6841da177e4SLinus Torvalds 685769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 686769be974SMarcel Holtmann { 687769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp; 688769be974SMarcel Holtmann struct hci_conn *conn; 689769be974SMarcel Holtmann 690769be974SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 691769be974SMarcel Holtmann 692769be974SMarcel Holtmann if (!status) 693769be974SMarcel Holtmann return; 694769be974SMarcel Holtmann 695769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); 696769be974SMarcel Holtmann if (!cp) 697769be974SMarcel Holtmann return; 698769be974SMarcel Holtmann 699769be974SMarcel Holtmann hci_dev_lock(hdev); 700769be974SMarcel Holtmann 701769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 702769be974SMarcel Holtmann if (conn) { 703769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 704769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 705769be974SMarcel Holtmann hci_conn_put(conn); 706769be974SMarcel Holtmann } 707769be974SMarcel Holtmann } 708769be974SMarcel Holtmann 709769be974SMarcel Holtmann hci_dev_unlock(hdev); 710769be974SMarcel Holtmann } 711769be974SMarcel Holtmann 712769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) 713769be974SMarcel Holtmann { 714769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp; 715769be974SMarcel Holtmann struct hci_conn *conn; 716769be974SMarcel Holtmann 717769be974SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 718769be974SMarcel Holtmann 719769be974SMarcel Holtmann if (!status) 720769be974SMarcel Holtmann return; 721769be974SMarcel Holtmann 722769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); 723769be974SMarcel Holtmann if (!cp) 724769be974SMarcel Holtmann return; 725769be974SMarcel Holtmann 726769be974SMarcel Holtmann hci_dev_lock(hdev); 727769be974SMarcel Holtmann 728769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 729769be974SMarcel Holtmann if (conn) { 730769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 731769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 732769be974SMarcel Holtmann hci_conn_put(conn); 733769be974SMarcel Holtmann } 734769be974SMarcel Holtmann } 735769be974SMarcel Holtmann 736769be974SMarcel Holtmann hci_dev_unlock(hdev); 737769be974SMarcel Holtmann } 738769be974SMarcel Holtmann 739a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 740a9de9248SMarcel Holtmann { 741b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp; 742b6a0dc82SMarcel Holtmann struct hci_conn *acl, *sco; 743b6a0dc82SMarcel Holtmann __u16 handle; 744b6a0dc82SMarcel Holtmann 745a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 746b6a0dc82SMarcel Holtmann 747b6a0dc82SMarcel Holtmann if (!status) 748b6a0dc82SMarcel Holtmann return; 749b6a0dc82SMarcel Holtmann 750b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN); 751b6a0dc82SMarcel Holtmann if (!cp) 752b6a0dc82SMarcel Holtmann return; 753b6a0dc82SMarcel Holtmann 754b6a0dc82SMarcel Holtmann handle = __le16_to_cpu(cp->handle); 755b6a0dc82SMarcel Holtmann 756b6a0dc82SMarcel Holtmann BT_DBG("%s handle %d", hdev->name, handle); 757b6a0dc82SMarcel Holtmann 758b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 759b6a0dc82SMarcel Holtmann 760b6a0dc82SMarcel Holtmann acl = hci_conn_hash_lookup_handle(hdev, handle); 761b6a0dc82SMarcel Holtmann if (acl && (sco = acl->link)) { 762b6a0dc82SMarcel Holtmann sco->state = BT_CLOSED; 763b6a0dc82SMarcel Holtmann 764b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(sco, status); 765b6a0dc82SMarcel Holtmann hci_conn_del(sco); 766b6a0dc82SMarcel Holtmann } 767b6a0dc82SMarcel Holtmann 768b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 769a9de9248SMarcel Holtmann } 770a9de9248SMarcel Holtmann 771a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 772a9de9248SMarcel Holtmann { 773a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp; 77404837f64SMarcel Holtmann struct hci_conn *conn; 77504837f64SMarcel Holtmann 776a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 777a9de9248SMarcel Holtmann 778a9de9248SMarcel Holtmann if (!status) 779a9de9248SMarcel Holtmann return; 780a9de9248SMarcel Holtmann 781a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE); 78204837f64SMarcel Holtmann if (!cp) 783a9de9248SMarcel Holtmann return; 78404837f64SMarcel Holtmann 78504837f64SMarcel Holtmann hci_dev_lock(hdev); 78604837f64SMarcel Holtmann 78704837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 788a9de9248SMarcel Holtmann if (conn) 78904837f64SMarcel Holtmann clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); 79004837f64SMarcel Holtmann 79104837f64SMarcel Holtmann hci_dev_unlock(hdev); 79204837f64SMarcel Holtmann } 79304837f64SMarcel Holtmann 794a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) 795a9de9248SMarcel Holtmann { 796a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp; 79704837f64SMarcel Holtmann struct hci_conn *conn; 79804837f64SMarcel Holtmann 799a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 800a9de9248SMarcel Holtmann 801a9de9248SMarcel Holtmann if (!status) 802a9de9248SMarcel Holtmann return; 803a9de9248SMarcel Holtmann 804a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE); 80504837f64SMarcel Holtmann if (!cp) 806a9de9248SMarcel Holtmann return; 80704837f64SMarcel Holtmann 80804837f64SMarcel Holtmann hci_dev_lock(hdev); 80904837f64SMarcel Holtmann 81004837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 811a9de9248SMarcel Holtmann if (conn) 81204837f64SMarcel Holtmann clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); 81304837f64SMarcel Holtmann 81404837f64SMarcel Holtmann hci_dev_unlock(hdev); 81504837f64SMarcel Holtmann } 81604837f64SMarcel Holtmann 8171da177e4SLinus Torvalds static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 8181da177e4SLinus Torvalds { 8191da177e4SLinus Torvalds __u8 status = *((__u8 *) skb->data); 8201da177e4SLinus Torvalds 8211da177e4SLinus Torvalds BT_DBG("%s status %d", hdev->name, status); 8221da177e4SLinus Torvalds 8231da177e4SLinus Torvalds clear_bit(HCI_INQUIRY, &hdev->flags); 824a9de9248SMarcel Holtmann 8251da177e4SLinus Torvalds hci_req_complete(hdev, status); 8266bd57416SMarcel Holtmann 827a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 8281da177e4SLinus Torvalds } 8291da177e4SLinus Torvalds 8301da177e4SLinus Torvalds static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 8311da177e4SLinus Torvalds { 83245bb4bf0SMarcel Holtmann struct inquiry_data data; 833a9de9248SMarcel Holtmann struct inquiry_info *info = (void *) (skb->data + 1); 8341da177e4SLinus Torvalds int num_rsp = *((__u8 *) skb->data); 8351da177e4SLinus Torvalds 8361da177e4SLinus Torvalds BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 8371da177e4SLinus Torvalds 83845bb4bf0SMarcel Holtmann if (!num_rsp) 83945bb4bf0SMarcel Holtmann return; 84045bb4bf0SMarcel Holtmann 8411da177e4SLinus Torvalds hci_dev_lock(hdev); 84245bb4bf0SMarcel Holtmann 8431da177e4SLinus Torvalds for (; num_rsp; num_rsp--) { 8441da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr); 8451da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode; 8461da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode; 8471da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode; 8481da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3); 8491da177e4SLinus Torvalds data.clock_offset = info->clock_offset; 8501da177e4SLinus Torvalds data.rssi = 0x00; 85141a96212SMarcel Holtmann data.ssp_mode = 0x00; 8521da177e4SLinus Torvalds info++; 8531da177e4SLinus Torvalds hci_inquiry_cache_update(hdev, &data); 8541da177e4SLinus Torvalds } 85545bb4bf0SMarcel Holtmann 8561da177e4SLinus Torvalds hci_dev_unlock(hdev); 8571da177e4SLinus Torvalds } 8581da177e4SLinus Torvalds 859a9de9248SMarcel Holtmann static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 8601da177e4SLinus Torvalds { 861a9de9248SMarcel Holtmann struct hci_ev_conn_complete *ev = (void *) skb->data; 862a9de9248SMarcel Holtmann struct hci_conn *conn; 8631da177e4SLinus Torvalds 864a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 86545bb4bf0SMarcel Holtmann 8661da177e4SLinus Torvalds hci_dev_lock(hdev); 86745bb4bf0SMarcel Holtmann 868a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 869a9de9248SMarcel Holtmann if (!conn) 870a9de9248SMarcel Holtmann goto unlock; 87145bb4bf0SMarcel Holtmann 872a9de9248SMarcel Holtmann if (!ev->status) { 873a9de9248SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 874769be974SMarcel Holtmann 875769be974SMarcel Holtmann if (conn->type == ACL_LINK) { 876769be974SMarcel Holtmann conn->state = BT_CONFIG; 877769be974SMarcel Holtmann hci_conn_hold(conn); 878769be974SMarcel Holtmann } else 879a9de9248SMarcel Holtmann conn->state = BT_CONNECTED; 880a9de9248SMarcel Holtmann 8817d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 8827d0db0a3SMarcel Holtmann 883a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags)) 884a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 885a9de9248SMarcel Holtmann 886a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags)) 887a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_ENCRYPT; 888a9de9248SMarcel Holtmann 889a9de9248SMarcel Holtmann /* Get remote features */ 890a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 891a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp; 892a9de9248SMarcel Holtmann cp.handle = ev->handle; 893769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, 894769be974SMarcel Holtmann sizeof(cp), &cp); 89545bb4bf0SMarcel Holtmann } 896a9de9248SMarcel Holtmann 897a9de9248SMarcel Holtmann /* Set packet type for incoming connection */ 898a8746417SMarcel Holtmann if (!conn->out && hdev->hci_ver < 3) { 899a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp; 900a9de9248SMarcel Holtmann cp.handle = ev->handle; 901a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 902a8746417SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, 903a8746417SMarcel Holtmann sizeof(cp), &cp); 904a9de9248SMarcel Holtmann } 905a9de9248SMarcel Holtmann } else 906a9de9248SMarcel Holtmann conn->state = BT_CLOSED; 90745bb4bf0SMarcel Holtmann 908a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 909a9de9248SMarcel Holtmann struct hci_conn *sco = conn->link; 910a9de9248SMarcel Holtmann if (sco) { 911b6a0dc82SMarcel Holtmann if (!ev->status) { 912b6a0dc82SMarcel Holtmann if (lmp_esco_capable(hdev)) 913b6a0dc82SMarcel Holtmann hci_setup_sync(sco, conn->handle); 914b6a0dc82SMarcel Holtmann else 915a9de9248SMarcel Holtmann hci_add_sco(sco, conn->handle); 916b6a0dc82SMarcel Holtmann } else { 917a9de9248SMarcel Holtmann hci_proto_connect_cfm(sco, ev->status); 918a9de9248SMarcel Holtmann hci_conn_del(sco); 919a9de9248SMarcel Holtmann } 9201da177e4SLinus Torvalds } 92145bb4bf0SMarcel Holtmann } 92245bb4bf0SMarcel Holtmann 923769be974SMarcel Holtmann if (ev->status) { 924a9de9248SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 925a9de9248SMarcel Holtmann hci_conn_del(conn); 926c89b6e6bSMarcel Holtmann } else if (ev->link_type != ACL_LINK) 927c89b6e6bSMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 928a9de9248SMarcel Holtmann 929a9de9248SMarcel Holtmann unlock: 9301da177e4SLinus Torvalds hci_dev_unlock(hdev); 931a9de9248SMarcel Holtmann 932a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 9331da177e4SLinus Torvalds } 9341da177e4SLinus Torvalds 9351da177e4SLinus Torvalds static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 9361da177e4SLinus Torvalds { 937a9de9248SMarcel Holtmann struct hci_ev_conn_request *ev = (void *) skb->data; 9381da177e4SLinus Torvalds int mask = hdev->link_mode; 9391da177e4SLinus Torvalds 940a9de9248SMarcel Holtmann BT_DBG("%s bdaddr %s type 0x%x", hdev->name, 9411da177e4SLinus Torvalds batostr(&ev->bdaddr), ev->link_type); 9421da177e4SLinus Torvalds 9431da177e4SLinus Torvalds mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); 9441da177e4SLinus Torvalds 9451da177e4SLinus Torvalds if (mask & HCI_LM_ACCEPT) { 9461da177e4SLinus Torvalds /* Connection accepted */ 947c7bdd502SMarcel Holtmann struct inquiry_entry *ie; 9481da177e4SLinus Torvalds struct hci_conn *conn; 9491da177e4SLinus Torvalds 9501da177e4SLinus Torvalds hci_dev_lock(hdev); 951b6a0dc82SMarcel Holtmann 952c7bdd502SMarcel Holtmann if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) 953c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3); 954c7bdd502SMarcel Holtmann 9551da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 9561da177e4SLinus Torvalds if (!conn) { 9571da177e4SLinus Torvalds if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) { 9581da177e4SLinus Torvalds BT_ERR("No memmory for new connection"); 9591da177e4SLinus Torvalds hci_dev_unlock(hdev); 9601da177e4SLinus Torvalds return; 9611da177e4SLinus Torvalds } 9621da177e4SLinus Torvalds } 963b6a0dc82SMarcel Holtmann 9641da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3); 9651da177e4SLinus Torvalds conn->state = BT_CONNECT; 966b6a0dc82SMarcel Holtmann 9671da177e4SLinus Torvalds hci_dev_unlock(hdev); 9681da177e4SLinus Torvalds 969b6a0dc82SMarcel Holtmann if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) { 970b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp; 971b6a0dc82SMarcel Holtmann 9721da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 9731da177e4SLinus Torvalds 9741da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 9751da177e4SLinus Torvalds cp.role = 0x00; /* Become master */ 9761da177e4SLinus Torvalds else 9771da177e4SLinus Torvalds cp.role = 0x01; /* Remain slave */ 9781da177e4SLinus Torvalds 979b6a0dc82SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, 980b6a0dc82SMarcel Holtmann sizeof(cp), &cp); 981b6a0dc82SMarcel Holtmann } else { 982b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp; 983b6a0dc82SMarcel Holtmann 984b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 985a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 986b6a0dc82SMarcel Holtmann 987b6a0dc82SMarcel Holtmann cp.tx_bandwidth = cpu_to_le32(0x00001f40); 988b6a0dc82SMarcel Holtmann cp.rx_bandwidth = cpu_to_le32(0x00001f40); 989b6a0dc82SMarcel Holtmann cp.max_latency = cpu_to_le16(0xffff); 990b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting); 991b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff; 992b6a0dc82SMarcel Holtmann 993b6a0dc82SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, 994b6a0dc82SMarcel Holtmann sizeof(cp), &cp); 995b6a0dc82SMarcel Holtmann } 9961da177e4SLinus Torvalds } else { 9971da177e4SLinus Torvalds /* Connection rejected */ 9981da177e4SLinus Torvalds struct hci_cp_reject_conn_req cp; 9991da177e4SLinus Torvalds 10001da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 10011da177e4SLinus Torvalds cp.reason = 0x0f; 1002a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); 10031da177e4SLinus Torvalds } 10041da177e4SLinus Torvalds } 10051da177e4SLinus Torvalds 10061da177e4SLinus Torvalds static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 10071da177e4SLinus Torvalds { 1008a9de9248SMarcel Holtmann struct hci_ev_disconn_complete *ev = (void *) skb->data; 100904837f64SMarcel Holtmann struct hci_conn *conn; 10101da177e4SLinus Torvalds 10111da177e4SLinus Torvalds BT_DBG("%s status %d", hdev->name, ev->status); 10121da177e4SLinus Torvalds 10131da177e4SLinus Torvalds if (ev->status) 10141da177e4SLinus Torvalds return; 10151da177e4SLinus Torvalds 10161da177e4SLinus Torvalds hci_dev_lock(hdev); 10171da177e4SLinus Torvalds 101804837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 10191da177e4SLinus Torvalds if (conn) { 10201da177e4SLinus Torvalds conn->state = BT_CLOSED; 10217d0db0a3SMarcel Holtmann 10227d0db0a3SMarcel Holtmann hci_conn_del_sysfs(conn); 10237d0db0a3SMarcel Holtmann 10242950f21aSMarcel Holtmann hci_proto_disconn_cfm(conn, ev->reason); 10251da177e4SLinus Torvalds hci_conn_del(conn); 10261da177e4SLinus Torvalds } 10271da177e4SLinus Torvalds 10281da177e4SLinus Torvalds hci_dev_unlock(hdev); 10291da177e4SLinus Torvalds } 10301da177e4SLinus Torvalds 1031a9de9248SMarcel Holtmann static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1032a9de9248SMarcel Holtmann { 1033a9de9248SMarcel Holtmann struct hci_ev_auth_complete *ev = (void *) skb->data; 1034a9de9248SMarcel Holtmann struct hci_conn *conn; 1035a9de9248SMarcel Holtmann 1036a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 1037a9de9248SMarcel Holtmann 1038a9de9248SMarcel Holtmann hci_dev_lock(hdev); 1039a9de9248SMarcel Holtmann 1040a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1041a9de9248SMarcel Holtmann if (conn) { 1042a9de9248SMarcel Holtmann if (!ev->status) 1043a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 1044a9de9248SMarcel Holtmann 1045a9de9248SMarcel Holtmann clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); 1046a9de9248SMarcel Holtmann 1047f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1048f8558555SMarcel Holtmann if (!ev->status && hdev->ssp_mode > 0 && 1049f8558555SMarcel Holtmann conn->ssp_mode > 0) { 1050f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 1051f8558555SMarcel Holtmann cp.handle = ev->handle; 1052f8558555SMarcel Holtmann cp.encrypt = 0x01; 1053f8558555SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, 1054f8558555SMarcel Holtmann sizeof(cp), &cp); 1055f8558555SMarcel Holtmann } else { 1056f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 1057f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1058f8558555SMarcel Holtmann hci_conn_put(conn); 1059f8558555SMarcel Holtmann } 1060f8558555SMarcel Holtmann } else 1061a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status); 1062a9de9248SMarcel Holtmann 1063a9de9248SMarcel Holtmann if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { 1064a9de9248SMarcel Holtmann if (!ev->status) { 1065a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 1066f8558555SMarcel Holtmann cp.handle = ev->handle; 1067f8558555SMarcel Holtmann cp.encrypt = 0x01; 1068f8558555SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, 1069f8558555SMarcel Holtmann sizeof(cp), &cp); 1070a9de9248SMarcel Holtmann } else { 1071a9de9248SMarcel Holtmann clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); 1072a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, 0x00); 1073a9de9248SMarcel Holtmann } 1074a9de9248SMarcel Holtmann } 1075a9de9248SMarcel Holtmann } 1076a9de9248SMarcel Holtmann 1077a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 1078a9de9248SMarcel Holtmann } 1079a9de9248SMarcel Holtmann 1080a9de9248SMarcel Holtmann static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) 1081a9de9248SMarcel Holtmann { 1082a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 1083a9de9248SMarcel Holtmann 1084a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 1085a9de9248SMarcel Holtmann } 1086a9de9248SMarcel Holtmann 1087a9de9248SMarcel Holtmann static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 1088a9de9248SMarcel Holtmann { 1089a9de9248SMarcel Holtmann struct hci_ev_encrypt_change *ev = (void *) skb->data; 1090a9de9248SMarcel Holtmann struct hci_conn *conn; 1091a9de9248SMarcel Holtmann 1092a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 1093a9de9248SMarcel Holtmann 1094a9de9248SMarcel Holtmann hci_dev_lock(hdev); 1095a9de9248SMarcel Holtmann 1096a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1097a9de9248SMarcel Holtmann if (conn) { 1098a9de9248SMarcel Holtmann if (!ev->status) { 1099ae293196SMarcel Holtmann if (ev->encrypt) { 1100ae293196SMarcel Holtmann /* Encryption implies authentication */ 1101ae293196SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 1102a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_ENCRYPT; 1103ae293196SMarcel Holtmann } else 1104a9de9248SMarcel Holtmann conn->link_mode &= ~HCI_LM_ENCRYPT; 1105a9de9248SMarcel Holtmann } 1106a9de9248SMarcel Holtmann 1107a9de9248SMarcel Holtmann clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); 1108a9de9248SMarcel Holtmann 1109f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1110f8558555SMarcel Holtmann if (!ev->status) 1111f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 1112f8558555SMarcel Holtmann 1113f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1114f8558555SMarcel Holtmann hci_conn_put(conn); 1115f8558555SMarcel Holtmann } else 1116a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, ev->encrypt); 1117a9de9248SMarcel Holtmann } 1118a9de9248SMarcel Holtmann 1119a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 1120a9de9248SMarcel Holtmann } 1121a9de9248SMarcel Holtmann 1122a9de9248SMarcel Holtmann static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1123a9de9248SMarcel Holtmann { 1124a9de9248SMarcel Holtmann struct hci_ev_change_link_key_complete *ev = (void *) skb->data; 1125a9de9248SMarcel Holtmann struct hci_conn *conn; 1126a9de9248SMarcel Holtmann 1127a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 1128a9de9248SMarcel Holtmann 1129a9de9248SMarcel Holtmann hci_dev_lock(hdev); 1130a9de9248SMarcel Holtmann 1131a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1132a9de9248SMarcel Holtmann if (conn) { 1133a9de9248SMarcel Holtmann if (!ev->status) 1134a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_SECURE; 1135a9de9248SMarcel Holtmann 1136a9de9248SMarcel Holtmann clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); 1137a9de9248SMarcel Holtmann 1138a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status); 1139a9de9248SMarcel Holtmann } 1140a9de9248SMarcel Holtmann 1141a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 1142a9de9248SMarcel Holtmann } 1143a9de9248SMarcel Holtmann 1144a9de9248SMarcel Holtmann static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb) 1145a9de9248SMarcel Holtmann { 1146a9de9248SMarcel Holtmann struct hci_ev_remote_features *ev = (void *) skb->data; 1147a9de9248SMarcel Holtmann struct hci_conn *conn; 1148a9de9248SMarcel Holtmann 1149a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 1150a9de9248SMarcel Holtmann 1151a9de9248SMarcel Holtmann hci_dev_lock(hdev); 1152a9de9248SMarcel Holtmann 1153a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1154769be974SMarcel Holtmann if (conn) { 1155769be974SMarcel Holtmann if (!ev->status) 1156a9de9248SMarcel Holtmann memcpy(conn->features, ev->features, 8); 1157a9de9248SMarcel Holtmann 1158769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1159769be974SMarcel Holtmann if (!ev->status && lmp_ssp_capable(hdev) && 1160769be974SMarcel Holtmann lmp_ssp_capable(conn)) { 1161769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp; 1162769be974SMarcel Holtmann cp.handle = ev->handle; 1163769be974SMarcel Holtmann cp.page = 0x01; 1164769be974SMarcel Holtmann hci_send_cmd(hdev, 1165769be974SMarcel Holtmann HCI_OP_READ_REMOTE_EXT_FEATURES, 1166769be974SMarcel Holtmann sizeof(cp), &cp); 1167769be974SMarcel Holtmann } else { 1168769be974SMarcel Holtmann conn->state = BT_CONNECTED; 1169769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1170769be974SMarcel Holtmann hci_conn_put(conn); 1171769be974SMarcel Holtmann } 1172769be974SMarcel Holtmann } 1173769be974SMarcel Holtmann } 1174769be974SMarcel Holtmann 1175a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 1176a9de9248SMarcel Holtmann } 1177a9de9248SMarcel Holtmann 1178a9de9248SMarcel Holtmann static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb) 1179a9de9248SMarcel Holtmann { 1180a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 1181a9de9248SMarcel Holtmann } 1182a9de9248SMarcel Holtmann 1183a9de9248SMarcel Holtmann static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1184a9de9248SMarcel Holtmann { 1185a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 1186a9de9248SMarcel Holtmann } 1187a9de9248SMarcel Holtmann 1188a9de9248SMarcel Holtmann static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1189a9de9248SMarcel Holtmann { 1190a9de9248SMarcel Holtmann struct hci_ev_cmd_complete *ev = (void *) skb->data; 1191a9de9248SMarcel Holtmann __u16 opcode; 1192a9de9248SMarcel Holtmann 1193a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 1194a9de9248SMarcel Holtmann 1195a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 1196a9de9248SMarcel Holtmann 1197a9de9248SMarcel Holtmann switch (opcode) { 1198a9de9248SMarcel Holtmann case HCI_OP_INQUIRY_CANCEL: 1199a9de9248SMarcel Holtmann hci_cc_inquiry_cancel(hdev, skb); 1200a9de9248SMarcel Holtmann break; 1201a9de9248SMarcel Holtmann 1202a9de9248SMarcel Holtmann case HCI_OP_EXIT_PERIODIC_INQ: 1203a9de9248SMarcel Holtmann hci_cc_exit_periodic_inq(hdev, skb); 1204a9de9248SMarcel Holtmann break; 1205a9de9248SMarcel Holtmann 1206a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ_CANCEL: 1207a9de9248SMarcel Holtmann hci_cc_remote_name_req_cancel(hdev, skb); 1208a9de9248SMarcel Holtmann break; 1209a9de9248SMarcel Holtmann 1210a9de9248SMarcel Holtmann case HCI_OP_ROLE_DISCOVERY: 1211a9de9248SMarcel Holtmann hci_cc_role_discovery(hdev, skb); 1212a9de9248SMarcel Holtmann break; 1213a9de9248SMarcel Holtmann 1214e4e8e37cSMarcel Holtmann case HCI_OP_READ_LINK_POLICY: 1215e4e8e37cSMarcel Holtmann hci_cc_read_link_policy(hdev, skb); 1216e4e8e37cSMarcel Holtmann break; 1217e4e8e37cSMarcel Holtmann 1218a9de9248SMarcel Holtmann case HCI_OP_WRITE_LINK_POLICY: 1219a9de9248SMarcel Holtmann hci_cc_write_link_policy(hdev, skb); 1220a9de9248SMarcel Holtmann break; 1221a9de9248SMarcel Holtmann 1222e4e8e37cSMarcel Holtmann case HCI_OP_READ_DEF_LINK_POLICY: 1223e4e8e37cSMarcel Holtmann hci_cc_read_def_link_policy(hdev, skb); 1224e4e8e37cSMarcel Holtmann break; 1225e4e8e37cSMarcel Holtmann 1226e4e8e37cSMarcel Holtmann case HCI_OP_WRITE_DEF_LINK_POLICY: 1227e4e8e37cSMarcel Holtmann hci_cc_write_def_link_policy(hdev, skb); 1228e4e8e37cSMarcel Holtmann break; 1229e4e8e37cSMarcel Holtmann 1230a9de9248SMarcel Holtmann case HCI_OP_RESET: 1231a9de9248SMarcel Holtmann hci_cc_reset(hdev, skb); 1232a9de9248SMarcel Holtmann break; 1233a9de9248SMarcel Holtmann 1234a9de9248SMarcel Holtmann case HCI_OP_WRITE_LOCAL_NAME: 1235a9de9248SMarcel Holtmann hci_cc_write_local_name(hdev, skb); 1236a9de9248SMarcel Holtmann break; 1237a9de9248SMarcel Holtmann 1238a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_NAME: 1239a9de9248SMarcel Holtmann hci_cc_read_local_name(hdev, skb); 1240a9de9248SMarcel Holtmann break; 1241a9de9248SMarcel Holtmann 1242a9de9248SMarcel Holtmann case HCI_OP_WRITE_AUTH_ENABLE: 1243a9de9248SMarcel Holtmann hci_cc_write_auth_enable(hdev, skb); 1244a9de9248SMarcel Holtmann break; 1245a9de9248SMarcel Holtmann 1246a9de9248SMarcel Holtmann case HCI_OP_WRITE_ENCRYPT_MODE: 1247a9de9248SMarcel Holtmann hci_cc_write_encrypt_mode(hdev, skb); 1248a9de9248SMarcel Holtmann break; 1249a9de9248SMarcel Holtmann 1250a9de9248SMarcel Holtmann case HCI_OP_WRITE_SCAN_ENABLE: 1251a9de9248SMarcel Holtmann hci_cc_write_scan_enable(hdev, skb); 1252a9de9248SMarcel Holtmann break; 1253a9de9248SMarcel Holtmann 1254a9de9248SMarcel Holtmann case HCI_OP_READ_CLASS_OF_DEV: 1255a9de9248SMarcel Holtmann hci_cc_read_class_of_dev(hdev, skb); 1256a9de9248SMarcel Holtmann break; 1257a9de9248SMarcel Holtmann 1258a9de9248SMarcel Holtmann case HCI_OP_WRITE_CLASS_OF_DEV: 1259a9de9248SMarcel Holtmann hci_cc_write_class_of_dev(hdev, skb); 1260a9de9248SMarcel Holtmann break; 1261a9de9248SMarcel Holtmann 1262a9de9248SMarcel Holtmann case HCI_OP_READ_VOICE_SETTING: 1263a9de9248SMarcel Holtmann hci_cc_read_voice_setting(hdev, skb); 1264a9de9248SMarcel Holtmann break; 1265a9de9248SMarcel Holtmann 1266a9de9248SMarcel Holtmann case HCI_OP_WRITE_VOICE_SETTING: 1267a9de9248SMarcel Holtmann hci_cc_write_voice_setting(hdev, skb); 1268a9de9248SMarcel Holtmann break; 1269a9de9248SMarcel Holtmann 1270a9de9248SMarcel Holtmann case HCI_OP_HOST_BUFFER_SIZE: 1271a9de9248SMarcel Holtmann hci_cc_host_buffer_size(hdev, skb); 1272a9de9248SMarcel Holtmann break; 1273a9de9248SMarcel Holtmann 1274333140b5SMarcel Holtmann case HCI_OP_READ_SSP_MODE: 1275333140b5SMarcel Holtmann hci_cc_read_ssp_mode(hdev, skb); 1276333140b5SMarcel Holtmann break; 1277333140b5SMarcel Holtmann 1278333140b5SMarcel Holtmann case HCI_OP_WRITE_SSP_MODE: 1279333140b5SMarcel Holtmann hci_cc_write_ssp_mode(hdev, skb); 1280333140b5SMarcel Holtmann break; 1281333140b5SMarcel Holtmann 1282a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_VERSION: 1283a9de9248SMarcel Holtmann hci_cc_read_local_version(hdev, skb); 1284a9de9248SMarcel Holtmann break; 1285a9de9248SMarcel Holtmann 1286a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_COMMANDS: 1287a9de9248SMarcel Holtmann hci_cc_read_local_commands(hdev, skb); 1288a9de9248SMarcel Holtmann break; 1289a9de9248SMarcel Holtmann 1290a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_FEATURES: 1291a9de9248SMarcel Holtmann hci_cc_read_local_features(hdev, skb); 1292a9de9248SMarcel Holtmann break; 1293a9de9248SMarcel Holtmann 1294a9de9248SMarcel Holtmann case HCI_OP_READ_BUFFER_SIZE: 1295a9de9248SMarcel Holtmann hci_cc_read_buffer_size(hdev, skb); 1296a9de9248SMarcel Holtmann break; 1297a9de9248SMarcel Holtmann 1298a9de9248SMarcel Holtmann case HCI_OP_READ_BD_ADDR: 1299a9de9248SMarcel Holtmann hci_cc_read_bd_addr(hdev, skb); 1300a9de9248SMarcel Holtmann break; 1301a9de9248SMarcel Holtmann 1302a9de9248SMarcel Holtmann default: 1303a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 1304a9de9248SMarcel Holtmann break; 1305a9de9248SMarcel Holtmann } 1306a9de9248SMarcel Holtmann 1307a9de9248SMarcel Holtmann if (ev->ncmd) { 1308a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 1309a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 1310a9de9248SMarcel Holtmann hci_sched_cmd(hdev); 1311a9de9248SMarcel Holtmann } 1312a9de9248SMarcel Holtmann } 1313a9de9248SMarcel Holtmann 1314a9de9248SMarcel Holtmann static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) 1315a9de9248SMarcel Holtmann { 1316a9de9248SMarcel Holtmann struct hci_ev_cmd_status *ev = (void *) skb->data; 1317a9de9248SMarcel Holtmann __u16 opcode; 1318a9de9248SMarcel Holtmann 1319a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 1320a9de9248SMarcel Holtmann 1321a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 1322a9de9248SMarcel Holtmann 1323a9de9248SMarcel Holtmann switch (opcode) { 1324a9de9248SMarcel Holtmann case HCI_OP_INQUIRY: 1325a9de9248SMarcel Holtmann hci_cs_inquiry(hdev, ev->status); 1326a9de9248SMarcel Holtmann break; 1327a9de9248SMarcel Holtmann 1328a9de9248SMarcel Holtmann case HCI_OP_CREATE_CONN: 1329a9de9248SMarcel Holtmann hci_cs_create_conn(hdev, ev->status); 1330a9de9248SMarcel Holtmann break; 1331a9de9248SMarcel Holtmann 1332a9de9248SMarcel Holtmann case HCI_OP_ADD_SCO: 1333a9de9248SMarcel Holtmann hci_cs_add_sco(hdev, ev->status); 1334a9de9248SMarcel Holtmann break; 1335a9de9248SMarcel Holtmann 1336f8558555SMarcel Holtmann case HCI_OP_AUTH_REQUESTED: 1337f8558555SMarcel Holtmann hci_cs_auth_requested(hdev, ev->status); 1338f8558555SMarcel Holtmann break; 1339f8558555SMarcel Holtmann 1340f8558555SMarcel Holtmann case HCI_OP_SET_CONN_ENCRYPT: 1341f8558555SMarcel Holtmann hci_cs_set_conn_encrypt(hdev, ev->status); 1342f8558555SMarcel Holtmann break; 1343f8558555SMarcel Holtmann 1344a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ: 1345a9de9248SMarcel Holtmann hci_cs_remote_name_req(hdev, ev->status); 1346a9de9248SMarcel Holtmann break; 1347a9de9248SMarcel Holtmann 1348769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_FEATURES: 1349769be974SMarcel Holtmann hci_cs_read_remote_features(hdev, ev->status); 1350769be974SMarcel Holtmann break; 1351769be974SMarcel Holtmann 1352769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_EXT_FEATURES: 1353769be974SMarcel Holtmann hci_cs_read_remote_ext_features(hdev, ev->status); 1354769be974SMarcel Holtmann break; 1355769be974SMarcel Holtmann 1356a9de9248SMarcel Holtmann case HCI_OP_SETUP_SYNC_CONN: 1357a9de9248SMarcel Holtmann hci_cs_setup_sync_conn(hdev, ev->status); 1358a9de9248SMarcel Holtmann break; 1359a9de9248SMarcel Holtmann 1360a9de9248SMarcel Holtmann case HCI_OP_SNIFF_MODE: 1361a9de9248SMarcel Holtmann hci_cs_sniff_mode(hdev, ev->status); 1362a9de9248SMarcel Holtmann break; 1363a9de9248SMarcel Holtmann 1364a9de9248SMarcel Holtmann case HCI_OP_EXIT_SNIFF_MODE: 1365a9de9248SMarcel Holtmann hci_cs_exit_sniff_mode(hdev, ev->status); 1366a9de9248SMarcel Holtmann break; 1367a9de9248SMarcel Holtmann 1368a9de9248SMarcel Holtmann default: 1369a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 1370a9de9248SMarcel Holtmann break; 1371a9de9248SMarcel Holtmann } 1372a9de9248SMarcel Holtmann 1373a9de9248SMarcel Holtmann if (ev->ncmd) { 1374a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 1375a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 1376a9de9248SMarcel Holtmann hci_sched_cmd(hdev); 1377a9de9248SMarcel Holtmann } 1378a9de9248SMarcel Holtmann } 1379a9de9248SMarcel Holtmann 1380a9de9248SMarcel Holtmann static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 1381a9de9248SMarcel Holtmann { 1382a9de9248SMarcel Holtmann struct hci_ev_role_change *ev = (void *) skb->data; 1383a9de9248SMarcel Holtmann struct hci_conn *conn; 1384a9de9248SMarcel Holtmann 1385a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 1386a9de9248SMarcel Holtmann 1387a9de9248SMarcel Holtmann hci_dev_lock(hdev); 1388a9de9248SMarcel Holtmann 1389a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 1390a9de9248SMarcel Holtmann if (conn) { 1391a9de9248SMarcel Holtmann if (!ev->status) { 1392a9de9248SMarcel Holtmann if (ev->role) 1393a9de9248SMarcel Holtmann conn->link_mode &= ~HCI_LM_MASTER; 1394a9de9248SMarcel Holtmann else 1395a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_MASTER; 1396a9de9248SMarcel Holtmann } 1397a9de9248SMarcel Holtmann 1398a9de9248SMarcel Holtmann clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend); 1399a9de9248SMarcel Holtmann 1400a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role); 1401a9de9248SMarcel Holtmann } 1402a9de9248SMarcel Holtmann 1403a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 1404a9de9248SMarcel Holtmann } 1405a9de9248SMarcel Holtmann 14061da177e4SLinus Torvalds static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) 14071da177e4SLinus Torvalds { 1408a9de9248SMarcel Holtmann struct hci_ev_num_comp_pkts *ev = (void *) skb->data; 14091ebb9252SMarcel Holtmann __le16 *ptr; 14101da177e4SLinus Torvalds int i; 14111da177e4SLinus Torvalds 14121da177e4SLinus Torvalds skb_pull(skb, sizeof(*ev)); 14131da177e4SLinus Torvalds 14141da177e4SLinus Torvalds BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl); 14151da177e4SLinus Torvalds 14161da177e4SLinus Torvalds if (skb->len < ev->num_hndl * 4) { 14171da177e4SLinus Torvalds BT_DBG("%s bad parameters", hdev->name); 14181da177e4SLinus Torvalds return; 14191da177e4SLinus Torvalds } 14201da177e4SLinus Torvalds 14211da177e4SLinus Torvalds tasklet_disable(&hdev->tx_task); 14221da177e4SLinus Torvalds 14231ebb9252SMarcel Holtmann for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) { 14241da177e4SLinus Torvalds struct hci_conn *conn; 14251da177e4SLinus Torvalds __u16 handle, count; 14261da177e4SLinus Torvalds 142783985319SHarvey Harrison handle = get_unaligned_le16(ptr++); 142883985319SHarvey Harrison count = get_unaligned_le16(ptr++); 14291da177e4SLinus Torvalds 14301da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 14311da177e4SLinus Torvalds if (conn) { 14321da177e4SLinus Torvalds conn->sent -= count; 14331da177e4SLinus Torvalds 14345b7f9909SMarcel Holtmann if (conn->type == ACL_LINK) { 14351da177e4SLinus Torvalds if ((hdev->acl_cnt += count) > hdev->acl_pkts) 14361da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts; 14375b7f9909SMarcel Holtmann } else { 14385b7f9909SMarcel Holtmann if ((hdev->sco_cnt += count) > hdev->sco_pkts) 14395b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 14401da177e4SLinus Torvalds } 14411da177e4SLinus Torvalds } 14421da177e4SLinus Torvalds } 1443a9de9248SMarcel Holtmann 14441da177e4SLinus Torvalds hci_sched_tx(hdev); 14451da177e4SLinus Torvalds 14461da177e4SLinus Torvalds tasklet_enable(&hdev->tx_task); 14471da177e4SLinus Torvalds } 14481da177e4SLinus Torvalds 144904837f64SMarcel Holtmann static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 14501da177e4SLinus Torvalds { 1451a9de9248SMarcel Holtmann struct hci_ev_mode_change *ev = (void *) skb->data; 145204837f64SMarcel Holtmann struct hci_conn *conn; 14531da177e4SLinus Torvalds 14541da177e4SLinus Torvalds BT_DBG("%s status %d", hdev->name, ev->status); 14551da177e4SLinus Torvalds 14561da177e4SLinus Torvalds hci_dev_lock(hdev); 14571da177e4SLinus Torvalds 145804837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 145904837f64SMarcel Holtmann if (conn) { 146004837f64SMarcel Holtmann conn->mode = ev->mode; 146104837f64SMarcel Holtmann conn->interval = __le16_to_cpu(ev->interval); 146204837f64SMarcel Holtmann 146304837f64SMarcel Holtmann if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { 146404837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE) 146504837f64SMarcel Holtmann conn->power_save = 1; 146604837f64SMarcel Holtmann else 146704837f64SMarcel Holtmann conn->power_save = 0; 146804837f64SMarcel Holtmann } 146904837f64SMarcel Holtmann } 147004837f64SMarcel Holtmann 147104837f64SMarcel Holtmann hci_dev_unlock(hdev); 147204837f64SMarcel Holtmann } 147304837f64SMarcel Holtmann 14741da177e4SLinus Torvalds static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 14751da177e4SLinus Torvalds { 1476a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 14771da177e4SLinus Torvalds } 14781da177e4SLinus Torvalds 14791da177e4SLinus Torvalds static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 14801da177e4SLinus Torvalds { 1481a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 14821da177e4SLinus Torvalds } 14831da177e4SLinus Torvalds 14841da177e4SLinus Torvalds static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 14851da177e4SLinus Torvalds { 1486a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 14871da177e4SLinus Torvalds } 14881da177e4SLinus Torvalds 148904837f64SMarcel Holtmann static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) 149004837f64SMarcel Holtmann { 1491a9de9248SMarcel Holtmann struct hci_ev_clock_offset *ev = (void *) skb->data; 149204837f64SMarcel Holtmann struct hci_conn *conn; 149304837f64SMarcel Holtmann 149404837f64SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 149504837f64SMarcel Holtmann 149604837f64SMarcel Holtmann hci_dev_lock(hdev); 149704837f64SMarcel Holtmann 149804837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 14991da177e4SLinus Torvalds if (conn && !ev->status) { 15001da177e4SLinus Torvalds struct inquiry_entry *ie; 15011da177e4SLinus Torvalds 15021da177e4SLinus Torvalds if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) { 15031da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset; 15041da177e4SLinus Torvalds ie->timestamp = jiffies; 15051da177e4SLinus Torvalds } 15061da177e4SLinus Torvalds } 15071da177e4SLinus Torvalds 15081da177e4SLinus Torvalds hci_dev_unlock(hdev); 15091da177e4SLinus Torvalds } 15101da177e4SLinus Torvalds 1511a8746417SMarcel Holtmann static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 1512a8746417SMarcel Holtmann { 1513a8746417SMarcel Holtmann struct hci_ev_pkt_type_change *ev = (void *) skb->data; 1514a8746417SMarcel Holtmann struct hci_conn *conn; 1515a8746417SMarcel Holtmann 1516a8746417SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 1517a8746417SMarcel Holtmann 1518a8746417SMarcel Holtmann hci_dev_lock(hdev); 1519a8746417SMarcel Holtmann 1520a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1521a8746417SMarcel Holtmann if (conn && !ev->status) 1522a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type); 1523a8746417SMarcel Holtmann 1524a8746417SMarcel Holtmann hci_dev_unlock(hdev); 1525a8746417SMarcel Holtmann } 1526a8746417SMarcel Holtmann 152785a1e930SMarcel Holtmann static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) 152885a1e930SMarcel Holtmann { 1529a9de9248SMarcel Holtmann struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; 153085a1e930SMarcel Holtmann struct inquiry_entry *ie; 153185a1e930SMarcel Holtmann 153285a1e930SMarcel Holtmann BT_DBG("%s", hdev->name); 153385a1e930SMarcel Holtmann 153485a1e930SMarcel Holtmann hci_dev_lock(hdev); 153585a1e930SMarcel Holtmann 153685a1e930SMarcel Holtmann if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) { 153785a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode; 153885a1e930SMarcel Holtmann ie->timestamp = jiffies; 153985a1e930SMarcel Holtmann } 154085a1e930SMarcel Holtmann 154185a1e930SMarcel Holtmann hci_dev_unlock(hdev); 154285a1e930SMarcel Holtmann } 154385a1e930SMarcel Holtmann 1544a9de9248SMarcel Holtmann static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb) 1545a9de9248SMarcel Holtmann { 1546a9de9248SMarcel Holtmann struct inquiry_data data; 1547a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 1548a9de9248SMarcel Holtmann 1549a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 1550a9de9248SMarcel Holtmann 1551a9de9248SMarcel Holtmann if (!num_rsp) 1552a9de9248SMarcel Holtmann return; 1553a9de9248SMarcel Holtmann 1554a9de9248SMarcel Holtmann hci_dev_lock(hdev); 1555a9de9248SMarcel Holtmann 1556a9de9248SMarcel Holtmann if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { 1557a9de9248SMarcel Holtmann struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1); 1558a9de9248SMarcel Holtmann 1559a9de9248SMarcel Holtmann for (; num_rsp; num_rsp--) { 1560a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 1561a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 1562a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 1563a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode; 1564a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 1565a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 1566a9de9248SMarcel Holtmann data.rssi = info->rssi; 156741a96212SMarcel Holtmann data.ssp_mode = 0x00; 1568a9de9248SMarcel Holtmann info++; 1569a9de9248SMarcel Holtmann hci_inquiry_cache_update(hdev, &data); 1570a9de9248SMarcel Holtmann } 1571a9de9248SMarcel Holtmann } else { 1572a9de9248SMarcel Holtmann struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); 1573a9de9248SMarcel Holtmann 1574a9de9248SMarcel Holtmann for (; num_rsp; num_rsp--) { 1575a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 1576a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 1577a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 1578a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 1579a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 1580a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 1581a9de9248SMarcel Holtmann data.rssi = info->rssi; 158241a96212SMarcel Holtmann data.ssp_mode = 0x00; 1583a9de9248SMarcel Holtmann info++; 1584a9de9248SMarcel Holtmann hci_inquiry_cache_update(hdev, &data); 1585a9de9248SMarcel Holtmann } 1586a9de9248SMarcel Holtmann } 1587a9de9248SMarcel Holtmann 1588a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 1589a9de9248SMarcel Holtmann } 1590a9de9248SMarcel Holtmann 1591a9de9248SMarcel Holtmann static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb) 1592a9de9248SMarcel Holtmann { 159341a96212SMarcel Holtmann struct hci_ev_remote_ext_features *ev = (void *) skb->data; 159441a96212SMarcel Holtmann struct hci_conn *conn; 159541a96212SMarcel Holtmann 1596a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 159741a96212SMarcel Holtmann 159841a96212SMarcel Holtmann hci_dev_lock(hdev); 159941a96212SMarcel Holtmann 160041a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 160141a96212SMarcel Holtmann if (conn) { 1602769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) { 160341a96212SMarcel Holtmann struct inquiry_entry *ie; 160441a96212SMarcel Holtmann 160541a96212SMarcel Holtmann if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) 160641a96212SMarcel Holtmann ie->data.ssp_mode = (ev->features[0] & 0x01); 160741a96212SMarcel Holtmann 160841a96212SMarcel Holtmann conn->ssp_mode = (ev->features[0] & 0x01); 160941a96212SMarcel Holtmann } 161041a96212SMarcel Holtmann 1611769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1612f8558555SMarcel Holtmann if (!ev->status && hdev->ssp_mode > 0 && 16138c1b2355SMarcel Holtmann conn->ssp_mode > 0 && conn->out && 16148c1b2355SMarcel Holtmann conn->sec_level != BT_SECURITY_SDP) { 1615f8558555SMarcel Holtmann struct hci_cp_auth_requested cp; 1616f8558555SMarcel Holtmann cp.handle = ev->handle; 1617f1c08ca5SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, 1618f8558555SMarcel Holtmann sizeof(cp), &cp); 1619f8558555SMarcel Holtmann } else { 1620769be974SMarcel Holtmann conn->state = BT_CONNECTED; 1621769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1622769be974SMarcel Holtmann hci_conn_put(conn); 1623769be974SMarcel Holtmann } 1624769be974SMarcel Holtmann } 1625f8558555SMarcel Holtmann } 1626769be974SMarcel Holtmann 162741a96212SMarcel Holtmann hci_dev_unlock(hdev); 1628a9de9248SMarcel Holtmann } 1629a9de9248SMarcel Holtmann 1630a9de9248SMarcel Holtmann static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1631a9de9248SMarcel Holtmann { 1632b6a0dc82SMarcel Holtmann struct hci_ev_sync_conn_complete *ev = (void *) skb->data; 1633b6a0dc82SMarcel Holtmann struct hci_conn *conn; 1634b6a0dc82SMarcel Holtmann 1635b6a0dc82SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 1636b6a0dc82SMarcel Holtmann 1637b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 1638b6a0dc82SMarcel Holtmann 1639b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 16409dc0a3afSMarcel Holtmann if (!conn) { 16419dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK) 16429dc0a3afSMarcel Holtmann goto unlock; 16439dc0a3afSMarcel Holtmann 16449dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 1645b6a0dc82SMarcel Holtmann if (!conn) 1646b6a0dc82SMarcel Holtmann goto unlock; 1647b6a0dc82SMarcel Holtmann 16489dc0a3afSMarcel Holtmann conn->type = SCO_LINK; 16499dc0a3afSMarcel Holtmann } 16509dc0a3afSMarcel Holtmann 1651efc7688bSMarcel Holtmann if (conn->out && ev->status == 0x1c && conn->attempt < 2) { 1652efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 1653efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK); 1654efc7688bSMarcel Holtmann hci_setup_sync(conn, conn->link->handle); 1655efc7688bSMarcel Holtmann goto unlock; 1656efc7688bSMarcel Holtmann } 1657efc7688bSMarcel Holtmann 1658b6a0dc82SMarcel Holtmann if (!ev->status) { 1659b6a0dc82SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 1660b6a0dc82SMarcel Holtmann conn->state = BT_CONNECTED; 16617d0db0a3SMarcel Holtmann 16627d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 1663b6a0dc82SMarcel Holtmann } else 1664b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED; 1665b6a0dc82SMarcel Holtmann 1666b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1667b6a0dc82SMarcel Holtmann if (ev->status) 1668b6a0dc82SMarcel Holtmann hci_conn_del(conn); 1669b6a0dc82SMarcel Holtmann 1670b6a0dc82SMarcel Holtmann unlock: 1671b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 1672a9de9248SMarcel Holtmann } 1673a9de9248SMarcel Holtmann 1674a9de9248SMarcel Holtmann static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb) 1675a9de9248SMarcel Holtmann { 1676a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 1677a9de9248SMarcel Holtmann } 1678a9de9248SMarcel Holtmann 167904837f64SMarcel Holtmann static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) 168004837f64SMarcel Holtmann { 1681a9de9248SMarcel Holtmann struct hci_ev_sniff_subrate *ev = (void *) skb->data; 168204837f64SMarcel Holtmann struct hci_conn *conn; 168304837f64SMarcel Holtmann 168404837f64SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 168504837f64SMarcel Holtmann 168604837f64SMarcel Holtmann hci_dev_lock(hdev); 168704837f64SMarcel Holtmann 168804837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 168904837f64SMarcel Holtmann if (conn) { 169004837f64SMarcel Holtmann } 169104837f64SMarcel Holtmann 169204837f64SMarcel Holtmann hci_dev_unlock(hdev); 169304837f64SMarcel Holtmann } 169404837f64SMarcel Holtmann 1695a9de9248SMarcel Holtmann static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 1696a9de9248SMarcel Holtmann { 1697a9de9248SMarcel Holtmann struct inquiry_data data; 1698a9de9248SMarcel Holtmann struct extended_inquiry_info *info = (void *) (skb->data + 1); 1699a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 1700a9de9248SMarcel Holtmann 1701a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 1702a9de9248SMarcel Holtmann 1703a9de9248SMarcel Holtmann if (!num_rsp) 1704a9de9248SMarcel Holtmann return; 1705a9de9248SMarcel Holtmann 1706a9de9248SMarcel Holtmann hci_dev_lock(hdev); 1707a9de9248SMarcel Holtmann 1708a9de9248SMarcel Holtmann for (; num_rsp; num_rsp--) { 1709a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 1710a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 1711a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 1712a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 1713a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 1714a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 1715a9de9248SMarcel Holtmann data.rssi = info->rssi; 171641a96212SMarcel Holtmann data.ssp_mode = 0x01; 1717a9de9248SMarcel Holtmann info++; 1718a9de9248SMarcel Holtmann hci_inquiry_cache_update(hdev, &data); 1719a9de9248SMarcel Holtmann } 1720a9de9248SMarcel Holtmann 1721a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 1722a9de9248SMarcel Holtmann } 1723a9de9248SMarcel Holtmann 17240493684eSMarcel Holtmann static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 17250493684eSMarcel Holtmann { 17260493684eSMarcel Holtmann struct hci_ev_io_capa_request *ev = (void *) skb->data; 17270493684eSMarcel Holtmann struct hci_conn *conn; 17280493684eSMarcel Holtmann 17290493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 17300493684eSMarcel Holtmann 17310493684eSMarcel Holtmann hci_dev_lock(hdev); 17320493684eSMarcel Holtmann 17330493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 17340493684eSMarcel Holtmann if (conn) 17350493684eSMarcel Holtmann hci_conn_hold(conn); 17360493684eSMarcel Holtmann 17370493684eSMarcel Holtmann hci_dev_unlock(hdev); 17380493684eSMarcel Holtmann } 17390493684eSMarcel Holtmann 17400493684eSMarcel Holtmann static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 17410493684eSMarcel Holtmann { 17420493684eSMarcel Holtmann struct hci_ev_simple_pair_complete *ev = (void *) skb->data; 17430493684eSMarcel Holtmann struct hci_conn *conn; 17440493684eSMarcel Holtmann 17450493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 17460493684eSMarcel Holtmann 17470493684eSMarcel Holtmann hci_dev_lock(hdev); 17480493684eSMarcel Holtmann 17490493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 17500493684eSMarcel Holtmann if (conn) 17510493684eSMarcel Holtmann hci_conn_put(conn); 17520493684eSMarcel Holtmann 17530493684eSMarcel Holtmann hci_dev_unlock(hdev); 17540493684eSMarcel Holtmann } 17550493684eSMarcel Holtmann 175641a96212SMarcel Holtmann static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb) 175741a96212SMarcel Holtmann { 175841a96212SMarcel Holtmann struct hci_ev_remote_host_features *ev = (void *) skb->data; 175941a96212SMarcel Holtmann struct inquiry_entry *ie; 176041a96212SMarcel Holtmann 176141a96212SMarcel Holtmann BT_DBG("%s", hdev->name); 176241a96212SMarcel Holtmann 176341a96212SMarcel Holtmann hci_dev_lock(hdev); 176441a96212SMarcel Holtmann 176541a96212SMarcel Holtmann if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) 176641a96212SMarcel Holtmann ie->data.ssp_mode = (ev->features[0] & 0x01); 176741a96212SMarcel Holtmann 176841a96212SMarcel Holtmann hci_dev_unlock(hdev); 176941a96212SMarcel Holtmann } 177041a96212SMarcel Holtmann 17711da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 17721da177e4SLinus Torvalds { 1773a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data; 1774a9de9248SMarcel Holtmann __u8 event = hdr->evt; 17751da177e4SLinus Torvalds 17761da177e4SLinus Torvalds skb_pull(skb, HCI_EVENT_HDR_SIZE); 17771da177e4SLinus Torvalds 1778a9de9248SMarcel Holtmann switch (event) { 17791da177e4SLinus Torvalds case HCI_EV_INQUIRY_COMPLETE: 17801da177e4SLinus Torvalds hci_inquiry_complete_evt(hdev, skb); 17811da177e4SLinus Torvalds break; 17821da177e4SLinus Torvalds 17831da177e4SLinus Torvalds case HCI_EV_INQUIRY_RESULT: 17841da177e4SLinus Torvalds hci_inquiry_result_evt(hdev, skb); 17851da177e4SLinus Torvalds break; 17861da177e4SLinus Torvalds 1787a9de9248SMarcel Holtmann case HCI_EV_CONN_COMPLETE: 1788a9de9248SMarcel Holtmann hci_conn_complete_evt(hdev, skb); 178921d9e30eSMarcel Holtmann break; 179021d9e30eSMarcel Holtmann 17911da177e4SLinus Torvalds case HCI_EV_CONN_REQUEST: 17921da177e4SLinus Torvalds hci_conn_request_evt(hdev, skb); 17931da177e4SLinus Torvalds break; 17941da177e4SLinus Torvalds 17951da177e4SLinus Torvalds case HCI_EV_DISCONN_COMPLETE: 17961da177e4SLinus Torvalds hci_disconn_complete_evt(hdev, skb); 17971da177e4SLinus Torvalds break; 17981da177e4SLinus Torvalds 17991da177e4SLinus Torvalds case HCI_EV_AUTH_COMPLETE: 18001da177e4SLinus Torvalds hci_auth_complete_evt(hdev, skb); 18011da177e4SLinus Torvalds break; 18021da177e4SLinus Torvalds 1803a9de9248SMarcel Holtmann case HCI_EV_REMOTE_NAME: 1804a9de9248SMarcel Holtmann hci_remote_name_evt(hdev, skb); 1805a9de9248SMarcel Holtmann break; 1806a9de9248SMarcel Holtmann 18071da177e4SLinus Torvalds case HCI_EV_ENCRYPT_CHANGE: 18081da177e4SLinus Torvalds hci_encrypt_change_evt(hdev, skb); 18091da177e4SLinus Torvalds break; 18101da177e4SLinus Torvalds 1811a9de9248SMarcel Holtmann case HCI_EV_CHANGE_LINK_KEY_COMPLETE: 1812a9de9248SMarcel Holtmann hci_change_link_key_complete_evt(hdev, skb); 1813a9de9248SMarcel Holtmann break; 1814a9de9248SMarcel Holtmann 1815a9de9248SMarcel Holtmann case HCI_EV_REMOTE_FEATURES: 1816a9de9248SMarcel Holtmann hci_remote_features_evt(hdev, skb); 1817a9de9248SMarcel Holtmann break; 1818a9de9248SMarcel Holtmann 1819a9de9248SMarcel Holtmann case HCI_EV_REMOTE_VERSION: 1820a9de9248SMarcel Holtmann hci_remote_version_evt(hdev, skb); 1821a9de9248SMarcel Holtmann break; 1822a9de9248SMarcel Holtmann 1823a9de9248SMarcel Holtmann case HCI_EV_QOS_SETUP_COMPLETE: 1824a9de9248SMarcel Holtmann hci_qos_setup_complete_evt(hdev, skb); 1825a9de9248SMarcel Holtmann break; 1826a9de9248SMarcel Holtmann 1827a9de9248SMarcel Holtmann case HCI_EV_CMD_COMPLETE: 1828a9de9248SMarcel Holtmann hci_cmd_complete_evt(hdev, skb); 1829a9de9248SMarcel Holtmann break; 1830a9de9248SMarcel Holtmann 1831a9de9248SMarcel Holtmann case HCI_EV_CMD_STATUS: 1832a9de9248SMarcel Holtmann hci_cmd_status_evt(hdev, skb); 1833a9de9248SMarcel Holtmann break; 1834a9de9248SMarcel Holtmann 1835a9de9248SMarcel Holtmann case HCI_EV_ROLE_CHANGE: 1836a9de9248SMarcel Holtmann hci_role_change_evt(hdev, skb); 1837a9de9248SMarcel Holtmann break; 1838a9de9248SMarcel Holtmann 1839a9de9248SMarcel Holtmann case HCI_EV_NUM_COMP_PKTS: 1840a9de9248SMarcel Holtmann hci_num_comp_pkts_evt(hdev, skb); 1841a9de9248SMarcel Holtmann break; 1842a9de9248SMarcel Holtmann 1843a9de9248SMarcel Holtmann case HCI_EV_MODE_CHANGE: 1844a9de9248SMarcel Holtmann hci_mode_change_evt(hdev, skb); 18451da177e4SLinus Torvalds break; 18461da177e4SLinus Torvalds 18471da177e4SLinus Torvalds case HCI_EV_PIN_CODE_REQ: 18481da177e4SLinus Torvalds hci_pin_code_request_evt(hdev, skb); 18491da177e4SLinus Torvalds break; 18501da177e4SLinus Torvalds 18511da177e4SLinus Torvalds case HCI_EV_LINK_KEY_REQ: 18521da177e4SLinus Torvalds hci_link_key_request_evt(hdev, skb); 18531da177e4SLinus Torvalds break; 18541da177e4SLinus Torvalds 18551da177e4SLinus Torvalds case HCI_EV_LINK_KEY_NOTIFY: 18561da177e4SLinus Torvalds hci_link_key_notify_evt(hdev, skb); 18571da177e4SLinus Torvalds break; 18581da177e4SLinus Torvalds 18591da177e4SLinus Torvalds case HCI_EV_CLOCK_OFFSET: 18601da177e4SLinus Torvalds hci_clock_offset_evt(hdev, skb); 18611da177e4SLinus Torvalds break; 18621da177e4SLinus Torvalds 1863a8746417SMarcel Holtmann case HCI_EV_PKT_TYPE_CHANGE: 1864a8746417SMarcel Holtmann hci_pkt_type_change_evt(hdev, skb); 1865a8746417SMarcel Holtmann break; 1866a8746417SMarcel Holtmann 186785a1e930SMarcel Holtmann case HCI_EV_PSCAN_REP_MODE: 186885a1e930SMarcel Holtmann hci_pscan_rep_mode_evt(hdev, skb); 186985a1e930SMarcel Holtmann break; 187085a1e930SMarcel Holtmann 1871a9de9248SMarcel Holtmann case HCI_EV_INQUIRY_RESULT_WITH_RSSI: 1872a9de9248SMarcel Holtmann hci_inquiry_result_with_rssi_evt(hdev, skb); 1873a9de9248SMarcel Holtmann break; 1874a9de9248SMarcel Holtmann 1875a9de9248SMarcel Holtmann case HCI_EV_REMOTE_EXT_FEATURES: 1876a9de9248SMarcel Holtmann hci_remote_ext_features_evt(hdev, skb); 1877a9de9248SMarcel Holtmann break; 1878a9de9248SMarcel Holtmann 1879a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_COMPLETE: 1880a9de9248SMarcel Holtmann hci_sync_conn_complete_evt(hdev, skb); 1881a9de9248SMarcel Holtmann break; 1882a9de9248SMarcel Holtmann 1883a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_CHANGED: 1884a9de9248SMarcel Holtmann hci_sync_conn_changed_evt(hdev, skb); 1885a9de9248SMarcel Holtmann break; 1886a9de9248SMarcel Holtmann 188704837f64SMarcel Holtmann case HCI_EV_SNIFF_SUBRATE: 188804837f64SMarcel Holtmann hci_sniff_subrate_evt(hdev, skb); 188904837f64SMarcel Holtmann break; 189004837f64SMarcel Holtmann 1891a9de9248SMarcel Holtmann case HCI_EV_EXTENDED_INQUIRY_RESULT: 1892a9de9248SMarcel Holtmann hci_extended_inquiry_result_evt(hdev, skb); 18931da177e4SLinus Torvalds break; 18941da177e4SLinus Torvalds 18950493684eSMarcel Holtmann case HCI_EV_IO_CAPA_REQUEST: 18960493684eSMarcel Holtmann hci_io_capa_request_evt(hdev, skb); 18970493684eSMarcel Holtmann break; 18980493684eSMarcel Holtmann 18990493684eSMarcel Holtmann case HCI_EV_SIMPLE_PAIR_COMPLETE: 19000493684eSMarcel Holtmann hci_simple_pair_complete_evt(hdev, skb); 19010493684eSMarcel Holtmann break; 19020493684eSMarcel Holtmann 190341a96212SMarcel Holtmann case HCI_EV_REMOTE_HOST_FEATURES: 190441a96212SMarcel Holtmann hci_remote_host_features_evt(hdev, skb); 190541a96212SMarcel Holtmann break; 190641a96212SMarcel Holtmann 19071da177e4SLinus Torvalds default: 1908a9de9248SMarcel Holtmann BT_DBG("%s event 0x%x", hdev->name, event); 19091da177e4SLinus Torvalds break; 19101da177e4SLinus Torvalds } 19111da177e4SLinus Torvalds 19121da177e4SLinus Torvalds kfree_skb(skb); 19131da177e4SLinus Torvalds hdev->stat.evt_rx++; 19141da177e4SLinus Torvalds } 19151da177e4SLinus Torvalds 19161da177e4SLinus Torvalds /* Generate internal stack event */ 19171da177e4SLinus Torvalds void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) 19181da177e4SLinus Torvalds { 19191da177e4SLinus Torvalds struct hci_event_hdr *hdr; 19201da177e4SLinus Torvalds struct hci_ev_stack_internal *ev; 19211da177e4SLinus Torvalds struct sk_buff *skb; 19221da177e4SLinus Torvalds 19231da177e4SLinus Torvalds skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC); 19241da177e4SLinus Torvalds if (!skb) 19251da177e4SLinus Torvalds return; 19261da177e4SLinus Torvalds 19271da177e4SLinus Torvalds hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE); 19281da177e4SLinus Torvalds hdr->evt = HCI_EV_STACK_INTERNAL; 19291da177e4SLinus Torvalds hdr->plen = sizeof(*ev) + dlen; 19301da177e4SLinus Torvalds 19311da177e4SLinus Torvalds ev = (void *) skb_put(skb, sizeof(*ev) + dlen); 19321da177e4SLinus Torvalds ev->type = type; 19331da177e4SLinus Torvalds memcpy(ev->data, data, dlen); 19341da177e4SLinus Torvalds 1935576c7d85SMarcel Holtmann bt_cb(skb)->incoming = 1; 1936a61bbcf2SPatrick McHardy __net_timestamp(skb); 1937576c7d85SMarcel Holtmann 19380d48d939SMarcel Holtmann bt_cb(skb)->pkt_type = HCI_EVENT_PKT; 19391da177e4SLinus Torvalds skb->dev = (void *) hdev; 19401da177e4SLinus Torvalds hci_send_to_sock(hdev, skb); 19411da177e4SLinus Torvalds kfree_skb(skb); 19421da177e4SLinus Torvalds } 1943