11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 32d0a0346SRon Shaffer Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. 40fe8c8d0SIulia Tanasescu Copyright 2023 NXP 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 91da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 101da177e4SLinus Torvalds published by the Free Software Foundation; 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 131da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 141da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 151da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 161da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 171da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 181da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 191da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 221da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 231da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 241da177e4SLinus Torvalds */ 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds /* Bluetooth HCI event handling. */ 271da177e4SLinus Torvalds 281da177e4SLinus Torvalds #include <asm/unaligned.h> 29b5412606SLuiz Augusto von Dentz #include <linux/crypto.h> 30b5412606SLuiz Augusto von Dentz #include <crypto/algapi.h> 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 331da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 34f0d6a0eaSMikel Astiz #include <net/bluetooth/mgmt.h> 357ef9fbf0SMarcel Holtmann 360857dd3bSJohan Hedberg #include "hci_request.h" 3723b9ceb7SMarcel Holtmann #include "hci_debugfs.h" 38b938790eSLuiz Augusto von Dentz #include "hci_codec.h" 392ceba539SJohan Hedberg #include "smp.h" 40145373cbSMiao-chen Chou #include "msft.h" 4101ce70b0SLuiz Augusto von Dentz #include "eir.h" 421da177e4SLinus Torvalds 43aa5b0345SMarcel Holtmann #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \ 44aa5b0345SMarcel Holtmann "\x00\x00\x00\x00\x00\x00\x00\x00" 45aa5b0345SMarcel Holtmann 46c45074d6SLuiz Augusto von Dentz #define secs_to_jiffies(_secs) msecs_to_jiffies((_secs) * 1000) 47c45074d6SLuiz Augusto von Dentz 481da177e4SLinus Torvalds /* Handle HCI Event packets */ 491da177e4SLinus Torvalds 50ae61a10dSLuiz Augusto von Dentz static void *hci_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb, 51ae61a10dSLuiz Augusto von Dentz u8 ev, size_t len) 52ae61a10dSLuiz Augusto von Dentz { 53ae61a10dSLuiz Augusto von Dentz void *data; 54ae61a10dSLuiz Augusto von Dentz 55ae61a10dSLuiz Augusto von Dentz data = skb_pull_data(skb, len); 56ae61a10dSLuiz Augusto von Dentz if (!data) 57ae61a10dSLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed Event: 0x%2.2x", ev); 58ae61a10dSLuiz Augusto von Dentz 59ae61a10dSLuiz Augusto von Dentz return data; 60ae61a10dSLuiz Augusto von Dentz } 61ae61a10dSLuiz Augusto von Dentz 62e3f3a1aeSLuiz Augusto von Dentz static void *hci_cc_skb_pull(struct hci_dev *hdev, struct sk_buff *skb, 63e3f3a1aeSLuiz Augusto von Dentz u16 op, size_t len) 64e3f3a1aeSLuiz Augusto von Dentz { 65e3f3a1aeSLuiz Augusto von Dentz void *data; 66e3f3a1aeSLuiz Augusto von Dentz 67e3f3a1aeSLuiz Augusto von Dentz data = skb_pull_data(skb, len); 68e3f3a1aeSLuiz Augusto von Dentz if (!data) 69e3f3a1aeSLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed Command Complete: 0x%4.4x", op); 70e3f3a1aeSLuiz Augusto von Dentz 71e3f3a1aeSLuiz Augusto von Dentz return data; 72e3f3a1aeSLuiz Augusto von Dentz } 73e3f3a1aeSLuiz Augusto von Dentz 7412cfe417SLuiz Augusto von Dentz static void *hci_le_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb, 7512cfe417SLuiz Augusto von Dentz u8 ev, size_t len) 7612cfe417SLuiz Augusto von Dentz { 7712cfe417SLuiz Augusto von Dentz void *data; 7812cfe417SLuiz Augusto von Dentz 7912cfe417SLuiz Augusto von Dentz data = skb_pull_data(skb, len); 8012cfe417SLuiz Augusto von Dentz if (!data) 8112cfe417SLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed LE Event: 0x%2.2x", ev); 8212cfe417SLuiz Augusto von Dentz 8312cfe417SLuiz Augusto von Dentz return data; 8412cfe417SLuiz Augusto von Dentz } 8512cfe417SLuiz Augusto von Dentz 86c8992cffSLuiz Augusto von Dentz static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data, 87c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 881da177e4SLinus Torvalds { 89c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 90e3f3a1aeSLuiz Augusto von Dentz 91e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 921da177e4SLinus Torvalds 93adf1d692SSonny Sasaka /* It is possible that we receive Inquiry Complete event right 94adf1d692SSonny Sasaka * before we receive Inquiry Cancel Command Complete event, in 95adf1d692SSonny Sasaka * which case the latter event should have status of Command 96adf1d692SSonny Sasaka * Disallowed (0x0c). This should not be treated as error, since 97adf1d692SSonny Sasaka * we actually achieve what Inquiry Cancel wants to achieve, 98adf1d692SSonny Sasaka * which is to end the last Inquiry session. 99adf1d692SSonny Sasaka */ 100e3f3a1aeSLuiz Augusto von Dentz if (rp->status == 0x0c && !test_bit(HCI_INQUIRY, &hdev->flags)) { 101adf1d692SSonny Sasaka bt_dev_warn(hdev, "Ignoring error of Inquiry Cancel command"); 102e3f3a1aeSLuiz Augusto von Dentz rp->status = 0x00; 103adf1d692SSonny Sasaka } 104adf1d692SSonny Sasaka 105e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 106c8992cffSLuiz Augusto von Dentz return rp->status; 1071da177e4SLinus Torvalds 10889352e7dSAndre Guedes clear_bit(HCI_INQUIRY, &hdev->flags); 1094e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */ 1103e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 11189352e7dSAndre Guedes 11250143a43SJohan Hedberg hci_dev_lock(hdev); 113168b8a25SJakub Pawlowski /* Set discovery state to stopped if we're not doing LE active 114168b8a25SJakub Pawlowski * scanning. 115168b8a25SJakub Pawlowski */ 116168b8a25SJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 117168b8a25SJakub Pawlowski hdev->le_scan_type != LE_SCAN_ACTIVE) 11850143a43SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 11950143a43SJohan Hedberg hci_dev_unlock(hdev); 12050143a43SJohan Hedberg 121a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 122c8992cffSLuiz Augusto von Dentz 123c8992cffSLuiz Augusto von Dentz return rp->status; 1241da177e4SLinus Torvalds } 1256bd57416SMarcel Holtmann 126c8992cffSLuiz Augusto von Dentz static u8 hci_cc_periodic_inq(struct hci_dev *hdev, void *data, 127c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1284d93483bSAndre Guedes { 129c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 130ae854a70SAndre Guedes 131e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 132e3f3a1aeSLuiz Augusto von Dentz 133e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 134c8992cffSLuiz Augusto von Dentz return rp->status; 135ae854a70SAndre Guedes 136a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_PERIODIC_INQ); 137c8992cffSLuiz Augusto von Dentz 138c8992cffSLuiz Augusto von Dentz return rp->status; 1394d93483bSAndre Guedes } 1404d93483bSAndre Guedes 141c8992cffSLuiz Augusto von Dentz static u8 hci_cc_exit_periodic_inq(struct hci_dev *hdev, void *data, 142c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1431da177e4SLinus Torvalds { 144c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 145a9de9248SMarcel Holtmann 146e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 147e3f3a1aeSLuiz Augusto von Dentz 148e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 149c8992cffSLuiz Augusto von Dentz return rp->status; 150a9de9248SMarcel Holtmann 151a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ); 152ae854a70SAndre Guedes 153a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 154c8992cffSLuiz Augusto von Dentz 155c8992cffSLuiz Augusto von Dentz return rp->status; 156a9de9248SMarcel Holtmann } 157a9de9248SMarcel Holtmann 158c8992cffSLuiz Augusto von Dentz static u8 hci_cc_remote_name_req_cancel(struct hci_dev *hdev, void *data, 159807deac2SGustavo Padovan struct sk_buff *skb) 160a9de9248SMarcel Holtmann { 161c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 162e3f3a1aeSLuiz Augusto von Dentz 163e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 164c8992cffSLuiz Augusto von Dentz 165c8992cffSLuiz Augusto von Dentz return rp->status; 166a9de9248SMarcel Holtmann } 167a9de9248SMarcel Holtmann 168c8992cffSLuiz Augusto von Dentz static u8 hci_cc_role_discovery(struct hci_dev *hdev, void *data, 169c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 170a9de9248SMarcel Holtmann { 171c8992cffSLuiz Augusto von Dentz struct hci_rp_role_discovery *rp = data; 1721da177e4SLinus Torvalds struct hci_conn *conn; 1731da177e4SLinus Torvalds 174e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1751da177e4SLinus Torvalds 176a9de9248SMarcel Holtmann if (rp->status) 177c8992cffSLuiz Augusto von Dentz return rp->status; 1781da177e4SLinus Torvalds 1791da177e4SLinus Torvalds hci_dev_lock(hdev); 1801da177e4SLinus Torvalds 181a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 18240bef302SJohan Hedberg if (conn) 18340bef302SJohan Hedberg conn->role = rp->role; 1841da177e4SLinus Torvalds 1851da177e4SLinus Torvalds hci_dev_unlock(hdev); 186c8992cffSLuiz Augusto von Dentz 187c8992cffSLuiz Augusto von Dentz return rp->status; 188a9de9248SMarcel Holtmann } 1891da177e4SLinus Torvalds 190c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_link_policy(struct hci_dev *hdev, void *data, 191c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 192e4e8e37cSMarcel Holtmann { 193c8992cffSLuiz Augusto von Dentz struct hci_rp_read_link_policy *rp = data; 194e4e8e37cSMarcel Holtmann struct hci_conn *conn; 195e4e8e37cSMarcel Holtmann 196e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 197e4e8e37cSMarcel Holtmann 198e4e8e37cSMarcel Holtmann if (rp->status) 199c8992cffSLuiz Augusto von Dentz return rp->status; 200e4e8e37cSMarcel Holtmann 201e4e8e37cSMarcel Holtmann hci_dev_lock(hdev); 202e4e8e37cSMarcel Holtmann 203e4e8e37cSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 204e4e8e37cSMarcel Holtmann if (conn) 205e4e8e37cSMarcel Holtmann conn->link_policy = __le16_to_cpu(rp->policy); 206e4e8e37cSMarcel Holtmann 207e4e8e37cSMarcel Holtmann hci_dev_unlock(hdev); 208c8992cffSLuiz Augusto von Dentz 209c8992cffSLuiz Augusto von Dentz return rp->status; 210e4e8e37cSMarcel Holtmann } 211e4e8e37cSMarcel Holtmann 212c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_link_policy(struct hci_dev *hdev, void *data, 213c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 214a9de9248SMarcel Holtmann { 215c8992cffSLuiz Augusto von Dentz struct hci_rp_write_link_policy *rp = data; 216a9de9248SMarcel Holtmann struct hci_conn *conn; 217a9de9248SMarcel Holtmann void *sent; 218a9de9248SMarcel Holtmann 219e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 220a9de9248SMarcel Holtmann 221a9de9248SMarcel Holtmann if (rp->status) 222c8992cffSLuiz Augusto von Dentz return rp->status; 223a9de9248SMarcel Holtmann 224a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY); 22504837f64SMarcel Holtmann if (!sent) 226c8992cffSLuiz Augusto von Dentz return rp->status; 22704837f64SMarcel Holtmann 22804837f64SMarcel Holtmann hci_dev_lock(hdev); 22904837f64SMarcel Holtmann 230a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 231e4e8e37cSMarcel Holtmann if (conn) 23283985319SHarvey Harrison conn->link_policy = get_unaligned_le16(sent + 2); 23304837f64SMarcel Holtmann 23404837f64SMarcel Holtmann hci_dev_unlock(hdev); 235c8992cffSLuiz Augusto von Dentz 236c8992cffSLuiz Augusto von Dentz return rp->status; 2371da177e4SLinus Torvalds } 2381da177e4SLinus Torvalds 239c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_link_policy(struct hci_dev *hdev, void *data, 240807deac2SGustavo Padovan struct sk_buff *skb) 241e4e8e37cSMarcel Holtmann { 242c8992cffSLuiz Augusto von Dentz struct hci_rp_read_def_link_policy *rp = data; 243e3f3a1aeSLuiz Augusto von Dentz 244e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 245e4e8e37cSMarcel Holtmann 246e4e8e37cSMarcel Holtmann if (rp->status) 247c8992cffSLuiz Augusto von Dentz return rp->status; 248e4e8e37cSMarcel Holtmann 249e4e8e37cSMarcel Holtmann hdev->link_policy = __le16_to_cpu(rp->policy); 250c8992cffSLuiz Augusto von Dentz 251c8992cffSLuiz Augusto von Dentz return rp->status; 252e4e8e37cSMarcel Holtmann } 253e4e8e37cSMarcel Holtmann 254c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_link_policy(struct hci_dev *hdev, void *data, 255807deac2SGustavo Padovan struct sk_buff *skb) 256e4e8e37cSMarcel Holtmann { 257c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 258e4e8e37cSMarcel Holtmann void *sent; 259e4e8e37cSMarcel Holtmann 260e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 261e3f3a1aeSLuiz Augusto von Dentz 262e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 263c8992cffSLuiz Augusto von Dentz return rp->status; 26445296acdSMarcel Holtmann 265e4e8e37cSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); 266e4e8e37cSMarcel Holtmann if (!sent) 267c8992cffSLuiz Augusto von Dentz return rp->status; 268e4e8e37cSMarcel Holtmann 269e4e8e37cSMarcel Holtmann hdev->link_policy = get_unaligned_le16(sent); 270c8992cffSLuiz Augusto von Dentz 271c8992cffSLuiz Augusto von Dentz return rp->status; 272e4e8e37cSMarcel Holtmann } 273e4e8e37cSMarcel Holtmann 274c8992cffSLuiz Augusto von Dentz static u8 hci_cc_reset(struct hci_dev *hdev, void *data, struct sk_buff *skb) 2751da177e4SLinus Torvalds { 276c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 277e3f3a1aeSLuiz Augusto von Dentz 278e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 279a9de9248SMarcel Holtmann 28010572132SGustavo F. Padovan clear_bit(HCI_RESET, &hdev->flags); 28110572132SGustavo F. Padovan 282e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 283c8992cffSLuiz Augusto von Dentz return rp->status; 2848761f9d6SMarcel Holtmann 285a297e97cSJohan Hedberg /* Reset all non-persistent flags */ 286eacb44dfSMarcel Holtmann hci_dev_clear_volatile_flags(hdev); 28769775ff6SAndre Guedes 28839c5d970SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 28939c5d970SJohan Hedberg 290bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 291bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2923f0f524bSJohan Hedberg 2933f0f524bSJohan Hedberg memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); 2943f0f524bSJohan Hedberg hdev->adv_data_len = 0; 295f8e808bdSMarcel Holtmann 296f8e808bdSMarcel Holtmann memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data)); 297f8e808bdSMarcel Holtmann hdev->scan_rsp_data_len = 0; 29806f5b778SMarcel Holtmann 299533553f8SMarcel Holtmann hdev->le_scan_type = LE_SCAN_PASSIVE; 300533553f8SMarcel Holtmann 30106f5b778SMarcel Holtmann hdev->ssp_debug_mode = 0; 302a4d5504dSMarcel Holtmann 3033d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->le_accept_list); 304cfdb0c2dSAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 305c8992cffSLuiz Augusto von Dentz 306c8992cffSLuiz Augusto von Dentz return rp->status; 307a9de9248SMarcel Holtmann } 308a9de9248SMarcel Holtmann 309c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_stored_link_key(struct hci_dev *hdev, void *data, 310c2f0f979SMarcel Holtmann struct sk_buff *skb) 311c2f0f979SMarcel Holtmann { 312c8992cffSLuiz Augusto von Dentz struct hci_rp_read_stored_link_key *rp = data; 313c2f0f979SMarcel Holtmann struct hci_cp_read_stored_link_key *sent; 314c2f0f979SMarcel Holtmann 315e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 316c2f0f979SMarcel Holtmann 317c2f0f979SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_READ_STORED_LINK_KEY); 318c2f0f979SMarcel Holtmann if (!sent) 319c8992cffSLuiz Augusto von Dentz return rp->status; 320c2f0f979SMarcel Holtmann 321c2f0f979SMarcel Holtmann if (!rp->status && sent->read_all == 0x01) { 322e88422bcSLuiz Augusto von Dentz hdev->stored_max_keys = le16_to_cpu(rp->max_keys); 323e88422bcSLuiz Augusto von Dentz hdev->stored_num_keys = le16_to_cpu(rp->num_keys); 324c2f0f979SMarcel Holtmann } 325c8992cffSLuiz Augusto von Dentz 326c8992cffSLuiz Augusto von Dentz return rp->status; 327c2f0f979SMarcel Holtmann } 328c2f0f979SMarcel Holtmann 329c8992cffSLuiz Augusto von Dentz static u8 hci_cc_delete_stored_link_key(struct hci_dev *hdev, void *data, 330a9366120SMarcel Holtmann struct sk_buff *skb) 331a9366120SMarcel Holtmann { 332c8992cffSLuiz Augusto von Dentz struct hci_rp_delete_stored_link_key *rp = data; 333889f0346SLuiz Augusto von Dentz u16 num_keys; 334e3f3a1aeSLuiz Augusto von Dentz 335e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 336a9366120SMarcel Holtmann 337a9366120SMarcel Holtmann if (rp->status) 338c8992cffSLuiz Augusto von Dentz return rp->status; 339a9366120SMarcel Holtmann 340889f0346SLuiz Augusto von Dentz num_keys = le16_to_cpu(rp->num_keys); 341889f0346SLuiz Augusto von Dentz 342889f0346SLuiz Augusto von Dentz if (num_keys <= hdev->stored_num_keys) 343889f0346SLuiz Augusto von Dentz hdev->stored_num_keys -= num_keys; 344a9366120SMarcel Holtmann else 345a9366120SMarcel Holtmann hdev->stored_num_keys = 0; 346c8992cffSLuiz Augusto von Dentz 347c8992cffSLuiz Augusto von Dentz return rp->status; 348a9366120SMarcel Holtmann } 349a9366120SMarcel Holtmann 350c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_local_name(struct hci_dev *hdev, void *data, 351c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 352a9de9248SMarcel Holtmann { 353c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 3541da177e4SLinus Torvalds void *sent; 3551da177e4SLinus Torvalds 356e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 3571da177e4SLinus Torvalds 358a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); 3591da177e4SLinus Torvalds if (!sent) 360c8992cffSLuiz Augusto von Dentz return rp->status; 3611da177e4SLinus Torvalds 36256e5cb86SJohan Hedberg hci_dev_lock(hdev); 36356e5cb86SJohan Hedberg 364d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 365e3f3a1aeSLuiz Augusto von Dentz mgmt_set_local_name_complete(hdev, sent, rp->status); 366e3f3a1aeSLuiz Augusto von Dentz else if (!rp->status) 36728cc7bdeSJohan Hedberg memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 368f51d5b24SJohan Hedberg 36956e5cb86SJohan Hedberg hci_dev_unlock(hdev); 370c8992cffSLuiz Augusto von Dentz 371c8992cffSLuiz Augusto von Dentz return rp->status; 372a9de9248SMarcel Holtmann } 373a9de9248SMarcel Holtmann 374c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_name(struct hci_dev *hdev, void *data, 375c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 376a9de9248SMarcel Holtmann { 377c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_name *rp = data; 378e3f3a1aeSLuiz Augusto von Dentz 379e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 380a9de9248SMarcel Holtmann 381a9de9248SMarcel Holtmann if (rp->status) 382c8992cffSLuiz Augusto von Dentz return rp->status; 383a9de9248SMarcel Holtmann 384d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 385d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) 3861f6c6378SJohan Hedberg memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); 387c8992cffSLuiz Augusto von Dentz 388c8992cffSLuiz Augusto von Dentz return rp->status; 389a9de9248SMarcel Holtmann } 390a9de9248SMarcel Holtmann 391c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_enable(struct hci_dev *hdev, void *data, 392c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 393a9de9248SMarcel Holtmann { 394c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 395a9de9248SMarcel Holtmann void *sent; 396a9de9248SMarcel Holtmann 397e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 398a9de9248SMarcel Holtmann 399a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); 400a9de9248SMarcel Holtmann if (!sent) 401c8992cffSLuiz Augusto von Dentz return rp->status; 4021da177e4SLinus Torvalds 4035c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 4045c1a4c8fSJaganath Kanakkassery 405e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) { 406a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 407a9de9248SMarcel Holtmann 4081da177e4SLinus Torvalds if (param == AUTH_ENABLED) 4091da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags); 4101da177e4SLinus Torvalds else 4111da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags); 4121da177e4SLinus Torvalds } 413a9de9248SMarcel Holtmann 414d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 415e3f3a1aeSLuiz Augusto von Dentz mgmt_auth_enable_complete(hdev, rp->status); 4165c1a4c8fSJaganath Kanakkassery 4175c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 418c8992cffSLuiz Augusto von Dentz 419c8992cffSLuiz Augusto von Dentz return rp->status; 420a9de9248SMarcel Holtmann } 4211da177e4SLinus Torvalds 422c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_encrypt_mode(struct hci_dev *hdev, void *data, 423c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 424a9de9248SMarcel Holtmann { 425c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 42645296acdSMarcel Holtmann __u8 param; 427a9de9248SMarcel Holtmann void *sent; 428a9de9248SMarcel Holtmann 429e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 430e3f3a1aeSLuiz Augusto von Dentz 431e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 432c8992cffSLuiz Augusto von Dentz return rp->status; 43345296acdSMarcel Holtmann 434a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); 4351da177e4SLinus Torvalds if (!sent) 436c8992cffSLuiz Augusto von Dentz return rp->status; 4371da177e4SLinus Torvalds 43845296acdSMarcel Holtmann param = *((__u8 *) sent); 439a9de9248SMarcel Holtmann 4401da177e4SLinus Torvalds if (param) 4411da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags); 4421da177e4SLinus Torvalds else 4431da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags); 444c8992cffSLuiz Augusto von Dentz 445c8992cffSLuiz Augusto von Dentz return rp->status; 4461da177e4SLinus Torvalds } 4471da177e4SLinus Torvalds 448c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_scan_enable(struct hci_dev *hdev, void *data, 449c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 450a9de9248SMarcel Holtmann { 451c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 45245296acdSMarcel Holtmann __u8 param; 453a9de9248SMarcel Holtmann void *sent; 4541da177e4SLinus Torvalds 455e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 456a9de9248SMarcel Holtmann 457a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); 4581da177e4SLinus Torvalds if (!sent) 459c8992cffSLuiz Augusto von Dentz return rp->status; 4601da177e4SLinus Torvalds 46136f7fc7eSJohan Hedberg param = *((__u8 *) sent); 462a9de9248SMarcel Holtmann 46356e5cb86SJohan Hedberg hci_dev_lock(hdev); 46456e5cb86SJohan Hedberg 465e3f3a1aeSLuiz Augusto von Dentz if (rp->status) { 4662d7cee58SJohan Hedberg hdev->discov_timeout = 0; 4672d7cee58SJohan Hedberg goto done; 4682d7cee58SJohan Hedberg } 4692d7cee58SJohan Hedberg 470bc6d2d04SJohan Hedberg if (param & SCAN_INQUIRY) 4711da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags); 472bc6d2d04SJohan Hedberg else 473bc6d2d04SJohan Hedberg clear_bit(HCI_ISCAN, &hdev->flags); 4741da177e4SLinus Torvalds 475031547d8SJohan Hedberg if (param & SCAN_PAGE) 4761da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags); 477bc6d2d04SJohan Hedberg else 478204e3990SJohan Hedberg clear_bit(HCI_PSCAN, &hdev->flags); 479a9de9248SMarcel Holtmann 48036f7fc7eSJohan Hedberg done: 48156e5cb86SJohan Hedberg hci_dev_unlock(hdev); 482c8992cffSLuiz Augusto von Dentz 483c8992cffSLuiz Augusto von Dentz return rp->status; 4841da177e4SLinus Torvalds } 4851da177e4SLinus Torvalds 486c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_event_filter(struct hci_dev *hdev, void *data, 487c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 488e5b0ad69SAbhishek Pandit-Subedi { 489c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 490e5b0ad69SAbhishek Pandit-Subedi struct hci_cp_set_event_filter *cp; 491e5b0ad69SAbhishek Pandit-Subedi void *sent; 492e5b0ad69SAbhishek Pandit-Subedi 493e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 494e3f3a1aeSLuiz Augusto von Dentz 495e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 496c8992cffSLuiz Augusto von Dentz return rp->status; 497e5b0ad69SAbhishek Pandit-Subedi 498e5b0ad69SAbhishek Pandit-Subedi sent = hci_sent_cmd_data(hdev, HCI_OP_SET_EVENT_FLT); 499e5b0ad69SAbhishek Pandit-Subedi if (!sent) 500c8992cffSLuiz Augusto von Dentz return rp->status; 501e5b0ad69SAbhishek Pandit-Subedi 502e5b0ad69SAbhishek Pandit-Subedi cp = (struct hci_cp_set_event_filter *)sent; 503e5b0ad69SAbhishek Pandit-Subedi 504e5b0ad69SAbhishek Pandit-Subedi if (cp->flt_type == HCI_FLT_CLEAR_ALL) 505e5b0ad69SAbhishek Pandit-Subedi hci_dev_clear_flag(hdev, HCI_EVENT_FILTER_CONFIGURED); 506e5b0ad69SAbhishek Pandit-Subedi else 507e5b0ad69SAbhishek Pandit-Subedi hci_dev_set_flag(hdev, HCI_EVENT_FILTER_CONFIGURED); 508c8992cffSLuiz Augusto von Dentz 509c8992cffSLuiz Augusto von Dentz return rp->status; 510e5b0ad69SAbhishek Pandit-Subedi } 511e5b0ad69SAbhishek Pandit-Subedi 512c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_class_of_dev(struct hci_dev *hdev, void *data, 513c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 514a9de9248SMarcel Holtmann { 515c8992cffSLuiz Augusto von Dentz struct hci_rp_read_class_of_dev *rp = data; 516e3f3a1aeSLuiz Augusto von Dentz 5177ee2ba3dSArnd Bergmann if (WARN_ON(!hdev)) 5187ee2ba3dSArnd Bergmann return HCI_ERROR_UNSPECIFIED; 5197ee2ba3dSArnd Bergmann 520e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 521a9de9248SMarcel Holtmann 522a9de9248SMarcel Holtmann if (rp->status) 523c8992cffSLuiz Augusto von Dentz return rp->status; 524a9de9248SMarcel Holtmann 525a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3); 526a9de9248SMarcel Holtmann 527e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "class 0x%.2x%.2x%.2x", hdev->dev_class[2], 528e3f3a1aeSLuiz Augusto von Dentz hdev->dev_class[1], hdev->dev_class[0]); 529c8992cffSLuiz Augusto von Dentz 530c8992cffSLuiz Augusto von Dentz return rp->status; 531a9de9248SMarcel Holtmann } 532a9de9248SMarcel Holtmann 533c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_class_of_dev(struct hci_dev *hdev, void *data, 534c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 535a9de9248SMarcel Holtmann { 536c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 537a9de9248SMarcel Holtmann void *sent; 538a9de9248SMarcel Holtmann 539e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 540a9de9248SMarcel Holtmann 541a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); 542a9de9248SMarcel Holtmann if (!sent) 543c8992cffSLuiz Augusto von Dentz return rp->status; 544a9de9248SMarcel Holtmann 5457f9a903cSMarcel Holtmann hci_dev_lock(hdev); 5467f9a903cSMarcel Holtmann 547e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) 548a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3); 5497f9a903cSMarcel Holtmann 550d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 551e3f3a1aeSLuiz Augusto von Dentz mgmt_set_class_of_dev_complete(hdev, sent, rp->status); 5527f9a903cSMarcel Holtmann 5537f9a903cSMarcel Holtmann hci_dev_unlock(hdev); 554c8992cffSLuiz Augusto von Dentz 555c8992cffSLuiz Augusto von Dentz return rp->status; 556a9de9248SMarcel Holtmann } 557a9de9248SMarcel Holtmann 558c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_voice_setting(struct hci_dev *hdev, void *data, 559c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 560a9de9248SMarcel Holtmann { 561c8992cffSLuiz Augusto von Dentz struct hci_rp_read_voice_setting *rp = data; 562a9de9248SMarcel Holtmann __u16 setting; 563a9de9248SMarcel Holtmann 564e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 565a9de9248SMarcel Holtmann 566a9de9248SMarcel Holtmann if (rp->status) 567c8992cffSLuiz Augusto von Dentz return rp->status; 568a9de9248SMarcel Holtmann 569a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting); 570a9de9248SMarcel Holtmann 571a9de9248SMarcel Holtmann if (hdev->voice_setting == setting) 572c8992cffSLuiz Augusto von Dentz return rp->status; 573a9de9248SMarcel Holtmann 574a9de9248SMarcel Holtmann hdev->voice_setting = setting; 575a9de9248SMarcel Holtmann 576e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting); 577a9de9248SMarcel Holtmann 5783c54711cSGustavo F. Padovan if (hdev->notify) 579a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 580c8992cffSLuiz Augusto von Dentz 581c8992cffSLuiz Augusto von Dentz return rp->status; 582a9de9248SMarcel Holtmann } 583a9de9248SMarcel Holtmann 584c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_voice_setting(struct hci_dev *hdev, void *data, 5858fc9ced3SGustavo Padovan struct sk_buff *skb) 586a9de9248SMarcel Holtmann { 587c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 588f383f275SMarcel Holtmann __u16 setting; 589a9de9248SMarcel Holtmann void *sent; 590a9de9248SMarcel Holtmann 591e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 592e3f3a1aeSLuiz Augusto von Dentz 593e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 594c8992cffSLuiz Augusto von Dentz return rp->status; 595f383f275SMarcel Holtmann 596a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); 597a9de9248SMarcel Holtmann if (!sent) 598c8992cffSLuiz Augusto von Dentz return rp->status; 599a9de9248SMarcel Holtmann 600f383f275SMarcel Holtmann setting = get_unaligned_le16(sent); 6011da177e4SLinus Torvalds 602f383f275SMarcel Holtmann if (hdev->voice_setting == setting) 603c8992cffSLuiz Augusto von Dentz return rp->status; 604f383f275SMarcel Holtmann 6051da177e4SLinus Torvalds hdev->voice_setting = setting; 6061da177e4SLinus Torvalds 607e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting); 6081da177e4SLinus Torvalds 6093c54711cSGustavo F. Padovan if (hdev->notify) 6101da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 611c8992cffSLuiz Augusto von Dentz 612c8992cffSLuiz Augusto von Dentz return rp->status; 6131da177e4SLinus Torvalds } 6141da177e4SLinus Torvalds 615c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_num_supported_iac(struct hci_dev *hdev, void *data, 616b4cb9fb2SMarcel Holtmann struct sk_buff *skb) 617b4cb9fb2SMarcel Holtmann { 618c8992cffSLuiz Augusto von Dentz struct hci_rp_read_num_supported_iac *rp = data; 619e3f3a1aeSLuiz Augusto von Dentz 620e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 621b4cb9fb2SMarcel Holtmann 622b4cb9fb2SMarcel Holtmann if (rp->status) 623c8992cffSLuiz Augusto von Dentz return rp->status; 624b4cb9fb2SMarcel Holtmann 625b4cb9fb2SMarcel Holtmann hdev->num_iac = rp->num_iac; 626b4cb9fb2SMarcel Holtmann 627e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "num iac %d", hdev->num_iac); 628c8992cffSLuiz Augusto von Dentz 629c8992cffSLuiz Augusto von Dentz return rp->status; 630b4cb9fb2SMarcel Holtmann } 631b4cb9fb2SMarcel Holtmann 632c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_mode(struct hci_dev *hdev, void *data, 633c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 634333140b5SMarcel Holtmann { 635c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 6365ed8eb2fSJohan Hedberg struct hci_cp_write_ssp_mode *sent; 637333140b5SMarcel Holtmann 638e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 639333140b5SMarcel Holtmann 640333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); 641333140b5SMarcel Holtmann if (!sent) 642c8992cffSLuiz Augusto von Dentz return rp->status; 643333140b5SMarcel Holtmann 6445c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 6455c1a4c8fSJaganath Kanakkassery 646e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) { 6475ed8eb2fSJohan Hedberg if (sent->mode) 648cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_SSP; 6495ed8eb2fSJohan Hedberg else 650cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_SSP; 6515ed8eb2fSJohan Hedberg } 6525ed8eb2fSJohan Hedberg 653e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) { 6545ed8eb2fSJohan Hedberg if (sent->mode) 655a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SSP_ENABLED); 65684bde9d6SJohan Hedberg else 657a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SSP_ENABLED); 658c0ecddc2SJohan Hedberg } 6595c1a4c8fSJaganath Kanakkassery 6605c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 661c8992cffSLuiz Augusto von Dentz 662c8992cffSLuiz Augusto von Dentz return rp->status; 663333140b5SMarcel Holtmann } 664333140b5SMarcel Holtmann 665c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_sc_support(struct hci_dev *hdev, void *data, 666c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 667eac83dc6SMarcel Holtmann { 668c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 669eac83dc6SMarcel Holtmann struct hci_cp_write_sc_support *sent; 670eac83dc6SMarcel Holtmann 671e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 672eac83dc6SMarcel Holtmann 673eac83dc6SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT); 674eac83dc6SMarcel Holtmann if (!sent) 675c8992cffSLuiz Augusto von Dentz return rp->status; 676eac83dc6SMarcel Holtmann 6775c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 6785c1a4c8fSJaganath Kanakkassery 679e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) { 680eac83dc6SMarcel Holtmann if (sent->support) 681eac83dc6SMarcel Holtmann hdev->features[1][0] |= LMP_HOST_SC; 682eac83dc6SMarcel Holtmann else 683eac83dc6SMarcel Holtmann hdev->features[1][0] &= ~LMP_HOST_SC; 684eac83dc6SMarcel Holtmann } 685eac83dc6SMarcel Holtmann 686e3f3a1aeSLuiz Augusto von Dentz if (!hci_dev_test_flag(hdev, HCI_MGMT) && !rp->status) { 687eac83dc6SMarcel Holtmann if (sent->support) 688a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SC_ENABLED); 689eac83dc6SMarcel Holtmann else 690a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SC_ENABLED); 691eac83dc6SMarcel Holtmann } 6925c1a4c8fSJaganath Kanakkassery 6935c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 694c8992cffSLuiz Augusto von Dentz 695c8992cffSLuiz Augusto von Dentz return rp->status; 696eac83dc6SMarcel Holtmann } 697eac83dc6SMarcel Holtmann 698c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_version(struct hci_dev *hdev, void *data, 699c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 700a9de9248SMarcel Holtmann { 701c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_version *rp = data; 702e3f3a1aeSLuiz Augusto von Dentz 703e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 7041143e5a6SMarcel Holtmann 705a9de9248SMarcel Holtmann if (rp->status) 706c8992cffSLuiz Augusto von Dentz return rp->status; 7071143e5a6SMarcel Holtmann 708d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 709d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) { 710a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver; 711e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 712d5859e22SJohan Hedberg hdev->lmp_ver = rp->lmp_ver; 713e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer); 714d5859e22SJohan Hedberg hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); 7150d5551f5SMarcel Holtmann } 716c8992cffSLuiz Augusto von Dentz 717c8992cffSLuiz Augusto von Dentz return rp->status; 718d5859e22SJohan Hedberg } 719d5859e22SJohan Hedberg 720278d933eSBrian Gix static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data, 721278d933eSBrian Gix struct sk_buff *skb) 722278d933eSBrian Gix { 723278d933eSBrian Gix struct hci_rp_read_enc_key_size *rp = data; 724278d933eSBrian Gix struct hci_conn *conn; 725278d933eSBrian Gix u16 handle; 726278d933eSBrian Gix u8 status = rp->status; 727278d933eSBrian Gix 728278d933eSBrian Gix bt_dev_dbg(hdev, "status 0x%2.2x", status); 729278d933eSBrian Gix 730278d933eSBrian Gix handle = le16_to_cpu(rp->handle); 731278d933eSBrian Gix 732278d933eSBrian Gix hci_dev_lock(hdev); 733278d933eSBrian Gix 734278d933eSBrian Gix conn = hci_conn_hash_lookup_handle(hdev, handle); 735278d933eSBrian Gix if (!conn) { 736278d933eSBrian Gix status = 0xFF; 737278d933eSBrian Gix goto done; 738278d933eSBrian Gix } 739278d933eSBrian Gix 740278d933eSBrian Gix /* While unexpected, the read_enc_key_size command may fail. The most 741278d933eSBrian Gix * secure approach is to then assume the key size is 0 to force a 742278d933eSBrian Gix * disconnection. 743278d933eSBrian Gix */ 744278d933eSBrian Gix if (status) { 745278d933eSBrian Gix bt_dev_err(hdev, "failed to read key size for handle %u", 746278d933eSBrian Gix handle); 747278d933eSBrian Gix conn->enc_key_size = 0; 748278d933eSBrian Gix } else { 749278d933eSBrian Gix conn->enc_key_size = rp->key_size; 750278d933eSBrian Gix status = 0; 75134c032a7SAlex Lu 75234c032a7SAlex Lu if (conn->enc_key_size < hdev->min_enc_key_size) { 75334c032a7SAlex Lu /* As slave role, the conn->state has been set to 75434c032a7SAlex Lu * BT_CONNECTED and l2cap conn req might not be received 75534c032a7SAlex Lu * yet, at this moment the l2cap layer almost does 75634c032a7SAlex Lu * nothing with the non-zero status. 75734c032a7SAlex Lu * So we also clear encrypt related bits, and then the 75834c032a7SAlex Lu * handler of l2cap conn req will get the right secure 75934c032a7SAlex Lu * state at a later time. 76034c032a7SAlex Lu */ 76134c032a7SAlex Lu status = HCI_ERROR_AUTH_FAILURE; 76234c032a7SAlex Lu clear_bit(HCI_CONN_ENCRYPT, &conn->flags); 76334c032a7SAlex Lu clear_bit(HCI_CONN_AES_CCM, &conn->flags); 76434c032a7SAlex Lu } 765278d933eSBrian Gix } 766278d933eSBrian Gix 76734c032a7SAlex Lu hci_encrypt_cfm(conn, status); 768278d933eSBrian Gix 769278d933eSBrian Gix done: 770278d933eSBrian Gix hci_dev_unlock(hdev); 771278d933eSBrian Gix 772278d933eSBrian Gix return status; 773278d933eSBrian Gix } 774278d933eSBrian Gix 775c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_commands(struct hci_dev *hdev, void *data, 7768fc9ced3SGustavo Padovan struct sk_buff *skb) 777a9de9248SMarcel Holtmann { 778c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_commands *rp = data; 779e3f3a1aeSLuiz Augusto von Dentz 780e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 781a9de9248SMarcel Holtmann 7826a070e6eSMarcel Holtmann if (rp->status) 783c8992cffSLuiz Augusto von Dentz return rp->status; 7846a070e6eSMarcel Holtmann 785d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 786d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) 787a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 788c8992cffSLuiz Augusto von Dentz 789c8992cffSLuiz Augusto von Dentz return rp->status; 790a9de9248SMarcel Holtmann } 791a9de9248SMarcel Holtmann 792c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_auth_payload_timeout(struct hci_dev *hdev, void *data, 793302975cbSSpoorthi Ravishankar Koppad struct sk_buff *skb) 794302975cbSSpoorthi Ravishankar Koppad { 795c8992cffSLuiz Augusto von Dentz struct hci_rp_read_auth_payload_to *rp = data; 796302975cbSSpoorthi Ravishankar Koppad struct hci_conn *conn; 797302975cbSSpoorthi Ravishankar Koppad 798e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 799302975cbSSpoorthi Ravishankar Koppad 800302975cbSSpoorthi Ravishankar Koppad if (rp->status) 801c8992cffSLuiz Augusto von Dentz return rp->status; 802302975cbSSpoorthi Ravishankar Koppad 803302975cbSSpoorthi Ravishankar Koppad hci_dev_lock(hdev); 804302975cbSSpoorthi Ravishankar Koppad 805302975cbSSpoorthi Ravishankar Koppad conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 806302975cbSSpoorthi Ravishankar Koppad if (conn) 807302975cbSSpoorthi Ravishankar Koppad conn->auth_payload_timeout = __le16_to_cpu(rp->timeout); 808302975cbSSpoorthi Ravishankar Koppad 809302975cbSSpoorthi Ravishankar Koppad hci_dev_unlock(hdev); 810c8992cffSLuiz Augusto von Dentz 811c8992cffSLuiz Augusto von Dentz return rp->status; 812302975cbSSpoorthi Ravishankar Koppad } 813302975cbSSpoorthi Ravishankar Koppad 814c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_payload_timeout(struct hci_dev *hdev, void *data, 815302975cbSSpoorthi Ravishankar Koppad struct sk_buff *skb) 816302975cbSSpoorthi Ravishankar Koppad { 817c8992cffSLuiz Augusto von Dentz struct hci_rp_write_auth_payload_to *rp = data; 818302975cbSSpoorthi Ravishankar Koppad struct hci_conn *conn; 819302975cbSSpoorthi Ravishankar Koppad void *sent; 820302975cbSSpoorthi Ravishankar Koppad 821e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 822302975cbSSpoorthi Ravishankar Koppad 823302975cbSSpoorthi Ravishankar Koppad sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO); 824302975cbSSpoorthi Ravishankar Koppad if (!sent) 825c8992cffSLuiz Augusto von Dentz return rp->status; 826302975cbSSpoorthi Ravishankar Koppad 827302975cbSSpoorthi Ravishankar Koppad hci_dev_lock(hdev); 828302975cbSSpoorthi Ravishankar Koppad 829302975cbSSpoorthi Ravishankar Koppad conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 8307aca0ac4SLuiz Augusto von Dentz if (!conn) { 8317aca0ac4SLuiz Augusto von Dentz rp->status = 0xff; 8327aca0ac4SLuiz Augusto von Dentz goto unlock; 8337aca0ac4SLuiz Augusto von Dentz } 8347aca0ac4SLuiz Augusto von Dentz 8357aca0ac4SLuiz Augusto von Dentz if (!rp->status) 836302975cbSSpoorthi Ravishankar Koppad conn->auth_payload_timeout = get_unaligned_le16(sent + 2); 837302975cbSSpoorthi Ravishankar Koppad 8387aca0ac4SLuiz Augusto von Dentz unlock: 839302975cbSSpoorthi Ravishankar Koppad hci_dev_unlock(hdev); 840c8992cffSLuiz Augusto von Dentz 841c8992cffSLuiz Augusto von Dentz return rp->status; 842302975cbSSpoorthi Ravishankar Koppad } 843302975cbSSpoorthi Ravishankar Koppad 844c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_features(struct hci_dev *hdev, void *data, 8458fc9ced3SGustavo Padovan struct sk_buff *skb) 846a9de9248SMarcel Holtmann { 847c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_features *rp = data; 848e3f3a1aeSLuiz Augusto von Dentz 849e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 850a9de9248SMarcel Holtmann 851a9de9248SMarcel Holtmann if (rp->status) 852c8992cffSLuiz Augusto von Dentz return rp->status; 853a9de9248SMarcel Holtmann 854a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8); 8551da177e4SLinus Torvalds 8561da177e4SLinus Torvalds /* Adjust default settings according to features 8571da177e4SLinus Torvalds * supported by device. */ 858a9de9248SMarcel Holtmann 859cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_3SLOT) 8601da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 8611da177e4SLinus Torvalds 862cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_5SLOT) 8631da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 8641da177e4SLinus Torvalds 865cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV2) { 8661da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2); 8675b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2); 8685b7f9909SMarcel Holtmann } 8691da177e4SLinus Torvalds 870cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV3) { 8711da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3); 8725b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3); 8735b7f9909SMarcel Holtmann } 8745b7f9909SMarcel Holtmann 87545db810fSAndre Guedes if (lmp_esco_capable(hdev)) 8765b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3); 8775b7f9909SMarcel Holtmann 878cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV4) 8795b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4); 8805b7f9909SMarcel Holtmann 881cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV5) 8825b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5); 8831da177e4SLinus Torvalds 884cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_2M) 885efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3); 886efc7688bSMarcel Holtmann 887cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_3M) 888efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3); 889efc7688bSMarcel Holtmann 890cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_3S_ESCO) 891efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 892c8992cffSLuiz Augusto von Dentz 893c8992cffSLuiz Augusto von Dentz return rp->status; 8941da177e4SLinus Torvalds } 8951da177e4SLinus Torvalds 896c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_ext_features(struct hci_dev *hdev, void *data, 897971e3a4bSAndre Guedes struct sk_buff *skb) 898971e3a4bSAndre Guedes { 899c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_ext_features *rp = data; 900e3f3a1aeSLuiz Augusto von Dentz 901e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 902971e3a4bSAndre Guedes 903971e3a4bSAndre Guedes if (rp->status) 904c8992cffSLuiz Augusto von Dentz return rp->status; 905971e3a4bSAndre Guedes 9068194f1efSVasily Khoruzhick if (hdev->max_page < rp->max_page) { 9078194f1efSVasily Khoruzhick if (test_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2, 9088194f1efSVasily Khoruzhick &hdev->quirks)) 9098194f1efSVasily Khoruzhick bt_dev_warn(hdev, "broken local ext features page 2"); 9108194f1efSVasily Khoruzhick else 911d2c5d77fSJohan Hedberg hdev->max_page = rp->max_page; 9128194f1efSVasily Khoruzhick } 913d2c5d77fSJohan Hedberg 914cad718edSJohan Hedberg if (rp->page < HCI_MAX_PAGES) 915cad718edSJohan Hedberg memcpy(hdev->features[rp->page], rp->features, 8); 916c8992cffSLuiz Augusto von Dentz 917c8992cffSLuiz Augusto von Dentz return rp->status; 918971e3a4bSAndre Guedes } 919971e3a4bSAndre Guedes 920c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_flow_control_mode(struct hci_dev *hdev, void *data, 9211e89cffbSAndrei Emeltchenko struct sk_buff *skb) 9221e89cffbSAndrei Emeltchenko { 923c8992cffSLuiz Augusto von Dentz struct hci_rp_read_flow_control_mode *rp = data; 924e3f3a1aeSLuiz Augusto von Dentz 925e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 9261e89cffbSAndrei Emeltchenko 92745296acdSMarcel Holtmann if (rp->status) 928c8992cffSLuiz Augusto von Dentz return rp->status; 92945296acdSMarcel Holtmann 9301e89cffbSAndrei Emeltchenko hdev->flow_ctl_mode = rp->mode; 931c8992cffSLuiz Augusto von Dentz 932c8992cffSLuiz Augusto von Dentz return rp->status; 9331e89cffbSAndrei Emeltchenko } 9341e89cffbSAndrei Emeltchenko 935c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_buffer_size(struct hci_dev *hdev, void *data, 936c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 937a9de9248SMarcel Holtmann { 938c8992cffSLuiz Augusto von Dentz struct hci_rp_read_buffer_size *rp = data; 939e3f3a1aeSLuiz Augusto von Dentz 940e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 941a9de9248SMarcel Holtmann 942a9de9248SMarcel Holtmann if (rp->status) 943c8992cffSLuiz Augusto von Dentz return rp->status; 944a9de9248SMarcel Holtmann 945a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu); 946a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu; 947a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt); 948a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt); 949da1f5198SMarcel Holtmann 950da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { 951da1f5198SMarcel Holtmann hdev->sco_mtu = 64; 952da1f5198SMarcel Holtmann hdev->sco_pkts = 8; 953da1f5198SMarcel Holtmann } 954da1f5198SMarcel Holtmann 955da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts; 956da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 9571da177e4SLinus Torvalds 958807deac2SGustavo Padovan BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, 959807deac2SGustavo Padovan hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts); 960c8992cffSLuiz Augusto von Dentz 961c8992cffSLuiz Augusto von Dentz return rp->status; 9621da177e4SLinus Torvalds } 9631da177e4SLinus Torvalds 964c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_bd_addr(struct hci_dev *hdev, void *data, 965c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 966a9de9248SMarcel Holtmann { 967c8992cffSLuiz Augusto von Dentz struct hci_rp_read_bd_addr *rp = data; 968e3f3a1aeSLuiz Augusto von Dentz 969e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 970a9de9248SMarcel Holtmann 971e30d3f5fSMarcel Holtmann if (rp->status) 972c8992cffSLuiz Augusto von Dentz return rp->status; 973e30d3f5fSMarcel Holtmann 974e30d3f5fSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 975a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr); 976e30d3f5fSMarcel Holtmann 977d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 978e30d3f5fSMarcel Holtmann bacpy(&hdev->setup_addr, &rp->bdaddr); 979c8992cffSLuiz Augusto von Dentz 980c8992cffSLuiz Augusto von Dentz return rp->status; 98123bb5763SJohan Hedberg } 98223bb5763SJohan Hedberg 983c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_pairing_opts(struct hci_dev *hdev, void *data, 984a4790360SMarcel Holtmann struct sk_buff *skb) 985a4790360SMarcel Holtmann { 986c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_pairing_opts *rp = data; 987e3f3a1aeSLuiz Augusto von Dentz 988e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 989a4790360SMarcel Holtmann 990a4790360SMarcel Holtmann if (rp->status) 991c8992cffSLuiz Augusto von Dentz return rp->status; 992a4790360SMarcel Holtmann 993a4790360SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 994a4790360SMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) { 995a4790360SMarcel Holtmann hdev->pairing_opts = rp->pairing_opts; 996a4790360SMarcel Holtmann hdev->max_enc_key_size = rp->max_key_size; 997a4790360SMarcel Holtmann } 998c8992cffSLuiz Augusto von Dentz 999c8992cffSLuiz Augusto von Dentz return rp->status; 1000a4790360SMarcel Holtmann } 1001a4790360SMarcel Holtmann 1002c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_activity(struct hci_dev *hdev, void *data, 1003f332ec66SJohan Hedberg struct sk_buff *skb) 1004f332ec66SJohan Hedberg { 1005c8992cffSLuiz Augusto von Dentz struct hci_rp_read_page_scan_activity *rp = data; 1006e3f3a1aeSLuiz Augusto von Dentz 1007e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1008f332ec66SJohan Hedberg 100945296acdSMarcel Holtmann if (rp->status) 1010c8992cffSLuiz Augusto von Dentz return rp->status; 101145296acdSMarcel Holtmann 101245296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) { 1013f332ec66SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(rp->interval); 1014f332ec66SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(rp->window); 1015f332ec66SJohan Hedberg } 1016c8992cffSLuiz Augusto von Dentz 1017c8992cffSLuiz Augusto von Dentz return rp->status; 1018f332ec66SJohan Hedberg } 1019f332ec66SJohan Hedberg 1020c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_activity(struct hci_dev *hdev, void *data, 10214a3ee763SJohan Hedberg struct sk_buff *skb) 10224a3ee763SJohan Hedberg { 1023c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 10244a3ee763SJohan Hedberg struct hci_cp_write_page_scan_activity *sent; 10254a3ee763SJohan Hedberg 1026e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1027e3f3a1aeSLuiz Augusto von Dentz 1028e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1029c8992cffSLuiz Augusto von Dentz return rp->status; 10304a3ee763SJohan Hedberg 10314a3ee763SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY); 10324a3ee763SJohan Hedberg if (!sent) 1033c8992cffSLuiz Augusto von Dentz return rp->status; 10344a3ee763SJohan Hedberg 10354a3ee763SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(sent->interval); 10364a3ee763SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(sent->window); 1037c8992cffSLuiz Augusto von Dentz 1038c8992cffSLuiz Augusto von Dentz return rp->status; 10394a3ee763SJohan Hedberg } 10404a3ee763SJohan Hedberg 1041c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_type(struct hci_dev *hdev, void *data, 1042f332ec66SJohan Hedberg struct sk_buff *skb) 1043f332ec66SJohan Hedberg { 1044c8992cffSLuiz Augusto von Dentz struct hci_rp_read_page_scan_type *rp = data; 1045e3f3a1aeSLuiz Augusto von Dentz 1046e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1047f332ec66SJohan Hedberg 104845296acdSMarcel Holtmann if (rp->status) 1049c8992cffSLuiz Augusto von Dentz return rp->status; 105045296acdSMarcel Holtmann 105145296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 1052f332ec66SJohan Hedberg hdev->page_scan_type = rp->type; 1053c8992cffSLuiz Augusto von Dentz 1054c8992cffSLuiz Augusto von Dentz return rp->status; 1055f332ec66SJohan Hedberg } 1056f332ec66SJohan Hedberg 1057c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_type(struct hci_dev *hdev, void *data, 10584a3ee763SJohan Hedberg struct sk_buff *skb) 10594a3ee763SJohan Hedberg { 1060c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 10614a3ee763SJohan Hedberg u8 *type; 10624a3ee763SJohan Hedberg 1063e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1064e3f3a1aeSLuiz Augusto von Dentz 1065e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1066c8992cffSLuiz Augusto von Dentz return rp->status; 10674a3ee763SJohan Hedberg 10684a3ee763SJohan Hedberg type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE); 10694a3ee763SJohan Hedberg if (type) 10704a3ee763SJohan Hedberg hdev->page_scan_type = *type; 1071c8992cffSLuiz Augusto von Dentz 1072c8992cffSLuiz Augusto von Dentz return rp->status; 10734a3ee763SJohan Hedberg } 10744a3ee763SJohan Hedberg 1075c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_data_block_size(struct hci_dev *hdev, void *data, 1076350ee4cfSAndrei Emeltchenko struct sk_buff *skb) 1077350ee4cfSAndrei Emeltchenko { 1078c8992cffSLuiz Augusto von Dentz struct hci_rp_read_data_block_size *rp = data; 1079e3f3a1aeSLuiz Augusto von Dentz 1080e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1081350ee4cfSAndrei Emeltchenko 1082350ee4cfSAndrei Emeltchenko if (rp->status) 1083c8992cffSLuiz Augusto von Dentz return rp->status; 1084350ee4cfSAndrei Emeltchenko 1085350ee4cfSAndrei Emeltchenko hdev->block_mtu = __le16_to_cpu(rp->max_acl_len); 1086350ee4cfSAndrei Emeltchenko hdev->block_len = __le16_to_cpu(rp->block_len); 1087350ee4cfSAndrei Emeltchenko hdev->num_blocks = __le16_to_cpu(rp->num_blocks); 1088350ee4cfSAndrei Emeltchenko 1089350ee4cfSAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 1090350ee4cfSAndrei Emeltchenko 1091350ee4cfSAndrei Emeltchenko BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, 1092350ee4cfSAndrei Emeltchenko hdev->block_cnt, hdev->block_len); 1093c8992cffSLuiz Augusto von Dentz 1094c8992cffSLuiz Augusto von Dentz return rp->status; 1095350ee4cfSAndrei Emeltchenko } 1096350ee4cfSAndrei Emeltchenko 1097c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_clock(struct hci_dev *hdev, void *data, 1098c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 109933f35721SJohan Hedberg { 1100c8992cffSLuiz Augusto von Dentz struct hci_rp_read_clock *rp = data; 110133f35721SJohan Hedberg struct hci_cp_read_clock *cp; 110233f35721SJohan Hedberg struct hci_conn *conn; 110333f35721SJohan Hedberg 1104e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1105e3f3a1aeSLuiz Augusto von Dentz 110633f35721SJohan Hedberg if (rp->status) 1107c8992cffSLuiz Augusto von Dentz return rp->status; 110833f35721SJohan Hedberg 110933f35721SJohan Hedberg hci_dev_lock(hdev); 111033f35721SJohan Hedberg 111133f35721SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK); 111233f35721SJohan Hedberg if (!cp) 111333f35721SJohan Hedberg goto unlock; 111433f35721SJohan Hedberg 111533f35721SJohan Hedberg if (cp->which == 0x00) { 111633f35721SJohan Hedberg hdev->clock = le32_to_cpu(rp->clock); 111733f35721SJohan Hedberg goto unlock; 111833f35721SJohan Hedberg } 111933f35721SJohan Hedberg 112033f35721SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 112133f35721SJohan Hedberg if (conn) { 112233f35721SJohan Hedberg conn->clock = le32_to_cpu(rp->clock); 112333f35721SJohan Hedberg conn->clock_accuracy = le16_to_cpu(rp->accuracy); 112433f35721SJohan Hedberg } 112533f35721SJohan Hedberg 112633f35721SJohan Hedberg unlock: 112733f35721SJohan Hedberg hci_dev_unlock(hdev); 1128c8992cffSLuiz Augusto von Dentz return rp->status; 112933f35721SJohan Hedberg } 113033f35721SJohan Hedberg 1131c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_amp_info(struct hci_dev *hdev, void *data, 1132928abaa7SAndrei Emeltchenko struct sk_buff *skb) 1133928abaa7SAndrei Emeltchenko { 1134c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_amp_info *rp = data; 1135e3f3a1aeSLuiz Augusto von Dentz 1136e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1137928abaa7SAndrei Emeltchenko 1138928abaa7SAndrei Emeltchenko if (rp->status) 1139c8992cffSLuiz Augusto von Dentz return rp->status; 1140928abaa7SAndrei Emeltchenko 1141928abaa7SAndrei Emeltchenko hdev->amp_status = rp->amp_status; 1142928abaa7SAndrei Emeltchenko hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); 1143928abaa7SAndrei Emeltchenko hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); 1144928abaa7SAndrei Emeltchenko hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); 1145928abaa7SAndrei Emeltchenko hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); 1146928abaa7SAndrei Emeltchenko hdev->amp_type = rp->amp_type; 1147928abaa7SAndrei Emeltchenko hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); 1148928abaa7SAndrei Emeltchenko hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); 1149928abaa7SAndrei Emeltchenko hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); 1150928abaa7SAndrei Emeltchenko hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); 1151c8992cffSLuiz Augusto von Dentz 1152c8992cffSLuiz Augusto von Dentz return rp->status; 1153928abaa7SAndrei Emeltchenko } 1154928abaa7SAndrei Emeltchenko 1155c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, void *data, 1156d5859e22SJohan Hedberg struct sk_buff *skb) 1157d5859e22SJohan Hedberg { 1158c8992cffSLuiz Augusto von Dentz struct hci_rp_read_inq_rsp_tx_power *rp = data; 1159e3f3a1aeSLuiz Augusto von Dentz 1160e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1161d5859e22SJohan Hedberg 116245296acdSMarcel Holtmann if (rp->status) 1163c8992cffSLuiz Augusto von Dentz return rp->status; 116445296acdSMarcel Holtmann 116591c4e9b1SMarcel Holtmann hdev->inq_tx_power = rp->tx_power; 1166c8992cffSLuiz Augusto von Dentz 1167c8992cffSLuiz Augusto von Dentz return rp->status; 1168d5859e22SJohan Hedberg } 1169d5859e22SJohan Hedberg 1170c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_err_data_reporting(struct hci_dev *hdev, void *data, 117100bce3fbSAlain Michaud struct sk_buff *skb) 117200bce3fbSAlain Michaud { 1173c8992cffSLuiz Augusto von Dentz struct hci_rp_read_def_err_data_reporting *rp = data; 1174e3f3a1aeSLuiz Augusto von Dentz 1175e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 117600bce3fbSAlain Michaud 117700bce3fbSAlain Michaud if (rp->status) 1178c8992cffSLuiz Augusto von Dentz return rp->status; 117900bce3fbSAlain Michaud 118000bce3fbSAlain Michaud hdev->err_data_reporting = rp->err_data_reporting; 1181c8992cffSLuiz Augusto von Dentz 1182c8992cffSLuiz Augusto von Dentz return rp->status; 118300bce3fbSAlain Michaud } 118400bce3fbSAlain Michaud 1185c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_err_data_reporting(struct hci_dev *hdev, void *data, 118600bce3fbSAlain Michaud struct sk_buff *skb) 118700bce3fbSAlain Michaud { 1188c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 118900bce3fbSAlain Michaud struct hci_cp_write_def_err_data_reporting *cp; 119000bce3fbSAlain Michaud 1191e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1192e3f3a1aeSLuiz Augusto von Dentz 1193e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1194c8992cffSLuiz Augusto von Dentz return rp->status; 119500bce3fbSAlain Michaud 119600bce3fbSAlain Michaud cp = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING); 119700bce3fbSAlain Michaud if (!cp) 1198c8992cffSLuiz Augusto von Dentz return rp->status; 119900bce3fbSAlain Michaud 120000bce3fbSAlain Michaud hdev->err_data_reporting = cp->err_data_reporting; 1201c8992cffSLuiz Augusto von Dentz 1202c8992cffSLuiz Augusto von Dentz return rp->status; 120300bce3fbSAlain Michaud } 120400bce3fbSAlain Michaud 1205c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_reply(struct hci_dev *hdev, void *data, 1206c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1207980e1a53SJohan Hedberg { 1208c8992cffSLuiz Augusto von Dentz struct hci_rp_pin_code_reply *rp = data; 1209980e1a53SJohan Hedberg struct hci_cp_pin_code_reply *cp; 1210980e1a53SJohan Hedberg struct hci_conn *conn; 1211980e1a53SJohan Hedberg 1212e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1213980e1a53SJohan Hedberg 121456e5cb86SJohan Hedberg hci_dev_lock(hdev); 121556e5cb86SJohan Hedberg 1216d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1217744cf19eSJohan Hedberg mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); 1218980e1a53SJohan Hedberg 1219fa1bd918SMikel Astiz if (rp->status) 122056e5cb86SJohan Hedberg goto unlock; 1221980e1a53SJohan Hedberg 1222980e1a53SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); 1223980e1a53SJohan Hedberg if (!cp) 122456e5cb86SJohan Hedberg goto unlock; 1225980e1a53SJohan Hedberg 1226980e1a53SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1227980e1a53SJohan Hedberg if (conn) 1228980e1a53SJohan Hedberg conn->pin_length = cp->pin_len; 122956e5cb86SJohan Hedberg 123056e5cb86SJohan Hedberg unlock: 123156e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1232c8992cffSLuiz Augusto von Dentz return rp->status; 1233980e1a53SJohan Hedberg } 1234980e1a53SJohan Hedberg 1235c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_neg_reply(struct hci_dev *hdev, void *data, 1236c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1237980e1a53SJohan Hedberg { 1238c8992cffSLuiz Augusto von Dentz struct hci_rp_pin_code_neg_reply *rp = data; 1239e3f3a1aeSLuiz Augusto von Dentz 1240e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1241980e1a53SJohan Hedberg 124256e5cb86SJohan Hedberg hci_dev_lock(hdev); 124356e5cb86SJohan Hedberg 1244d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1245744cf19eSJohan Hedberg mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, 1246980e1a53SJohan Hedberg rp->status); 124756e5cb86SJohan Hedberg 124856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1249c8992cffSLuiz Augusto von Dentz 1250c8992cffSLuiz Augusto von Dentz return rp->status; 1251980e1a53SJohan Hedberg } 125256e5cb86SJohan Hedberg 1253c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size(struct hci_dev *hdev, void *data, 12546ed58ec5SVille Tervo struct sk_buff *skb) 12556ed58ec5SVille Tervo { 1256c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_buffer_size *rp = data; 1257e3f3a1aeSLuiz Augusto von Dentz 1258e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 12596ed58ec5SVille Tervo 12606ed58ec5SVille Tervo if (rp->status) 1261c8992cffSLuiz Augusto von Dentz return rp->status; 12626ed58ec5SVille Tervo 12636ed58ec5SVille Tervo hdev->le_mtu = __le16_to_cpu(rp->le_mtu); 12646ed58ec5SVille Tervo hdev->le_pkts = rp->le_max_pkt; 12656ed58ec5SVille Tervo 12666ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 12676ed58ec5SVille Tervo 12686ed58ec5SVille Tervo BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); 1269c8992cffSLuiz Augusto von Dentz 1270c8992cffSLuiz Augusto von Dentz return rp->status; 12716ed58ec5SVille Tervo } 1272980e1a53SJohan Hedberg 1273c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_local_features(struct hci_dev *hdev, void *data, 127460e77321SJohan Hedberg struct sk_buff *skb) 127560e77321SJohan Hedberg { 1276c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_local_features *rp = data; 127760e77321SJohan Hedberg 127860e77321SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 127960e77321SJohan Hedberg 128045296acdSMarcel Holtmann if (rp->status) 1281c8992cffSLuiz Augusto von Dentz return rp->status; 128245296acdSMarcel Holtmann 128360e77321SJohan Hedberg memcpy(hdev->le_features, rp->features, 8); 1284c8992cffSLuiz Augusto von Dentz 1285c8992cffSLuiz Augusto von Dentz return rp->status; 128660e77321SJohan Hedberg } 128760e77321SJohan Hedberg 1288c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, void *data, 12898fa19098SJohan Hedberg struct sk_buff *skb) 12908fa19098SJohan Hedberg { 1291c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_adv_tx_power *rp = data; 1292e3f3a1aeSLuiz Augusto von Dentz 1293e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 12948fa19098SJohan Hedberg 129545296acdSMarcel Holtmann if (rp->status) 1296c8992cffSLuiz Augusto von Dentz return rp->status; 129745296acdSMarcel Holtmann 12988fa19098SJohan Hedberg hdev->adv_tx_power = rp->tx_power; 1299c8992cffSLuiz Augusto von Dentz 1300c8992cffSLuiz Augusto von Dentz return rp->status; 13018fa19098SJohan Hedberg } 13028fa19098SJohan Hedberg 1303c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_reply(struct hci_dev *hdev, void *data, 1304c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1305a5c29683SJohan Hedberg { 1306c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data; 1307e3f3a1aeSLuiz Augusto von Dentz 1308e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1309a5c29683SJohan Hedberg 131056e5cb86SJohan Hedberg hci_dev_lock(hdev); 131156e5cb86SJohan Hedberg 1312d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 131304124681SGustavo F. Padovan mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0, 131404124681SGustavo F. Padovan rp->status); 131556e5cb86SJohan Hedberg 131656e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1317c8992cffSLuiz Augusto von Dentz 1318c8992cffSLuiz Augusto von Dentz return rp->status; 1319a5c29683SJohan Hedberg } 1320a5c29683SJohan Hedberg 1321c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, void *data, 1322a5c29683SJohan Hedberg struct sk_buff *skb) 1323a5c29683SJohan Hedberg { 1324c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data; 1325e3f3a1aeSLuiz Augusto von Dentz 1326e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1327a5c29683SJohan Hedberg 132856e5cb86SJohan Hedberg hci_dev_lock(hdev); 132956e5cb86SJohan Hedberg 1330d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1331744cf19eSJohan Hedberg mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, 133204124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 133356e5cb86SJohan Hedberg 133456e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1335c8992cffSLuiz Augusto von Dentz 1336c8992cffSLuiz Augusto von Dentz return rp->status; 1337a5c29683SJohan Hedberg } 1338a5c29683SJohan Hedberg 1339c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_reply(struct hci_dev *hdev, void *data, 1340c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 13411143d458SBrian Gix { 1342c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data; 1343e3f3a1aeSLuiz Augusto von Dentz 1344e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 13451143d458SBrian Gix 13461143d458SBrian Gix hci_dev_lock(hdev); 13471143d458SBrian Gix 1348d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1349272d90dfSJohan Hedberg mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 1350272d90dfSJohan Hedberg 0, rp->status); 13511143d458SBrian Gix 13521143d458SBrian Gix hci_dev_unlock(hdev); 1353c8992cffSLuiz Augusto von Dentz 1354c8992cffSLuiz Augusto von Dentz return rp->status; 13551143d458SBrian Gix } 13561143d458SBrian Gix 1357c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, void *data, 13581143d458SBrian Gix struct sk_buff *skb) 13591143d458SBrian Gix { 1360c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data; 1361e3f3a1aeSLuiz Augusto von Dentz 1362e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 13631143d458SBrian Gix 13641143d458SBrian Gix hci_dev_lock(hdev); 13651143d458SBrian Gix 1366d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 13671143d458SBrian Gix mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, 136804124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 13691143d458SBrian Gix 13701143d458SBrian Gix hci_dev_unlock(hdev); 1371c8992cffSLuiz Augusto von Dentz 1372c8992cffSLuiz Augusto von Dentz return rp->status; 13731143d458SBrian Gix } 13741143d458SBrian Gix 1375c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_data(struct hci_dev *hdev, void *data, 1376c35938b2SSzymon Janc struct sk_buff *skb) 1377c35938b2SSzymon Janc { 1378c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_oob_data *rp = data; 1379e3f3a1aeSLuiz Augusto von Dentz 1380e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1381c8992cffSLuiz Augusto von Dentz 1382c8992cffSLuiz Augusto von Dentz return rp->status; 13834d2d2796SMarcel Holtmann } 13844d2d2796SMarcel Holtmann 1385c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, void *data, 13864d2d2796SMarcel Holtmann struct sk_buff *skb) 13874d2d2796SMarcel Holtmann { 1388c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_oob_ext_data *rp = data; 1389e3f3a1aeSLuiz Augusto von Dentz 1390e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1391c8992cffSLuiz Augusto von Dentz 1392c8992cffSLuiz Augusto von Dentz return rp->status; 1393c35938b2SSzymon Janc } 1394c35938b2SSzymon Janc 1395c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_random_addr(struct hci_dev *hdev, void *data, 1396c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 13977a4cd51dSMarcel Holtmann { 1398c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 13997a4cd51dSMarcel Holtmann bdaddr_t *sent; 14007a4cd51dSMarcel Holtmann 1401e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1402e3f3a1aeSLuiz Augusto von Dentz 1403e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1404c8992cffSLuiz Augusto von Dentz return rp->status; 140545296acdSMarcel Holtmann 14067a4cd51dSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR); 14077a4cd51dSMarcel Holtmann if (!sent) 1408c8992cffSLuiz Augusto von Dentz return rp->status; 14097a4cd51dSMarcel Holtmann 14107a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 14117a4cd51dSMarcel Holtmann 14127a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, sent); 14137a4cd51dSMarcel Holtmann 1414c45074d6SLuiz Augusto von Dentz if (!bacmp(&hdev->rpa, sent)) { 1415c45074d6SLuiz Augusto von Dentz hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED); 1416c45074d6SLuiz Augusto von Dentz queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, 1417c45074d6SLuiz Augusto von Dentz secs_to_jiffies(hdev->rpa_timeout)); 1418c45074d6SLuiz Augusto von Dentz } 1419c45074d6SLuiz Augusto von Dentz 14207a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 1421c8992cffSLuiz Augusto von Dentz 1422c8992cffSLuiz Augusto von Dentz return rp->status; 14237a4cd51dSMarcel Holtmann } 14247a4cd51dSMarcel Holtmann 1425c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_default_phy(struct hci_dev *hdev, void *data, 1426c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 14270314f286SJaganath Kanakkassery { 1428c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 14290314f286SJaganath Kanakkassery struct hci_cp_le_set_default_phy *cp; 14300314f286SJaganath Kanakkassery 1431e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1432e3f3a1aeSLuiz Augusto von Dentz 1433e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1434c8992cffSLuiz Augusto von Dentz return rp->status; 14350314f286SJaganath Kanakkassery 14360314f286SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_DEFAULT_PHY); 14370314f286SJaganath Kanakkassery if (!cp) 1438c8992cffSLuiz Augusto von Dentz return rp->status; 14390314f286SJaganath Kanakkassery 14400314f286SJaganath Kanakkassery hci_dev_lock(hdev); 14410314f286SJaganath Kanakkassery 14420314f286SJaganath Kanakkassery hdev->le_tx_def_phys = cp->tx_phys; 14430314f286SJaganath Kanakkassery hdev->le_rx_def_phys = cp->rx_phys; 14440314f286SJaganath Kanakkassery 14450314f286SJaganath Kanakkassery hci_dev_unlock(hdev); 1446c8992cffSLuiz Augusto von Dentz 1447c8992cffSLuiz Augusto von Dentz return rp->status; 14480314f286SJaganath Kanakkassery } 14490314f286SJaganath Kanakkassery 1450c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev, void *data, 1451a73c046aSJaganath Kanakkassery struct sk_buff *skb) 1452a73c046aSJaganath Kanakkassery { 1453c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1454a73c046aSJaganath Kanakkassery struct hci_cp_le_set_adv_set_rand_addr *cp; 1455c45074d6SLuiz Augusto von Dentz struct adv_info *adv; 1456a73c046aSJaganath Kanakkassery 1457e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1458e3f3a1aeSLuiz Augusto von Dentz 1459e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1460c8992cffSLuiz Augusto von Dentz return rp->status; 1461a73c046aSJaganath Kanakkassery 1462a73c046aSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR); 1463c45074d6SLuiz Augusto von Dentz /* Update only in case the adv instance since handle 0x00 shall be using 1464c45074d6SLuiz Augusto von Dentz * HCI_OP_LE_SET_RANDOM_ADDR since that allows both extended and 1465c45074d6SLuiz Augusto von Dentz * non-extended adverting. 1466c45074d6SLuiz Augusto von Dentz */ 1467c45074d6SLuiz Augusto von Dentz if (!cp || !cp->handle) 1468c8992cffSLuiz Augusto von Dentz return rp->status; 1469a73c046aSJaganath Kanakkassery 1470a73c046aSJaganath Kanakkassery hci_dev_lock(hdev); 1471a73c046aSJaganath Kanakkassery 1472c45074d6SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, cp->handle); 1473c45074d6SLuiz Augusto von Dentz if (adv) { 1474c45074d6SLuiz Augusto von Dentz bacpy(&adv->random_addr, &cp->bdaddr); 1475c45074d6SLuiz Augusto von Dentz if (!bacmp(&hdev->rpa, &cp->bdaddr)) { 1476c45074d6SLuiz Augusto von Dentz adv->rpa_expired = false; 1477c45074d6SLuiz Augusto von Dentz queue_delayed_work(hdev->workqueue, 1478c45074d6SLuiz Augusto von Dentz &adv->rpa_expired_cb, 1479c45074d6SLuiz Augusto von Dentz secs_to_jiffies(hdev->rpa_timeout)); 1480c45074d6SLuiz Augusto von Dentz } 1481a73c046aSJaganath Kanakkassery } 1482a73c046aSJaganath Kanakkassery 1483a73c046aSJaganath Kanakkassery hci_dev_unlock(hdev); 1484c8992cffSLuiz Augusto von Dentz 1485c8992cffSLuiz Augusto von Dentz return rp->status; 1486a73c046aSJaganath Kanakkassery } 1487a73c046aSJaganath Kanakkassery 1488c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_remove_adv_set(struct hci_dev *hdev, void *data, 1489c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1490cba6b758SLuiz Augusto von Dentz { 1491c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1492cba6b758SLuiz Augusto von Dentz u8 *instance; 1493cba6b758SLuiz Augusto von Dentz int err; 1494cba6b758SLuiz Augusto von Dentz 1495e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1496e3f3a1aeSLuiz Augusto von Dentz 1497e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1498c8992cffSLuiz Augusto von Dentz return rp->status; 1499cba6b758SLuiz Augusto von Dentz 1500cba6b758SLuiz Augusto von Dentz instance = hci_sent_cmd_data(hdev, HCI_OP_LE_REMOVE_ADV_SET); 1501cba6b758SLuiz Augusto von Dentz if (!instance) 1502c8992cffSLuiz Augusto von Dentz return rp->status; 1503cba6b758SLuiz Augusto von Dentz 1504cba6b758SLuiz Augusto von Dentz hci_dev_lock(hdev); 1505cba6b758SLuiz Augusto von Dentz 1506cba6b758SLuiz Augusto von Dentz err = hci_remove_adv_instance(hdev, *instance); 1507cba6b758SLuiz Augusto von Dentz if (!err) 1508cba6b758SLuiz Augusto von Dentz mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd), hdev, 1509cba6b758SLuiz Augusto von Dentz *instance); 1510cba6b758SLuiz Augusto von Dentz 1511cba6b758SLuiz Augusto von Dentz hci_dev_unlock(hdev); 1512c8992cffSLuiz Augusto von Dentz 1513c8992cffSLuiz Augusto von Dentz return rp->status; 1514cba6b758SLuiz Augusto von Dentz } 1515cba6b758SLuiz Augusto von Dentz 1516c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_adv_sets(struct hci_dev *hdev, void *data, 1517c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1518cba6b758SLuiz Augusto von Dentz { 1519c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1520cba6b758SLuiz Augusto von Dentz struct adv_info *adv, *n; 1521cba6b758SLuiz Augusto von Dentz int err; 1522cba6b758SLuiz Augusto von Dentz 1523e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1524e3f3a1aeSLuiz Augusto von Dentz 1525e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1526c8992cffSLuiz Augusto von Dentz return rp->status; 1527cba6b758SLuiz Augusto von Dentz 1528cba6b758SLuiz Augusto von Dentz if (!hci_sent_cmd_data(hdev, HCI_OP_LE_CLEAR_ADV_SETS)) 1529c8992cffSLuiz Augusto von Dentz return rp->status; 1530cba6b758SLuiz Augusto von Dentz 1531cba6b758SLuiz Augusto von Dentz hci_dev_lock(hdev); 1532cba6b758SLuiz Augusto von Dentz 1533cba6b758SLuiz Augusto von Dentz list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) { 1534cba6b758SLuiz Augusto von Dentz u8 instance = adv->instance; 1535cba6b758SLuiz Augusto von Dentz 1536cba6b758SLuiz Augusto von Dentz err = hci_remove_adv_instance(hdev, instance); 1537cba6b758SLuiz Augusto von Dentz if (!err) 1538cba6b758SLuiz Augusto von Dentz mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd), 1539cba6b758SLuiz Augusto von Dentz hdev, instance); 1540cba6b758SLuiz Augusto von Dentz } 1541cba6b758SLuiz Augusto von Dentz 1542cba6b758SLuiz Augusto von Dentz hci_dev_unlock(hdev); 1543c8992cffSLuiz Augusto von Dentz 1544c8992cffSLuiz Augusto von Dentz return rp->status; 1545cba6b758SLuiz Augusto von Dentz } 1546cba6b758SLuiz Augusto von Dentz 1547c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_transmit_power(struct hci_dev *hdev, void *data, 15487c395ea5SDaniel Winkler struct sk_buff *skb) 15497c395ea5SDaniel Winkler { 1550c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_transmit_power *rp = data; 1551e3f3a1aeSLuiz Augusto von Dentz 1552e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 15537c395ea5SDaniel Winkler 15547c395ea5SDaniel Winkler if (rp->status) 1555c8992cffSLuiz Augusto von Dentz return rp->status; 15567c395ea5SDaniel Winkler 15577c395ea5SDaniel Winkler hdev->min_le_tx_power = rp->min_le_tx_power; 15587c395ea5SDaniel Winkler hdev->max_le_tx_power = rp->max_le_tx_power; 1559c8992cffSLuiz Augusto von Dentz 1560c8992cffSLuiz Augusto von Dentz return rp->status; 15617c395ea5SDaniel Winkler } 15627c395ea5SDaniel Winkler 1563853b70b5SLuiz Augusto von Dentz static u8 hci_cc_le_set_privacy_mode(struct hci_dev *hdev, void *data, 1564853b70b5SLuiz Augusto von Dentz struct sk_buff *skb) 1565853b70b5SLuiz Augusto von Dentz { 1566853b70b5SLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1567853b70b5SLuiz Augusto von Dentz struct hci_cp_le_set_privacy_mode *cp; 1568853b70b5SLuiz Augusto von Dentz struct hci_conn_params *params; 1569853b70b5SLuiz Augusto von Dentz 1570853b70b5SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1571853b70b5SLuiz Augusto von Dentz 1572853b70b5SLuiz Augusto von Dentz if (rp->status) 1573853b70b5SLuiz Augusto von Dentz return rp->status; 1574853b70b5SLuiz Augusto von Dentz 1575853b70b5SLuiz Augusto von Dentz cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PRIVACY_MODE); 1576853b70b5SLuiz Augusto von Dentz if (!cp) 1577853b70b5SLuiz Augusto von Dentz return rp->status; 1578853b70b5SLuiz Augusto von Dentz 1579853b70b5SLuiz Augusto von Dentz hci_dev_lock(hdev); 1580853b70b5SLuiz Augusto von Dentz 1581853b70b5SLuiz Augusto von Dentz params = hci_conn_params_lookup(hdev, &cp->bdaddr, cp->bdaddr_type); 1582853b70b5SLuiz Augusto von Dentz if (params) 1583195ef75eSPauli Virtanen WRITE_ONCE(params->privacy_mode, cp->mode); 1584853b70b5SLuiz Augusto von Dentz 1585853b70b5SLuiz Augusto von Dentz hci_dev_unlock(hdev); 1586853b70b5SLuiz Augusto von Dentz 1587853b70b5SLuiz Augusto von Dentz return rp->status; 1588853b70b5SLuiz Augusto von Dentz } 1589853b70b5SLuiz Augusto von Dentz 1590c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_enable(struct hci_dev *hdev, void *data, 1591c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1592c1d5dc4aSJohan Hedberg { 1593c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1594e3f3a1aeSLuiz Augusto von Dentz __u8 *sent; 1595c1d5dc4aSJohan Hedberg 1596e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1597e3f3a1aeSLuiz Augusto von Dentz 1598e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1599c8992cffSLuiz Augusto von Dentz return rp->status; 1600c1d5dc4aSJohan Hedberg 160145296acdSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE); 160245296acdSMarcel Holtmann if (!sent) 1603c8992cffSLuiz Augusto von Dentz return rp->status; 16043c857757SJohan Hedberg 1605c1d5dc4aSJohan Hedberg hci_dev_lock(hdev); 1606c1d5dc4aSJohan Hedberg 160749c922bbSStephen Hemminger /* If we're doing connection initiation as peripheral. Set a 16083c857757SJohan Hedberg * timeout in case something goes wrong. 16093c857757SJohan Hedberg */ 16103c857757SJohan Hedberg if (*sent) { 16113c857757SJohan Hedberg struct hci_conn *conn; 16123c857757SJohan Hedberg 1613a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ADV); 161466c417c1SJohan Hedberg 1615e7d9ab73SJakub Pawlowski conn = hci_lookup_le_connect(hdev); 16163c857757SJohan Hedberg if (conn) 16173c857757SJohan Hedberg queue_delayed_work(hdev->workqueue, 16183c857757SJohan Hedberg &conn->le_conn_timeout, 161909ae260bSJohan Hedberg conn->conn_timeout); 162066c417c1SJohan Hedberg } else { 1621a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV); 16223c857757SJohan Hedberg } 16233c857757SJohan Hedberg 162404b4edcbSJohan Hedberg hci_dev_unlock(hdev); 1625c8992cffSLuiz Augusto von Dentz 1626c8992cffSLuiz Augusto von Dentz return rp->status; 1627c1d5dc4aSJohan Hedberg } 1628c1d5dc4aSJohan Hedberg 1629c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data, 1630de181e88SJaganath Kanakkassery struct sk_buff *skb) 1631de181e88SJaganath Kanakkassery { 1632de181e88SJaganath Kanakkassery struct hci_cp_le_set_ext_adv_enable *cp; 163310279313SLuiz Augusto von Dentz struct hci_cp_ext_adv_set *set; 163410279313SLuiz Augusto von Dentz struct adv_info *adv = NULL, *n; 1635c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1636de181e88SJaganath Kanakkassery 1637e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1638e3f3a1aeSLuiz Augusto von Dentz 1639e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1640c8992cffSLuiz Augusto von Dentz return rp->status; 1641de181e88SJaganath Kanakkassery 1642de181e88SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE); 1643de181e88SJaganath Kanakkassery if (!cp) 1644c8992cffSLuiz Augusto von Dentz return rp->status; 1645de181e88SJaganath Kanakkassery 164610279313SLuiz Augusto von Dentz set = (void *)cp->data; 164710279313SLuiz Augusto von Dentz 1648de181e88SJaganath Kanakkassery hci_dev_lock(hdev); 1649de181e88SJaganath Kanakkassery 165010279313SLuiz Augusto von Dentz if (cp->num_of_sets) 165110279313SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, set->handle); 165210279313SLuiz Augusto von Dentz 1653de181e88SJaganath Kanakkassery if (cp->enable) { 1654de181e88SJaganath Kanakkassery struct hci_conn *conn; 1655de181e88SJaganath Kanakkassery 1656de181e88SJaganath Kanakkassery hci_dev_set_flag(hdev, HCI_LE_ADV); 1657de181e88SJaganath Kanakkassery 16586a42e9bfSIulia Tanasescu if (adv && !adv->periodic) 165910279313SLuiz Augusto von Dentz adv->enabled = true; 166010279313SLuiz Augusto von Dentz 1661de181e88SJaganath Kanakkassery conn = hci_lookup_le_connect(hdev); 1662de181e88SJaganath Kanakkassery if (conn) 1663de181e88SJaganath Kanakkassery queue_delayed_work(hdev->workqueue, 1664de181e88SJaganath Kanakkassery &conn->le_conn_timeout, 1665de181e88SJaganath Kanakkassery conn->conn_timeout); 166645b7749fSJaganath Kanakkassery } else { 16672128939fSArchie Pusaka if (cp->num_of_sets) { 16682128939fSArchie Pusaka if (adv) 166910279313SLuiz Augusto von Dentz adv->enabled = false; 16702128939fSArchie Pusaka 167110279313SLuiz Augusto von Dentz /* If just one instance was disabled check if there are 167210279313SLuiz Augusto von Dentz * any other instance enabled before clearing HCI_LE_ADV 167310279313SLuiz Augusto von Dentz */ 167410279313SLuiz Augusto von Dentz list_for_each_entry_safe(adv, n, &hdev->adv_instances, 167510279313SLuiz Augusto von Dentz list) { 167610279313SLuiz Augusto von Dentz if (adv->enabled) 167710279313SLuiz Augusto von Dentz goto unlock; 167810279313SLuiz Augusto von Dentz } 167910279313SLuiz Augusto von Dentz } else { 168010279313SLuiz Augusto von Dentz /* All instances shall be considered disabled */ 168110279313SLuiz Augusto von Dentz list_for_each_entry_safe(adv, n, &hdev->adv_instances, 168210279313SLuiz Augusto von Dentz list) 168310279313SLuiz Augusto von Dentz adv->enabled = false; 168410279313SLuiz Augusto von Dentz } 168510279313SLuiz Augusto von Dentz 168645b7749fSJaganath Kanakkassery hci_dev_clear_flag(hdev, HCI_LE_ADV); 1687de181e88SJaganath Kanakkassery } 1688de181e88SJaganath Kanakkassery 168910279313SLuiz Augusto von Dentz unlock: 1690de181e88SJaganath Kanakkassery hci_dev_unlock(hdev); 1691c8992cffSLuiz Augusto von Dentz return rp->status; 1692de181e88SJaganath Kanakkassery } 1693de181e88SJaganath Kanakkassery 1694c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_param(struct hci_dev *hdev, void *data, 1695c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1696533553f8SMarcel Holtmann { 1697533553f8SMarcel Holtmann struct hci_cp_le_set_scan_param *cp; 1698c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1699533553f8SMarcel Holtmann 1700e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1701e3f3a1aeSLuiz Augusto von Dentz 1702e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1703c8992cffSLuiz Augusto von Dentz return rp->status; 170445296acdSMarcel Holtmann 1705533553f8SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM); 1706533553f8SMarcel Holtmann if (!cp) 1707c8992cffSLuiz Augusto von Dentz return rp->status; 1708533553f8SMarcel Holtmann 1709533553f8SMarcel Holtmann hci_dev_lock(hdev); 1710533553f8SMarcel Holtmann 1711533553f8SMarcel Holtmann hdev->le_scan_type = cp->type; 1712533553f8SMarcel Holtmann 1713533553f8SMarcel Holtmann hci_dev_unlock(hdev); 1714c8992cffSLuiz Augusto von Dentz 1715c8992cffSLuiz Augusto von Dentz return rp->status; 1716533553f8SMarcel Holtmann } 1717533553f8SMarcel Holtmann 1718c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_param(struct hci_dev *hdev, void *data, 1719a2344b9eSJaganath Kanakkassery struct sk_buff *skb) 1720a2344b9eSJaganath Kanakkassery { 1721a2344b9eSJaganath Kanakkassery struct hci_cp_le_set_ext_scan_params *cp; 1722c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1723a2344b9eSJaganath Kanakkassery struct hci_cp_le_scan_phy_params *phy_param; 1724a2344b9eSJaganath Kanakkassery 1725e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1726e3f3a1aeSLuiz Augusto von Dentz 1727e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1728c8992cffSLuiz Augusto von Dentz return rp->status; 1729a2344b9eSJaganath Kanakkassery 1730a2344b9eSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_PARAMS); 1731a2344b9eSJaganath Kanakkassery if (!cp) 1732c8992cffSLuiz Augusto von Dentz return rp->status; 1733a2344b9eSJaganath Kanakkassery 1734a2344b9eSJaganath Kanakkassery phy_param = (void *)cp->data; 1735a2344b9eSJaganath Kanakkassery 1736a2344b9eSJaganath Kanakkassery hci_dev_lock(hdev); 1737a2344b9eSJaganath Kanakkassery 1738a2344b9eSJaganath Kanakkassery hdev->le_scan_type = phy_param->type; 1739a2344b9eSJaganath Kanakkassery 1740a2344b9eSJaganath Kanakkassery hci_dev_unlock(hdev); 1741c8992cffSLuiz Augusto von Dentz 1742c8992cffSLuiz Augusto von Dentz return rp->status; 1743a2344b9eSJaganath Kanakkassery } 1744a2344b9eSJaganath Kanakkassery 1745b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev) 1746b9a6328fSJohan Hedberg { 1747b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1748b9a6328fSJohan Hedberg 1749b9a6328fSJohan Hedberg return bacmp(&d->last_adv_addr, BDADDR_ANY); 1750b9a6328fSJohan Hedberg } 1751b9a6328fSJohan Hedberg 1752b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev) 1753b9a6328fSJohan Hedberg { 1754b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1755b9a6328fSJohan Hedberg 1756b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, BDADDR_ANY); 1757b9a6328fSJohan Hedberg d->last_adv_data_len = 0; 1758b9a6328fSJohan Hedberg } 1759b9a6328fSJohan Hedberg 1760b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr, 1761c70a7e4cSMarcel Holtmann u8 bdaddr_type, s8 rssi, u32 flags, 1762c70a7e4cSMarcel Holtmann u8 *data, u8 len) 1763b9a6328fSJohan Hedberg { 1764b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1765b9a6328fSJohan Hedberg 1766112b5090SLuiz Augusto von Dentz if (len > max_adv_len(hdev)) 1767a2ec905dSAlain Michaud return; 1768a2ec905dSAlain Michaud 1769b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, bdaddr); 1770b9a6328fSJohan Hedberg d->last_adv_addr_type = bdaddr_type; 1771ff5cd29fSJohan Hedberg d->last_adv_rssi = rssi; 1772c70a7e4cSMarcel Holtmann d->last_adv_flags = flags; 1773b9a6328fSJohan Hedberg memcpy(d->last_adv_data, data, len); 1774b9a6328fSJohan Hedberg d->last_adv_data_len = len; 1775b9a6328fSJohan Hedberg } 1776b9a6328fSJohan Hedberg 17773baef810SJaganath Kanakkassery static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable) 1778eb9d91f5SAndre Guedes { 17795c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 17805c1a4c8fSJaganath Kanakkassery 17813baef810SJaganath Kanakkassery switch (enable) { 17823fd319b8SAndre Guedes case LE_SCAN_ENABLE: 1783a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_SCAN); 1784b9a6328fSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_ACTIVE) 1785b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 1786b338d917SBrian Gix if (hci_dev_test_flag(hdev, HCI_MESH)) 1787b338d917SBrian Gix hci_discovery_set_state(hdev, DISCOVERY_FINDING); 178868a8aea4SAndrei Emeltchenko break; 178968a8aea4SAndrei Emeltchenko 179076a388beSAndre Guedes case LE_SCAN_DISABLE: 1791b9a6328fSJohan Hedberg /* We do this here instead of when setting DISCOVERY_STOPPED 1792b9a6328fSJohan Hedberg * since the latter would potentially require waiting for 1793b9a6328fSJohan Hedberg * inquiry to stop too. 1794b9a6328fSJohan Hedberg */ 1795b9a6328fSJohan Hedberg if (has_pending_adv_report(hdev)) { 1796b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1797b9a6328fSJohan Hedberg 1798b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 1799ab0aa433SJohan Hedberg d->last_adv_addr_type, NULL, 1800c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 1801ab0aa433SJohan Hedberg d->last_adv_data, 1802b338d917SBrian Gix d->last_adv_data_len, NULL, 0, 0); 1803b9a6328fSJohan Hedberg } 1804b9a6328fSJohan Hedberg 1805317ac8cbSJohan Hedberg /* Cancel this timer so that we don't try to disable scanning 1806317ac8cbSJohan Hedberg * when it's already disabled. 1807317ac8cbSJohan Hedberg */ 1808317ac8cbSJohan Hedberg cancel_delayed_work(&hdev->le_scan_disable); 1809317ac8cbSJohan Hedberg 1810a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_SCAN); 1811e8bb6b97SJohan Hedberg 181281ad6fd9SJohan Hedberg /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we 181381ad6fd9SJohan Hedberg * interrupted scanning due to a connect request. Mark 1814abfeea47SLuiz Augusto von Dentz * therefore discovery as stopped. 181581ad6fd9SJohan Hedberg */ 1816a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED)) 181781ad6fd9SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 1818b338d917SBrian Gix else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) && 1819b338d917SBrian Gix hdev->discovery.state == DISCOVERY_FINDING) 1820b338d917SBrian Gix queue_work(hdev->workqueue, &hdev->reenable_adv_work); 1821e8bb6b97SJohan Hedberg 182268a8aea4SAndrei Emeltchenko break; 182368a8aea4SAndrei Emeltchenko 182468a8aea4SAndrei Emeltchenko default: 18252064ee33SMarcel Holtmann bt_dev_err(hdev, "use of reserved LE_Scan_Enable param %d", 18263baef810SJaganath Kanakkassery enable); 182768a8aea4SAndrei Emeltchenko break; 182835815085SAndre Guedes } 18295c1a4c8fSJaganath Kanakkassery 18305c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 1831eb9d91f5SAndre Guedes } 1832eb9d91f5SAndre Guedes 1833c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_enable(struct hci_dev *hdev, void *data, 18343baef810SJaganath Kanakkassery struct sk_buff *skb) 18353baef810SJaganath Kanakkassery { 18363baef810SJaganath Kanakkassery struct hci_cp_le_set_scan_enable *cp; 1837c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 18383baef810SJaganath Kanakkassery 1839e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1840e3f3a1aeSLuiz Augusto von Dentz 1841e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1842c8992cffSLuiz Augusto von Dentz return rp->status; 18433baef810SJaganath Kanakkassery 18443baef810SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); 18453baef810SJaganath Kanakkassery if (!cp) 1846c8992cffSLuiz Augusto von Dentz return rp->status; 18473baef810SJaganath Kanakkassery 18483baef810SJaganath Kanakkassery le_set_scan_enable_complete(hdev, cp->enable); 1849c8992cffSLuiz Augusto von Dentz 1850c8992cffSLuiz Augusto von Dentz return rp->status; 18513baef810SJaganath Kanakkassery } 18523baef810SJaganath Kanakkassery 1853c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_enable(struct hci_dev *hdev, void *data, 1854a2344b9eSJaganath Kanakkassery struct sk_buff *skb) 1855a2344b9eSJaganath Kanakkassery { 1856a2344b9eSJaganath Kanakkassery struct hci_cp_le_set_ext_scan_enable *cp; 1857c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1858a2344b9eSJaganath Kanakkassery 1859e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1860e3f3a1aeSLuiz Augusto von Dentz 1861e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1862c8992cffSLuiz Augusto von Dentz return rp->status; 1863a2344b9eSJaganath Kanakkassery 1864a2344b9eSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_ENABLE); 1865a2344b9eSJaganath Kanakkassery if (!cp) 1866c8992cffSLuiz Augusto von Dentz return rp->status; 1867a2344b9eSJaganath Kanakkassery 1868a2344b9eSJaganath Kanakkassery le_set_scan_enable_complete(hdev, cp->enable); 1869c8992cffSLuiz Augusto von Dentz 1870c8992cffSLuiz Augusto von Dentz return rp->status; 1871a2344b9eSJaganath Kanakkassery } 1872a2344b9eSJaganath Kanakkassery 1873c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_num_adv_sets(struct hci_dev *hdev, void *data, 18746b49bcb4SJaganath Kanakkassery struct sk_buff *skb) 18756b49bcb4SJaganath Kanakkassery { 1876c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_num_supported_adv_sets *rp = data; 1877e3f3a1aeSLuiz Augusto von Dentz 1878e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x No of Adv sets %u", rp->status, 18796b49bcb4SJaganath Kanakkassery rp->num_of_sets); 18806b49bcb4SJaganath Kanakkassery 18816b49bcb4SJaganath Kanakkassery if (rp->status) 1882c8992cffSLuiz Augusto von Dentz return rp->status; 18836b49bcb4SJaganath Kanakkassery 18846b49bcb4SJaganath Kanakkassery hdev->le_num_of_adv_sets = rp->num_of_sets; 1885c8992cffSLuiz Augusto von Dentz 1886c8992cffSLuiz Augusto von Dentz return rp->status; 18876b49bcb4SJaganath Kanakkassery } 18886b49bcb4SJaganath Kanakkassery 1889c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_accept_list_size(struct hci_dev *hdev, void *data, 1890cf1d081fSJohan Hedberg struct sk_buff *skb) 1891cf1d081fSJohan Hedberg { 1892c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_accept_list_size *rp = data; 1893e3f3a1aeSLuiz Augusto von Dentz 1894e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size); 1895cf1d081fSJohan Hedberg 189645296acdSMarcel Holtmann if (rp->status) 1897c8992cffSLuiz Augusto von Dentz return rp->status; 189845296acdSMarcel Holtmann 18993d4f9c00SArchie Pusaka hdev->le_accept_list_size = rp->size; 1900c8992cffSLuiz Augusto von Dentz 1901c8992cffSLuiz Augusto von Dentz return rp->status; 1902cf1d081fSJohan Hedberg } 1903cf1d081fSJohan Hedberg 1904c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_accept_list(struct hci_dev *hdev, void *data, 19050f36b589SMarcel Holtmann struct sk_buff *skb) 19060f36b589SMarcel Holtmann { 1907c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 19080f36b589SMarcel Holtmann 1909e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1910e3f3a1aeSLuiz Augusto von Dentz 1911e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1912c8992cffSLuiz Augusto von Dentz return rp->status; 191345296acdSMarcel Holtmann 19145e2b6064SNiels Dossche hci_dev_lock(hdev); 19153d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->le_accept_list); 19165e2b6064SNiels Dossche hci_dev_unlock(hdev); 1917c8992cffSLuiz Augusto von Dentz 1918c8992cffSLuiz Augusto von Dentz return rp->status; 19190f36b589SMarcel Holtmann } 19200f36b589SMarcel Holtmann 1921c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_accept_list(struct hci_dev *hdev, void *data, 19220f36b589SMarcel Holtmann struct sk_buff *skb) 19230f36b589SMarcel Holtmann { 19243d4f9c00SArchie Pusaka struct hci_cp_le_add_to_accept_list *sent; 1925c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 19260f36b589SMarcel Holtmann 1927e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1928e3f3a1aeSLuiz Augusto von Dentz 1929e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1930c8992cffSLuiz Augusto von Dentz return rp->status; 193145296acdSMarcel Holtmann 19323d4f9c00SArchie Pusaka sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST); 19330f36b589SMarcel Holtmann if (!sent) 1934c8992cffSLuiz Augusto von Dentz return rp->status; 19350f36b589SMarcel Holtmann 19365e2b6064SNiels Dossche hci_dev_lock(hdev); 19373d4f9c00SArchie Pusaka hci_bdaddr_list_add(&hdev->le_accept_list, &sent->bdaddr, 1938dcc36c16SJohan Hedberg sent->bdaddr_type); 19395e2b6064SNiels Dossche hci_dev_unlock(hdev); 1940c8992cffSLuiz Augusto von Dentz 1941c8992cffSLuiz Augusto von Dentz return rp->status; 19420f36b589SMarcel Holtmann } 19430f36b589SMarcel Holtmann 1944c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_accept_list(struct hci_dev *hdev, void *data, 19450f36b589SMarcel Holtmann struct sk_buff *skb) 19460f36b589SMarcel Holtmann { 19473d4f9c00SArchie Pusaka struct hci_cp_le_del_from_accept_list *sent; 1948c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 19490f36b589SMarcel Holtmann 1950e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1951e3f3a1aeSLuiz Augusto von Dentz 1952e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1953c8992cffSLuiz Augusto von Dentz return rp->status; 195445296acdSMarcel Holtmann 19553d4f9c00SArchie Pusaka sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_ACCEPT_LIST); 19560f36b589SMarcel Holtmann if (!sent) 1957c8992cffSLuiz Augusto von Dentz return rp->status; 19580f36b589SMarcel Holtmann 19595e2b6064SNiels Dossche hci_dev_lock(hdev); 19603d4f9c00SArchie Pusaka hci_bdaddr_list_del(&hdev->le_accept_list, &sent->bdaddr, 1961dcc36c16SJohan Hedberg sent->bdaddr_type); 19625e2b6064SNiels Dossche hci_dev_unlock(hdev); 1963c8992cffSLuiz Augusto von Dentz 1964c8992cffSLuiz Augusto von Dentz return rp->status; 19650f36b589SMarcel Holtmann } 19660f36b589SMarcel Holtmann 1967c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_supported_states(struct hci_dev *hdev, void *data, 19689b008c04SJohan Hedberg struct sk_buff *skb) 19699b008c04SJohan Hedberg { 1970c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_supported_states *rp = data; 1971e3f3a1aeSLuiz Augusto von Dentz 1972e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 19739b008c04SJohan Hedberg 197445296acdSMarcel Holtmann if (rp->status) 1975c8992cffSLuiz Augusto von Dentz return rp->status; 197645296acdSMarcel Holtmann 19779b008c04SJohan Hedberg memcpy(hdev->le_states, rp->le_states, 8); 1978c8992cffSLuiz Augusto von Dentz 1979c8992cffSLuiz Augusto von Dentz return rp->status; 19809b008c04SJohan Hedberg } 19819b008c04SJohan Hedberg 1982c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_def_data_len(struct hci_dev *hdev, void *data, 1983a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1984a8e1bfaaSMarcel Holtmann { 1985c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_def_data_len *rp = data; 1986e3f3a1aeSLuiz Augusto von Dentz 1987e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1988a8e1bfaaSMarcel Holtmann 1989a8e1bfaaSMarcel Holtmann if (rp->status) 1990c8992cffSLuiz Augusto von Dentz return rp->status; 1991a8e1bfaaSMarcel Holtmann 1992a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(rp->tx_len); 1993a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(rp->tx_time); 1994c8992cffSLuiz Augusto von Dentz 1995c8992cffSLuiz Augusto von Dentz return rp->status; 1996a8e1bfaaSMarcel Holtmann } 1997a8e1bfaaSMarcel Holtmann 1998c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_write_def_data_len(struct hci_dev *hdev, void *data, 1999a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 2000a8e1bfaaSMarcel Holtmann { 2001a8e1bfaaSMarcel Holtmann struct hci_cp_le_write_def_data_len *sent; 2002c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 2003a8e1bfaaSMarcel Holtmann 2004e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2005e3f3a1aeSLuiz Augusto von Dentz 2006e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2007c8992cffSLuiz Augusto von Dentz return rp->status; 2008a8e1bfaaSMarcel Holtmann 2009a8e1bfaaSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN); 2010a8e1bfaaSMarcel Holtmann if (!sent) 2011c8992cffSLuiz Augusto von Dentz return rp->status; 2012a8e1bfaaSMarcel Holtmann 2013a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(sent->tx_len); 2014a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(sent->tx_time); 2015c8992cffSLuiz Augusto von Dentz 2016c8992cffSLuiz Augusto von Dentz return rp->status; 2017a8e1bfaaSMarcel Holtmann } 2018a8e1bfaaSMarcel Holtmann 2019c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_resolv_list(struct hci_dev *hdev, void *data, 2020b950aa88SAnkit Navik struct sk_buff *skb) 2021b950aa88SAnkit Navik { 2022b950aa88SAnkit Navik struct hci_cp_le_add_to_resolv_list *sent; 2023c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 2024b950aa88SAnkit Navik 2025e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2026e3f3a1aeSLuiz Augusto von Dentz 2027e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2028c8992cffSLuiz Augusto von Dentz return rp->status; 2029b950aa88SAnkit Navik 2030b950aa88SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_RESOLV_LIST); 2031b950aa88SAnkit Navik if (!sent) 2032c8992cffSLuiz Augusto von Dentz return rp->status; 2033b950aa88SAnkit Navik 20345e2b6064SNiels Dossche hci_dev_lock(hdev); 2035b950aa88SAnkit Navik hci_bdaddr_list_add_with_irk(&hdev->le_resolv_list, &sent->bdaddr, 2036b950aa88SAnkit Navik sent->bdaddr_type, sent->peer_irk, 2037b950aa88SAnkit Navik sent->local_irk); 20385e2b6064SNiels Dossche hci_dev_unlock(hdev); 2039c8992cffSLuiz Augusto von Dentz 2040c8992cffSLuiz Augusto von Dentz return rp->status; 2041b950aa88SAnkit Navik } 2042b950aa88SAnkit Navik 2043c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_resolv_list(struct hci_dev *hdev, void *data, 2044b950aa88SAnkit Navik struct sk_buff *skb) 2045b950aa88SAnkit Navik { 2046b950aa88SAnkit Navik struct hci_cp_le_del_from_resolv_list *sent; 2047c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 2048b950aa88SAnkit Navik 2049e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2050e3f3a1aeSLuiz Augusto von Dentz 2051e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2052c8992cffSLuiz Augusto von Dentz return rp->status; 2053b950aa88SAnkit Navik 2054b950aa88SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_RESOLV_LIST); 2055b950aa88SAnkit Navik if (!sent) 2056c8992cffSLuiz Augusto von Dentz return rp->status; 2057b950aa88SAnkit Navik 20585e2b6064SNiels Dossche hci_dev_lock(hdev); 2059b950aa88SAnkit Navik hci_bdaddr_list_del_with_irk(&hdev->le_resolv_list, &sent->bdaddr, 2060b950aa88SAnkit Navik sent->bdaddr_type); 20615e2b6064SNiels Dossche hci_dev_unlock(hdev); 2062c8992cffSLuiz Augusto von Dentz 2063c8992cffSLuiz Augusto von Dentz return rp->status; 2064b950aa88SAnkit Navik } 2065b950aa88SAnkit Navik 2066c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_resolv_list(struct hci_dev *hdev, void *data, 2067545f2596SAnkit Navik struct sk_buff *skb) 2068545f2596SAnkit Navik { 2069c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 2070545f2596SAnkit Navik 2071e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2072e3f3a1aeSLuiz Augusto von Dentz 2073e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2074c8992cffSLuiz Augusto von Dentz return rp->status; 2075545f2596SAnkit Navik 20765e2b6064SNiels Dossche hci_dev_lock(hdev); 2077545f2596SAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 20785e2b6064SNiels Dossche hci_dev_unlock(hdev); 2079c8992cffSLuiz Augusto von Dentz 2080c8992cffSLuiz Augusto von Dentz return rp->status; 2081545f2596SAnkit Navik } 2082545f2596SAnkit Navik 2083c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_resolv_list_size(struct hci_dev *hdev, void *data, 2084cfdb0c2dSAnkit Navik struct sk_buff *skb) 2085cfdb0c2dSAnkit Navik { 2086c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_resolv_list_size *rp = data; 2087e3f3a1aeSLuiz Augusto von Dentz 2088e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size); 2089cfdb0c2dSAnkit Navik 2090cfdb0c2dSAnkit Navik if (rp->status) 2091c8992cffSLuiz Augusto von Dentz return rp->status; 2092cfdb0c2dSAnkit Navik 2093cfdb0c2dSAnkit Navik hdev->le_resolv_list_size = rp->size; 2094c8992cffSLuiz Augusto von Dentz 2095c8992cffSLuiz Augusto von Dentz return rp->status; 2096cfdb0c2dSAnkit Navik } 2097cfdb0c2dSAnkit Navik 2098c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_addr_resolution_enable(struct hci_dev *hdev, void *data, 2099aa12af77SAnkit Navik struct sk_buff *skb) 2100aa12af77SAnkit Navik { 2101c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 2102e3f3a1aeSLuiz Augusto von Dentz __u8 *sent; 2103aa12af77SAnkit Navik 2104e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2105e3f3a1aeSLuiz Augusto von Dentz 2106e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2107c8992cffSLuiz Augusto von Dentz return rp->status; 2108aa12af77SAnkit Navik 2109aa12af77SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE); 2110aa12af77SAnkit Navik if (!sent) 2111c8992cffSLuiz Augusto von Dentz return rp->status; 2112aa12af77SAnkit Navik 2113aa12af77SAnkit Navik hci_dev_lock(hdev); 2114aa12af77SAnkit Navik 2115aa12af77SAnkit Navik if (*sent) 2116aa12af77SAnkit Navik hci_dev_set_flag(hdev, HCI_LL_RPA_RESOLUTION); 2117aa12af77SAnkit Navik else 2118aa12af77SAnkit Navik hci_dev_clear_flag(hdev, HCI_LL_RPA_RESOLUTION); 2119aa12af77SAnkit Navik 2120aa12af77SAnkit Navik hci_dev_unlock(hdev); 2121c8992cffSLuiz Augusto von Dentz 2122c8992cffSLuiz Augusto von Dentz return rp->status; 2123aa12af77SAnkit Navik } 2124aa12af77SAnkit Navik 2125c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_max_data_len(struct hci_dev *hdev, void *data, 2126a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 2127a8e1bfaaSMarcel Holtmann { 2128c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_max_data_len *rp = data; 2129e3f3a1aeSLuiz Augusto von Dentz 2130e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2131a8e1bfaaSMarcel Holtmann 2132a8e1bfaaSMarcel Holtmann if (rp->status) 2133c8992cffSLuiz Augusto von Dentz return rp->status; 2134a8e1bfaaSMarcel Holtmann 2135a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = le16_to_cpu(rp->tx_len); 2136a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = le16_to_cpu(rp->tx_time); 2137a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = le16_to_cpu(rp->rx_len); 2138a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = le16_to_cpu(rp->rx_time); 2139c8992cffSLuiz Augusto von Dentz 2140c8992cffSLuiz Augusto von Dentz return rp->status; 2141a8e1bfaaSMarcel Holtmann } 2142a8e1bfaaSMarcel Holtmann 2143c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_le_host_supported(struct hci_dev *hdev, void *data, 2144f9b49306SAndre Guedes struct sk_buff *skb) 2145f9b49306SAndre Guedes { 214606199cf8SJohan Hedberg struct hci_cp_write_le_host_supported *sent; 2147c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 2148f9b49306SAndre Guedes 2149e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2150e3f3a1aeSLuiz Augusto von Dentz 2151e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2152c8992cffSLuiz Augusto von Dentz return rp->status; 215345296acdSMarcel Holtmann 215406199cf8SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); 21558f984dfaSJohan Hedberg if (!sent) 2156c8992cffSLuiz Augusto von Dentz return rp->status; 2157f9b49306SAndre Guedes 21585c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 21595c1a4c8fSJaganath Kanakkassery 2160416a4ae5SJohan Hedberg if (sent->le) { 2161cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE; 2162a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ENABLED); 2163416a4ae5SJohan Hedberg } else { 2164cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE; 2165a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ENABLED); 2166a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_ADVERTISING); 2167416a4ae5SJohan Hedberg } 216853b2caabSJohan Hedberg 216953b2caabSJohan Hedberg if (sent->simul) 2170cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE_BREDR; 217153b2caabSJohan Hedberg else 2172cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; 21735c1a4c8fSJaganath Kanakkassery 21745c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 2175c8992cffSLuiz Augusto von Dentz 2176c8992cffSLuiz Augusto von Dentz return rp->status; 21778f984dfaSJohan Hedberg } 2178f9b49306SAndre Guedes 2179c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_adv_param(struct hci_dev *hdev, void *data, 2180c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 218156ed2cb8SJohan Hedberg { 218256ed2cb8SJohan Hedberg struct hci_cp_le_set_adv_param *cp; 2183c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 218456ed2cb8SJohan Hedberg 2185e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2186e3f3a1aeSLuiz Augusto von Dentz 2187e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2188c8992cffSLuiz Augusto von Dentz return rp->status; 218956ed2cb8SJohan Hedberg 219056ed2cb8SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM); 219156ed2cb8SJohan Hedberg if (!cp) 2192c8992cffSLuiz Augusto von Dentz return rp->status; 219356ed2cb8SJohan Hedberg 219456ed2cb8SJohan Hedberg hci_dev_lock(hdev); 219556ed2cb8SJohan Hedberg hdev->adv_addr_type = cp->own_address_type; 219656ed2cb8SJohan Hedberg hci_dev_unlock(hdev); 2197c8992cffSLuiz Augusto von Dentz 2198c8992cffSLuiz Augusto von Dentz return rp->status; 219956ed2cb8SJohan Hedberg } 220056ed2cb8SJohan Hedberg 2201c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_ext_adv_param(struct hci_dev *hdev, void *data, 2202c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 2203de181e88SJaganath Kanakkassery { 2204c8992cffSLuiz Augusto von Dentz struct hci_rp_le_set_ext_adv_params *rp = data; 2205de181e88SJaganath Kanakkassery struct hci_cp_le_set_ext_adv_params *cp; 2206de181e88SJaganath Kanakkassery struct adv_info *adv_instance; 2207de181e88SJaganath Kanakkassery 2208e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2209de181e88SJaganath Kanakkassery 2210de181e88SJaganath Kanakkassery if (rp->status) 2211c8992cffSLuiz Augusto von Dentz return rp->status; 2212de181e88SJaganath Kanakkassery 2213de181e88SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS); 2214de181e88SJaganath Kanakkassery if (!cp) 2215c8992cffSLuiz Augusto von Dentz return rp->status; 2216de181e88SJaganath Kanakkassery 2217de181e88SJaganath Kanakkassery hci_dev_lock(hdev); 2218de181e88SJaganath Kanakkassery hdev->adv_addr_type = cp->own_addr_type; 221925e70886SDaniel Winkler if (!cp->handle) { 2220de181e88SJaganath Kanakkassery /* Store in hdev for instance 0 */ 2221de181e88SJaganath Kanakkassery hdev->adv_tx_power = rp->tx_power; 2222de181e88SJaganath Kanakkassery } else { 222325e70886SDaniel Winkler adv_instance = hci_find_adv_instance(hdev, cp->handle); 2224de181e88SJaganath Kanakkassery if (adv_instance) 2225de181e88SJaganath Kanakkassery adv_instance->tx_power = rp->tx_power; 2226de181e88SJaganath Kanakkassery } 2227a0fb3726SJaganath Kanakkassery /* Update adv data as tx power is known now */ 2228651cd3d6SBrian Gix hci_update_adv_data(hdev, cp->handle); 222912410572SDaniel Winkler 2230de181e88SJaganath Kanakkassery hci_dev_unlock(hdev); 2231c8992cffSLuiz Augusto von Dentz 2232c8992cffSLuiz Augusto von Dentz return rp->status; 2233de181e88SJaganath Kanakkassery } 2234de181e88SJaganath Kanakkassery 2235c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_rssi(struct hci_dev *hdev, void *data, 2236c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 22375ae76a94SAndrzej Kaczmarek { 2238c8992cffSLuiz Augusto von Dentz struct hci_rp_read_rssi *rp = data; 22395ae76a94SAndrzej Kaczmarek struct hci_conn *conn; 22405ae76a94SAndrzej Kaczmarek 2241e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 22425ae76a94SAndrzej Kaczmarek 22435ae76a94SAndrzej Kaczmarek if (rp->status) 2244c8992cffSLuiz Augusto von Dentz return rp->status; 22455ae76a94SAndrzej Kaczmarek 22465ae76a94SAndrzej Kaczmarek hci_dev_lock(hdev); 22475ae76a94SAndrzej Kaczmarek 22485ae76a94SAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 22495ae76a94SAndrzej Kaczmarek if (conn) 22505ae76a94SAndrzej Kaczmarek conn->rssi = rp->rssi; 22515ae76a94SAndrzej Kaczmarek 22525ae76a94SAndrzej Kaczmarek hci_dev_unlock(hdev); 2253c8992cffSLuiz Augusto von Dentz 2254c8992cffSLuiz Augusto von Dentz return rp->status; 22555ae76a94SAndrzej Kaczmarek } 22565ae76a94SAndrzej Kaczmarek 2257c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_tx_power(struct hci_dev *hdev, void *data, 2258c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 22595a134faeSAndrzej Kaczmarek { 22605a134faeSAndrzej Kaczmarek struct hci_cp_read_tx_power *sent; 2261c8992cffSLuiz Augusto von Dentz struct hci_rp_read_tx_power *rp = data; 22625a134faeSAndrzej Kaczmarek struct hci_conn *conn; 22635a134faeSAndrzej Kaczmarek 2264e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 22655a134faeSAndrzej Kaczmarek 22665a134faeSAndrzej Kaczmarek if (rp->status) 2267c8992cffSLuiz Augusto von Dentz return rp->status; 22685a134faeSAndrzej Kaczmarek 22695a134faeSAndrzej Kaczmarek sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER); 22705a134faeSAndrzej Kaczmarek if (!sent) 2271c8992cffSLuiz Augusto von Dentz return rp->status; 22725a134faeSAndrzej Kaczmarek 22735a134faeSAndrzej Kaczmarek hci_dev_lock(hdev); 22745a134faeSAndrzej Kaczmarek 22755a134faeSAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 2276d0455ed9SAndrzej Kaczmarek if (!conn) 2277d0455ed9SAndrzej Kaczmarek goto unlock; 22785a134faeSAndrzej Kaczmarek 2279d0455ed9SAndrzej Kaczmarek switch (sent->type) { 2280d0455ed9SAndrzej Kaczmarek case 0x00: 2281d0455ed9SAndrzej Kaczmarek conn->tx_power = rp->tx_power; 2282d0455ed9SAndrzej Kaczmarek break; 2283d0455ed9SAndrzej Kaczmarek case 0x01: 2284d0455ed9SAndrzej Kaczmarek conn->max_tx_power = rp->tx_power; 2285d0455ed9SAndrzej Kaczmarek break; 2286d0455ed9SAndrzej Kaczmarek } 2287d0455ed9SAndrzej Kaczmarek 2288d0455ed9SAndrzej Kaczmarek unlock: 22895a134faeSAndrzej Kaczmarek hci_dev_unlock(hdev); 2290c8992cffSLuiz Augusto von Dentz return rp->status; 22915a134faeSAndrzej Kaczmarek } 22925a134faeSAndrzej Kaczmarek 2293c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, void *data, 2294c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 2295c50b33c8SMarcel Holtmann { 2296c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 2297c50b33c8SMarcel Holtmann u8 *mode; 2298c50b33c8SMarcel Holtmann 2299e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2300e3f3a1aeSLuiz Augusto von Dentz 2301e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2302c8992cffSLuiz Augusto von Dentz return rp->status; 2303c50b33c8SMarcel Holtmann 2304c50b33c8SMarcel Holtmann mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE); 2305c50b33c8SMarcel Holtmann if (mode) 2306c50b33c8SMarcel Holtmann hdev->ssp_debug_mode = *mode; 2307c8992cffSLuiz Augusto von Dentz 2308c8992cffSLuiz Augusto von Dentz return rp->status; 2309c50b33c8SMarcel Holtmann } 2310c50b33c8SMarcel Holtmann 23116039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) 2312a9de9248SMarcel Holtmann { 2313147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2314a9de9248SMarcel Holtmann 2315a9de9248SMarcel Holtmann if (status) { 2316a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 2317314b2381SJohan Hedberg return; 2318314b2381SJohan Hedberg } 2319314b2381SJohan Hedberg 232090d6a397SLuiz Augusto von Dentz if (hci_sent_cmd_data(hdev, HCI_OP_INQUIRY)) 232189352e7dSAndre Guedes set_bit(HCI_INQUIRY, &hdev->flags); 2322a9de9248SMarcel Holtmann } 2323a9de9248SMarcel Holtmann 23246039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 23251da177e4SLinus Torvalds { 2326a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp; 23271da177e4SLinus Torvalds struct hci_conn *conn; 23281da177e4SLinus Torvalds 2329147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2330a9de9248SMarcel Holtmann 2331a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); 23321da177e4SLinus Torvalds if (!cp) 23331da177e4SLinus Torvalds return; 23341da177e4SLinus Torvalds 23351da177e4SLinus Torvalds hci_dev_lock(hdev); 23361da177e4SLinus Torvalds 23371da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 23381da177e4SLinus Torvalds 2339147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "bdaddr %pMR hcon %p", &cp->bdaddr, conn); 23401da177e4SLinus Torvalds 23411da177e4SLinus Torvalds if (status) { 23421da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) { 23434c67bc74SMarcel Holtmann if (status != 0x0c || conn->attempt > 2) { 23441da177e4SLinus Torvalds conn->state = BT_CLOSED; 2345539c496dSJohan Hedberg hci_connect_cfm(conn, status); 23461da177e4SLinus Torvalds hci_conn_del(conn); 23474c67bc74SMarcel Holtmann } else 23484c67bc74SMarcel Holtmann conn->state = BT_CONNECT2; 23491da177e4SLinus Torvalds } 23501da177e4SLinus Torvalds } else { 23511da177e4SLinus Torvalds if (!conn) { 235284cb0143SZiyang Xuan conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr, 2353a5c4e309SJohan Hedberg HCI_ROLE_MASTER); 2354a5c4e309SJohan Hedberg if (!conn) 23552064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for new connection"); 23561da177e4SLinus Torvalds } 23571da177e4SLinus Torvalds } 23581da177e4SLinus Torvalds 23591da177e4SLinus Torvalds hci_dev_unlock(hdev); 23601da177e4SLinus Torvalds } 23611da177e4SLinus Torvalds 2362a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) 23631da177e4SLinus Torvalds { 2364a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp; 236506149746SLuiz Augusto von Dentz struct hci_conn *acl; 236606149746SLuiz Augusto von Dentz struct hci_link *link; 23671da177e4SLinus Torvalds __u16 handle; 23681da177e4SLinus Torvalds 2369147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2370b6a0dc82SMarcel Holtmann 2371a9de9248SMarcel Holtmann if (!status) 2372a9de9248SMarcel Holtmann return; 2373a9de9248SMarcel Holtmann 2374a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 23751da177e4SLinus Torvalds if (!cp) 2376a9de9248SMarcel Holtmann return; 23771da177e4SLinus Torvalds 23781da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle); 23791da177e4SLinus Torvalds 2380147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x", handle); 23811da177e4SLinus Torvalds 23821da177e4SLinus Torvalds hci_dev_lock(hdev); 23831da177e4SLinus Torvalds 23841da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle); 23855a08ecceSAndrei Emeltchenko if (acl) { 238606149746SLuiz Augusto von Dentz link = list_first_entry_or_null(&acl->link_list, 238706149746SLuiz Augusto von Dentz struct hci_link, list); 238806149746SLuiz Augusto von Dentz if (link && link->conn) { 238906149746SLuiz Augusto von Dentz link->conn->state = BT_CLOSED; 23901da177e4SLinus Torvalds 239106149746SLuiz Augusto von Dentz hci_connect_cfm(link->conn, status); 239206149746SLuiz Augusto von Dentz hci_conn_del(link->conn); 23931da177e4SLinus Torvalds } 23945a08ecceSAndrei Emeltchenko } 23951da177e4SLinus Torvalds 23961da177e4SLinus Torvalds hci_dev_unlock(hdev); 23971da177e4SLinus Torvalds } 23981da177e4SLinus Torvalds 2399f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) 2400f8558555SMarcel Holtmann { 2401f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp; 2402f8558555SMarcel Holtmann struct hci_conn *conn; 2403f8558555SMarcel Holtmann 2404147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2405f8558555SMarcel Holtmann 2406f8558555SMarcel Holtmann if (!status) 2407f8558555SMarcel Holtmann return; 2408f8558555SMarcel Holtmann 2409f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); 2410f8558555SMarcel Holtmann if (!cp) 2411f8558555SMarcel Holtmann return; 2412f8558555SMarcel Holtmann 2413f8558555SMarcel Holtmann hci_dev_lock(hdev); 2414f8558555SMarcel Holtmann 2415f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2416f8558555SMarcel Holtmann if (conn) { 2417f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2418539c496dSJohan Hedberg hci_connect_cfm(conn, status); 241976a68ba0SDavid Herrmann hci_conn_drop(conn); 2420f8558555SMarcel Holtmann } 2421f8558555SMarcel Holtmann } 2422f8558555SMarcel Holtmann 2423f8558555SMarcel Holtmann hci_dev_unlock(hdev); 2424f8558555SMarcel Holtmann } 2425f8558555SMarcel Holtmann 2426f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) 2427f8558555SMarcel Holtmann { 2428f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp; 2429f8558555SMarcel Holtmann struct hci_conn *conn; 2430f8558555SMarcel Holtmann 2431147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2432f8558555SMarcel Holtmann 2433f8558555SMarcel Holtmann if (!status) 2434f8558555SMarcel Holtmann return; 2435f8558555SMarcel Holtmann 2436f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); 2437f8558555SMarcel Holtmann if (!cp) 2438f8558555SMarcel Holtmann return; 2439f8558555SMarcel Holtmann 2440f8558555SMarcel Holtmann hci_dev_lock(hdev); 2441f8558555SMarcel Holtmann 2442f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2443f8558555SMarcel Holtmann if (conn) { 2444f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2445539c496dSJohan Hedberg hci_connect_cfm(conn, status); 244676a68ba0SDavid Herrmann hci_conn_drop(conn); 2447f8558555SMarcel Holtmann } 2448f8558555SMarcel Holtmann } 2449f8558555SMarcel Holtmann 2450f8558555SMarcel Holtmann hci_dev_unlock(hdev); 2451f8558555SMarcel Holtmann } 2452f8558555SMarcel Holtmann 2453127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev, 2454392599b9SJohan Hedberg struct hci_conn *conn) 2455392599b9SJohan Hedberg { 2456392599b9SJohan Hedberg if (conn->state != BT_CONFIG || !conn->out) 2457392599b9SJohan Hedberg return 0; 2458392599b9SJohan Hedberg 2459765c2a96SJohan Hedberg if (conn->pending_sec_level == BT_SECURITY_SDP) 2460392599b9SJohan Hedberg return 0; 2461392599b9SJohan Hedberg 2462392599b9SJohan Hedberg /* Only request authentication for SSP connections or non-SSP 2463264b8b4eSJohan Hedberg * devices with sec_level MEDIUM or HIGH or if MITM protection 2464264b8b4eSJohan Hedberg * is requested. 2465264b8b4eSJohan Hedberg */ 2466807deac2SGustavo Padovan if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && 24677e3691e1SJohan Hedberg conn->pending_sec_level != BT_SECURITY_FIPS && 2468264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_HIGH && 2469264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_MEDIUM) 2470392599b9SJohan Hedberg return 0; 2471392599b9SJohan Hedberg 2472392599b9SJohan Hedberg return 1; 2473392599b9SJohan Hedberg } 2474392599b9SJohan Hedberg 24756039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev, 247600abfe44SGustavo F. Padovan struct inquiry_entry *e) 247730dc78e1SJohan Hedberg { 247830dc78e1SJohan Hedberg struct hci_cp_remote_name_req cp; 247930dc78e1SJohan Hedberg 248030dc78e1SJohan Hedberg memset(&cp, 0, sizeof(cp)); 248130dc78e1SJohan Hedberg 248230dc78e1SJohan Hedberg bacpy(&cp.bdaddr, &e->data.bdaddr); 248330dc78e1SJohan Hedberg cp.pscan_rep_mode = e->data.pscan_rep_mode; 248430dc78e1SJohan Hedberg cp.pscan_mode = e->data.pscan_mode; 248530dc78e1SJohan Hedberg cp.clock_offset = e->data.clock_offset; 248630dc78e1SJohan Hedberg 248730dc78e1SJohan Hedberg return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 248830dc78e1SJohan Hedberg } 248930dc78e1SJohan Hedberg 2490b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev) 249130dc78e1SJohan Hedberg { 249230dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 249330dc78e1SJohan Hedberg struct inquiry_entry *e; 249430dc78e1SJohan Hedberg 2495b644ba33SJohan Hedberg if (list_empty(&discov->resolve)) 2496b644ba33SJohan Hedberg return false; 2497b644ba33SJohan Hedberg 2498dbf6811aSArchie Pusaka /* We should stop if we already spent too much time resolving names. */ 2499dbf6811aSArchie Pusaka if (time_after(jiffies, discov->name_resolve_timeout)) { 2500dbf6811aSArchie Pusaka bt_dev_warn_ratelimited(hdev, "Name resolve takes too long."); 2501dbf6811aSArchie Pusaka return false; 2502dbf6811aSArchie Pusaka } 2503dbf6811aSArchie Pusaka 2504b644ba33SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 2505c810089cSRam Malovany if (!e) 2506c810089cSRam Malovany return false; 2507c810089cSRam Malovany 2508b644ba33SJohan Hedberg if (hci_resolve_name(hdev, e) == 0) { 2509b644ba33SJohan Hedberg e->name_state = NAME_PENDING; 2510b644ba33SJohan Hedberg return true; 2511b644ba33SJohan Hedberg } 2512b644ba33SJohan Hedberg 2513b644ba33SJohan Hedberg return false; 2514b644ba33SJohan Hedberg } 2515b644ba33SJohan Hedberg 2516b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, 2517b644ba33SJohan Hedberg bdaddr_t *bdaddr, u8 *name, u8 name_len) 2518b644ba33SJohan Hedberg { 2519b644ba33SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 2520b644ba33SJohan Hedberg struct inquiry_entry *e; 2521b644ba33SJohan Hedberg 252260cb49d2SJohan Hedberg /* Update the mgmt connected state if necessary. Be careful with 252360cb49d2SJohan Hedberg * conn objects that exist but are not (yet) connected however. 252460cb49d2SJohan Hedberg * Only those in BT_CONFIG or BT_CONNECTED states can be 252560cb49d2SJohan Hedberg * considered connected. 252660cb49d2SJohan Hedberg */ 25270b3df53cSLuiz Augusto von Dentz if (conn && (conn->state == BT_CONFIG || conn->state == BT_CONNECTED)) 25281c6ed31bSYu Liu mgmt_device_connected(hdev, conn, name, name_len); 2529b644ba33SJohan Hedberg 2530b644ba33SJohan Hedberg if (discov->state == DISCOVERY_STOPPED) 2531b644ba33SJohan Hedberg return; 2532b644ba33SJohan Hedberg 253330dc78e1SJohan Hedberg if (discov->state == DISCOVERY_STOPPING) 253430dc78e1SJohan Hedberg goto discov_complete; 253530dc78e1SJohan Hedberg 253630dc78e1SJohan Hedberg if (discov->state != DISCOVERY_RESOLVING) 253730dc78e1SJohan Hedberg return; 253830dc78e1SJohan Hedberg 253930dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); 25407cc8380eSRam Malovany /* If the device was not found in a list of found devices names of which 25417cc8380eSRam Malovany * are pending. there is no need to continue resolving a next name as it 25427cc8380eSRam Malovany * will be done upon receiving another Remote Name Request Complete 25437cc8380eSRam Malovany * Event */ 25447cc8380eSRam Malovany if (!e) 25457cc8380eSRam Malovany return; 25467cc8380eSRam Malovany 254730dc78e1SJohan Hedberg list_del(&e->list); 2548ea13aed5SArchie Pusaka 2549ea13aed5SArchie Pusaka e->name_state = name ? NAME_KNOWN : NAME_NOT_KNOWN; 2550ea13aed5SArchie Pusaka mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, e->data.rssi, 2551ea13aed5SArchie Pusaka name, name_len); 255230dc78e1SJohan Hedberg 2553b644ba33SJohan Hedberg if (hci_resolve_next_name(hdev)) 255430dc78e1SJohan Hedberg return; 255530dc78e1SJohan Hedberg 255630dc78e1SJohan Hedberg discov_complete: 255730dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 255830dc78e1SJohan Hedberg } 255930dc78e1SJohan Hedberg 2560a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 25611da177e4SLinus Torvalds { 2562127178d2SJohan Hedberg struct hci_cp_remote_name_req *cp; 2563127178d2SJohan Hedberg struct hci_conn *conn; 2564127178d2SJohan Hedberg 2565147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2566127178d2SJohan Hedberg 2567127178d2SJohan Hedberg /* If successful wait for the name req complete event before 2568127178d2SJohan Hedberg * checking for the need to do authentication */ 2569127178d2SJohan Hedberg if (!status) 2570127178d2SJohan Hedberg return; 2571127178d2SJohan Hedberg 2572127178d2SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); 2573127178d2SJohan Hedberg if (!cp) 2574127178d2SJohan Hedberg return; 2575127178d2SJohan Hedberg 2576127178d2SJohan Hedberg hci_dev_lock(hdev); 2577127178d2SJohan Hedberg 2578127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 2579b644ba33SJohan Hedberg 2580d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 2581b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); 2582b644ba33SJohan Hedberg 258379c6c70cSJohan Hedberg if (!conn) 258479c6c70cSJohan Hedberg goto unlock; 258579c6c70cSJohan Hedberg 258679c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 258779c6c70cSJohan Hedberg goto unlock; 258879c6c70cSJohan Hedberg 258951a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 2590c1f23a2bSJohannes Berg struct hci_cp_auth_requested auth_cp; 2591c1f23a2bSJohannes Berg 2592977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 2593977f8fceSJohan Hedberg 2594c1f23a2bSJohannes Berg auth_cp.handle = __cpu_to_le16(conn->handle); 2595c1f23a2bSJohannes Berg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, 2596c1f23a2bSJohannes Berg sizeof(auth_cp), &auth_cp); 2597127178d2SJohan Hedberg } 2598127178d2SJohan Hedberg 259979c6c70cSJohan Hedberg unlock: 2600127178d2SJohan Hedberg hci_dev_unlock(hdev); 2601a9de9248SMarcel Holtmann } 26021da177e4SLinus Torvalds 2603769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 2604769be974SMarcel Holtmann { 2605769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp; 2606769be974SMarcel Holtmann struct hci_conn *conn; 2607769be974SMarcel Holtmann 2608147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2609769be974SMarcel Holtmann 2610769be974SMarcel Holtmann if (!status) 2611769be974SMarcel Holtmann return; 2612769be974SMarcel Holtmann 2613769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); 2614769be974SMarcel Holtmann if (!cp) 2615769be974SMarcel Holtmann return; 2616769be974SMarcel Holtmann 2617769be974SMarcel Holtmann hci_dev_lock(hdev); 2618769be974SMarcel Holtmann 2619769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2620769be974SMarcel Holtmann if (conn) { 2621769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 2622539c496dSJohan Hedberg hci_connect_cfm(conn, status); 262376a68ba0SDavid Herrmann hci_conn_drop(conn); 2624769be974SMarcel Holtmann } 2625769be974SMarcel Holtmann } 2626769be974SMarcel Holtmann 2627769be974SMarcel Holtmann hci_dev_unlock(hdev); 2628769be974SMarcel Holtmann } 2629769be974SMarcel Holtmann 2630769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) 2631769be974SMarcel Holtmann { 2632769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp; 2633769be974SMarcel Holtmann struct hci_conn *conn; 2634769be974SMarcel Holtmann 2635147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2636769be974SMarcel Holtmann 2637769be974SMarcel Holtmann if (!status) 2638769be974SMarcel Holtmann return; 2639769be974SMarcel Holtmann 2640769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); 2641769be974SMarcel Holtmann if (!cp) 2642769be974SMarcel Holtmann return; 2643769be974SMarcel Holtmann 2644769be974SMarcel Holtmann hci_dev_lock(hdev); 2645769be974SMarcel Holtmann 2646769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2647769be974SMarcel Holtmann if (conn) { 2648769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 2649539c496dSJohan Hedberg hci_connect_cfm(conn, status); 265076a68ba0SDavid Herrmann hci_conn_drop(conn); 2651769be974SMarcel Holtmann } 2652769be974SMarcel Holtmann } 2653769be974SMarcel Holtmann 2654769be974SMarcel Holtmann hci_dev_unlock(hdev); 2655769be974SMarcel Holtmann } 2656769be974SMarcel Holtmann 265706149746SLuiz Augusto von Dentz static void hci_setup_sync_conn_status(struct hci_dev *hdev, __u16 handle, 265806149746SLuiz Augusto von Dentz __u8 status) 265906149746SLuiz Augusto von Dentz { 266006149746SLuiz Augusto von Dentz struct hci_conn *acl; 266106149746SLuiz Augusto von Dentz struct hci_link *link; 266206149746SLuiz Augusto von Dentz 266306149746SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x status 0x%2.2x", handle, status); 266406149746SLuiz Augusto von Dentz 266506149746SLuiz Augusto von Dentz hci_dev_lock(hdev); 266606149746SLuiz Augusto von Dentz 266706149746SLuiz Augusto von Dentz acl = hci_conn_hash_lookup_handle(hdev, handle); 266806149746SLuiz Augusto von Dentz if (acl) { 266906149746SLuiz Augusto von Dentz link = list_first_entry_or_null(&acl->link_list, 267006149746SLuiz Augusto von Dentz struct hci_link, list); 267106149746SLuiz Augusto von Dentz if (link && link->conn) { 267206149746SLuiz Augusto von Dentz link->conn->state = BT_CLOSED; 267306149746SLuiz Augusto von Dentz 267406149746SLuiz Augusto von Dentz hci_connect_cfm(link->conn, status); 267506149746SLuiz Augusto von Dentz hci_conn_del(link->conn); 267606149746SLuiz Augusto von Dentz } 267706149746SLuiz Augusto von Dentz } 267806149746SLuiz Augusto von Dentz 267906149746SLuiz Augusto von Dentz hci_dev_unlock(hdev); 268006149746SLuiz Augusto von Dentz } 268106149746SLuiz Augusto von Dentz 2682a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 2683a9de9248SMarcel Holtmann { 2684b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp; 2685b6a0dc82SMarcel Holtmann 2686147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2687b6a0dc82SMarcel Holtmann 2688b6a0dc82SMarcel Holtmann if (!status) 2689b6a0dc82SMarcel Holtmann return; 2690b6a0dc82SMarcel Holtmann 2691b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN); 2692b6a0dc82SMarcel Holtmann if (!cp) 2693b6a0dc82SMarcel Holtmann return; 2694b6a0dc82SMarcel Holtmann 269506149746SLuiz Augusto von Dentz hci_setup_sync_conn_status(hdev, __le16_to_cpu(cp->handle), status); 2696a9de9248SMarcel Holtmann } 2697a9de9248SMarcel Holtmann 2698b2af264aSKiran K static void hci_cs_enhanced_setup_sync_conn(struct hci_dev *hdev, __u8 status) 2699b2af264aSKiran K { 2700b2af264aSKiran K struct hci_cp_enhanced_setup_sync_conn *cp; 2701b2af264aSKiran K 2702b2af264aSKiran K bt_dev_dbg(hdev, "status 0x%2.2x", status); 2703b2af264aSKiran K 2704b2af264aSKiran K if (!status) 2705b2af264aSKiran K return; 2706b2af264aSKiran K 2707b2af264aSKiran K cp = hci_sent_cmd_data(hdev, HCI_OP_ENHANCED_SETUP_SYNC_CONN); 2708b2af264aSKiran K if (!cp) 2709b2af264aSKiran K return; 2710b2af264aSKiran K 271106149746SLuiz Augusto von Dentz hci_setup_sync_conn_status(hdev, __le16_to_cpu(cp->handle), status); 2712b2af264aSKiran K } 2713b2af264aSKiran K 2714a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 2715a9de9248SMarcel Holtmann { 2716a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp; 271704837f64SMarcel Holtmann struct hci_conn *conn; 271804837f64SMarcel Holtmann 2719147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2720a9de9248SMarcel Holtmann 2721a9de9248SMarcel Holtmann if (!status) 2722a9de9248SMarcel Holtmann return; 2723a9de9248SMarcel Holtmann 2724a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE); 272504837f64SMarcel Holtmann if (!cp) 2726a9de9248SMarcel Holtmann return; 272704837f64SMarcel Holtmann 272804837f64SMarcel Holtmann hci_dev_lock(hdev); 272904837f64SMarcel Holtmann 273004837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2731e73439d8SMarcel Holtmann if (conn) { 273251a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 273304837f64SMarcel Holtmann 273451a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 2735e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 2736e73439d8SMarcel Holtmann } 2737e73439d8SMarcel Holtmann 273804837f64SMarcel Holtmann hci_dev_unlock(hdev); 273904837f64SMarcel Holtmann } 274004837f64SMarcel Holtmann 2741a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) 2742a9de9248SMarcel Holtmann { 2743a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp; 274404837f64SMarcel Holtmann struct hci_conn *conn; 274504837f64SMarcel Holtmann 2746147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2747a9de9248SMarcel Holtmann 2748a9de9248SMarcel Holtmann if (!status) 2749a9de9248SMarcel Holtmann return; 2750a9de9248SMarcel Holtmann 2751a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE); 275204837f64SMarcel Holtmann if (!cp) 2753a9de9248SMarcel Holtmann return; 275404837f64SMarcel Holtmann 275504837f64SMarcel Holtmann hci_dev_lock(hdev); 275604837f64SMarcel Holtmann 275704837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2758e73439d8SMarcel Holtmann if (conn) { 275951a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 276004837f64SMarcel Holtmann 276151a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 2762e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 2763e73439d8SMarcel Holtmann } 2764e73439d8SMarcel Holtmann 276504837f64SMarcel Holtmann hci_dev_unlock(hdev); 276604837f64SMarcel Holtmann } 276704837f64SMarcel Holtmann 276888c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) 276988c3df13SJohan Hedberg { 277088c3df13SJohan Hedberg struct hci_cp_disconnect *cp; 2771182ee45dSLuiz Augusto von Dentz struct hci_conn_params *params; 277288c3df13SJohan Hedberg struct hci_conn *conn; 2773182ee45dSLuiz Augusto von Dentz bool mgmt_conn; 277488c3df13SJohan Hedberg 2775147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2776147306ccSLuiz Augusto von Dentz 2777182ee45dSLuiz Augusto von Dentz /* Wait for HCI_EV_DISCONN_COMPLETE if status 0x00 and not suspended 2778182ee45dSLuiz Augusto von Dentz * otherwise cleanup the connection immediately. 2779182ee45dSLuiz Augusto von Dentz */ 2780182ee45dSLuiz Augusto von Dentz if (!status && !hdev->suspended) 278188c3df13SJohan Hedberg return; 278288c3df13SJohan Hedberg 278388c3df13SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT); 278488c3df13SJohan Hedberg if (!cp) 278588c3df13SJohan Hedberg return; 278688c3df13SJohan Hedberg 278788c3df13SJohan Hedberg hci_dev_lock(hdev); 278888c3df13SJohan Hedberg 278988c3df13SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2790182ee45dSLuiz Augusto von Dentz if (!conn) 2791182ee45dSLuiz Augusto von Dentz goto unlock; 2792182ee45dSLuiz Augusto von Dentz 2793182ee45dSLuiz Augusto von Dentz if (status) { 279488c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 279588c3df13SJohan Hedberg conn->dst_type, status); 279688c3df13SJohan Hedberg 27971eeaa1aeSLuiz Augusto von Dentz if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) { 27987087c4f6SLuiz Augusto von Dentz hdev->cur_adv_instance = conn->adv_instance; 2799abfeea47SLuiz Augusto von Dentz hci_enable_advertising(hdev); 28007087c4f6SLuiz Augusto von Dentz } 28017087c4f6SLuiz Augusto von Dentz 28027f7cfcb6SPauli Virtanen /* Inform sockets conn is gone before we delete it */ 28037f7cfcb6SPauli Virtanen hci_disconn_cfm(conn, HCI_ERROR_UNSPECIFIED); 28047f7cfcb6SPauli Virtanen 2805182ee45dSLuiz Augusto von Dentz goto done; 2806182ee45dSLuiz Augusto von Dentz } 2807182ee45dSLuiz Augusto von Dentz 2808182ee45dSLuiz Augusto von Dentz mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); 2809182ee45dSLuiz Augusto von Dentz 2810182ee45dSLuiz Augusto von Dentz if (conn->type == ACL_LINK) { 2811629f66aaSAlain Michaud if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) 2812182ee45dSLuiz Augusto von Dentz hci_remove_link_key(hdev, &conn->dst); 2813182ee45dSLuiz Augusto von Dentz } 2814182ee45dSLuiz Augusto von Dentz 2815182ee45dSLuiz Augusto von Dentz params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 2816182ee45dSLuiz Augusto von Dentz if (params) { 2817182ee45dSLuiz Augusto von Dentz switch (params->auto_connect) { 2818182ee45dSLuiz Augusto von Dentz case HCI_AUTO_CONN_LINK_LOSS: 2819182ee45dSLuiz Augusto von Dentz if (cp->reason != HCI_ERROR_CONNECTION_TIMEOUT) 2820182ee45dSLuiz Augusto von Dentz break; 2821182ee45dSLuiz Augusto von Dentz fallthrough; 2822182ee45dSLuiz Augusto von Dentz 2823182ee45dSLuiz Augusto von Dentz case HCI_AUTO_CONN_DIRECT: 2824182ee45dSLuiz Augusto von Dentz case HCI_AUTO_CONN_ALWAYS: 2825195ef75eSPauli Virtanen hci_pend_le_list_del_init(params); 2826195ef75eSPauli Virtanen hci_pend_le_list_add(params, &hdev->pend_le_conns); 2827182ee45dSLuiz Augusto von Dentz break; 2828182ee45dSLuiz Augusto von Dentz 2829182ee45dSLuiz Augusto von Dentz default: 2830182ee45dSLuiz Augusto von Dentz break; 2831182ee45dSLuiz Augusto von Dentz } 2832182ee45dSLuiz Augusto von Dentz } 2833182ee45dSLuiz Augusto von Dentz 2834182ee45dSLuiz Augusto von Dentz mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, 2835182ee45dSLuiz Augusto von Dentz cp->reason, mgmt_conn); 2836182ee45dSLuiz Augusto von Dentz 2837182ee45dSLuiz Augusto von Dentz hci_disconn_cfm(conn, cp->reason); 2838182ee45dSLuiz Augusto von Dentz 2839182ee45dSLuiz Augusto von Dentz done: 2840b8d29052SJoseph Hwang /* If the disconnection failed for any reason, the upper layer 2841b8d29052SJoseph Hwang * does not retry to disconnect in current implementation. 2842b8d29052SJoseph Hwang * Hence, we need to do some basic cleanup here and re-enable 2843b8d29052SJoseph Hwang * advertising if necessary. 2844b8d29052SJoseph Hwang */ 2845b8d29052SJoseph Hwang hci_conn_del(conn); 2846182ee45dSLuiz Augusto von Dentz unlock: 284788c3df13SJohan Hedberg hci_dev_unlock(hdev); 284888c3df13SJohan Hedberg } 284988c3df13SJohan Hedberg 2850d850bf08SLuiz Augusto von Dentz static u8 ev_bdaddr_type(struct hci_dev *hdev, u8 type, bool *resolved) 28514ec4d63bSLuiz Augusto von Dentz { 28524ec4d63bSLuiz Augusto von Dentz /* When using controller based address resolution, then the new 28534ec4d63bSLuiz Augusto von Dentz * address types 0x02 and 0x03 are used. These types need to be 28544ec4d63bSLuiz Augusto von Dentz * converted back into either public address or random address type 28554ec4d63bSLuiz Augusto von Dentz */ 28564ec4d63bSLuiz Augusto von Dentz switch (type) { 28574ec4d63bSLuiz Augusto von Dentz case ADDR_LE_DEV_PUBLIC_RESOLVED: 2858d850bf08SLuiz Augusto von Dentz if (resolved) 2859d850bf08SLuiz Augusto von Dentz *resolved = true; 28604ec4d63bSLuiz Augusto von Dentz return ADDR_LE_DEV_PUBLIC; 28614ec4d63bSLuiz Augusto von Dentz case ADDR_LE_DEV_RANDOM_RESOLVED: 2862d850bf08SLuiz Augusto von Dentz if (resolved) 2863d850bf08SLuiz Augusto von Dentz *resolved = true; 28644ec4d63bSLuiz Augusto von Dentz return ADDR_LE_DEV_RANDOM; 28654ec4d63bSLuiz Augusto von Dentz } 28664ec4d63bSLuiz Augusto von Dentz 2867d850bf08SLuiz Augusto von Dentz if (resolved) 2868d850bf08SLuiz Augusto von Dentz *resolved = false; 28694ec4d63bSLuiz Augusto von Dentz return type; 28704ec4d63bSLuiz Augusto von Dentz } 28714ec4d63bSLuiz Augusto von Dentz 2872d12fb056SJaganath Kanakkassery static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr, 2873d12fb056SJaganath Kanakkassery u8 peer_addr_type, u8 own_address_type, 2874d12fb056SJaganath Kanakkassery u8 filter_policy) 2875d12fb056SJaganath Kanakkassery { 2876d12fb056SJaganath Kanakkassery struct hci_conn *conn; 2877d12fb056SJaganath Kanakkassery 2878d12fb056SJaganath Kanakkassery conn = hci_conn_hash_lookup_le(hdev, peer_addr, 2879d12fb056SJaganath Kanakkassery peer_addr_type); 2880d12fb056SJaganath Kanakkassery if (!conn) 2881d12fb056SJaganath Kanakkassery return; 2882d12fb056SJaganath Kanakkassery 2883d850bf08SLuiz Augusto von Dentz own_address_type = ev_bdaddr_type(hdev, own_address_type, NULL); 2884b31bc00bSSathish Narasimman 2885d12fb056SJaganath Kanakkassery /* Store the initiator and responder address information which 2886d12fb056SJaganath Kanakkassery * is needed for SMP. These values will not change during the 2887d12fb056SJaganath Kanakkassery * lifetime of the connection. 2888d12fb056SJaganath Kanakkassery */ 2889d12fb056SJaganath Kanakkassery conn->init_addr_type = own_address_type; 2890d12fb056SJaganath Kanakkassery if (own_address_type == ADDR_LE_DEV_RANDOM) 2891d12fb056SJaganath Kanakkassery bacpy(&conn->init_addr, &hdev->random_addr); 2892d12fb056SJaganath Kanakkassery else 2893d12fb056SJaganath Kanakkassery bacpy(&conn->init_addr, &hdev->bdaddr); 2894d12fb056SJaganath Kanakkassery 2895d12fb056SJaganath Kanakkassery conn->resp_addr_type = peer_addr_type; 2896d12fb056SJaganath Kanakkassery bacpy(&conn->resp_addr, peer_addr); 2897d12fb056SJaganath Kanakkassery } 2898d12fb056SJaganath Kanakkassery 2899cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) 2900cb1d68f7SJohan Hedberg { 2901cb1d68f7SJohan Hedberg struct hci_cp_le_create_conn *cp; 2902cb1d68f7SJohan Hedberg 2903147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2904cb1d68f7SJohan Hedberg 2905cb1d68f7SJohan Hedberg /* All connection failure handling is taken care of by the 29069b3628d7SLuiz Augusto von Dentz * hci_conn_failed function which is triggered by the HCI 2907cb1d68f7SJohan Hedberg * request completion callbacks used for connecting. 2908cb1d68f7SJohan Hedberg */ 2909cb1d68f7SJohan Hedberg if (status) 2910cb1d68f7SJohan Hedberg return; 2911cb1d68f7SJohan Hedberg 2912cb1d68f7SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); 2913cb1d68f7SJohan Hedberg if (!cp) 2914cb1d68f7SJohan Hedberg return; 2915cb1d68f7SJohan Hedberg 2916cb1d68f7SJohan Hedberg hci_dev_lock(hdev); 2917cb1d68f7SJohan Hedberg 2918d12fb056SJaganath Kanakkassery cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type, 2919d12fb056SJaganath Kanakkassery cp->own_address_type, cp->filter_policy); 2920cb1d68f7SJohan Hedberg 2921cb1d68f7SJohan Hedberg hci_dev_unlock(hdev); 2922cb1d68f7SJohan Hedberg } 2923cb1d68f7SJohan Hedberg 29244d94f95dSJaganath Kanakkassery static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status) 29254d94f95dSJaganath Kanakkassery { 29264d94f95dSJaganath Kanakkassery struct hci_cp_le_ext_create_conn *cp; 29274d94f95dSJaganath Kanakkassery 2928147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 29294d94f95dSJaganath Kanakkassery 29304d94f95dSJaganath Kanakkassery /* All connection failure handling is taken care of by the 29319b3628d7SLuiz Augusto von Dentz * hci_conn_failed function which is triggered by the HCI 29324d94f95dSJaganath Kanakkassery * request completion callbacks used for connecting. 29334d94f95dSJaganath Kanakkassery */ 29344d94f95dSJaganath Kanakkassery if (status) 29354d94f95dSJaganath Kanakkassery return; 29364d94f95dSJaganath Kanakkassery 29374d94f95dSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_EXT_CREATE_CONN); 29384d94f95dSJaganath Kanakkassery if (!cp) 29394d94f95dSJaganath Kanakkassery return; 29404d94f95dSJaganath Kanakkassery 29414d94f95dSJaganath Kanakkassery hci_dev_lock(hdev); 29424d94f95dSJaganath Kanakkassery 29434d94f95dSJaganath Kanakkassery cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type, 29444d94f95dSJaganath Kanakkassery cp->own_addr_type, cp->filter_policy); 29454d94f95dSJaganath Kanakkassery 29464d94f95dSJaganath Kanakkassery hci_dev_unlock(hdev); 29474d94f95dSJaganath Kanakkassery } 29484d94f95dSJaganath Kanakkassery 29490fe29fd1SMarcel Holtmann static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status) 29500fe29fd1SMarcel Holtmann { 29510fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features *cp; 29520fe29fd1SMarcel Holtmann struct hci_conn *conn; 29530fe29fd1SMarcel Holtmann 2954147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 29550fe29fd1SMarcel Holtmann 29560fe29fd1SMarcel Holtmann if (!status) 29570fe29fd1SMarcel Holtmann return; 29580fe29fd1SMarcel Holtmann 29590fe29fd1SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_READ_REMOTE_FEATURES); 29600fe29fd1SMarcel Holtmann if (!cp) 29610fe29fd1SMarcel Holtmann return; 29620fe29fd1SMarcel Holtmann 29630fe29fd1SMarcel Holtmann hci_dev_lock(hdev); 29640fe29fd1SMarcel Holtmann 29650fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 29660fe29fd1SMarcel Holtmann if (conn) { 29670fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) { 29680fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status); 29690fe29fd1SMarcel Holtmann hci_conn_drop(conn); 29700fe29fd1SMarcel Holtmann } 29710fe29fd1SMarcel Holtmann } 29720fe29fd1SMarcel Holtmann 29730fe29fd1SMarcel Holtmann hci_dev_unlock(hdev); 29740fe29fd1SMarcel Holtmann } 29750fe29fd1SMarcel Holtmann 297681d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) 297781d0c8adSJohan Hedberg { 297881d0c8adSJohan Hedberg struct hci_cp_le_start_enc *cp; 297981d0c8adSJohan Hedberg struct hci_conn *conn; 298081d0c8adSJohan Hedberg 2981147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 298281d0c8adSJohan Hedberg 298381d0c8adSJohan Hedberg if (!status) 298481d0c8adSJohan Hedberg return; 298581d0c8adSJohan Hedberg 298681d0c8adSJohan Hedberg hci_dev_lock(hdev); 298781d0c8adSJohan Hedberg 298881d0c8adSJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC); 298981d0c8adSJohan Hedberg if (!cp) 299081d0c8adSJohan Hedberg goto unlock; 299181d0c8adSJohan Hedberg 299281d0c8adSJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 299381d0c8adSJohan Hedberg if (!conn) 299481d0c8adSJohan Hedberg goto unlock; 299581d0c8adSJohan Hedberg 299681d0c8adSJohan Hedberg if (conn->state != BT_CONNECTED) 299781d0c8adSJohan Hedberg goto unlock; 299881d0c8adSJohan Hedberg 299981d0c8adSJohan Hedberg hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 300081d0c8adSJohan Hedberg hci_conn_drop(conn); 300181d0c8adSJohan Hedberg 300281d0c8adSJohan Hedberg unlock: 300381d0c8adSJohan Hedberg hci_dev_unlock(hdev); 300481d0c8adSJohan Hedberg } 300581d0c8adSJohan Hedberg 300650fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status) 300750fc85f1SKuba Pawlak { 300850fc85f1SKuba Pawlak struct hci_cp_switch_role *cp; 300950fc85f1SKuba Pawlak struct hci_conn *conn; 301050fc85f1SKuba Pawlak 301150fc85f1SKuba Pawlak BT_DBG("%s status 0x%2.2x", hdev->name, status); 301250fc85f1SKuba Pawlak 301350fc85f1SKuba Pawlak if (!status) 301450fc85f1SKuba Pawlak return; 301550fc85f1SKuba Pawlak 301650fc85f1SKuba Pawlak cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE); 301750fc85f1SKuba Pawlak if (!cp) 301850fc85f1SKuba Pawlak return; 301950fc85f1SKuba Pawlak 302050fc85f1SKuba Pawlak hci_dev_lock(hdev); 302150fc85f1SKuba Pawlak 302250fc85f1SKuba Pawlak conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 302350fc85f1SKuba Pawlak if (conn) 302450fc85f1SKuba Pawlak clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 302550fc85f1SKuba Pawlak 302650fc85f1SKuba Pawlak hci_dev_unlock(hdev); 302750fc85f1SKuba Pawlak } 302850fc85f1SKuba Pawlak 30293e54c589SLuiz Augusto von Dentz static void hci_inquiry_complete_evt(struct hci_dev *hdev, void *data, 30303e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 30311da177e4SLinus Torvalds { 30323e54c589SLuiz Augusto von Dentz struct hci_ev_status *ev = data; 303330dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 303430dc78e1SJohan Hedberg struct inquiry_entry *e; 30351da177e4SLinus Torvalds 30363e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 30371da177e4SLinus Torvalds 3038a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 303989352e7dSAndre Guedes 304089352e7dSAndre Guedes if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 304189352e7dSAndre Guedes return; 304289352e7dSAndre Guedes 30434e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */ 30443e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 30453e13fa1eSAndre Guedes 3046d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 304730dc78e1SJohan Hedberg return; 304830dc78e1SJohan Hedberg 304956e5cb86SJohan Hedberg hci_dev_lock(hdev); 305030dc78e1SJohan Hedberg 3051343f935bSAndre Guedes if (discov->state != DISCOVERY_FINDING) 305230dc78e1SJohan Hedberg goto unlock; 305330dc78e1SJohan Hedberg 305430dc78e1SJohan Hedberg if (list_empty(&discov->resolve)) { 305507d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in 305607d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion. 305707d2334aSJakub Pawlowski * 305807d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously 305907d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery 306007d2334aSJakub Pawlowski * state to indicate completion. 306107d2334aSJakub Pawlowski */ 306207d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 306307d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) 3064ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 306530dc78e1SJohan Hedberg goto unlock; 306630dc78e1SJohan Hedberg } 306730dc78e1SJohan Hedberg 306830dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 306930dc78e1SJohan Hedberg if (e && hci_resolve_name(hdev, e) == 0) { 307030dc78e1SJohan Hedberg e->name_state = NAME_PENDING; 307130dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); 3072dbf6811aSArchie Pusaka discov->name_resolve_timeout = jiffies + NAME_RESOLVE_DURATION; 307330dc78e1SJohan Hedberg } else { 307407d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in 307507d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion. 307607d2334aSJakub Pawlowski * 307707d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously 307807d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery 307907d2334aSJakub Pawlowski * state to indicate completion. 308007d2334aSJakub Pawlowski */ 308107d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 308207d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) 308330dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 308430dc78e1SJohan Hedberg } 308530dc78e1SJohan Hedberg 308630dc78e1SJohan Hedberg unlock: 308756e5cb86SJohan Hedberg hci_dev_unlock(hdev); 30881da177e4SLinus Torvalds } 30891da177e4SLinus Torvalds 30903e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_evt(struct hci_dev *hdev, void *edata, 30913e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 30921da177e4SLinus Torvalds { 30933e54c589SLuiz Augusto von Dentz struct hci_ev_inquiry_result *ev = edata; 309445bb4bf0SMarcel Holtmann struct inquiry_data data; 309527d9eb4bSLuiz Augusto von Dentz int i; 30961da177e4SLinus Torvalds 309727d9eb4bSLuiz Augusto von Dentz if (!hci_ev_skb_pull(hdev, skb, HCI_EV_INQUIRY_RESULT, 309827d9eb4bSLuiz Augusto von Dentz flex_array_size(ev, info, ev->num))) 309927d9eb4bSLuiz Augusto von Dentz return; 310027d9eb4bSLuiz Augusto von Dentz 31013e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num %d", ev->num); 310227d9eb4bSLuiz Augusto von Dentz 310327d9eb4bSLuiz Augusto von Dentz if (!ev->num) 310445bb4bf0SMarcel Holtmann return; 310545bb4bf0SMarcel Holtmann 3106d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 31071519cc17SAndre Guedes return; 31081519cc17SAndre Guedes 31091da177e4SLinus Torvalds hci_dev_lock(hdev); 311045bb4bf0SMarcel Holtmann 311127d9eb4bSLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) { 311227d9eb4bSLuiz Augusto von Dentz struct inquiry_info *info = &ev->info[i]; 3113af58925cSMarcel Holtmann u32 flags; 31143175405bSJohan Hedberg 31151da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr); 31161da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode; 31171da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode; 31181da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode; 31191da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3); 31201da177e4SLinus Torvalds data.clock_offset = info->clock_offset; 3121efb2513fSMarcel Holtmann data.rssi = HCI_RSSI_INVALID; 312241a96212SMarcel Holtmann data.ssp_mode = 0x00; 31233175405bSJohan Hedberg 3124af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 3125af58925cSMarcel Holtmann 312648264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3127efb2513fSMarcel Holtmann info->dev_class, HCI_RSSI_INVALID, 3128b338d917SBrian Gix flags, NULL, 0, NULL, 0, 0); 31291da177e4SLinus Torvalds } 313045bb4bf0SMarcel Holtmann 31311da177e4SLinus Torvalds hci_dev_unlock(hdev); 31321da177e4SLinus Torvalds } 31331da177e4SLinus Torvalds 31343e54c589SLuiz Augusto von Dentz static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, 31353e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 31361da177e4SLinus Torvalds { 31373e54c589SLuiz Augusto von Dentz struct hci_ev_conn_complete *ev = data; 3138a9de9248SMarcel Holtmann struct hci_conn *conn; 3139c86cc5a3SLuiz Augusto von Dentz u8 status = ev->status; 31401da177e4SLinus Torvalds 3141c86cc5a3SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 314245bb4bf0SMarcel Holtmann 31431da177e4SLinus Torvalds hci_dev_lock(hdev); 314445bb4bf0SMarcel Holtmann 3145a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 31469499237aSMarcel Holtmann if (!conn) { 3147aef2aa4fSLuiz Augusto von Dentz /* In case of error status and there is no connection pending 3148aef2aa4fSLuiz Augusto von Dentz * just unlock as there is nothing to cleanup. 3149aef2aa4fSLuiz Augusto von Dentz */ 3150aef2aa4fSLuiz Augusto von Dentz if (ev->status) 3151aef2aa4fSLuiz Augusto von Dentz goto unlock; 3152aef2aa4fSLuiz Augusto von Dentz 3153a46b7ed4SSonny Sasaka /* Connection may not exist if auto-connected. Check the bredr 3154a46b7ed4SSonny Sasaka * allowlist to see if this device is allowed to auto connect. 3155a46b7ed4SSonny Sasaka * If link is an ACL type, create a connection class 31564f40afc6SAbhishek Pandit-Subedi * automatically. 3157a46b7ed4SSonny Sasaka * 3158a46b7ed4SSonny Sasaka * Auto-connect will only occur if the event filter is 3159a46b7ed4SSonny Sasaka * programmed with a given address. Right now, event filter is 3160a46b7ed4SSonny Sasaka * only used during suspend. 31614f40afc6SAbhishek Pandit-Subedi */ 3162a46b7ed4SSonny Sasaka if (ev->link_type == ACL_LINK && 31633d4f9c00SArchie Pusaka hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, 3164a46b7ed4SSonny Sasaka &ev->bdaddr, 3165a46b7ed4SSonny Sasaka BDADDR_BREDR)) { 316684cb0143SZiyang Xuan conn = hci_conn_add_unset(hdev, ev->link_type, 316784cb0143SZiyang Xuan &ev->bdaddr, HCI_ROLE_SLAVE); 31684f40afc6SAbhishek Pandit-Subedi if (!conn) { 31694f40afc6SAbhishek Pandit-Subedi bt_dev_err(hdev, "no memory for new conn"); 31704f40afc6SAbhishek Pandit-Subedi goto unlock; 31714f40afc6SAbhishek Pandit-Subedi } 31722d186fcdSAbhishek Pandit-Subedi } else { 31739499237aSMarcel Holtmann if (ev->link_type != SCO_LINK) 31749499237aSMarcel Holtmann goto unlock; 31759499237aSMarcel Holtmann 31762d186fcdSAbhishek Pandit-Subedi conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, 31772d186fcdSAbhishek Pandit-Subedi &ev->bdaddr); 3178a9de9248SMarcel Holtmann if (!conn) 3179a9de9248SMarcel Holtmann goto unlock; 318045bb4bf0SMarcel Holtmann 31819499237aSMarcel Holtmann conn->type = SCO_LINK; 31829499237aSMarcel Holtmann } 31832d186fcdSAbhishek Pandit-Subedi } 31849499237aSMarcel Holtmann 3185d5ebaa7cSSoenke Huster /* The HCI_Connection_Complete event is only sent once per connection. 3186d5ebaa7cSSoenke Huster * Processing it more than once per connection can corrupt kernel memory. 3187d5ebaa7cSSoenke Huster * 3188d5ebaa7cSSoenke Huster * As the connection handle is set here for the first time, it indicates 3189d5ebaa7cSSoenke Huster * whether the connection is already set up. 3190d5ebaa7cSSoenke Huster */ 31919f78191cSLuiz Augusto von Dentz if (!HCI_CONN_HANDLE_UNSET(conn->handle)) { 3192d5ebaa7cSSoenke Huster bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection"); 3193d5ebaa7cSSoenke Huster goto unlock; 3194d5ebaa7cSSoenke Huster } 3195d5ebaa7cSSoenke Huster 3196c86cc5a3SLuiz Augusto von Dentz if (!status) { 319716e3b642SLuiz Augusto von Dentz status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle)); 319816e3b642SLuiz Augusto von Dentz if (status) 3199c86cc5a3SLuiz Augusto von Dentz goto done; 3200769be974SMarcel Holtmann 3201769be974SMarcel Holtmann if (conn->type == ACL_LINK) { 3202769be974SMarcel Holtmann conn->state = BT_CONFIG; 3203769be974SMarcel Holtmann hci_conn_hold(conn); 3204a9ea3ed9SSzymon Janc 3205a9ea3ed9SSzymon Janc if (!conn->out && !hci_conn_ssp_enabled(conn) && 3206a9ea3ed9SSzymon Janc !hci_find_link_key(hdev, &ev->bdaddr)) 3207a9ea3ed9SSzymon Janc conn->disc_timeout = HCI_PAIRING_TIMEOUT; 3208a9ea3ed9SSzymon Janc else 3209052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 3210769be974SMarcel Holtmann } else 3211a9de9248SMarcel Holtmann conn->state = BT_CONNECTED; 3212a9de9248SMarcel Holtmann 321323b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 32147d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 32157d0db0a3SMarcel Holtmann 3216a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags)) 32174dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 3218a9de9248SMarcel Holtmann 3219a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags)) 32204dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 3221a9de9248SMarcel Holtmann 32224a328401SHui Wang /* "Link key request" completed ahead of "connect request" completes */ 32234a328401SHui Wang if (ev->encr_mode == 1 && !test_bit(HCI_CONN_ENCRYPT, &conn->flags) && 32244a328401SHui Wang ev->link_type == ACL_LINK) { 32254a328401SHui Wang struct link_key *key; 32264a328401SHui Wang struct hci_cp_read_enc_key_size cp; 32274a328401SHui Wang 32284a328401SHui Wang key = hci_find_link_key(hdev, &ev->bdaddr); 32294a328401SHui Wang if (key) { 32304a328401SHui Wang set_bit(HCI_CONN_ENCRYPT, &conn->flags); 32314a328401SHui Wang 3232*62e3a7cbSLuiz Augusto von Dentz if (!read_key_size_capable(hdev)) { 32334a328401SHui Wang conn->enc_key_size = HCI_LINK_KEY_SIZE; 32344a328401SHui Wang } else { 32354a328401SHui Wang cp.handle = cpu_to_le16(conn->handle); 32364a328401SHui Wang if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE, 32374a328401SHui Wang sizeof(cp), &cp)) { 32384a328401SHui Wang bt_dev_err(hdev, "sending read key size failed"); 32394a328401SHui Wang conn->enc_key_size = HCI_LINK_KEY_SIZE; 32404a328401SHui Wang } 32414a328401SHui Wang } 32424a328401SHui Wang 32434a328401SHui Wang hci_encrypt_cfm(conn, ev->status); 32444a328401SHui Wang } 32454a328401SHui Wang } 32464a328401SHui Wang 3247a9de9248SMarcel Holtmann /* Get remote features */ 3248a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 3249a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp; 3250a9de9248SMarcel Holtmann cp.handle = ev->handle; 3251769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, 3252769be974SMarcel Holtmann sizeof(cp), &cp); 325322f433dcSJohan Hedberg 3254bb876725SBrian Gix hci_update_scan(hdev); 325545bb4bf0SMarcel Holtmann } 3256a9de9248SMarcel Holtmann 3257a9de9248SMarcel Holtmann /* Set packet type for incoming connection */ 3258d095c1ebSAndrei Emeltchenko if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) { 3259a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp; 3260a9de9248SMarcel Holtmann cp.handle = ev->handle; 3261a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 326204124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), 326304124681SGustavo F. Padovan &cp); 3264a9de9248SMarcel Holtmann } 326517d5c04cSJohan Hedberg } 326645bb4bf0SMarcel Holtmann 3267e73439d8SMarcel Holtmann if (conn->type == ACL_LINK) 3268e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 326945bb4bf0SMarcel Holtmann 3270c86cc5a3SLuiz Augusto von Dentz done: 3271c86cc5a3SLuiz Augusto von Dentz if (status) { 32729b3628d7SLuiz Augusto von Dentz hci_conn_failed(conn, status); 32731f8330eaSSathish Narsimman } else if (ev->link_type == SCO_LINK) { 32741f8330eaSSathish Narsimman switch (conn->setting & SCO_AIRMODE_MASK) { 32751f8330eaSSathish Narsimman case SCO_AIRMODE_CVSD: 32761f8330eaSSathish Narsimman if (hdev->notify) 32771f8330eaSSathish Narsimman hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD); 32781f8330eaSSathish Narsimman break; 32791f8330eaSSathish Narsimman } 32801f8330eaSSathish Narsimman 3281c86cc5a3SLuiz Augusto von Dentz hci_connect_cfm(conn, status); 32821f8330eaSSathish Narsimman } 3283a9de9248SMarcel Holtmann 3284a9de9248SMarcel Holtmann unlock: 32851da177e4SLinus Torvalds hci_dev_unlock(hdev); 3286a9de9248SMarcel Holtmann 3287a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 32881da177e4SLinus Torvalds } 32891da177e4SLinus Torvalds 329070c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr) 329170c46425SJohan Hedberg { 329270c46425SJohan Hedberg struct hci_cp_reject_conn_req cp; 329370c46425SJohan Hedberg 329470c46425SJohan Hedberg bacpy(&cp.bdaddr, bdaddr); 329570c46425SJohan Hedberg cp.reason = HCI_ERROR_REJ_BAD_ADDR; 329670c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); 329770c46425SJohan Hedberg } 329870c46425SJohan Hedberg 32993e54c589SLuiz Augusto von Dentz static void hci_conn_request_evt(struct hci_dev *hdev, void *data, 33003e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 33011da177e4SLinus Torvalds { 33023e54c589SLuiz Augusto von Dentz struct hci_ev_conn_request *ev = data; 33031da177e4SLinus Torvalds int mask = hdev->link_mode; 330470c46425SJohan Hedberg struct inquiry_entry *ie; 330570c46425SJohan Hedberg struct hci_conn *conn; 330620714bfeSFrédéric Dalleau __u8 flags = 0; 33071da177e4SLinus Torvalds 33083e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type); 33091da177e4SLinus Torvalds 33101ffc6f8cSLee, Chun-Yi /* Reject incoming connection from device with same BD ADDR against 33111ffc6f8cSLee, Chun-Yi * CVE-2020-26555 33121ffc6f8cSLee, Chun-Yi */ 33139d1a3c74SArnd Bergmann if (hdev && !bacmp(&hdev->bdaddr, &ev->bdaddr)) { 33141ffc6f8cSLee, Chun-Yi bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n", 33151ffc6f8cSLee, Chun-Yi &ev->bdaddr); 33161ffc6f8cSLee, Chun-Yi hci_reject_conn(hdev, &ev->bdaddr); 33171ffc6f8cSLee, Chun-Yi return; 33181ffc6f8cSLee, Chun-Yi } 33191ffc6f8cSLee, Chun-Yi 332020714bfeSFrédéric Dalleau mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, 332120714bfeSFrédéric Dalleau &flags); 33221da177e4SLinus Torvalds 332370c46425SJohan Hedberg if (!(mask & HCI_LM_ACCEPT)) { 332470c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 332570c46425SJohan Hedberg return; 332670c46425SJohan Hedberg } 332770c46425SJohan Hedberg 3328fb048caeSNiels Dossche hci_dev_lock(hdev); 3329fb048caeSNiels Dossche 33303d4f9c00SArchie Pusaka if (hci_bdaddr_list_lookup(&hdev->reject_list, &ev->bdaddr, 3331dcc36c16SJohan Hedberg BDADDR_BREDR)) { 333270c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 3333fb048caeSNiels Dossche goto unlock; 333470c46425SJohan Hedberg } 333546c4c941SJohan Hedberg 33363d4f9c00SArchie Pusaka /* Require HCI_CONNECTABLE or an accept list entry to accept the 33376a8fc95cSJohan Hedberg * connection. These features are only touched through mgmt so 33386a8fc95cSJohan Hedberg * only do the checks if HCI_MGMT is set. 33396a8fc95cSJohan Hedberg */ 3340d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT) && 3341d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONNECTABLE) && 33423d4f9c00SArchie Pusaka !hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, &ev->bdaddr, 3343a55bd29dSJohan Hedberg BDADDR_BREDR)) { 3344a55bd29dSJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 3345fb048caeSNiels Dossche goto unlock; 3346a55bd29dSJohan Hedberg } 334770c46425SJohan Hedberg 33481da177e4SLinus Torvalds /* Connection accepted */ 33491da177e4SLinus Torvalds 3350cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3351cc11b9c1SAndrei Emeltchenko if (ie) 3352c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3); 3353c7bdd502SMarcel Holtmann 33548fc9ced3SGustavo Padovan conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, 33558fc9ced3SGustavo Padovan &ev->bdaddr); 33561da177e4SLinus Torvalds if (!conn) { 335784cb0143SZiyang Xuan conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr, 3358a5c4e309SJohan Hedberg HCI_ROLE_SLAVE); 3359cc11b9c1SAndrei Emeltchenko if (!conn) { 33602064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for new connection"); 3361fb048caeSNiels Dossche goto unlock; 33621da177e4SLinus Torvalds } 33631da177e4SLinus Torvalds } 3364b6a0dc82SMarcel Holtmann 33651da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3); 3366b6a0dc82SMarcel Holtmann 33671da177e4SLinus Torvalds hci_dev_unlock(hdev); 33681da177e4SLinus Torvalds 336920714bfeSFrédéric Dalleau if (ev->link_type == ACL_LINK || 337020714bfeSFrédéric Dalleau (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) { 3371b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp; 337220714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 3373b6a0dc82SMarcel Holtmann 33741da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 33751da177e4SLinus Torvalds 33761da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 337774be523cSArchie Pusaka cp.role = 0x00; /* Become central */ 33781da177e4SLinus Torvalds else 337974be523cSArchie Pusaka cp.role = 0x01; /* Remain peripheral */ 33801da177e4SLinus Torvalds 338170c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); 338220714bfeSFrédéric Dalleau } else if (!(flags & HCI_PROTO_DEFER)) { 3383b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp; 338420714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 3385b6a0dc82SMarcel Holtmann 3386b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 3387a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 3388b6a0dc82SMarcel Holtmann 3389dcf4adbfSJoe Perches cp.tx_bandwidth = cpu_to_le32(0x00001f40); 3390dcf4adbfSJoe Perches cp.rx_bandwidth = cpu_to_le32(0x00001f40); 3391dcf4adbfSJoe Perches cp.max_latency = cpu_to_le16(0xffff); 3392b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting); 3393b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff; 3394b6a0dc82SMarcel Holtmann 339570c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), 339670c46425SJohan Hedberg &cp); 339720714bfeSFrédéric Dalleau } else { 339820714bfeSFrédéric Dalleau conn->state = BT_CONNECT2; 3399539c496dSJohan Hedberg hci_connect_cfm(conn, 0); 3400b6a0dc82SMarcel Holtmann } 3401fb048caeSNiels Dossche 3402fb048caeSNiels Dossche return; 3403fb048caeSNiels Dossche unlock: 3404fb048caeSNiels Dossche hci_dev_unlock(hdev); 34051da177e4SLinus Torvalds } 34061da177e4SLinus Torvalds 3407f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err) 3408f0d6a0eaSMikel Astiz { 3409f0d6a0eaSMikel Astiz switch (err) { 3410f0d6a0eaSMikel Astiz case HCI_ERROR_CONNECTION_TIMEOUT: 3411f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_TIMEOUT; 3412f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_USER_TERM: 3413f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_LOW_RESOURCES: 3414f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_POWER_OFF: 3415f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_REMOTE; 3416f0d6a0eaSMikel Astiz case HCI_ERROR_LOCAL_HOST_TERM: 3417f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_LOCAL_HOST; 3418f0d6a0eaSMikel Astiz default: 3419f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_UNKNOWN; 3420f0d6a0eaSMikel Astiz } 3421f0d6a0eaSMikel Astiz } 3422f0d6a0eaSMikel Astiz 34233e54c589SLuiz Augusto von Dentz static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data, 34243e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 34251da177e4SLinus Torvalds { 34263e54c589SLuiz Augusto von Dentz struct hci_ev_disconn_complete *ev = data; 3427160b9251SSzymon Janc u8 reason; 34289fcb18efSAndre Guedes struct hci_conn_params *params; 342904837f64SMarcel Holtmann struct hci_conn *conn; 343012d4a3b2SJohan Hedberg bool mgmt_connected; 34311da177e4SLinus Torvalds 34323e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 34331da177e4SLinus Torvalds 34341da177e4SLinus Torvalds hci_dev_lock(hdev); 34351da177e4SLinus Torvalds 343604837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3437f7520543SJohan Hedberg if (!conn) 3438f7520543SJohan Hedberg goto unlock; 3439f7520543SJohan Hedberg 3440f0d6a0eaSMikel Astiz if (ev->status) { 344188c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 344288c3df13SJohan Hedberg conn->dst_type, ev->status); 3443abf54a50SAndre Guedes goto unlock; 3444abf54a50SAndre Guedes } 3445f0d6a0eaSMikel Astiz 34463846220bSAndre Guedes conn->state = BT_CLOSED; 34473846220bSAndre Guedes 344812d4a3b2SJohan Hedberg mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); 3449160b9251SSzymon Janc 3450160b9251SSzymon Janc if (test_bit(HCI_CONN_AUTH_FAILURE, &conn->flags)) 3451160b9251SSzymon Janc reason = MGMT_DEV_DISCONN_AUTH_FAILURE; 3452160b9251SSzymon Janc else 3453160b9251SSzymon Janc reason = hci_to_mgmt_reason(ev->reason); 3454160b9251SSzymon Janc 345512d4a3b2SJohan Hedberg mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, 345612d4a3b2SJohan Hedberg reason, mgmt_connected); 3457f7520543SJohan Hedberg 345822f433dcSJohan Hedberg if (conn->type == ACL_LINK) { 3459629f66aaSAlain Michaud if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) 34606ec5bcadSVishal Agarwal hci_remove_link_key(hdev, &conn->dst); 34613846220bSAndre Guedes 3462bb876725SBrian Gix hci_update_scan(hdev); 346322f433dcSJohan Hedberg } 346422f433dcSJohan Hedberg 34659fcb18efSAndre Guedes params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 34669fcb18efSAndre Guedes if (params) { 34679fcb18efSAndre Guedes switch (params->auto_connect) { 34689fcb18efSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 34699fcb18efSAndre Guedes if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) 34709fcb18efSAndre Guedes break; 347119186c7bSGustavo A. R. Silva fallthrough; 34729fcb18efSAndre Guedes 34734b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 34749fcb18efSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 3475195ef75eSPauli Virtanen hci_pend_le_list_del_init(params); 3476195ef75eSPauli Virtanen hci_pend_le_list_add(params, &hdev->pend_le_conns); 34775bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev); 34789fcb18efSAndre Guedes break; 34799fcb18efSAndre Guedes 34809fcb18efSAndre Guedes default: 34819fcb18efSAndre Guedes break; 34829fcb18efSAndre Guedes } 34839fcb18efSAndre Guedes } 34849fcb18efSAndre Guedes 34853a6d576bSJohan Hedberg hci_disconn_cfm(conn, ev->reason); 34862210246cSJohan Hedberg 34872210246cSJohan Hedberg /* Re-enable advertising if necessary, since it might 34882210246cSJohan Hedberg * have been disabled by the connection. From the 34892210246cSJohan Hedberg * HCI_LE_Set_Advertise_Enable command description in 34902210246cSJohan Hedberg * the core specification (v4.0): 34912210246cSJohan Hedberg * "The Controller shall continue advertising until the Host 34922210246cSJohan Hedberg * issues an LE_Set_Advertise_Enable command with 34932210246cSJohan Hedberg * Advertising_Enable set to 0x00 (Advertising is disabled) 34942210246cSJohan Hedberg * or until a connection is created or until the Advertising 34952210246cSJohan Hedberg * is timed out due to Directed Advertising." 34962210246cSJohan Hedberg */ 34971eeaa1aeSLuiz Augusto von Dentz if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) { 34987087c4f6SLuiz Augusto von Dentz hdev->cur_adv_instance = conn->adv_instance; 3499abfeea47SLuiz Augusto von Dentz hci_enable_advertising(hdev); 35007087c4f6SLuiz Augusto von Dentz } 35017087c4f6SLuiz Augusto von Dentz 35027087c4f6SLuiz Augusto von Dentz hci_conn_del(conn); 35031da177e4SLinus Torvalds 3504f7520543SJohan Hedberg unlock: 35051da177e4SLinus Torvalds hci_dev_unlock(hdev); 35061da177e4SLinus Torvalds } 35071da177e4SLinus Torvalds 35083e54c589SLuiz Augusto von Dentz static void hci_auth_complete_evt(struct hci_dev *hdev, void *data, 35093e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 3510a9de9248SMarcel Holtmann { 35113e54c589SLuiz Augusto von Dentz struct hci_ev_auth_complete *ev = data; 3512a9de9248SMarcel Holtmann struct hci_conn *conn; 3513a9de9248SMarcel Holtmann 35143e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 3515a9de9248SMarcel Holtmann 3516a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3517a9de9248SMarcel Holtmann 3518a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3519d7556e20SWaldemar Rymarkiewicz if (!conn) 3520d7556e20SWaldemar Rymarkiewicz goto unlock; 3521d7556e20SWaldemar Rymarkiewicz 3522765c2a96SJohan Hedberg if (!ev->status) { 3523160b9251SSzymon Janc clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); 35244dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 3525765c2a96SJohan Hedberg conn->sec_level = conn->pending_sec_level; 35262a611692SJohan Hedberg } else { 3527160b9251SSzymon Janc if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING) 3528160b9251SSzymon Janc set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); 3529160b9251SSzymon Janc 3530e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 35312a611692SJohan Hedberg } 3532a9de9248SMarcel Holtmann 353351a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 3534a9de9248SMarcel Holtmann 3535f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 3536aa64a8b5SJohan Hedberg if (!ev->status && hci_conn_ssp_enabled(conn)) { 3537f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 3538f8558555SMarcel Holtmann cp.handle = ev->handle; 3539f8558555SMarcel Holtmann cp.encrypt = 0x01; 3540d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 3541d7556e20SWaldemar Rymarkiewicz &cp); 3542f8558555SMarcel Holtmann } else { 3543f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 3544539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 354576a68ba0SDavid Herrmann hci_conn_drop(conn); 3546f8558555SMarcel Holtmann } 3547052b30b0SMarcel Holtmann } else { 3548a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status); 3549a9de9248SMarcel Holtmann 3550052b30b0SMarcel Holtmann hci_conn_hold(conn); 3551052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 355276a68ba0SDavid Herrmann hci_conn_drop(conn); 3553052b30b0SMarcel Holtmann } 3554052b30b0SMarcel Holtmann 355551a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { 3556a9de9248SMarcel Holtmann if (!ev->status) { 3557a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 3558f8558555SMarcel Holtmann cp.handle = ev->handle; 3559f8558555SMarcel Holtmann cp.encrypt = 0x01; 3560d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 3561d7556e20SWaldemar Rymarkiewicz &cp); 3562a9de9248SMarcel Holtmann } else { 356351a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 35643ca44c16SLuiz Augusto von Dentz hci_encrypt_cfm(conn, ev->status); 3565a9de9248SMarcel Holtmann } 3566a9de9248SMarcel Holtmann } 3567a9de9248SMarcel Holtmann 3568d7556e20SWaldemar Rymarkiewicz unlock: 3569a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3570a9de9248SMarcel Holtmann } 3571a9de9248SMarcel Holtmann 35723e54c589SLuiz Augusto von Dentz static void hci_remote_name_evt(struct hci_dev *hdev, void *data, 35733e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 3574a9de9248SMarcel Holtmann { 35753e54c589SLuiz Augusto von Dentz struct hci_ev_remote_name *ev = data; 3576127178d2SJohan Hedberg struct hci_conn *conn; 3577127178d2SJohan Hedberg 35783e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 3579a9de9248SMarcel Holtmann 3580127178d2SJohan Hedberg hci_dev_lock(hdev); 3581127178d2SJohan Hedberg 3582127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3583b644ba33SJohan Hedberg 3584d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 3585b644ba33SJohan Hedberg goto check_auth; 3586b644ba33SJohan Hedberg 3587b644ba33SJohan Hedberg if (ev->status == 0) 3588b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, 3589b644ba33SJohan Hedberg strnlen(ev->name, HCI_MAX_NAME_LENGTH)); 3590b644ba33SJohan Hedberg else 3591b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); 3592b644ba33SJohan Hedberg 3593b644ba33SJohan Hedberg check_auth: 359479c6c70cSJohan Hedberg if (!conn) 359579c6c70cSJohan Hedberg goto unlock; 359679c6c70cSJohan Hedberg 359779c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 359879c6c70cSJohan Hedberg goto unlock; 359979c6c70cSJohan Hedberg 360051a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 3601127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 3602977f8fceSJohan Hedberg 3603977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 3604977f8fceSJohan Hedberg 3605127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 3606127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 3607127178d2SJohan Hedberg } 3608127178d2SJohan Hedberg 360979c6c70cSJohan Hedberg unlock: 3610127178d2SJohan Hedberg hci_dev_unlock(hdev); 3611a9de9248SMarcel Holtmann } 3612a9de9248SMarcel Holtmann 36133e54c589SLuiz Augusto von Dentz static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data, 36143e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 3615a9de9248SMarcel Holtmann { 36163e54c589SLuiz Augusto von Dentz struct hci_ev_encrypt_change *ev = data; 3617a9de9248SMarcel Holtmann struct hci_conn *conn; 3618a9de9248SMarcel Holtmann 36193e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 3620a9de9248SMarcel Holtmann 3621a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3622a9de9248SMarcel Holtmann 3623a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3624dc8357ccSMarcel Holtmann if (!conn) 3625dc8357ccSMarcel Holtmann goto unlock; 3626dc8357ccSMarcel Holtmann 3627a9de9248SMarcel Holtmann if (!ev->status) { 3628ae293196SMarcel Holtmann if (ev->encrypt) { 3629ae293196SMarcel Holtmann /* Encryption implies authentication */ 36304dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 36314dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 3632da85e5e5SVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 3633abf76badSMarcel Holtmann 3634914a6ffeSMarcel Holtmann /* P-256 authentication key implies FIPS */ 3635914a6ffeSMarcel Holtmann if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256) 36364dae2798SJohan Hedberg set_bit(HCI_CONN_FIPS, &conn->flags); 3637914a6ffeSMarcel Holtmann 3638abf76badSMarcel Holtmann if ((conn->type == ACL_LINK && ev->encrypt == 0x02) || 3639abf76badSMarcel Holtmann conn->type == LE_LINK) 3640abf76badSMarcel Holtmann set_bit(HCI_CONN_AES_CCM, &conn->flags); 3641abf76badSMarcel Holtmann } else { 36424dae2798SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT, &conn->flags); 3643abf76badSMarcel Holtmann clear_bit(HCI_CONN_AES_CCM, &conn->flags); 3644abf76badSMarcel Holtmann } 3645a9de9248SMarcel Holtmann } 3646a9de9248SMarcel Holtmann 36477ed3fa20SJohan Hedberg /* We should disregard the current RPA and generate a new one 36487ed3fa20SJohan Hedberg * whenever the encryption procedure fails. 36497ed3fa20SJohan Hedberg */ 3650a73c046aSJaganath Kanakkassery if (ev->status && conn->type == LE_LINK) { 3651a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); 3652a73c046aSJaganath Kanakkassery hci_adv_instances_set_rpa_expired(hdev, true); 3653a73c046aSJaganath Kanakkassery } 36547ed3fa20SJohan Hedberg 365551a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 3656a9de9248SMarcel Holtmann 36578746f135SLuiz Augusto von Dentz /* Check link security requirements are met */ 36588746f135SLuiz Augusto von Dentz if (!hci_conn_check_link_mode(conn)) 36598746f135SLuiz Augusto von Dentz ev->status = HCI_ERROR_AUTH_FAILURE; 36608746f135SLuiz Augusto von Dentz 3661a7d7723aSGustavo Padovan if (ev->status && conn->state == BT_CONNECTED) { 3662160b9251SSzymon Janc if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING) 3663160b9251SSzymon Janc set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); 3664160b9251SSzymon Janc 36658746f135SLuiz Augusto von Dentz /* Notify upper layers so they can cleanup before 36668746f135SLuiz Augusto von Dentz * disconnecting. 366740b552aaSMarcel Holtmann */ 36688746f135SLuiz Augusto von Dentz hci_encrypt_cfm(conn, ev->status); 36698746f135SLuiz Augusto von Dentz hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 367040b552aaSMarcel Holtmann hci_conn_drop(conn); 367140b552aaSMarcel Holtmann goto unlock; 367240b552aaSMarcel Holtmann } 367340b552aaSMarcel Holtmann 3674821f3766SJohan Hedberg /* Try reading the encryption key size for encrypted ACL links */ 3675821f3766SJohan Hedberg if (!ev->status && ev->encrypt && conn->type == ACL_LINK) { 3676821f3766SJohan Hedberg struct hci_cp_read_enc_key_size cp; 3677821f3766SJohan Hedberg 3678821f3766SJohan Hedberg /* Only send HCI_Read_Encryption_Key_Size if the 3679821f3766SJohan Hedberg * controller really supports it. If it doesn't, assume 3680821f3766SJohan Hedberg * the default size (16). 3681821f3766SJohan Hedberg */ 3682*62e3a7cbSLuiz Augusto von Dentz if (!read_key_size_capable(hdev)) { 3683821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 3684821f3766SJohan Hedberg goto notify; 3685821f3766SJohan Hedberg } 3686821f3766SJohan Hedberg 3687821f3766SJohan Hedberg cp.handle = cpu_to_le16(conn->handle); 3688278d933eSBrian Gix if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE, 3689278d933eSBrian Gix sizeof(cp), &cp)) { 36902064ee33SMarcel Holtmann bt_dev_err(hdev, "sending read key size failed"); 3691821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 3692821f3766SJohan Hedberg goto notify; 3693821f3766SJohan Hedberg } 3694821f3766SJohan Hedberg 3695821f3766SJohan Hedberg goto unlock; 3696821f3766SJohan Hedberg } 3697821f3766SJohan Hedberg 3698302975cbSSpoorthi Ravishankar Koppad /* Set the default Authenticated Payload Timeout after 3699302975cbSSpoorthi Ravishankar Koppad * an LE Link is established. As per Core Spec v5.0, Vol 2, Part B 3700302975cbSSpoorthi Ravishankar Koppad * Section 3.3, the HCI command WRITE_AUTH_PAYLOAD_TIMEOUT should be 3701302975cbSSpoorthi Ravishankar Koppad * sent when the link is active and Encryption is enabled, the conn 3702302975cbSSpoorthi Ravishankar Koppad * type can be either LE or ACL and controller must support LMP Ping. 3703302975cbSSpoorthi Ravishankar Koppad * Ensure for AES-CCM encryption as well. 3704302975cbSSpoorthi Ravishankar Koppad */ 3705302975cbSSpoorthi Ravishankar Koppad if (test_bit(HCI_CONN_ENCRYPT, &conn->flags) && 3706302975cbSSpoorthi Ravishankar Koppad test_bit(HCI_CONN_AES_CCM, &conn->flags) && 3707302975cbSSpoorthi Ravishankar Koppad ((conn->type == ACL_LINK && lmp_ping_capable(hdev)) || 3708302975cbSSpoorthi Ravishankar Koppad (conn->type == LE_LINK && (hdev->le_features[0] & HCI_LE_PING)))) { 3709302975cbSSpoorthi Ravishankar Koppad struct hci_cp_write_auth_payload_to cp; 3710302975cbSSpoorthi Ravishankar Koppad 3711302975cbSSpoorthi Ravishankar Koppad cp.handle = cpu_to_le16(conn->handle); 3712302975cbSSpoorthi Ravishankar Koppad cp.timeout = cpu_to_le16(hdev->auth_payload_timeout); 37137aca0ac4SLuiz Augusto von Dentz if (hci_send_cmd(conn->hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO, 3714399dea9dSLuiz Augusto von Dentz sizeof(cp), &cp)) 37157aca0ac4SLuiz Augusto von Dentz bt_dev_err(hdev, "write auth payload timeout failed"); 3716302975cbSSpoorthi Ravishankar Koppad } 3717302975cbSSpoorthi Ravishankar Koppad 3718821f3766SJohan Hedberg notify: 37193ca44c16SLuiz Augusto von Dentz hci_encrypt_cfm(conn, ev->status); 3720a9de9248SMarcel Holtmann 3721a7d7723aSGustavo Padovan unlock: 3722a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3723a9de9248SMarcel Holtmann } 3724a9de9248SMarcel Holtmann 37253e54c589SLuiz Augusto von Dentz static void hci_change_link_key_complete_evt(struct hci_dev *hdev, void *data, 3726807deac2SGustavo Padovan struct sk_buff *skb) 3727a9de9248SMarcel Holtmann { 37283e54c589SLuiz Augusto von Dentz struct hci_ev_change_link_key_complete *ev = data; 3729a9de9248SMarcel Holtmann struct hci_conn *conn; 3730a9de9248SMarcel Holtmann 37313e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 3732a9de9248SMarcel Holtmann 3733a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3734a9de9248SMarcel Holtmann 3735a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3736a9de9248SMarcel Holtmann if (conn) { 3737a9de9248SMarcel Holtmann if (!ev->status) 37384dae2798SJohan Hedberg set_bit(HCI_CONN_SECURE, &conn->flags); 3739a9de9248SMarcel Holtmann 374051a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 3741a9de9248SMarcel Holtmann 3742a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status); 3743a9de9248SMarcel Holtmann } 3744a9de9248SMarcel Holtmann 3745a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3746a9de9248SMarcel Holtmann } 3747a9de9248SMarcel Holtmann 37483e54c589SLuiz Augusto von Dentz static void hci_remote_features_evt(struct hci_dev *hdev, void *data, 3749807deac2SGustavo Padovan struct sk_buff *skb) 3750a9de9248SMarcel Holtmann { 37513e54c589SLuiz Augusto von Dentz struct hci_ev_remote_features *ev = data; 3752a9de9248SMarcel Holtmann struct hci_conn *conn; 3753a9de9248SMarcel Holtmann 37543e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 3755a9de9248SMarcel Holtmann 3756a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3757a9de9248SMarcel Holtmann 3758a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3759ccd556feSJohan Hedberg if (!conn) 3760ccd556feSJohan Hedberg goto unlock; 3761ccd556feSJohan Hedberg 3762769be974SMarcel Holtmann if (!ev->status) 3763cad718edSJohan Hedberg memcpy(conn->features[0], ev->features, 8); 3764a9de9248SMarcel Holtmann 3765ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 3766ccd556feSJohan Hedberg goto unlock; 3767ccd556feSJohan Hedberg 3768ac363cf9SSzymon Janc if (!ev->status && lmp_ext_feat_capable(hdev) && 3769ac363cf9SSzymon Janc lmp_ext_feat_capable(conn)) { 3770769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp; 3771769be974SMarcel Holtmann cp.handle = ev->handle; 3772769be974SMarcel Holtmann cp.page = 0x01; 3773ccd556feSJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, 3774769be974SMarcel Holtmann sizeof(cp), &cp); 3775392599b9SJohan Hedberg goto unlock; 3776392599b9SJohan Hedberg } 3777392599b9SJohan Hedberg 3778671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 3779127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 3780127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 3781127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 3782127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 3783127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 37840b3df53cSLuiz Augusto von Dentz } else { 37851c6ed31bSYu Liu mgmt_device_connected(hdev, conn, NULL, 0); 37860b3df53cSLuiz Augusto von Dentz } 3787392599b9SJohan Hedberg 3788127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 3789769be974SMarcel Holtmann conn->state = BT_CONNECTED; 3790539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 379176a68ba0SDavid Herrmann hci_conn_drop(conn); 3792769be974SMarcel Holtmann } 3793769be974SMarcel Holtmann 3794ccd556feSJohan Hedberg unlock: 3795a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3796a9de9248SMarcel Holtmann } 3797a9de9248SMarcel Holtmann 3798ecb71f25SKiran K static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd) 3799de75cd0dSManish Mandlik { 3800de75cd0dSManish Mandlik cancel_delayed_work(&hdev->cmd_timer); 3801de75cd0dSManish Mandlik 3802deee93d1STetsuo Handa rcu_read_lock(); 3803de75cd0dSManish Mandlik if (!test_bit(HCI_RESET, &hdev->flags)) { 3804de75cd0dSManish Mandlik if (ncmd) { 3805de75cd0dSManish Mandlik cancel_delayed_work(&hdev->ncmd_timer); 3806de75cd0dSManish Mandlik atomic_set(&hdev->cmd_cnt, 1); 3807de75cd0dSManish Mandlik } else { 3808877afadaSSchspa Shi if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) 3809deee93d1STetsuo Handa queue_delayed_work(hdev->workqueue, &hdev->ncmd_timer, 3810de75cd0dSManish Mandlik HCI_NCMD_TIMEOUT); 3811de75cd0dSManish Mandlik } 3812de75cd0dSManish Mandlik } 3813deee93d1STetsuo Handa rcu_read_unlock(); 3814de75cd0dSManish Mandlik } 3815de75cd0dSManish Mandlik 381626afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev *hdev, void *data, 381726afbd82SLuiz Augusto von Dentz struct sk_buff *skb) 381826afbd82SLuiz Augusto von Dentz { 381926afbd82SLuiz Augusto von Dentz struct hci_rp_le_read_buffer_size_v2 *rp = data; 382026afbd82SLuiz Augusto von Dentz 382126afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 382226afbd82SLuiz Augusto von Dentz 382326afbd82SLuiz Augusto von Dentz if (rp->status) 382426afbd82SLuiz Augusto von Dentz return rp->status; 382526afbd82SLuiz Augusto von Dentz 382626afbd82SLuiz Augusto von Dentz hdev->le_mtu = __le16_to_cpu(rp->acl_mtu); 382726afbd82SLuiz Augusto von Dentz hdev->le_pkts = rp->acl_max_pkt; 382826afbd82SLuiz Augusto von Dentz hdev->iso_mtu = __le16_to_cpu(rp->iso_mtu); 382926afbd82SLuiz Augusto von Dentz hdev->iso_pkts = rp->iso_max_pkt; 383026afbd82SLuiz Augusto von Dentz 383126afbd82SLuiz Augusto von Dentz hdev->le_cnt = hdev->le_pkts; 383226afbd82SLuiz Augusto von Dentz hdev->iso_cnt = hdev->iso_pkts; 383326afbd82SLuiz Augusto von Dentz 383426afbd82SLuiz Augusto von Dentz BT_DBG("%s acl mtu %d:%d iso mtu %d:%d", hdev->name, hdev->acl_mtu, 383526afbd82SLuiz Augusto von Dentz hdev->acl_pkts, hdev->iso_mtu, hdev->iso_pkts); 383626afbd82SLuiz Augusto von Dentz 383726afbd82SLuiz Augusto von Dentz return rp->status; 383826afbd82SLuiz Augusto von Dentz } 383926afbd82SLuiz Augusto von Dentz 384066dee215SPauli Virtanen static void hci_unbound_cis_failed(struct hci_dev *hdev, u8 cig, u8 status) 384166dee215SPauli Virtanen { 384266dee215SPauli Virtanen struct hci_conn *conn, *tmp; 384366dee215SPauli Virtanen 384466dee215SPauli Virtanen lockdep_assert_held(&hdev->lock); 384566dee215SPauli Virtanen 384666dee215SPauli Virtanen list_for_each_entry_safe(conn, tmp, &hdev->conn_hash.list, list) { 384766dee215SPauli Virtanen if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY) || 384866dee215SPauli Virtanen conn->state == BT_OPEN || conn->iso_qos.ucast.cig != cig) 384966dee215SPauli Virtanen continue; 385066dee215SPauli Virtanen 385166dee215SPauli Virtanen if (HCI_CONN_HANDLE_UNSET(conn->handle)) 385266dee215SPauli Virtanen hci_conn_failed(conn, status); 385366dee215SPauli Virtanen } 385466dee215SPauli Virtanen } 385566dee215SPauli Virtanen 385626afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data, 385726afbd82SLuiz Augusto von Dentz struct sk_buff *skb) 385826afbd82SLuiz Augusto von Dentz { 385926afbd82SLuiz Augusto von Dentz struct hci_rp_le_set_cig_params *rp = data; 386071e95884SPauli Virtanen struct hci_cp_le_set_cig_params *cp; 386126afbd82SLuiz Augusto von Dentz struct hci_conn *conn; 386271e95884SPauli Virtanen u8 status = rp->status; 38637f74563eSPauli Virtanen bool pending = false; 386471e95884SPauli Virtanen int i; 386526afbd82SLuiz Augusto von Dentz 386626afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 386726afbd82SLuiz Augusto von Dentz 386871e95884SPauli Virtanen cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_CIG_PARAMS); 3869db9cbcadSPauli Virtanen if (!rp->status && (!cp || rp->num_handles != cp->num_cis || 3870db9cbcadSPauli Virtanen rp->cig_id != cp->cig_id)) { 387171e95884SPauli Virtanen bt_dev_err(hdev, "unexpected Set CIG Parameters response data"); 387271e95884SPauli Virtanen status = HCI_ERROR_UNSPECIFIED; 387371e95884SPauli Virtanen } 387471e95884SPauli Virtanen 387526afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev); 387626afbd82SLuiz Augusto von Dentz 387766dee215SPauli Virtanen /* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E page 2554 387866dee215SPauli Virtanen * 387966dee215SPauli Virtanen * If the Status return parameter is non-zero, then the state of the CIG 388066dee215SPauli Virtanen * and its CIS configurations shall not be changed by the command. If 388166dee215SPauli Virtanen * the CIG did not already exist, it shall not be created. 388266dee215SPauli Virtanen */ 388371e95884SPauli Virtanen if (status) { 388466dee215SPauli Virtanen /* Keep current configuration, fail only the unbound CIS */ 388566dee215SPauli Virtanen hci_unbound_cis_failed(hdev, rp->cig_id, status); 388626afbd82SLuiz Augusto von Dentz goto unlock; 388726afbd82SLuiz Augusto von Dentz } 388826afbd82SLuiz Augusto von Dentz 388971e95884SPauli Virtanen /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2553 389071e95884SPauli Virtanen * 389171e95884SPauli Virtanen * If the Status return parameter is zero, then the Controller shall 389271e95884SPauli Virtanen * set the Connection_Handle arrayed return parameter to the connection 389371e95884SPauli Virtanen * handle(s) corresponding to the CIS configurations specified in 389471e95884SPauli Virtanen * the CIS_IDs command parameter, in the same order. 389571e95884SPauli Virtanen */ 389671e95884SPauli Virtanen for (i = 0; i < rp->num_handles; ++i) { 389771e95884SPauli Virtanen conn = hci_conn_hash_lookup_cis(hdev, NULL, 0, rp->cig_id, 389871e95884SPauli Virtanen cp->cis[i].cis_id); 389971e95884SPauli Virtanen if (!conn || !bacmp(&conn->dst, BDADDR_ANY)) 390026afbd82SLuiz Augusto von Dentz continue; 390126afbd82SLuiz Augusto von Dentz 390271e95884SPauli Virtanen if (conn->state != BT_BOUND && conn->state != BT_CONNECT) 390371e95884SPauli Virtanen continue; 390471e95884SPauli Virtanen 390516e3b642SLuiz Augusto von Dentz if (hci_conn_set_handle(conn, __le16_to_cpu(rp->handle[i]))) 390616e3b642SLuiz Augusto von Dentz continue; 390726afbd82SLuiz Augusto von Dentz 39087f74563eSPauli Virtanen if (conn->state == BT_CONNECT) 39097f74563eSPauli Virtanen pending = true; 3910e9d50f76SLuiz Augusto von Dentz } 391126afbd82SLuiz Augusto von Dentz 391226afbd82SLuiz Augusto von Dentz unlock: 39137f74563eSPauli Virtanen if (pending) 39147f74563eSPauli Virtanen hci_le_create_cis_pending(hdev); 39157f74563eSPauli Virtanen 391626afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev); 391726afbd82SLuiz Augusto von Dentz 391826afbd82SLuiz Augusto von Dentz return rp->status; 391926afbd82SLuiz Augusto von Dentz } 392026afbd82SLuiz Augusto von Dentz 392126afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_setup_iso_path(struct hci_dev *hdev, void *data, 392226afbd82SLuiz Augusto von Dentz struct sk_buff *skb) 392326afbd82SLuiz Augusto von Dentz { 392426afbd82SLuiz Augusto von Dentz struct hci_rp_le_setup_iso_path *rp = data; 392526afbd82SLuiz Augusto von Dentz struct hci_cp_le_setup_iso_path *cp; 392626afbd82SLuiz Augusto von Dentz struct hci_conn *conn; 392726afbd82SLuiz Augusto von Dentz 392826afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 392926afbd82SLuiz Augusto von Dentz 393026afbd82SLuiz Augusto von Dentz cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SETUP_ISO_PATH); 393126afbd82SLuiz Augusto von Dentz if (!cp) 393226afbd82SLuiz Augusto von Dentz return rp->status; 393326afbd82SLuiz Augusto von Dentz 393426afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev); 393526afbd82SLuiz Augusto von Dentz 393626afbd82SLuiz Augusto von Dentz conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 393726afbd82SLuiz Augusto von Dentz if (!conn) 393826afbd82SLuiz Augusto von Dentz goto unlock; 393926afbd82SLuiz Augusto von Dentz 394026afbd82SLuiz Augusto von Dentz if (rp->status) { 394126afbd82SLuiz Augusto von Dentz hci_connect_cfm(conn, rp->status); 394226afbd82SLuiz Augusto von Dentz hci_conn_del(conn); 394326afbd82SLuiz Augusto von Dentz goto unlock; 394426afbd82SLuiz Augusto von Dentz } 394526afbd82SLuiz Augusto von Dentz 394626afbd82SLuiz Augusto von Dentz switch (cp->direction) { 394726afbd82SLuiz Augusto von Dentz /* Input (Host to Controller) */ 394826afbd82SLuiz Augusto von Dentz case 0x00: 394926afbd82SLuiz Augusto von Dentz /* Only confirm connection if output only */ 39500fe8c8d0SIulia Tanasescu if (conn->iso_qos.ucast.out.sdu && !conn->iso_qos.ucast.in.sdu) 395126afbd82SLuiz Augusto von Dentz hci_connect_cfm(conn, rp->status); 395226afbd82SLuiz Augusto von Dentz break; 395326afbd82SLuiz Augusto von Dentz /* Output (Controller to Host) */ 395426afbd82SLuiz Augusto von Dentz case 0x01: 395526afbd82SLuiz Augusto von Dentz /* Confirm connection since conn->iso_qos is always configured 395626afbd82SLuiz Augusto von Dentz * last. 395726afbd82SLuiz Augusto von Dentz */ 395826afbd82SLuiz Augusto von Dentz hci_connect_cfm(conn, rp->status); 39590b3df53cSLuiz Augusto von Dentz 39600b3df53cSLuiz Augusto von Dentz /* Notify device connected in case it is a BIG Sync */ 39610b3df53cSLuiz Augusto von Dentz if (!rp->status && test_bit(HCI_CONN_BIG_SYNC, &conn->flags)) 39620b3df53cSLuiz Augusto von Dentz mgmt_device_connected(hdev, conn, NULL, 0); 39630b3df53cSLuiz Augusto von Dentz 396426afbd82SLuiz Augusto von Dentz break; 396526afbd82SLuiz Augusto von Dentz } 396626afbd82SLuiz Augusto von Dentz 396726afbd82SLuiz Augusto von Dentz unlock: 396826afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev); 396926afbd82SLuiz Augusto von Dentz return rp->status; 397026afbd82SLuiz Augusto von Dentz } 397126afbd82SLuiz Augusto von Dentz 3972eca0ae4aSLuiz Augusto von Dentz static void hci_cs_le_create_big(struct hci_dev *hdev, u8 status) 3973eca0ae4aSLuiz Augusto von Dentz { 3974eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 3975eca0ae4aSLuiz Augusto von Dentz } 3976eca0ae4aSLuiz Augusto von Dentz 3977eca0ae4aSLuiz Augusto von Dentz static u8 hci_cc_set_per_adv_param(struct hci_dev *hdev, void *data, 3978eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb) 3979eca0ae4aSLuiz Augusto von Dentz { 3980eca0ae4aSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 3981eca0ae4aSLuiz Augusto von Dentz struct hci_cp_le_set_per_adv_params *cp; 3982eca0ae4aSLuiz Augusto von Dentz 3983eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 3984eca0ae4aSLuiz Augusto von Dentz 3985eca0ae4aSLuiz Augusto von Dentz if (rp->status) 3986eca0ae4aSLuiz Augusto von Dentz return rp->status; 3987eca0ae4aSLuiz Augusto von Dentz 3988eca0ae4aSLuiz Augusto von Dentz cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PER_ADV_PARAMS); 3989eca0ae4aSLuiz Augusto von Dentz if (!cp) 3990eca0ae4aSLuiz Augusto von Dentz return rp->status; 3991eca0ae4aSLuiz Augusto von Dentz 3992eca0ae4aSLuiz Augusto von Dentz /* TODO: set the conn state */ 3993eca0ae4aSLuiz Augusto von Dentz return rp->status; 3994eca0ae4aSLuiz Augusto von Dentz } 3995eca0ae4aSLuiz Augusto von Dentz 3996eca0ae4aSLuiz Augusto von Dentz static u8 hci_cc_le_set_per_adv_enable(struct hci_dev *hdev, void *data, 3997eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb) 3998eca0ae4aSLuiz Augusto von Dentz { 3999eca0ae4aSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 40006a42e9bfSIulia Tanasescu struct hci_cp_le_set_per_adv_enable *cp; 40016a42e9bfSIulia Tanasescu struct adv_info *adv = NULL, *n; 40026a42e9bfSIulia Tanasescu u8 per_adv_cnt = 0; 4003eca0ae4aSLuiz Augusto von Dentz 4004eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 4005eca0ae4aSLuiz Augusto von Dentz 4006eca0ae4aSLuiz Augusto von Dentz if (rp->status) 4007eca0ae4aSLuiz Augusto von Dentz return rp->status; 4008eca0ae4aSLuiz Augusto von Dentz 40096a42e9bfSIulia Tanasescu cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PER_ADV_ENABLE); 40106a42e9bfSIulia Tanasescu if (!cp) 4011eca0ae4aSLuiz Augusto von Dentz return rp->status; 4012eca0ae4aSLuiz Augusto von Dentz 4013eca0ae4aSLuiz Augusto von Dentz hci_dev_lock(hdev); 4014eca0ae4aSLuiz Augusto von Dentz 40156a42e9bfSIulia Tanasescu adv = hci_find_adv_instance(hdev, cp->handle); 4016eca0ae4aSLuiz Augusto von Dentz 40176a42e9bfSIulia Tanasescu if (cp->enable) { 40186a42e9bfSIulia Tanasescu hci_dev_set_flag(hdev, HCI_LE_PER_ADV); 40196a42e9bfSIulia Tanasescu 40206a42e9bfSIulia Tanasescu if (adv) 40216a42e9bfSIulia Tanasescu adv->enabled = true; 40226a42e9bfSIulia Tanasescu } else { 40236a42e9bfSIulia Tanasescu /* If just one instance was disabled check if there are 40246a42e9bfSIulia Tanasescu * any other instance enabled before clearing HCI_LE_PER_ADV. 40256a42e9bfSIulia Tanasescu * The current periodic adv instance will be marked as 40266a42e9bfSIulia Tanasescu * disabled once extended advertising is also disabled. 40276a42e9bfSIulia Tanasescu */ 40286a42e9bfSIulia Tanasescu list_for_each_entry_safe(adv, n, &hdev->adv_instances, 40296a42e9bfSIulia Tanasescu list) { 40306a42e9bfSIulia Tanasescu if (adv->periodic && adv->enabled) 40316a42e9bfSIulia Tanasescu per_adv_cnt++; 40326a42e9bfSIulia Tanasescu } 40336a42e9bfSIulia Tanasescu 40346a42e9bfSIulia Tanasescu if (per_adv_cnt > 1) 40356a42e9bfSIulia Tanasescu goto unlock; 40366a42e9bfSIulia Tanasescu 40376a42e9bfSIulia Tanasescu hci_dev_clear_flag(hdev, HCI_LE_PER_ADV); 40386a42e9bfSIulia Tanasescu } 40396a42e9bfSIulia Tanasescu 40406a42e9bfSIulia Tanasescu unlock: 4041eca0ae4aSLuiz Augusto von Dentz hci_dev_unlock(hdev); 4042eca0ae4aSLuiz Augusto von Dentz 4043eca0ae4aSLuiz Augusto von Dentz return rp->status; 4044eca0ae4aSLuiz Augusto von Dentz } 4045eca0ae4aSLuiz Augusto von Dentz 4046c8992cffSLuiz Augusto von Dentz #define HCI_CC_VL(_op, _func, _min, _max) \ 4047c8992cffSLuiz Augusto von Dentz { \ 4048c8992cffSLuiz Augusto von Dentz .op = _op, \ 4049c8992cffSLuiz Augusto von Dentz .func = _func, \ 4050c8992cffSLuiz Augusto von Dentz .min_len = _min, \ 4051c8992cffSLuiz Augusto von Dentz .max_len = _max, \ 4052c8992cffSLuiz Augusto von Dentz } 4053c8992cffSLuiz Augusto von Dentz 4054c8992cffSLuiz Augusto von Dentz #define HCI_CC(_op, _func, _len) \ 4055c8992cffSLuiz Augusto von Dentz HCI_CC_VL(_op, _func, _len, _len) 4056c8992cffSLuiz Augusto von Dentz 4057c8992cffSLuiz Augusto von Dentz #define HCI_CC_STATUS(_op, _func) \ 4058c8992cffSLuiz Augusto von Dentz HCI_CC(_op, _func, sizeof(struct hci_ev_status)) 4059c8992cffSLuiz Augusto von Dentz 4060c8992cffSLuiz Augusto von Dentz static const struct hci_cc { 4061c8992cffSLuiz Augusto von Dentz u16 op; 4062c8992cffSLuiz Augusto von Dentz u8 (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb); 4063c8992cffSLuiz Augusto von Dentz u16 min_len; 4064c8992cffSLuiz Augusto von Dentz u16 max_len; 4065c8992cffSLuiz Augusto von Dentz } hci_cc_table[] = { 4066c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_INQUIRY_CANCEL, hci_cc_inquiry_cancel), 4067c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_PERIODIC_INQ, hci_cc_periodic_inq), 4068c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_EXIT_PERIODIC_INQ, hci_cc_exit_periodic_inq), 4069c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_REMOTE_NAME_REQ_CANCEL, 4070c8992cffSLuiz Augusto von Dentz hci_cc_remote_name_req_cancel), 4071c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_ROLE_DISCOVERY, hci_cc_role_discovery, 4072c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_role_discovery)), 4073c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LINK_POLICY, hci_cc_read_link_policy, 4074c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_link_policy)), 4075c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_WRITE_LINK_POLICY, hci_cc_write_link_policy, 4076c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_write_link_policy)), 4077c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_DEF_LINK_POLICY, hci_cc_read_def_link_policy, 4078c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_def_link_policy)), 4079c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_DEF_LINK_POLICY, 4080c8992cffSLuiz Augusto von Dentz hci_cc_write_def_link_policy), 4081c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_RESET, hci_cc_reset), 4082c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_STORED_LINK_KEY, hci_cc_read_stored_link_key, 4083c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_stored_link_key)), 4084c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_DELETE_STORED_LINK_KEY, hci_cc_delete_stored_link_key, 4085c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_delete_stored_link_key)), 4086c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_LOCAL_NAME, hci_cc_write_local_name), 4087c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_NAME, hci_cc_read_local_name, 4088c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_name)), 4089c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_AUTH_ENABLE, hci_cc_write_auth_enable), 4090c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_ENCRYPT_MODE, hci_cc_write_encrypt_mode), 4091c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SCAN_ENABLE, hci_cc_write_scan_enable), 4092c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_SET_EVENT_FLT, hci_cc_set_event_filter), 4093c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_CLASS_OF_DEV, hci_cc_read_class_of_dev, 4094c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_class_of_dev)), 4095c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_CLASS_OF_DEV, hci_cc_write_class_of_dev), 4096c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_VOICE_SETTING, hci_cc_read_voice_setting, 4097c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_voice_setting)), 4098c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_VOICE_SETTING, hci_cc_write_voice_setting), 4099c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_NUM_SUPPORTED_IAC, hci_cc_read_num_supported_iac, 4100c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_num_supported_iac)), 4101c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SSP_MODE, hci_cc_write_ssp_mode), 4102c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SC_SUPPORT, hci_cc_write_sc_support), 4103c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_AUTH_PAYLOAD_TO, hci_cc_read_auth_payload_timeout, 4104c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_auth_payload_to)), 4105c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_WRITE_AUTH_PAYLOAD_TO, hci_cc_write_auth_payload_timeout, 4106c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_write_auth_payload_to)), 4107c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_VERSION, hci_cc_read_local_version, 4108c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_version)), 4109c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_COMMANDS, hci_cc_read_local_commands, 4110c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_commands)), 4111c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_FEATURES, hci_cc_read_local_features, 4112c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_features)), 4113c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_EXT_FEATURES, hci_cc_read_local_ext_features, 4114c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_ext_features)), 4115c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_BUFFER_SIZE, hci_cc_read_buffer_size, 4116c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_buffer_size)), 4117c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_BD_ADDR, hci_cc_read_bd_addr, 4118c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_bd_addr)), 4119c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_PAIRING_OPTS, hci_cc_read_local_pairing_opts, 4120c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_pairing_opts)), 4121c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_PAGE_SCAN_ACTIVITY, hci_cc_read_page_scan_activity, 4122c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_page_scan_activity)), 4123c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_ACTIVITY, 4124c8992cffSLuiz Augusto von Dentz hci_cc_write_page_scan_activity), 4125c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_PAGE_SCAN_TYPE, hci_cc_read_page_scan_type, 4126c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_page_scan_type)), 4127c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_TYPE, hci_cc_write_page_scan_type), 4128c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_DATA_BLOCK_SIZE, hci_cc_read_data_block_size, 4129c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_data_block_size)), 4130c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_FLOW_CONTROL_MODE, hci_cc_read_flow_control_mode, 4131c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_flow_control_mode)), 4132c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_AMP_INFO, hci_cc_read_local_amp_info, 4133c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_amp_info)), 4134c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_CLOCK, hci_cc_read_clock, 4135c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_clock)), 4136278d933eSBrian Gix HCI_CC(HCI_OP_READ_ENC_KEY_SIZE, hci_cc_read_enc_key_size, 4137278d933eSBrian Gix sizeof(struct hci_rp_read_enc_key_size)), 4138c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_INQ_RSP_TX_POWER, hci_cc_read_inq_rsp_tx_power, 4139c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_inq_rsp_tx_power)), 4140c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_DEF_ERR_DATA_REPORTING, 4141c8992cffSLuiz Augusto von Dentz hci_cc_read_def_err_data_reporting, 4142c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_def_err_data_reporting)), 4143c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_DEF_ERR_DATA_REPORTING, 4144c8992cffSLuiz Augusto von Dentz hci_cc_write_def_err_data_reporting), 4145c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_PIN_CODE_REPLY, hci_cc_pin_code_reply, 4146c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_pin_code_reply)), 4147c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_PIN_CODE_NEG_REPLY, hci_cc_pin_code_neg_reply, 4148c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_pin_code_neg_reply)), 4149c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_OOB_DATA, hci_cc_read_local_oob_data, 4150c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_oob_data)), 4151c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_OOB_EXT_DATA, hci_cc_read_local_oob_ext_data, 4152c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_oob_ext_data)), 4153c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE, hci_cc_le_read_buffer_size, 4154c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_buffer_size)), 4155c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_LOCAL_FEATURES, hci_cc_le_read_local_features, 4156c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_local_features)), 4157c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_ADV_TX_POWER, hci_cc_le_read_adv_tx_power, 4158c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_adv_tx_power)), 4159c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_CONFIRM_REPLY, hci_cc_user_confirm_reply, 4160c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)), 4161c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_CONFIRM_NEG_REPLY, hci_cc_user_confirm_neg_reply, 4162c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)), 4163c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_PASSKEY_REPLY, hci_cc_user_passkey_reply, 4164c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)), 4165c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_PASSKEY_NEG_REPLY, hci_cc_user_passkey_neg_reply, 4166c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)), 4167c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_RANDOM_ADDR, hci_cc_le_set_random_addr), 4168c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADV_ENABLE, hci_cc_le_set_adv_enable), 4169c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_PARAM, hci_cc_le_set_scan_param), 4170c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_ENABLE, hci_cc_le_set_scan_enable), 4171c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_ACCEPT_LIST_SIZE, 4172c8992cffSLuiz Augusto von Dentz hci_cc_le_read_accept_list_size, 4173c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_accept_list_size)), 4174c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_CLEAR_ACCEPT_LIST, hci_cc_le_clear_accept_list), 4175c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_ADD_TO_ACCEPT_LIST, 4176c8992cffSLuiz Augusto von Dentz hci_cc_le_add_to_accept_list), 4177c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_ACCEPT_LIST, 4178c8992cffSLuiz Augusto von Dentz hci_cc_le_del_from_accept_list), 4179c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_SUPPORTED_STATES, hci_cc_le_read_supported_states, 4180c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_supported_states)), 4181c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_DEF_DATA_LEN, hci_cc_le_read_def_data_len, 4182c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_def_data_len)), 4183c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_WRITE_DEF_DATA_LEN, 4184c8992cffSLuiz Augusto von Dentz hci_cc_le_write_def_data_len), 4185c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_ADD_TO_RESOLV_LIST, 4186c8992cffSLuiz Augusto von Dentz hci_cc_le_add_to_resolv_list), 4187c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_RESOLV_LIST, 4188c8992cffSLuiz Augusto von Dentz hci_cc_le_del_from_resolv_list), 4189c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_CLEAR_RESOLV_LIST, 4190c8992cffSLuiz Augusto von Dentz hci_cc_le_clear_resolv_list), 4191c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_RESOLV_LIST_SIZE, hci_cc_le_read_resolv_list_size, 4192c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_resolv_list_size)), 4193c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 4194c8992cffSLuiz Augusto von Dentz hci_cc_le_set_addr_resolution_enable), 4195c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_MAX_DATA_LEN, hci_cc_le_read_max_data_len, 4196c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_max_data_len)), 4197c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_LE_HOST_SUPPORTED, 4198c8992cffSLuiz Augusto von Dentz hci_cc_write_le_host_supported), 4199c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADV_PARAM, hci_cc_set_adv_param), 4200c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_RSSI, hci_cc_read_rssi, 4201c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_rssi)), 4202c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_TX_POWER, hci_cc_read_tx_power, 4203c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_tx_power)), 4204c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SSP_DEBUG_MODE, hci_cc_write_ssp_debug_mode), 4205c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_PARAMS, 4206c8992cffSLuiz Augusto von Dentz hci_cc_le_set_ext_scan_param), 4207c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_ENABLE, 4208c8992cffSLuiz Augusto von Dentz hci_cc_le_set_ext_scan_enable), 4209c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_DEFAULT_PHY, hci_cc_le_set_default_phy), 4210c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS, 4211c8992cffSLuiz Augusto von Dentz hci_cc_le_read_num_adv_sets, 4212c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_num_supported_adv_sets)), 4213c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_SET_EXT_ADV_PARAMS, hci_cc_set_ext_adv_param, 4214c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_set_ext_adv_params)), 4215c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_EXT_ADV_ENABLE, 4216c8992cffSLuiz Augusto von Dentz hci_cc_le_set_ext_adv_enable), 4217c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADV_SET_RAND_ADDR, 4218c8992cffSLuiz Augusto von Dentz hci_cc_le_set_adv_set_random_addr), 4219c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_REMOVE_ADV_SET, hci_cc_le_remove_adv_set), 4220c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_CLEAR_ADV_SETS, hci_cc_le_clear_adv_sets), 4221eca0ae4aSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_PER_ADV_PARAMS, hci_cc_set_per_adv_param), 4222eca0ae4aSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_PER_ADV_ENABLE, 4223eca0ae4aSLuiz Augusto von Dentz hci_cc_le_set_per_adv_enable), 4224c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_TRANSMIT_POWER, hci_cc_le_read_transmit_power, 4225853b70b5SLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_transmit_power)), 422626afbd82SLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_PRIVACY_MODE, hci_cc_le_set_privacy_mode), 422726afbd82SLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE_V2, hci_cc_le_read_buffer_size_v2, 422826afbd82SLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_buffer_size_v2)), 422926afbd82SLuiz Augusto von Dentz HCI_CC_VL(HCI_OP_LE_SET_CIG_PARAMS, hci_cc_le_set_cig_params, 423026afbd82SLuiz Augusto von Dentz sizeof(struct hci_rp_le_set_cig_params), HCI_MAX_EVENT_SIZE), 423126afbd82SLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_SETUP_ISO_PATH, hci_cc_le_setup_iso_path, 423226afbd82SLuiz Augusto von Dentz sizeof(struct hci_rp_le_setup_iso_path)), 4233c8992cffSLuiz Augusto von Dentz }; 4234c8992cffSLuiz Augusto von Dentz 4235c8992cffSLuiz Augusto von Dentz static u8 hci_cc_func(struct hci_dev *hdev, const struct hci_cc *cc, 4236c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 4237c8992cffSLuiz Augusto von Dentz { 4238c8992cffSLuiz Augusto von Dentz void *data; 4239c8992cffSLuiz Augusto von Dentz 4240c8992cffSLuiz Augusto von Dentz if (skb->len < cc->min_len) { 4241c8992cffSLuiz Augusto von Dentz bt_dev_err(hdev, "unexpected cc 0x%4.4x length: %u < %u", 4242c8992cffSLuiz Augusto von Dentz cc->op, skb->len, cc->min_len); 4243c8992cffSLuiz Augusto von Dentz return HCI_ERROR_UNSPECIFIED; 4244c8992cffSLuiz Augusto von Dentz } 4245c8992cffSLuiz Augusto von Dentz 4246c8992cffSLuiz Augusto von Dentz /* Just warn if the length is over max_len size it still be possible to 4247c8992cffSLuiz Augusto von Dentz * partially parse the cc so leave to callback to decide if that is 4248c8992cffSLuiz Augusto von Dentz * acceptable. 4249c8992cffSLuiz Augusto von Dentz */ 4250c8992cffSLuiz Augusto von Dentz if (skb->len > cc->max_len) 4251c8992cffSLuiz Augusto von Dentz bt_dev_warn(hdev, "unexpected cc 0x%4.4x length: %u > %u", 4252c8992cffSLuiz Augusto von Dentz cc->op, skb->len, cc->max_len); 4253c8992cffSLuiz Augusto von Dentz 4254c8992cffSLuiz Augusto von Dentz data = hci_cc_skb_pull(hdev, skb, cc->op, cc->min_len); 4255c8992cffSLuiz Augusto von Dentz if (!data) 4256c8992cffSLuiz Augusto von Dentz return HCI_ERROR_UNSPECIFIED; 4257c8992cffSLuiz Augusto von Dentz 4258c8992cffSLuiz Augusto von Dentz return cc->func(hdev, data, skb); 4259c8992cffSLuiz Augusto von Dentz } 4260c8992cffSLuiz Augusto von Dentz 42613e54c589SLuiz Augusto von Dentz static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data, 42623e54c589SLuiz Augusto von Dentz struct sk_buff *skb, u16 *opcode, u8 *status, 4263e6214487SJohan Hedberg hci_req_complete_t *req_complete, 4264e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 4265a9de9248SMarcel Holtmann { 42663e54c589SLuiz Augusto von Dentz struct hci_ev_cmd_complete *ev = data; 4267c8992cffSLuiz Augusto von Dentz int i; 4268e6214487SJohan Hedberg 4269e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode); 4270a9de9248SMarcel Holtmann 4271c8992cffSLuiz Augusto von Dentz bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode); 4272a9de9248SMarcel Holtmann 4273c8992cffSLuiz Augusto von Dentz for (i = 0; i < ARRAY_SIZE(hci_cc_table); i++) { 4274c8992cffSLuiz Augusto von Dentz if (hci_cc_table[i].op == *opcode) { 4275c8992cffSLuiz Augusto von Dentz *status = hci_cc_func(hdev, &hci_cc_table[i], skb); 42764d93483bSAndre Guedes break; 4277c8992cffSLuiz Augusto von Dentz } 4278a9de9248SMarcel Holtmann } 4279a9de9248SMarcel Holtmann 4280afcb3369SHans de Goede if (i == ARRAY_SIZE(hci_cc_table)) { 4281afcb3369SHans de Goede /* Unknown opcode, assume byte 0 contains the status, so 4282afcb3369SHans de Goede * that e.g. __hci_cmd_sync() properly returns errors 4283afcb3369SHans de Goede * for vendor specific commands send by HCI drivers. 4284afcb3369SHans de Goede * If a vendor doesn't actually follow this convention we may 4285afcb3369SHans de Goede * need to introduce a vendor CC table in order to properly set 4286afcb3369SHans de Goede * the status. 4287afcb3369SHans de Goede */ 4288afcb3369SHans de Goede *status = skb->data[0]; 4289afcb3369SHans de Goede } 4290afcb3369SHans de Goede 4291ecb71f25SKiran K handle_cmd_cnt_and_timer(hdev, ev->ncmd); 4292600b2150SJohan Hedberg 4293e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, *status, req_complete, 4294e6214487SJohan Hedberg req_complete_skb); 42959238f36aSJohan Hedberg 4296f80c5dadSJoão Paulo Rechi Vita if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) { 4297f80c5dadSJoão Paulo Rechi Vita bt_dev_err(hdev, 4298f80c5dadSJoão Paulo Rechi Vita "unexpected event for opcode 0x%4.4x", *opcode); 4299f80c5dadSJoão Paulo Rechi Vita return; 4300f80c5dadSJoão Paulo Rechi Vita } 4301f80c5dadSJoão Paulo Rechi Vita 4302600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 4303c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 4304a9de9248SMarcel Holtmann } 4305a9de9248SMarcel Holtmann 430626afbd82SLuiz Augusto von Dentz static void hci_cs_le_create_cis(struct hci_dev *hdev, u8 status) 430726afbd82SLuiz Augusto von Dentz { 430826afbd82SLuiz Augusto von Dentz struct hci_cp_le_create_cis *cp; 43097f74563eSPauli Virtanen bool pending = false; 431026afbd82SLuiz Augusto von Dentz int i; 431126afbd82SLuiz Augusto von Dentz 431226afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 431326afbd82SLuiz Augusto von Dentz 431426afbd82SLuiz Augusto von Dentz if (!status) 431526afbd82SLuiz Augusto von Dentz return; 431626afbd82SLuiz Augusto von Dentz 431726afbd82SLuiz Augusto von Dentz cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CIS); 431826afbd82SLuiz Augusto von Dentz if (!cp) 431926afbd82SLuiz Augusto von Dentz return; 432026afbd82SLuiz Augusto von Dentz 432126afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev); 432226afbd82SLuiz Augusto von Dentz 432326afbd82SLuiz Augusto von Dentz /* Remove connection if command failed */ 432426afbd82SLuiz Augusto von Dentz for (i = 0; cp->num_cis; cp->num_cis--, i++) { 432526afbd82SLuiz Augusto von Dentz struct hci_conn *conn; 432626afbd82SLuiz Augusto von Dentz u16 handle; 432726afbd82SLuiz Augusto von Dentz 432826afbd82SLuiz Augusto von Dentz handle = __le16_to_cpu(cp->cis[i].cis_handle); 432926afbd82SLuiz Augusto von Dentz 433026afbd82SLuiz Augusto von Dentz conn = hci_conn_hash_lookup_handle(hdev, handle); 433126afbd82SLuiz Augusto von Dentz if (conn) { 43327f74563eSPauli Virtanen if (test_and_clear_bit(HCI_CONN_CREATE_CIS, 43337f74563eSPauli Virtanen &conn->flags)) 43347f74563eSPauli Virtanen pending = true; 433526afbd82SLuiz Augusto von Dentz conn->state = BT_CLOSED; 433626afbd82SLuiz Augusto von Dentz hci_connect_cfm(conn, status); 433726afbd82SLuiz Augusto von Dentz hci_conn_del(conn); 433826afbd82SLuiz Augusto von Dentz } 433926afbd82SLuiz Augusto von Dentz } 434026afbd82SLuiz Augusto von Dentz 43417f74563eSPauli Virtanen if (pending) 43427f74563eSPauli Virtanen hci_le_create_cis_pending(hdev); 43437f74563eSPauli Virtanen 434426afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev); 434526afbd82SLuiz Augusto von Dentz } 434626afbd82SLuiz Augusto von Dentz 4347147306ccSLuiz Augusto von Dentz #define HCI_CS(_op, _func) \ 4348147306ccSLuiz Augusto von Dentz { \ 4349147306ccSLuiz Augusto von Dentz .op = _op, \ 4350147306ccSLuiz Augusto von Dentz .func = _func, \ 4351147306ccSLuiz Augusto von Dentz } 4352147306ccSLuiz Augusto von Dentz 4353147306ccSLuiz Augusto von Dentz static const struct hci_cs { 4354147306ccSLuiz Augusto von Dentz u16 op; 4355147306ccSLuiz Augusto von Dentz void (*func)(struct hci_dev *hdev, __u8 status); 4356147306ccSLuiz Augusto von Dentz } hci_cs_table[] = { 4357147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_INQUIRY, hci_cs_inquiry), 4358147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_CREATE_CONN, hci_cs_create_conn), 4359147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_DISCONNECT, hci_cs_disconnect), 4360147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_ADD_SCO, hci_cs_add_sco), 4361147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_AUTH_REQUESTED, hci_cs_auth_requested), 4362147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SET_CONN_ENCRYPT, hci_cs_set_conn_encrypt), 4363147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_REMOTE_NAME_REQ, hci_cs_remote_name_req), 4364147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_READ_REMOTE_FEATURES, hci_cs_read_remote_features), 4365147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_READ_REMOTE_EXT_FEATURES, 4366147306ccSLuiz Augusto von Dentz hci_cs_read_remote_ext_features), 4367147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SETUP_SYNC_CONN, hci_cs_setup_sync_conn), 4368147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_ENHANCED_SETUP_SYNC_CONN, 4369147306ccSLuiz Augusto von Dentz hci_cs_enhanced_setup_sync_conn), 4370147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SNIFF_MODE, hci_cs_sniff_mode), 4371147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_EXIT_SNIFF_MODE, hci_cs_exit_sniff_mode), 4372147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SWITCH_ROLE, hci_cs_switch_role), 4373147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_CREATE_CONN, hci_cs_le_create_conn), 4374147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_READ_REMOTE_FEATURES, hci_cs_le_read_remote_features), 4375147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_START_ENC, hci_cs_le_start_enc), 437626afbd82SLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_EXT_CREATE_CONN, hci_cs_le_ext_create_conn), 437726afbd82SLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_CREATE_CIS, hci_cs_le_create_cis), 4378eca0ae4aSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_CREATE_BIG, hci_cs_le_create_big), 4379147306ccSLuiz Augusto von Dentz }; 4380147306ccSLuiz Augusto von Dentz 43813e54c589SLuiz Augusto von Dentz static void hci_cmd_status_evt(struct hci_dev *hdev, void *data, 43823e54c589SLuiz Augusto von Dentz struct sk_buff *skb, u16 *opcode, u8 *status, 4383e6214487SJohan Hedberg hci_req_complete_t *req_complete, 4384e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 4385a9de9248SMarcel Holtmann { 43863e54c589SLuiz Augusto von Dentz struct hci_ev_cmd_status *ev = data; 4387147306ccSLuiz Augusto von Dentz int i; 4388a9de9248SMarcel Holtmann 4389e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode); 4390e6214487SJohan Hedberg *status = ev->status; 4391a9de9248SMarcel Holtmann 4392147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode); 4393a9de9248SMarcel Holtmann 4394147306ccSLuiz Augusto von Dentz for (i = 0; i < ARRAY_SIZE(hci_cs_table); i++) { 4395147306ccSLuiz Augusto von Dentz if (hci_cs_table[i].op == *opcode) { 4396147306ccSLuiz Augusto von Dentz hci_cs_table[i].func(hdev, ev->status); 4397a9de9248SMarcel Holtmann break; 4398147306ccSLuiz Augusto von Dentz } 4399a9de9248SMarcel Holtmann } 4400a9de9248SMarcel Holtmann 4401ecb71f25SKiran K handle_cmd_cnt_and_timer(hdev, ev->ncmd); 4402600b2150SJohan Hedberg 4403444c6dd5SJohan Hedberg /* Indicate request completion if the command failed. Also, if 4404444c6dd5SJohan Hedberg * we're not waiting for a special event and we get a success 4405444c6dd5SJohan Hedberg * command status we should try to flag the request as completed 4406444c6dd5SJohan Hedberg * (since for this kind of commands there will not be a command 4407444c6dd5SJohan Hedberg * complete event). 4408444c6dd5SJohan Hedberg */ 44092af7aa66SLuiz Augusto von Dentz if (ev->status || (hdev->req_skb && !hci_skb_event(hdev->req_skb))) { 4410e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete, 4411e6214487SJohan Hedberg req_complete_skb); 4412f80c5dadSJoão Paulo Rechi Vita if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) { 441385b56857SLuiz Augusto von Dentz bt_dev_err(hdev, "unexpected event for opcode 0x%4.4x", 441485b56857SLuiz Augusto von Dentz *opcode); 4415f80c5dadSJoão Paulo Rechi Vita return; 4416f80c5dadSJoão Paulo Rechi Vita } 441785b56857SLuiz Augusto von Dentz } 4418f80c5dadSJoão Paulo Rechi Vita 4419600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 4420c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 4421a9de9248SMarcel Holtmann } 4422a9de9248SMarcel Holtmann 44233e54c589SLuiz Augusto von Dentz static void hci_hardware_error_evt(struct hci_dev *hdev, void *data, 44243e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 442524dfa343SMarcel Holtmann { 44263e54c589SLuiz Augusto von Dentz struct hci_ev_hardware_error *ev = data; 4427ae61a10dSLuiz Augusto von Dentz 44283e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "code 0x%2.2x", ev->code); 442924dfa343SMarcel Holtmann 4430c7741d16SMarcel Holtmann hdev->hw_error_code = ev->code; 4431c7741d16SMarcel Holtmann 4432c7741d16SMarcel Holtmann queue_work(hdev->req_workqueue, &hdev->error_reset); 443324dfa343SMarcel Holtmann } 443424dfa343SMarcel Holtmann 44353e54c589SLuiz Augusto von Dentz static void hci_role_change_evt(struct hci_dev *hdev, void *data, 44363e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 4437a9de9248SMarcel Holtmann { 44383e54c589SLuiz Augusto von Dentz struct hci_ev_role_change *ev = data; 4439a9de9248SMarcel Holtmann struct hci_conn *conn; 4440a9de9248SMarcel Holtmann 44413e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 4442a9de9248SMarcel Holtmann 4443a9de9248SMarcel Holtmann hci_dev_lock(hdev); 4444a9de9248SMarcel Holtmann 4445a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 4446a9de9248SMarcel Holtmann if (conn) { 444740bef302SJohan Hedberg if (!ev->status) 444840bef302SJohan Hedberg conn->role = ev->role; 4449a9de9248SMarcel Holtmann 445051a8efd7SJohan Hedberg clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 4451a9de9248SMarcel Holtmann 4452a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role); 4453a9de9248SMarcel Holtmann } 4454a9de9248SMarcel Holtmann 4455a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 4456a9de9248SMarcel Holtmann } 4457a9de9248SMarcel Holtmann 44583e54c589SLuiz Augusto von Dentz static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data, 44593e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 44601da177e4SLinus Torvalds { 44613e54c589SLuiz Augusto von Dentz struct hci_ev_num_comp_pkts *ev = data; 44621da177e4SLinus Torvalds int i; 44631da177e4SLinus Torvalds 4464aadc3d2fSLuiz Augusto von Dentz if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_PKTS, 4465aadc3d2fSLuiz Augusto von Dentz flex_array_size(ev, handles, ev->num))) 4466aadc3d2fSLuiz Augusto von Dentz return; 4467aadc3d2fSLuiz Augusto von Dentz 446832ac5b9bSAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) { 44692064ee33SMarcel Holtmann bt_dev_err(hdev, "wrong event for mode %d", hdev->flow_ctl_mode); 447032ac5b9bSAndrei Emeltchenko return; 447132ac5b9bSAndrei Emeltchenko } 447232ac5b9bSAndrei Emeltchenko 44733e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num %d", ev->num); 44741da177e4SLinus Torvalds 4475aadc3d2fSLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) { 4476613a1c0cSAndrei Emeltchenko struct hci_comp_pkts_info *info = &ev->handles[i]; 44771da177e4SLinus Torvalds struct hci_conn *conn; 44781da177e4SLinus Torvalds __u16 handle, count; 44791da177e4SLinus Torvalds 4480613a1c0cSAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 4481613a1c0cSAndrei Emeltchenko count = __le16_to_cpu(info->count); 44821da177e4SLinus Torvalds 44831da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 4484f4280918SAndrei Emeltchenko if (!conn) 4485f4280918SAndrei Emeltchenko continue; 4486f4280918SAndrei Emeltchenko 44871da177e4SLinus Torvalds conn->sent -= count; 44881da177e4SLinus Torvalds 4489f4280918SAndrei Emeltchenko switch (conn->type) { 4490f4280918SAndrei Emeltchenko case ACL_LINK: 449170f23020SAndrei Emeltchenko hdev->acl_cnt += count; 449270f23020SAndrei Emeltchenko if (hdev->acl_cnt > hdev->acl_pkts) 44931da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts; 4494f4280918SAndrei Emeltchenko break; 4495f4280918SAndrei Emeltchenko 4496f4280918SAndrei Emeltchenko case LE_LINK: 44976ed58ec5SVille Tervo if (hdev->le_pkts) { 44986ed58ec5SVille Tervo hdev->le_cnt += count; 44996ed58ec5SVille Tervo if (hdev->le_cnt > hdev->le_pkts) 45006ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 45016ed58ec5SVille Tervo } else { 45026ed58ec5SVille Tervo hdev->acl_cnt += count; 45036ed58ec5SVille Tervo if (hdev->acl_cnt > hdev->acl_pkts) 45046ed58ec5SVille Tervo hdev->acl_cnt = hdev->acl_pkts; 45056ed58ec5SVille Tervo } 4506f4280918SAndrei Emeltchenko break; 4507f4280918SAndrei Emeltchenko 4508f4280918SAndrei Emeltchenko case SCO_LINK: 450970f23020SAndrei Emeltchenko hdev->sco_cnt += count; 451070f23020SAndrei Emeltchenko if (hdev->sco_cnt > hdev->sco_pkts) 45115b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 4512f4280918SAndrei Emeltchenko break; 4513f4280918SAndrei Emeltchenko 451426afbd82SLuiz Augusto von Dentz case ISO_LINK: 451526afbd82SLuiz Augusto von Dentz if (hdev->iso_pkts) { 451626afbd82SLuiz Augusto von Dentz hdev->iso_cnt += count; 451726afbd82SLuiz Augusto von Dentz if (hdev->iso_cnt > hdev->iso_pkts) 451826afbd82SLuiz Augusto von Dentz hdev->iso_cnt = hdev->iso_pkts; 451926afbd82SLuiz Augusto von Dentz } else if (hdev->le_pkts) { 452026afbd82SLuiz Augusto von Dentz hdev->le_cnt += count; 452126afbd82SLuiz Augusto von Dentz if (hdev->le_cnt > hdev->le_pkts) 452226afbd82SLuiz Augusto von Dentz hdev->le_cnt = hdev->le_pkts; 452326afbd82SLuiz Augusto von Dentz } else { 452426afbd82SLuiz Augusto von Dentz hdev->acl_cnt += count; 452526afbd82SLuiz Augusto von Dentz if (hdev->acl_cnt > hdev->acl_pkts) 452626afbd82SLuiz Augusto von Dentz hdev->acl_cnt = hdev->acl_pkts; 452726afbd82SLuiz Augusto von Dentz } 452826afbd82SLuiz Augusto von Dentz break; 452926afbd82SLuiz Augusto von Dentz 4530f4280918SAndrei Emeltchenko default: 45312064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown type %d conn %p", 45322064ee33SMarcel Holtmann conn->type, conn); 4533f4280918SAndrei Emeltchenko break; 45341da177e4SLinus Torvalds } 45351da177e4SLinus Torvalds } 4536a9de9248SMarcel Holtmann 45373eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 45381da177e4SLinus Torvalds } 45391da177e4SLinus Torvalds 454076ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev, 454176ef7cf7SAndrei Emeltchenko __u16 handle) 454276ef7cf7SAndrei Emeltchenko { 454376ef7cf7SAndrei Emeltchenko struct hci_chan *chan; 454476ef7cf7SAndrei Emeltchenko 454576ef7cf7SAndrei Emeltchenko switch (hdev->dev_type) { 4546ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 454776ef7cf7SAndrei Emeltchenko return hci_conn_hash_lookup_handle(hdev, handle); 454876ef7cf7SAndrei Emeltchenko case HCI_AMP: 454976ef7cf7SAndrei Emeltchenko chan = hci_chan_lookup_handle(hdev, handle); 455076ef7cf7SAndrei Emeltchenko if (chan) 455176ef7cf7SAndrei Emeltchenko return chan->conn; 455276ef7cf7SAndrei Emeltchenko break; 455376ef7cf7SAndrei Emeltchenko default: 45542064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type); 455576ef7cf7SAndrei Emeltchenko break; 455676ef7cf7SAndrei Emeltchenko } 455776ef7cf7SAndrei Emeltchenko 455876ef7cf7SAndrei Emeltchenko return NULL; 455976ef7cf7SAndrei Emeltchenko } 456076ef7cf7SAndrei Emeltchenko 45613e54c589SLuiz Augusto von Dentz static void hci_num_comp_blocks_evt(struct hci_dev *hdev, void *data, 45623e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 456325e89e99SAndrei Emeltchenko { 45643e54c589SLuiz Augusto von Dentz struct hci_ev_num_comp_blocks *ev = data; 456525e89e99SAndrei Emeltchenko int i; 456625e89e99SAndrei Emeltchenko 4567ae61a10dSLuiz Augusto von Dentz if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_BLOCKS, 4568ae61a10dSLuiz Augusto von Dentz flex_array_size(ev, handles, ev->num_hndl))) 4569ae61a10dSLuiz Augusto von Dentz return; 4570ae61a10dSLuiz Augusto von Dentz 457125e89e99SAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) { 45723e54c589SLuiz Augusto von Dentz bt_dev_err(hdev, "wrong event for mode %d", 45733e54c589SLuiz Augusto von Dentz hdev->flow_ctl_mode); 457425e89e99SAndrei Emeltchenko return; 457525e89e99SAndrei Emeltchenko } 457625e89e99SAndrei Emeltchenko 45773e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num_blocks %d num_hndl %d", ev->num_blocks, 457825e89e99SAndrei Emeltchenko ev->num_hndl); 457925e89e99SAndrei Emeltchenko 458025e89e99SAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 458125e89e99SAndrei Emeltchenko struct hci_comp_blocks_info *info = &ev->handles[i]; 458276ef7cf7SAndrei Emeltchenko struct hci_conn *conn = NULL; 458325e89e99SAndrei Emeltchenko __u16 handle, block_count; 458425e89e99SAndrei Emeltchenko 458525e89e99SAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 458625e89e99SAndrei Emeltchenko block_count = __le16_to_cpu(info->blocks); 458725e89e99SAndrei Emeltchenko 458876ef7cf7SAndrei Emeltchenko conn = __hci_conn_lookup_handle(hdev, handle); 458925e89e99SAndrei Emeltchenko if (!conn) 459025e89e99SAndrei Emeltchenko continue; 459125e89e99SAndrei Emeltchenko 459225e89e99SAndrei Emeltchenko conn->sent -= block_count; 459325e89e99SAndrei Emeltchenko 459425e89e99SAndrei Emeltchenko switch (conn->type) { 459525e89e99SAndrei Emeltchenko case ACL_LINK: 4596bd1eb66bSAndrei Emeltchenko case AMP_LINK: 459725e89e99SAndrei Emeltchenko hdev->block_cnt += block_count; 459825e89e99SAndrei Emeltchenko if (hdev->block_cnt > hdev->num_blocks) 459925e89e99SAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 460025e89e99SAndrei Emeltchenko break; 460125e89e99SAndrei Emeltchenko 460225e89e99SAndrei Emeltchenko default: 46032064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown type %d conn %p", 46042064ee33SMarcel Holtmann conn->type, conn); 460525e89e99SAndrei Emeltchenko break; 460625e89e99SAndrei Emeltchenko } 460725e89e99SAndrei Emeltchenko } 460825e89e99SAndrei Emeltchenko 460925e89e99SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->tx_work); 461025e89e99SAndrei Emeltchenko } 461125e89e99SAndrei Emeltchenko 46123e54c589SLuiz Augusto von Dentz static void hci_mode_change_evt(struct hci_dev *hdev, void *data, 46133e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 46141da177e4SLinus Torvalds { 46153e54c589SLuiz Augusto von Dentz struct hci_ev_mode_change *ev = data; 461604837f64SMarcel Holtmann struct hci_conn *conn; 46171da177e4SLinus Torvalds 46183e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 46191da177e4SLinus Torvalds 46201da177e4SLinus Torvalds hci_dev_lock(hdev); 46211da177e4SLinus Torvalds 462204837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 462304837f64SMarcel Holtmann if (conn) { 462404837f64SMarcel Holtmann conn->mode = ev->mode; 462504837f64SMarcel Holtmann 46268fc9ced3SGustavo Padovan if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, 46278fc9ced3SGustavo Padovan &conn->flags)) { 462804837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE) 462958a681efSJohan Hedberg set_bit(HCI_CONN_POWER_SAVE, &conn->flags); 463004837f64SMarcel Holtmann else 463158a681efSJohan Hedberg clear_bit(HCI_CONN_POWER_SAVE, &conn->flags); 463204837f64SMarcel Holtmann } 4633e73439d8SMarcel Holtmann 463451a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 4635e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 463604837f64SMarcel Holtmann } 463704837f64SMarcel Holtmann 463804837f64SMarcel Holtmann hci_dev_unlock(hdev); 463904837f64SMarcel Holtmann } 464004837f64SMarcel Holtmann 46413e54c589SLuiz Augusto von Dentz static void hci_pin_code_request_evt(struct hci_dev *hdev, void *data, 46423e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 46431da177e4SLinus Torvalds { 46443e54c589SLuiz Augusto von Dentz struct hci_ev_pin_code_req *ev = data; 4645052b30b0SMarcel Holtmann struct hci_conn *conn; 4646052b30b0SMarcel Holtmann 46473e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 4648052b30b0SMarcel Holtmann 4649052b30b0SMarcel Holtmann hci_dev_lock(hdev); 4650052b30b0SMarcel Holtmann 4651052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 4652b6f98044SWaldemar Rymarkiewicz if (!conn) 4653b6f98044SWaldemar Rymarkiewicz goto unlock; 4654b6f98044SWaldemar Rymarkiewicz 4655b6f98044SWaldemar Rymarkiewicz if (conn->state == BT_CONNECTED) { 4656052b30b0SMarcel Holtmann hci_conn_hold(conn); 4657052b30b0SMarcel Holtmann conn->disc_timeout = HCI_PAIRING_TIMEOUT; 465876a68ba0SDavid Herrmann hci_conn_drop(conn); 4659052b30b0SMarcel Holtmann } 4660052b30b0SMarcel Holtmann 4661d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 46622f407f0aSJohan Hedberg !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) { 466303b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, 466403b555e1SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 4665d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_MGMT)) { 4666a770bb5aSWaldemar Rymarkiewicz u8 secure; 4667a770bb5aSWaldemar Rymarkiewicz 4668a770bb5aSWaldemar Rymarkiewicz if (conn->pending_sec_level == BT_SECURITY_HIGH) 4669a770bb5aSWaldemar Rymarkiewicz secure = 1; 4670a770bb5aSWaldemar Rymarkiewicz else 4671a770bb5aSWaldemar Rymarkiewicz secure = 0; 4672a770bb5aSWaldemar Rymarkiewicz 4673744cf19eSJohan Hedberg mgmt_pin_code_request(hdev, &ev->bdaddr, secure); 4674a770bb5aSWaldemar Rymarkiewicz } 4675980e1a53SJohan Hedberg 4676b6f98044SWaldemar Rymarkiewicz unlock: 4677052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 46781da177e4SLinus Torvalds } 46791da177e4SLinus Torvalds 4680cb6f3f7aSJohan Hedberg static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len) 4681cb6f3f7aSJohan Hedberg { 4682cb6f3f7aSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION) 4683cb6f3f7aSJohan Hedberg return; 4684cb6f3f7aSJohan Hedberg 4685cb6f3f7aSJohan Hedberg conn->pin_length = pin_len; 4686cb6f3f7aSJohan Hedberg conn->key_type = key_type; 4687cb6f3f7aSJohan Hedberg 4688cb6f3f7aSJohan Hedberg switch (key_type) { 4689cb6f3f7aSJohan Hedberg case HCI_LK_LOCAL_UNIT: 4690cb6f3f7aSJohan Hedberg case HCI_LK_REMOTE_UNIT: 4691cb6f3f7aSJohan Hedberg case HCI_LK_DEBUG_COMBINATION: 4692cb6f3f7aSJohan Hedberg return; 4693cb6f3f7aSJohan Hedberg case HCI_LK_COMBINATION: 4694cb6f3f7aSJohan Hedberg if (pin_len == 16) 4695cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH; 4696cb6f3f7aSJohan Hedberg else 4697cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM; 4698cb6f3f7aSJohan Hedberg break; 4699cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P192: 4700cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P256: 4701cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM; 4702cb6f3f7aSJohan Hedberg break; 4703cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P192: 4704cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH; 4705cb6f3f7aSJohan Hedberg break; 4706cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P256: 4707cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_FIPS; 4708cb6f3f7aSJohan Hedberg break; 4709cb6f3f7aSJohan Hedberg } 4710cb6f3f7aSJohan Hedberg } 4711cb6f3f7aSJohan Hedberg 47123e54c589SLuiz Augusto von Dentz static void hci_link_key_request_evt(struct hci_dev *hdev, void *data, 47133e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 47141da177e4SLinus Torvalds { 47153e54c589SLuiz Augusto von Dentz struct hci_ev_link_key_req *ev = data; 471655ed8ca1SJohan Hedberg struct hci_cp_link_key_reply cp; 471755ed8ca1SJohan Hedberg struct hci_conn *conn; 471855ed8ca1SJohan Hedberg struct link_key *key; 471955ed8ca1SJohan Hedberg 47203e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 472155ed8ca1SJohan Hedberg 4722d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 472355ed8ca1SJohan Hedberg return; 472455ed8ca1SJohan Hedberg 472555ed8ca1SJohan Hedberg hci_dev_lock(hdev); 472655ed8ca1SJohan Hedberg 472755ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, &ev->bdaddr); 472855ed8ca1SJohan Hedberg if (!key) { 47293e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "link key not found for %pMR", &ev->bdaddr); 473055ed8ca1SJohan Hedberg goto not_found; 473155ed8ca1SJohan Hedberg } 473255ed8ca1SJohan Hedberg 47333e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "found key type %u for %pMR", key->type, &ev->bdaddr); 473455ed8ca1SJohan Hedberg 473555ed8ca1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 473660b83f57SWaldemar Rymarkiewicz if (conn) { 4737fe8bc5acSJohan Hedberg clear_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags); 4738fe8bc5acSJohan Hedberg 473966138ce8SMarcel Holtmann if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 || 474066138ce8SMarcel Holtmann key->type == HCI_LK_UNAUTH_COMBINATION_P256) && 4741807deac2SGustavo Padovan conn->auth_type != 0xff && (conn->auth_type & 0x01)) { 47423e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "ignoring unauthenticated key"); 474355ed8ca1SJohan Hedberg goto not_found; 474455ed8ca1SJohan Hedberg } 474555ed8ca1SJohan Hedberg 474660b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && 4747f3fb0b58SJohan Hedberg (conn->pending_sec_level == BT_SECURITY_HIGH || 4748f3fb0b58SJohan Hedberg conn->pending_sec_level == BT_SECURITY_FIPS)) { 47493e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "ignoring key unauthenticated for high security"); 475060b83f57SWaldemar Rymarkiewicz goto not_found; 475160b83f57SWaldemar Rymarkiewicz } 475260b83f57SWaldemar Rymarkiewicz 4753cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len); 475460b83f57SWaldemar Rymarkiewicz } 475560b83f57SWaldemar Rymarkiewicz 475655ed8ca1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 47579b3b4460SAndrei Emeltchenko memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE); 475855ed8ca1SJohan Hedberg 475955ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); 476055ed8ca1SJohan Hedberg 476155ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 476255ed8ca1SJohan Hedberg 476355ed8ca1SJohan Hedberg return; 476455ed8ca1SJohan Hedberg 476555ed8ca1SJohan Hedberg not_found: 476655ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); 476755ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 47681da177e4SLinus Torvalds } 47691da177e4SLinus Torvalds 47703e54c589SLuiz Augusto von Dentz static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data, 47713e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 47721da177e4SLinus Torvalds { 47733e54c589SLuiz Augusto von Dentz struct hci_ev_link_key_notify *ev = data; 4774052b30b0SMarcel Holtmann struct hci_conn *conn; 47757652ff6aSJohan Hedberg struct link_key *key; 47767652ff6aSJohan Hedberg bool persistent; 477755ed8ca1SJohan Hedberg u8 pin_len = 0; 4778052b30b0SMarcel Holtmann 47793e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 4780052b30b0SMarcel Holtmann 4781052b30b0SMarcel Holtmann hci_dev_lock(hdev); 4782052b30b0SMarcel Holtmann 4783052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 478482c13d42SJohan Hedberg if (!conn) 478582c13d42SJohan Hedberg goto unlock; 478682c13d42SJohan Hedberg 478733155c4aSLee, Chun-Yi /* Ignore NULL link key against CVE-2020-26555 */ 4788b5412606SLuiz Augusto von Dentz if (!crypto_memneq(ev->link_key, ZERO_KEY, HCI_LINK_KEY_SIZE)) { 478933155c4aSLee, Chun-Yi bt_dev_dbg(hdev, "Ignore NULL link key (ZERO KEY) for %pMR", 479033155c4aSLee, Chun-Yi &ev->bdaddr); 479133155c4aSLee, Chun-Yi hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 479233155c4aSLee, Chun-Yi hci_conn_drop(conn); 479333155c4aSLee, Chun-Yi goto unlock; 479433155c4aSLee, Chun-Yi } 479533155c4aSLee, Chun-Yi 4796052b30b0SMarcel Holtmann hci_conn_hold(conn); 4797052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 479876a68ba0SDavid Herrmann hci_conn_drop(conn); 479982c13d42SJohan Hedberg 4800fe8bc5acSJohan Hedberg set_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags); 4801cb6f3f7aSJohan Hedberg conn_set_key(conn, ev->key_type, conn->pin_length); 4802052b30b0SMarcel Holtmann 4803d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 48047652ff6aSJohan Hedberg goto unlock; 480555ed8ca1SJohan Hedberg 48067652ff6aSJohan Hedberg key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key, 48077652ff6aSJohan Hedberg ev->key_type, pin_len, &persistent); 48087652ff6aSJohan Hedberg if (!key) 48097652ff6aSJohan Hedberg goto unlock; 48107652ff6aSJohan Hedberg 4811cb6f3f7aSJohan Hedberg /* Update connection information since adding the key will have 4812cb6f3f7aSJohan Hedberg * fixed up the type in the case of changed combination keys. 4813cb6f3f7aSJohan Hedberg */ 4814cb6f3f7aSJohan Hedberg if (ev->key_type == HCI_LK_CHANGED_COMBINATION) 4815cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len); 4816cb6f3f7aSJohan Hedberg 48177652ff6aSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 48187652ff6aSJohan Hedberg 48196d5650c4SJohan Hedberg /* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag 48206d5650c4SJohan Hedberg * is set. If it's not set simply remove the key from the kernel 48216d5650c4SJohan Hedberg * list (we've still notified user space about it but with 48226d5650c4SJohan Hedberg * store_hint being 0). 48236d5650c4SJohan Hedberg */ 48246d5650c4SJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION && 4825d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) { 48260378b597SJohan Hedberg list_del_rcu(&key->list); 48270378b597SJohan Hedberg kfree_rcu(key, rcu); 482882c13d42SJohan Hedberg goto unlock; 482982c13d42SJohan Hedberg } 483082c13d42SJohan Hedberg 4831af6a9c32SJohan Hedberg if (persistent) 4832af6a9c32SJohan Hedberg clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 4833af6a9c32SJohan Hedberg else 4834af6a9c32SJohan Hedberg set_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 48357652ff6aSJohan Hedberg 48367652ff6aSJohan Hedberg unlock: 4837052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 48381da177e4SLinus Torvalds } 48391da177e4SLinus Torvalds 48403e54c589SLuiz Augusto von Dentz static void hci_clock_offset_evt(struct hci_dev *hdev, void *data, 48413e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 484204837f64SMarcel Holtmann { 48433e54c589SLuiz Augusto von Dentz struct hci_ev_clock_offset *ev = data; 484404837f64SMarcel Holtmann struct hci_conn *conn; 484504837f64SMarcel Holtmann 48463e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 484704837f64SMarcel Holtmann 484804837f64SMarcel Holtmann hci_dev_lock(hdev); 484904837f64SMarcel Holtmann 485004837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 48511da177e4SLinus Torvalds if (conn && !ev->status) { 48521da177e4SLinus Torvalds struct inquiry_entry *ie; 48531da177e4SLinus Torvalds 4854cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 4855cc11b9c1SAndrei Emeltchenko if (ie) { 48561da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset; 48571da177e4SLinus Torvalds ie->timestamp = jiffies; 48581da177e4SLinus Torvalds } 48591da177e4SLinus Torvalds } 48601da177e4SLinus Torvalds 48611da177e4SLinus Torvalds hci_dev_unlock(hdev); 48621da177e4SLinus Torvalds } 48631da177e4SLinus Torvalds 48643e54c589SLuiz Augusto von Dentz static void hci_pkt_type_change_evt(struct hci_dev *hdev, void *data, 48653e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 4866a8746417SMarcel Holtmann { 48673e54c589SLuiz Augusto von Dentz struct hci_ev_pkt_type_change *ev = data; 4868a8746417SMarcel Holtmann struct hci_conn *conn; 4869a8746417SMarcel Holtmann 48703e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 4871a8746417SMarcel Holtmann 4872a8746417SMarcel Holtmann hci_dev_lock(hdev); 4873a8746417SMarcel Holtmann 4874a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 4875a8746417SMarcel Holtmann if (conn && !ev->status) 4876a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type); 4877a8746417SMarcel Holtmann 4878a8746417SMarcel Holtmann hci_dev_unlock(hdev); 4879a8746417SMarcel Holtmann } 4880a8746417SMarcel Holtmann 48813e54c589SLuiz Augusto von Dentz static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, void *data, 48823e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 488385a1e930SMarcel Holtmann { 48843e54c589SLuiz Augusto von Dentz struct hci_ev_pscan_rep_mode *ev = data; 488585a1e930SMarcel Holtmann struct inquiry_entry *ie; 488685a1e930SMarcel Holtmann 48873e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 488885a1e930SMarcel Holtmann 488985a1e930SMarcel Holtmann hci_dev_lock(hdev); 489085a1e930SMarcel Holtmann 4891cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 4892cc11b9c1SAndrei Emeltchenko if (ie) { 489385a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode; 489485a1e930SMarcel Holtmann ie->timestamp = jiffies; 489585a1e930SMarcel Holtmann } 489685a1e930SMarcel Holtmann 489785a1e930SMarcel Holtmann hci_dev_unlock(hdev); 489885a1e930SMarcel Holtmann } 489985a1e930SMarcel Holtmann 49003e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, void *edata, 4901807deac2SGustavo Padovan struct sk_buff *skb) 4902a9de9248SMarcel Holtmann { 490372279d17SLuiz Augusto von Dentz struct hci_ev_inquiry_result_rssi *ev = edata; 4904a9de9248SMarcel Holtmann struct inquiry_data data; 49058d08d324SLuiz Augusto von Dentz int i; 4906a9de9248SMarcel Holtmann 490772279d17SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num_rsp %d", ev->num); 49088d08d324SLuiz Augusto von Dentz 490972279d17SLuiz Augusto von Dentz if (!ev->num) 4910a9de9248SMarcel Holtmann return; 4911a9de9248SMarcel Holtmann 4912d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 49131519cc17SAndre Guedes return; 49141519cc17SAndre Guedes 4915a9de9248SMarcel Holtmann hci_dev_lock(hdev); 4916a9de9248SMarcel Holtmann 491772279d17SLuiz Augusto von Dentz if (skb->len == array_size(ev->num, 491872279d17SLuiz Augusto von Dentz sizeof(struct inquiry_info_rssi_pscan))) { 49198d08d324SLuiz Augusto von Dentz struct inquiry_info_rssi_pscan *info; 4920a9de9248SMarcel Holtmann 492172279d17SLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) { 4922af58925cSMarcel Holtmann u32 flags; 4923af58925cSMarcel Holtmann 4924fee64503SLuiz Augusto von Dentz info = hci_ev_skb_pull(hdev, skb, 4925fee64503SLuiz Augusto von Dentz HCI_EV_INQUIRY_RESULT_WITH_RSSI, 4926fee64503SLuiz Augusto von Dentz sizeof(*info)); 4927fee64503SLuiz Augusto von Dentz if (!info) { 4928fee64503SLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x", 4929fee64503SLuiz Augusto von Dentz HCI_EV_INQUIRY_RESULT_WITH_RSSI); 4930c07ba878SDan Carpenter goto unlock; 4931fee64503SLuiz Augusto von Dentz } 4932fee64503SLuiz Augusto von Dentz 4933a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 4934a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 4935a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 4936a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode; 4937a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 4938a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 4939a9de9248SMarcel Holtmann data.rssi = info->rssi; 494041a96212SMarcel Holtmann data.ssp_mode = 0x00; 49413175405bSJohan Hedberg 4942af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 4943af58925cSMarcel Holtmann 494448264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 4945e17acd40SJohan Hedberg info->dev_class, info->rssi, 4946b338d917SBrian Gix flags, NULL, 0, NULL, 0, 0); 4947a9de9248SMarcel Holtmann } 494872279d17SLuiz Augusto von Dentz } else if (skb->len == array_size(ev->num, 494972279d17SLuiz Augusto von Dentz sizeof(struct inquiry_info_rssi))) { 49508d08d324SLuiz Augusto von Dentz struct inquiry_info_rssi *info; 4951a9de9248SMarcel Holtmann 495272279d17SLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) { 4953af58925cSMarcel Holtmann u32 flags; 4954af58925cSMarcel Holtmann 4955fee64503SLuiz Augusto von Dentz info = hci_ev_skb_pull(hdev, skb, 4956fee64503SLuiz Augusto von Dentz HCI_EV_INQUIRY_RESULT_WITH_RSSI, 4957fee64503SLuiz Augusto von Dentz sizeof(*info)); 4958fee64503SLuiz Augusto von Dentz if (!info) { 4959fee64503SLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x", 4960fee64503SLuiz Augusto von Dentz HCI_EV_INQUIRY_RESULT_WITH_RSSI); 4961c07ba878SDan Carpenter goto unlock; 4962fee64503SLuiz Augusto von Dentz } 4963fee64503SLuiz Augusto von Dentz 4964a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 4965a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 4966a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 4967a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 4968a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 4969a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 4970a9de9248SMarcel Holtmann data.rssi = info->rssi; 497141a96212SMarcel Holtmann data.ssp_mode = 0x00; 4972af58925cSMarcel Holtmann 4973af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 4974af58925cSMarcel Holtmann 497548264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 4976e17acd40SJohan Hedberg info->dev_class, info->rssi, 4977b338d917SBrian Gix flags, NULL, 0, NULL, 0, 0); 4978a9de9248SMarcel Holtmann } 49798d08d324SLuiz Augusto von Dentz } else { 49808d08d324SLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x", 49818d08d324SLuiz Augusto von Dentz HCI_EV_INQUIRY_RESULT_WITH_RSSI); 4982a9de9248SMarcel Holtmann } 4983c07ba878SDan Carpenter unlock: 4984a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 4985a9de9248SMarcel Holtmann } 4986a9de9248SMarcel Holtmann 49873e54c589SLuiz Augusto von Dentz static void hci_remote_ext_features_evt(struct hci_dev *hdev, void *data, 4988807deac2SGustavo Padovan struct sk_buff *skb) 4989a9de9248SMarcel Holtmann { 49903e54c589SLuiz Augusto von Dentz struct hci_ev_remote_ext_features *ev = data; 499141a96212SMarcel Holtmann struct hci_conn *conn; 499241a96212SMarcel Holtmann 49933e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 499441a96212SMarcel Holtmann 499541a96212SMarcel Holtmann hci_dev_lock(hdev); 499641a96212SMarcel Holtmann 499741a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 4998ccd556feSJohan Hedberg if (!conn) 4999ccd556feSJohan Hedberg goto unlock; 5000ccd556feSJohan Hedberg 5001cad718edSJohan Hedberg if (ev->page < HCI_MAX_PAGES) 5002cad718edSJohan Hedberg memcpy(conn->features[ev->page], ev->features, 8); 5003cad718edSJohan Hedberg 5004769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) { 500541a96212SMarcel Holtmann struct inquiry_entry *ie; 500641a96212SMarcel Holtmann 5007cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 5008cc11b9c1SAndrei Emeltchenko if (ie) 500902b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 501041a96212SMarcel Holtmann 5011bbb0eadaSJaganath Kanakkassery if (ev->features[0] & LMP_HOST_SSP) { 501258a681efSJohan Hedberg set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 5013bbb0eadaSJaganath Kanakkassery } else { 5014bbb0eadaSJaganath Kanakkassery /* It is mandatory by the Bluetooth specification that 5015bbb0eadaSJaganath Kanakkassery * Extended Inquiry Results are only used when Secure 5016bbb0eadaSJaganath Kanakkassery * Simple Pairing is enabled, but some devices violate 5017bbb0eadaSJaganath Kanakkassery * this. 5018bbb0eadaSJaganath Kanakkassery * 5019bbb0eadaSJaganath Kanakkassery * To make these devices work, the internal SSP 5020bbb0eadaSJaganath Kanakkassery * enabled flag needs to be cleared if the remote host 5021bbb0eadaSJaganath Kanakkassery * features do not indicate SSP support */ 5022bbb0eadaSJaganath Kanakkassery clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 5023bbb0eadaSJaganath Kanakkassery } 5024eb9a8f3fSMarcel Holtmann 5025eb9a8f3fSMarcel Holtmann if (ev->features[0] & LMP_HOST_SC) 5026eb9a8f3fSMarcel Holtmann set_bit(HCI_CONN_SC_ENABLED, &conn->flags); 502741a96212SMarcel Holtmann } 502841a96212SMarcel Holtmann 5029ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 5030ccd556feSJohan Hedberg goto unlock; 5031ccd556feSJohan Hedberg 5032671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 5033127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 5034127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 5035127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 5036127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 5037127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 50380b3df53cSLuiz Augusto von Dentz } else { 50391c6ed31bSYu Liu mgmt_device_connected(hdev, conn, NULL, 0); 50400b3df53cSLuiz Augusto von Dentz } 5041392599b9SJohan Hedberg 5042127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 5043769be974SMarcel Holtmann conn->state = BT_CONNECTED; 5044539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 504576a68ba0SDavid Herrmann hci_conn_drop(conn); 5046769be974SMarcel Holtmann } 5047769be974SMarcel Holtmann 5048ccd556feSJohan Hedberg unlock: 504941a96212SMarcel Holtmann hci_dev_unlock(hdev); 5050a9de9248SMarcel Holtmann } 5051a9de9248SMarcel Holtmann 50523e54c589SLuiz Augusto von Dentz static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data, 5053807deac2SGustavo Padovan struct sk_buff *skb) 5054a9de9248SMarcel Holtmann { 50553e54c589SLuiz Augusto von Dentz struct hci_ev_sync_conn_complete *ev = data; 5056b6a0dc82SMarcel Holtmann struct hci_conn *conn; 5057c86cc5a3SLuiz Augusto von Dentz u8 status = ev->status; 5058b6a0dc82SMarcel Holtmann 50593afee211SSoenke Huster switch (ev->link_type) { 50603afee211SSoenke Huster case SCO_LINK: 50613afee211SSoenke Huster case ESCO_LINK: 50623afee211SSoenke Huster break; 50633afee211SSoenke Huster default: 50643afee211SSoenke Huster /* As per Core 5.3 Vol 4 Part E 7.7.35 (p.2219), Link_Type 50653afee211SSoenke Huster * for HCI_Synchronous_Connection_Complete is limited to 50663afee211SSoenke Huster * either SCO or eSCO 50673afee211SSoenke Huster */ 50683afee211SSoenke Huster bt_dev_err(hdev, "Ignoring connect complete event for invalid link type"); 50693afee211SSoenke Huster return; 50703afee211SSoenke Huster } 50713afee211SSoenke Huster 5072c86cc5a3SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 5073b6a0dc82SMarcel Holtmann 5074b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 5075b6a0dc82SMarcel Holtmann 5076b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 50779dc0a3afSMarcel Holtmann if (!conn) { 50789dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK) 50799dc0a3afSMarcel Holtmann goto unlock; 50809dc0a3afSMarcel Holtmann 5081618353b1SKuba Pawlak /* When the link type in the event indicates SCO connection 5082618353b1SKuba Pawlak * and lookup of the connection object fails, then check 5083618353b1SKuba Pawlak * if an eSCO connection object exists. 5084618353b1SKuba Pawlak * 5085618353b1SKuba Pawlak * The core limits the synchronous connections to either 5086618353b1SKuba Pawlak * SCO or eSCO. The eSCO connection is preferred and tried 5087618353b1SKuba Pawlak * to be setup first and until successfully established, 5088618353b1SKuba Pawlak * the link type will be hinted as eSCO. 5089618353b1SKuba Pawlak */ 50909dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 5091b6a0dc82SMarcel Holtmann if (!conn) 5092b6a0dc82SMarcel Holtmann goto unlock; 50939dc0a3afSMarcel Holtmann } 50949dc0a3afSMarcel Holtmann 5095d5ebaa7cSSoenke Huster /* The HCI_Synchronous_Connection_Complete event is only sent once per connection. 5096d5ebaa7cSSoenke Huster * Processing it more than once per connection can corrupt kernel memory. 509792fe24a7SDesmond Cheong Zhi Xi * 5098d5ebaa7cSSoenke Huster * As the connection handle is set here for the first time, it indicates 5099d5ebaa7cSSoenke Huster * whether the connection is already set up. 510092fe24a7SDesmond Cheong Zhi Xi */ 51019f78191cSLuiz Augusto von Dentz if (!HCI_CONN_HANDLE_UNSET(conn->handle)) { 5102d5ebaa7cSSoenke Huster bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete event for existing connection"); 510392fe24a7SDesmond Cheong Zhi Xi goto unlock; 510492fe24a7SDesmond Cheong Zhi Xi } 510592fe24a7SDesmond Cheong Zhi Xi 5106c86cc5a3SLuiz Augusto von Dentz switch (status) { 5107d5ebaa7cSSoenke Huster case 0x00: 510816e3b642SLuiz Augusto von Dentz status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle)); 510916e3b642SLuiz Augusto von Dentz if (status) { 5110c86cc5a3SLuiz Augusto von Dentz conn->state = BT_CLOSED; 5111c86cc5a3SLuiz Augusto von Dentz break; 5112c86cc5a3SLuiz Augusto von Dentz } 5113c86cc5a3SLuiz Augusto von Dentz 5114732547f9SMarcel Holtmann conn->state = BT_CONNECTED; 5115618353b1SKuba Pawlak conn->type = ev->link_type; 5116732547f9SMarcel Holtmann 511723b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 5118732547f9SMarcel Holtmann hci_conn_add_sysfs(conn); 5119732547f9SMarcel Holtmann break; 5120732547f9SMarcel Holtmann 512181218d20SNick Pelly case 0x10: /* Connection Accept Timeout */ 51221a4c958cSFrédéric Dalleau case 0x0d: /* Connection Rejected due to Limited Resources */ 5123705e5711SStephen Coe case 0x11: /* Unsupported Feature or Parameter Value */ 5124732547f9SMarcel Holtmann case 0x1c: /* SCO interval rejected */ 51251038a00bSNick Pelly case 0x1a: /* Unsupported Remote Feature */ 512656b5453aSHsin-Yu Chao case 0x1e: /* Invalid LMP Parameters */ 5127732547f9SMarcel Holtmann case 0x1f: /* Unspecified error */ 512827539bc4SAndrew Earl case 0x20: /* Unsupported LMP Parameter value */ 51292dea632fSFrédéric Dalleau if (conn->out) { 5130efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 5131efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK); 513206149746SLuiz Augusto von Dentz if (hci_setup_sync(conn, conn->parent->handle)) 5133efc7688bSMarcel Holtmann goto unlock; 5134efc7688bSMarcel Holtmann } 513519186c7bSGustavo A. R. Silva fallthrough; 5136efc7688bSMarcel Holtmann 5137732547f9SMarcel Holtmann default: 5138b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED; 5139732547f9SMarcel Holtmann break; 5140732547f9SMarcel Holtmann } 5141b6a0dc82SMarcel Holtmann 51421f8330eaSSathish Narsimman bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode); 5143f4f9fa0cSChethan T N /* Notify only in case of SCO over HCI transport data path which 5144f4f9fa0cSChethan T N * is zero and non-zero value shall be non-HCI transport data path 5145f4f9fa0cSChethan T N */ 5146a27c519aSJackie Liu if (conn->codec.data_path == 0 && hdev->notify) { 5147a27c519aSJackie Liu switch (ev->air_mode) { 5148a27c519aSJackie Liu case 0x02: 5149a27c519aSJackie Liu hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD); 5150a27c519aSJackie Liu break; 5151a27c519aSJackie Liu case 0x03: 5152a27c519aSJackie Liu hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP); 5153a27c519aSJackie Liu break; 5154a27c519aSJackie Liu } 5155f4f9fa0cSChethan T N } 5156f4f9fa0cSChethan T N 5157c86cc5a3SLuiz Augusto von Dentz hci_connect_cfm(conn, status); 5158c86cc5a3SLuiz Augusto von Dentz if (status) 5159b6a0dc82SMarcel Holtmann hci_conn_del(conn); 5160b6a0dc82SMarcel Holtmann 5161b6a0dc82SMarcel Holtmann unlock: 5162b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 5163a9de9248SMarcel Holtmann } 5164a9de9248SMarcel Holtmann 5165efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len) 5166efdcf8e3SMarcel Holtmann { 5167efdcf8e3SMarcel Holtmann size_t parsed = 0; 5168efdcf8e3SMarcel Holtmann 5169efdcf8e3SMarcel Holtmann while (parsed < eir_len) { 5170efdcf8e3SMarcel Holtmann u8 field_len = eir[0]; 5171efdcf8e3SMarcel Holtmann 5172efdcf8e3SMarcel Holtmann if (field_len == 0) 5173efdcf8e3SMarcel Holtmann return parsed; 5174efdcf8e3SMarcel Holtmann 5175efdcf8e3SMarcel Holtmann parsed += field_len + 1; 5176efdcf8e3SMarcel Holtmann eir += field_len + 1; 5177efdcf8e3SMarcel Holtmann } 5178efdcf8e3SMarcel Holtmann 5179efdcf8e3SMarcel Holtmann return eir_len; 5180efdcf8e3SMarcel Holtmann } 5181efdcf8e3SMarcel Holtmann 51823e54c589SLuiz Augusto von Dentz static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, void *edata, 5183807deac2SGustavo Padovan struct sk_buff *skb) 5184a9de9248SMarcel Holtmann { 51853e54c589SLuiz Augusto von Dentz struct hci_ev_ext_inquiry_result *ev = edata; 5186a9de9248SMarcel Holtmann struct inquiry_data data; 51879d939d94SVishal Agarwal size_t eir_len; 518870a6b8deSLuiz Augusto von Dentz int i; 5189a9de9248SMarcel Holtmann 519070a6b8deSLuiz Augusto von Dentz if (!hci_ev_skb_pull(hdev, skb, HCI_EV_EXTENDED_INQUIRY_RESULT, 519170a6b8deSLuiz Augusto von Dentz flex_array_size(ev, info, ev->num))) 519270a6b8deSLuiz Augusto von Dentz return; 519370a6b8deSLuiz Augusto von Dentz 51943e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num %d", ev->num); 519570a6b8deSLuiz Augusto von Dentz 519670a6b8deSLuiz Augusto von Dentz if (!ev->num) 5197a9de9248SMarcel Holtmann return; 5198a9de9248SMarcel Holtmann 5199d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 52001519cc17SAndre Guedes return; 52011519cc17SAndre Guedes 5202a9de9248SMarcel Holtmann hci_dev_lock(hdev); 5203a9de9248SMarcel Holtmann 520470a6b8deSLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) { 520570a6b8deSLuiz Augusto von Dentz struct extended_inquiry_info *info = &ev->info[i]; 5206af58925cSMarcel Holtmann u32 flags; 5207af58925cSMarcel Holtmann bool name_known; 5208561aafbcSJohan Hedberg 5209a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 5210a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 5211a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 5212a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 5213a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 5214a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 5215a9de9248SMarcel Holtmann data.rssi = info->rssi; 521641a96212SMarcel Holtmann data.ssp_mode = 0x01; 5217561aafbcSJohan Hedberg 5218d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 52190d3b7f64SJohan Hedberg name_known = eir_get_data(info->data, 52204ddb1930SJohan Hedberg sizeof(info->data), 52210d3b7f64SJohan Hedberg EIR_NAME_COMPLETE, NULL); 5222561aafbcSJohan Hedberg else 5223561aafbcSJohan Hedberg name_known = true; 5224561aafbcSJohan Hedberg 5225af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, name_known); 5226af58925cSMarcel Holtmann 52279d939d94SVishal Agarwal eir_len = eir_get_length(info->data, sizeof(info->data)); 5228af58925cSMarcel Holtmann 522948264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 5230af58925cSMarcel Holtmann info->dev_class, info->rssi, 5231b338d917SBrian Gix flags, info->data, eir_len, NULL, 0, 0); 5232a9de9248SMarcel Holtmann } 5233a9de9248SMarcel Holtmann 5234a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 5235a9de9248SMarcel Holtmann } 5236a9de9248SMarcel Holtmann 52373e54c589SLuiz Augusto von Dentz static void hci_key_refresh_complete_evt(struct hci_dev *hdev, void *data, 52381c2e0041SJohan Hedberg struct sk_buff *skb) 52391c2e0041SJohan Hedberg { 52403e54c589SLuiz Augusto von Dentz struct hci_ev_key_refresh_complete *ev = data; 52411c2e0041SJohan Hedberg struct hci_conn *conn; 52421c2e0041SJohan Hedberg 52433e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x handle 0x%4.4x", ev->status, 52441c2e0041SJohan Hedberg __le16_to_cpu(ev->handle)); 52451c2e0041SJohan Hedberg 52461c2e0041SJohan Hedberg hci_dev_lock(hdev); 52471c2e0041SJohan Hedberg 52481c2e0041SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 52491c2e0041SJohan Hedberg if (!conn) 52501c2e0041SJohan Hedberg goto unlock; 52511c2e0041SJohan Hedberg 52529eb1fbfaSJohan Hedberg /* For BR/EDR the necessary steps are taken through the 52539eb1fbfaSJohan Hedberg * auth_complete event. 52549eb1fbfaSJohan Hedberg */ 52559eb1fbfaSJohan Hedberg if (conn->type != LE_LINK) 52569eb1fbfaSJohan Hedberg goto unlock; 52579eb1fbfaSJohan Hedberg 52581c2e0041SJohan Hedberg if (!ev->status) 52591c2e0041SJohan Hedberg conn->sec_level = conn->pending_sec_level; 52601c2e0041SJohan Hedberg 52611c2e0041SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 52621c2e0041SJohan Hedberg 52631c2e0041SJohan Hedberg if (ev->status && conn->state == BT_CONNECTED) { 5264bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 526576a68ba0SDavid Herrmann hci_conn_drop(conn); 52661c2e0041SJohan Hedberg goto unlock; 52671c2e0041SJohan Hedberg } 52681c2e0041SJohan Hedberg 52691c2e0041SJohan Hedberg if (conn->state == BT_CONFIG) { 52701c2e0041SJohan Hedberg if (!ev->status) 52711c2e0041SJohan Hedberg conn->state = BT_CONNECTED; 52721c2e0041SJohan Hedberg 5273539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 527476a68ba0SDavid Herrmann hci_conn_drop(conn); 52751c2e0041SJohan Hedberg } else { 52761c2e0041SJohan Hedberg hci_auth_cfm(conn, ev->status); 52771c2e0041SJohan Hedberg 52781c2e0041SJohan Hedberg hci_conn_hold(conn); 52791c2e0041SJohan Hedberg conn->disc_timeout = HCI_DISCONN_TIMEOUT; 528076a68ba0SDavid Herrmann hci_conn_drop(conn); 52811c2e0041SJohan Hedberg } 52821c2e0041SJohan Hedberg 52831c2e0041SJohan Hedberg unlock: 52841c2e0041SJohan Hedberg hci_dev_unlock(hdev); 52851c2e0041SJohan Hedberg } 52861c2e0041SJohan Hedberg 52876039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn) 528817fa4b9dSJohan Hedberg { 528917fa4b9dSJohan Hedberg /* If remote requests no-bonding follow that lead */ 5290acabae96SMikel Astiz if (conn->remote_auth == HCI_AT_NO_BONDING || 5291acabae96SMikel Astiz conn->remote_auth == HCI_AT_NO_BONDING_MITM) 529258797bf7SWaldemar Rymarkiewicz return conn->remote_auth | (conn->auth_type & 0x01); 529317fa4b9dSJohan Hedberg 5294b7f94c88SMikel Astiz /* If both remote and local have enough IO capabilities, require 5295b7f94c88SMikel Astiz * MITM protection 5296b7f94c88SMikel Astiz */ 5297b7f94c88SMikel Astiz if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT && 5298b7f94c88SMikel Astiz conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) 5299b7f94c88SMikel Astiz return conn->remote_auth | 0x01; 5300b7f94c88SMikel Astiz 53017e74170aSTimo Mueller /* No MITM protection possible so ignore remote requirement */ 53027e74170aSTimo Mueller return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01); 530317fa4b9dSJohan Hedberg } 530417fa4b9dSJohan Hedberg 5305a83ed81eSMarcel Holtmann static u8 bredr_oob_data_present(struct hci_conn *conn) 5306a83ed81eSMarcel Holtmann { 5307a83ed81eSMarcel Holtmann struct hci_dev *hdev = conn->hdev; 5308a83ed81eSMarcel Holtmann struct oob_data *data; 5309a83ed81eSMarcel Holtmann 5310a83ed81eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR); 5311a83ed81eSMarcel Holtmann if (!data) 5312a83ed81eSMarcel Holtmann return 0x00; 5313a83ed81eSMarcel Holtmann 5314bf21d793SMarcel Holtmann if (bredr_sc_enabled(hdev)) { 5315bf21d793SMarcel Holtmann /* When Secure Connections is enabled, then just 5316bf21d793SMarcel Holtmann * return the present value stored with the OOB 5317bf21d793SMarcel Holtmann * data. The stored value contains the right present 5318bf21d793SMarcel Holtmann * information. However it can only be trusted when 5319bf21d793SMarcel Holtmann * not in Secure Connection Only mode. 5320aa5b0345SMarcel Holtmann */ 5321d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SC_ONLY)) 5322bf21d793SMarcel Holtmann return data->present; 5323bf21d793SMarcel Holtmann 5324bf21d793SMarcel Holtmann /* When Secure Connections Only mode is enabled, then 5325bf21d793SMarcel Holtmann * the P-256 values are required. If they are not 5326bf21d793SMarcel Holtmann * available, then do not declare that OOB data is 5327bf21d793SMarcel Holtmann * present. 5328bf21d793SMarcel Holtmann */ 5329b5412606SLuiz Augusto von Dentz if (!crypto_memneq(data->rand256, ZERO_KEY, 16) || 5330b5412606SLuiz Augusto von Dentz !crypto_memneq(data->hash256, ZERO_KEY, 16)) 5331aa5b0345SMarcel Holtmann return 0x00; 5332aa5b0345SMarcel Holtmann 5333bf21d793SMarcel Holtmann return 0x02; 5334bf21d793SMarcel Holtmann } 5335659c7fb0SMarcel Holtmann 5336659c7fb0SMarcel Holtmann /* When Secure Connections is not enabled or actually 5337659c7fb0SMarcel Holtmann * not supported by the hardware, then check that if 5338659c7fb0SMarcel Holtmann * P-192 data values are present. 5339659c7fb0SMarcel Holtmann */ 5340b5412606SLuiz Augusto von Dentz if (!crypto_memneq(data->rand192, ZERO_KEY, 16) || 5341b5412606SLuiz Augusto von Dentz !crypto_memneq(data->hash192, ZERO_KEY, 16)) 5342659c7fb0SMarcel Holtmann return 0x00; 5343659c7fb0SMarcel Holtmann 5344a83ed81eSMarcel Holtmann return 0x01; 5345659c7fb0SMarcel Holtmann } 5346a83ed81eSMarcel Holtmann 53473e54c589SLuiz Augusto von Dentz static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data, 53483e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 53490493684eSMarcel Holtmann { 53503e54c589SLuiz Augusto von Dentz struct hci_ev_io_capa_request *ev = data; 53510493684eSMarcel Holtmann struct hci_conn *conn; 53520493684eSMarcel Holtmann 53533e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 53540493684eSMarcel Holtmann 53550493684eSMarcel Holtmann hci_dev_lock(hdev); 53560493684eSMarcel Holtmann 53570493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 5358fba268acSLuiz Augusto von Dentz if (!conn || !hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) 535903b555e1SJohan Hedberg goto unlock; 536003b555e1SJohan Hedberg 5361fba268acSLuiz Augusto von Dentz /* Assume remote supports SSP since it has triggered this event */ 5362fba268acSLuiz Augusto von Dentz set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 5363fba268acSLuiz Augusto von Dentz 53640493684eSMarcel Holtmann hci_conn_hold(conn); 53650493684eSMarcel Holtmann 5366d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 536703b555e1SJohan Hedberg goto unlock; 536803b555e1SJohan Hedberg 53692f407f0aSJohan Hedberg /* Allow pairing if we're pairable, the initiators of the 53702f407f0aSJohan Hedberg * pairing or if the remote is not requesting bonding. 53712f407f0aSJohan Hedberg */ 5372d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE) || 53732f407f0aSJohan Hedberg test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) || 537403b555e1SJohan Hedberg (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { 537517fa4b9dSJohan Hedberg struct hci_cp_io_capability_reply cp; 537617fa4b9dSJohan Hedberg 537717fa4b9dSJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 53787a7f1e7cSHemant Gupta /* Change the IO capability from KeyboardDisplay 53797a7f1e7cSHemant Gupta * to DisplayYesNo as it is not supported by BT spec. */ 53807a7f1e7cSHemant Gupta cp.capability = (conn->io_capability == 0x04) ? 5381a767631aSMikel Astiz HCI_IO_DISPLAY_YESNO : conn->io_capability; 5382b7f94c88SMikel Astiz 5383b7f94c88SMikel Astiz /* If we are initiators, there is no remote information yet */ 5384b7f94c88SMikel Astiz if (conn->remote_auth == 0xff) { 5385b16c6604SMikel Astiz /* Request MITM protection if our IO caps allow it 53864ad51a75SJohan Hedberg * except for the no-bonding case. 5387b16c6604SMikel Astiz */ 53886fd6b915SMikel Astiz if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 53899f743d74SJohan Hedberg conn->auth_type != HCI_AT_NO_BONDING) 53906c53823aSJohan Hedberg conn->auth_type |= 0x01; 5391b7f94c88SMikel Astiz } else { 53927cbc9bd9SJohan Hedberg conn->auth_type = hci_get_auth_req(conn); 5393b7f94c88SMikel Astiz } 539417fa4b9dSJohan Hedberg 539582c295b1SJohan Hedberg /* If we're not bondable, force one of the non-bondable 539682c295b1SJohan Hedberg * authentication requirement values. 539782c295b1SJohan Hedberg */ 5398d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE)) 539982c295b1SJohan Hedberg conn->auth_type &= HCI_AT_NO_BONDING_MITM; 540082c295b1SJohan Hedberg 540182c295b1SJohan Hedberg cp.authentication = conn->auth_type; 5402a83ed81eSMarcel Holtmann cp.oob_data = bredr_oob_data_present(conn); 5403ce85ee13SSzymon Janc 540417fa4b9dSJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, 540517fa4b9dSJohan Hedberg sizeof(cp), &cp); 540603b555e1SJohan Hedberg } else { 540703b555e1SJohan Hedberg struct hci_cp_io_capability_neg_reply cp; 540803b555e1SJohan Hedberg 540903b555e1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 54109f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; 541103b555e1SJohan Hedberg 541203b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, 541303b555e1SJohan Hedberg sizeof(cp), &cp); 541403b555e1SJohan Hedberg } 541503b555e1SJohan Hedberg 541603b555e1SJohan Hedberg unlock: 541703b555e1SJohan Hedberg hci_dev_unlock(hdev); 541803b555e1SJohan Hedberg } 541903b555e1SJohan Hedberg 54203e54c589SLuiz Augusto von Dentz static void hci_io_capa_reply_evt(struct hci_dev *hdev, void *data, 54213e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 542203b555e1SJohan Hedberg { 54233e54c589SLuiz Augusto von Dentz struct hci_ev_io_capa_reply *ev = data; 542403b555e1SJohan Hedberg struct hci_conn *conn; 542503b555e1SJohan Hedberg 54263e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 542703b555e1SJohan Hedberg 542803b555e1SJohan Hedberg hci_dev_lock(hdev); 542903b555e1SJohan Hedberg 543003b555e1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 543103b555e1SJohan Hedberg if (!conn) 543203b555e1SJohan Hedberg goto unlock; 543303b555e1SJohan Hedberg 543403b555e1SJohan Hedberg conn->remote_cap = ev->capability; 543503b555e1SJohan Hedberg conn->remote_auth = ev->authentication; 543603b555e1SJohan Hedberg 543703b555e1SJohan Hedberg unlock: 54380493684eSMarcel Holtmann hci_dev_unlock(hdev); 54390493684eSMarcel Holtmann } 54400493684eSMarcel Holtmann 54413e54c589SLuiz Augusto von Dentz static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data, 5442a5c29683SJohan Hedberg struct sk_buff *skb) 5443a5c29683SJohan Hedberg { 54443e54c589SLuiz Augusto von Dentz struct hci_ev_user_confirm_req *ev = data; 544555bc1a37SJohan Hedberg int loc_mitm, rem_mitm, confirm_hint = 0; 54467a828908SJohan Hedberg struct hci_conn *conn; 5447a5c29683SJohan Hedberg 54483e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 5449a5c29683SJohan Hedberg 5450a5c29683SJohan Hedberg hci_dev_lock(hdev); 5451a5c29683SJohan Hedberg 5452d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 54537a828908SJohan Hedberg goto unlock; 54547a828908SJohan Hedberg 54557a828908SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 54567a828908SJohan Hedberg if (!conn) 54577a828908SJohan Hedberg goto unlock; 54587a828908SJohan Hedberg 54597a828908SJohan Hedberg loc_mitm = (conn->auth_type & 0x01); 54607a828908SJohan Hedberg rem_mitm = (conn->remote_auth & 0x01); 54617a828908SJohan Hedberg 54627a828908SJohan Hedberg /* If we require MITM but the remote device can't provide that 54636c53823aSJohan Hedberg * (it has NoInputNoOutput) then reject the confirmation 54646c53823aSJohan Hedberg * request. We check the security level here since it doesn't 54656c53823aSJohan Hedberg * necessarily match conn->auth_type. 54666fd6b915SMikel Astiz */ 54676c53823aSJohan Hedberg if (conn->pending_sec_level > BT_SECURITY_MEDIUM && 54686c53823aSJohan Hedberg conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) { 54693e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "Rejecting request: remote device can't provide MITM"); 54707a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, 54717a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 54727a828908SJohan Hedberg goto unlock; 54737a828908SJohan Hedberg } 54747a828908SJohan Hedberg 54757a828908SJohan Hedberg /* If no side requires MITM protection; auto-accept */ 5476a767631aSMikel Astiz if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) && 5477a767631aSMikel Astiz (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) { 547855bc1a37SJohan Hedberg 547955bc1a37SJohan Hedberg /* If we're not the initiators request authorization to 548055bc1a37SJohan Hedberg * proceed from user space (mgmt_user_confirm with 5481ba15a58bSJohan Hedberg * confirm_hint set to 1). The exception is if neither 548202f3e254SJohan Hedberg * side had MITM or if the local IO capability is 548302f3e254SJohan Hedberg * NoInputNoOutput, in which case we do auto-accept 5484ba15a58bSJohan Hedberg */ 5485ba15a58bSJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && 548602f3e254SJohan Hedberg conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 5487ba15a58bSJohan Hedberg (loc_mitm || rem_mitm)) { 54883e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "Confirming auto-accept as acceptor"); 548955bc1a37SJohan Hedberg confirm_hint = 1; 549055bc1a37SJohan Hedberg goto confirm; 549155bc1a37SJohan Hedberg } 549255bc1a37SJohan Hedberg 5493cee5f20fSHoward Chung /* If there already exists link key in local host, leave the 5494cee5f20fSHoward Chung * decision to user space since the remote device could be 5495cee5f20fSHoward Chung * legitimate or malicious. 5496cee5f20fSHoward Chung */ 5497cee5f20fSHoward Chung if (hci_find_link_key(hdev, &ev->bdaddr)) { 5498cee5f20fSHoward Chung bt_dev_dbg(hdev, "Local host already has link key"); 5499cee5f20fSHoward Chung confirm_hint = 1; 5500cee5f20fSHoward Chung goto confirm; 5501cee5f20fSHoward Chung } 5502cee5f20fSHoward Chung 55039f61656aSJohan Hedberg BT_DBG("Auto-accept of user confirmation with %ums delay", 55049f61656aSJohan Hedberg hdev->auto_accept_delay); 55059f61656aSJohan Hedberg 55069f61656aSJohan Hedberg if (hdev->auto_accept_delay > 0) { 55079f61656aSJohan Hedberg int delay = msecs_to_jiffies(hdev->auto_accept_delay); 55087bc18d9dSJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 55097bc18d9dSJohan Hedberg &conn->auto_accept_work, delay); 55109f61656aSJohan Hedberg goto unlock; 55119f61656aSJohan Hedberg } 55129f61656aSJohan Hedberg 55137a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, 55147a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 55157a828908SJohan Hedberg goto unlock; 55167a828908SJohan Hedberg } 55177a828908SJohan Hedberg 551855bc1a37SJohan Hedberg confirm: 551939adbffeSJohan Hedberg mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, 552039adbffeSJohan Hedberg le32_to_cpu(ev->passkey), confirm_hint); 5521a5c29683SJohan Hedberg 55227a828908SJohan Hedberg unlock: 5523a5c29683SJohan Hedberg hci_dev_unlock(hdev); 5524a5c29683SJohan Hedberg } 5525a5c29683SJohan Hedberg 55263e54c589SLuiz Augusto von Dentz static void hci_user_passkey_request_evt(struct hci_dev *hdev, void *data, 55271143d458SBrian Gix struct sk_buff *skb) 55281143d458SBrian Gix { 55293e54c589SLuiz Augusto von Dentz struct hci_ev_user_passkey_req *ev = data; 5530ae61a10dSLuiz Augusto von Dentz 55313e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 55321143d458SBrian Gix 5533d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 5534272d90dfSJohan Hedberg mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); 55351143d458SBrian Gix } 55361143d458SBrian Gix 55373e54c589SLuiz Augusto von Dentz static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data, 553892a25256SJohan Hedberg struct sk_buff *skb) 553992a25256SJohan Hedberg { 55403e54c589SLuiz Augusto von Dentz struct hci_ev_user_passkey_notify *ev = data; 554192a25256SJohan Hedberg struct hci_conn *conn; 554292a25256SJohan Hedberg 55433e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 554492a25256SJohan Hedberg 554592a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 554692a25256SJohan Hedberg if (!conn) 554792a25256SJohan Hedberg return; 554892a25256SJohan Hedberg 554992a25256SJohan Hedberg conn->passkey_notify = __le32_to_cpu(ev->passkey); 555092a25256SJohan Hedberg conn->passkey_entered = 0; 555192a25256SJohan Hedberg 5552d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 555392a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 555492a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 555592a25256SJohan Hedberg conn->passkey_entered); 555692a25256SJohan Hedberg } 555792a25256SJohan Hedberg 55583e54c589SLuiz Augusto von Dentz static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data, 55593e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 556092a25256SJohan Hedberg { 55613e54c589SLuiz Augusto von Dentz struct hci_ev_keypress_notify *ev = data; 556292a25256SJohan Hedberg struct hci_conn *conn; 556392a25256SJohan Hedberg 55643e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 556592a25256SJohan Hedberg 556692a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 556792a25256SJohan Hedberg if (!conn) 556892a25256SJohan Hedberg return; 556992a25256SJohan Hedberg 557092a25256SJohan Hedberg switch (ev->type) { 557192a25256SJohan Hedberg case HCI_KEYPRESS_STARTED: 557292a25256SJohan Hedberg conn->passkey_entered = 0; 557392a25256SJohan Hedberg return; 557492a25256SJohan Hedberg 557592a25256SJohan Hedberg case HCI_KEYPRESS_ENTERED: 557692a25256SJohan Hedberg conn->passkey_entered++; 557792a25256SJohan Hedberg break; 557892a25256SJohan Hedberg 557992a25256SJohan Hedberg case HCI_KEYPRESS_ERASED: 558092a25256SJohan Hedberg conn->passkey_entered--; 558192a25256SJohan Hedberg break; 558292a25256SJohan Hedberg 558392a25256SJohan Hedberg case HCI_KEYPRESS_CLEARED: 558492a25256SJohan Hedberg conn->passkey_entered = 0; 558592a25256SJohan Hedberg break; 558692a25256SJohan Hedberg 558792a25256SJohan Hedberg case HCI_KEYPRESS_COMPLETED: 558892a25256SJohan Hedberg return; 558992a25256SJohan Hedberg } 559092a25256SJohan Hedberg 5591d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 559292a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 559392a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 559492a25256SJohan Hedberg conn->passkey_entered); 559592a25256SJohan Hedberg } 559692a25256SJohan Hedberg 55973e54c589SLuiz Augusto von Dentz static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data, 5598807deac2SGustavo Padovan struct sk_buff *skb) 55990493684eSMarcel Holtmann { 56003e54c589SLuiz Augusto von Dentz struct hci_ev_simple_pair_complete *ev = data; 56010493684eSMarcel Holtmann struct hci_conn *conn; 56020493684eSMarcel Holtmann 56033e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 56040493684eSMarcel Holtmann 56050493684eSMarcel Holtmann hci_dev_lock(hdev); 56060493684eSMarcel Holtmann 56070493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 5608c7f59461SZiyang Xuan if (!conn || !hci_conn_ssp_enabled(conn)) 56092a611692SJohan Hedberg goto unlock; 56102a611692SJohan Hedberg 5611c1d4fa7aSJohan Hedberg /* Reset the authentication requirement to unknown */ 5612c1d4fa7aSJohan Hedberg conn->remote_auth = 0xff; 5613c1d4fa7aSJohan Hedberg 56142a611692SJohan Hedberg /* To avoid duplicate auth_failed events to user space we check 56152a611692SJohan Hedberg * the HCI_CONN_AUTH_PEND flag which will be set if we 56162a611692SJohan Hedberg * initiated the authentication. A traditional auth_complete 56172a611692SJohan Hedberg * event gets always produced as initiator and is also mapped to 56182a611692SJohan Hedberg * the mgmt_auth_failed event */ 5619fa1bd918SMikel Astiz if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) 5620e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 56212a611692SJohan Hedberg 562276a68ba0SDavid Herrmann hci_conn_drop(conn); 56230493684eSMarcel Holtmann 56242a611692SJohan Hedberg unlock: 56250493684eSMarcel Holtmann hci_dev_unlock(hdev); 56260493684eSMarcel Holtmann } 56270493684eSMarcel Holtmann 56283e54c589SLuiz Augusto von Dentz static void hci_remote_host_features_evt(struct hci_dev *hdev, void *data, 5629807deac2SGustavo Padovan struct sk_buff *skb) 563041a96212SMarcel Holtmann { 56313e54c589SLuiz Augusto von Dentz struct hci_ev_remote_host_features *ev = data; 563241a96212SMarcel Holtmann struct inquiry_entry *ie; 5633cad718edSJohan Hedberg struct hci_conn *conn; 563441a96212SMarcel Holtmann 56353e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 563641a96212SMarcel Holtmann 563741a96212SMarcel Holtmann hci_dev_lock(hdev); 563841a96212SMarcel Holtmann 5639cad718edSJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 5640cad718edSJohan Hedberg if (conn) 5641cad718edSJohan Hedberg memcpy(conn->features[1], ev->features, 8); 5642cad718edSJohan Hedberg 5643cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 5644cc11b9c1SAndrei Emeltchenko if (ie) 564502b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 564641a96212SMarcel Holtmann 564741a96212SMarcel Holtmann hci_dev_unlock(hdev); 564841a96212SMarcel Holtmann } 564941a96212SMarcel Holtmann 56503e54c589SLuiz Augusto von Dentz static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, void *edata, 56512763eda6SSzymon Janc struct sk_buff *skb) 56522763eda6SSzymon Janc { 56533e54c589SLuiz Augusto von Dentz struct hci_ev_remote_oob_data_request *ev = edata; 56542763eda6SSzymon Janc struct oob_data *data; 56552763eda6SSzymon Janc 56563e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 56572763eda6SSzymon Janc 56582763eda6SSzymon Janc hci_dev_lock(hdev); 56592763eda6SSzymon Janc 5660d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 5661e1ba1f15SSzymon Janc goto unlock; 5662e1ba1f15SSzymon Janc 56636928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR); 56646665d057SMarcel Holtmann if (!data) { 56656665d057SMarcel Holtmann struct hci_cp_remote_oob_data_neg_reply cp; 56666665d057SMarcel Holtmann 56676665d057SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 56686665d057SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, 56696665d057SMarcel Holtmann sizeof(cp), &cp); 56706665d057SMarcel Holtmann goto unlock; 56716665d057SMarcel Holtmann } 56726665d057SMarcel Holtmann 5673710f11c0SJohan Hedberg if (bredr_sc_enabled(hdev)) { 5674519ca9d0SMarcel Holtmann struct hci_cp_remote_oob_ext_data_reply cp; 5675519ca9d0SMarcel Holtmann 5676519ca9d0SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 5677d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) { 56786665d057SMarcel Holtmann memset(cp.hash192, 0, sizeof(cp.hash192)); 56796665d057SMarcel Holtmann memset(cp.rand192, 0, sizeof(cp.rand192)); 56806665d057SMarcel Holtmann } else { 5681519ca9d0SMarcel Holtmann memcpy(cp.hash192, data->hash192, sizeof(cp.hash192)); 568238da1703SJohan Hedberg memcpy(cp.rand192, data->rand192, sizeof(cp.rand192)); 56836665d057SMarcel Holtmann } 5684519ca9d0SMarcel Holtmann memcpy(cp.hash256, data->hash256, sizeof(cp.hash256)); 568538da1703SJohan Hedberg memcpy(cp.rand256, data->rand256, sizeof(cp.rand256)); 5686519ca9d0SMarcel Holtmann 5687519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY, 5688519ca9d0SMarcel Holtmann sizeof(cp), &cp); 5689519ca9d0SMarcel Holtmann } else { 56902763eda6SSzymon Janc struct hci_cp_remote_oob_data_reply cp; 56912763eda6SSzymon Janc 56922763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 5693519ca9d0SMarcel Holtmann memcpy(cp.hash, data->hash192, sizeof(cp.hash)); 569438da1703SJohan Hedberg memcpy(cp.rand, data->rand192, sizeof(cp.rand)); 56952763eda6SSzymon Janc 5696519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, 5697519ca9d0SMarcel Holtmann sizeof(cp), &cp); 5698519ca9d0SMarcel Holtmann } 56992763eda6SSzymon Janc 5700e1ba1f15SSzymon Janc unlock: 57012763eda6SSzymon Janc hci_dev_unlock(hdev); 57022763eda6SSzymon Janc } 57032763eda6SSzymon Janc 5704a77a6a14SArron Wang #if IS_ENABLED(CONFIG_BT_HS) 57053e54c589SLuiz Augusto von Dentz static void hci_chan_selected_evt(struct hci_dev *hdev, void *data, 57063e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 5707a77a6a14SArron Wang { 57083e54c589SLuiz Augusto von Dentz struct hci_ev_channel_selected *ev = data; 5709a77a6a14SArron Wang struct hci_conn *hcon; 5710a77a6a14SArron Wang 57113e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%2.2x", ev->phy_handle); 5712a77a6a14SArron Wang 5713a77a6a14SArron Wang hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 5714a77a6a14SArron Wang if (!hcon) 5715a77a6a14SArron Wang return; 5716a77a6a14SArron Wang 5717a77a6a14SArron Wang amp_read_loc_assoc_final_data(hdev, hcon); 5718a77a6a14SArron Wang } 5719a77a6a14SArron Wang 57203e54c589SLuiz Augusto von Dentz static void hci_phy_link_complete_evt(struct hci_dev *hdev, void *data, 5721d5e91192SAndrei Emeltchenko struct sk_buff *skb) 5722d5e91192SAndrei Emeltchenko { 57233e54c589SLuiz Augusto von Dentz struct hci_ev_phy_link_complete *ev = data; 5724d5e91192SAndrei Emeltchenko struct hci_conn *hcon, *bredr_hcon; 5725d5e91192SAndrei Emeltchenko 57263e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%2.2x status 0x%2.2x", ev->phy_handle, 5727d5e91192SAndrei Emeltchenko ev->status); 5728d5e91192SAndrei Emeltchenko 5729d5e91192SAndrei Emeltchenko hci_dev_lock(hdev); 5730d5e91192SAndrei Emeltchenko 5731d5e91192SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 57323ae1dc75SSergey Shtylyov if (!hcon) 57333ae1dc75SSergey Shtylyov goto unlock; 5734d5e91192SAndrei Emeltchenko 57353ae1dc75SSergey Shtylyov if (!hcon->amp_mgr) 57363ae1dc75SSergey Shtylyov goto unlock; 57376dfccd13SAnmol Karn 5738d5e91192SAndrei Emeltchenko if (ev->status) { 5739d5e91192SAndrei Emeltchenko hci_conn_del(hcon); 57403ae1dc75SSergey Shtylyov goto unlock; 5741d5e91192SAndrei Emeltchenko } 5742d5e91192SAndrei Emeltchenko 5743d5e91192SAndrei Emeltchenko bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon; 5744d5e91192SAndrei Emeltchenko 5745d5e91192SAndrei Emeltchenko hcon->state = BT_CONNECTED; 5746d5e91192SAndrei Emeltchenko bacpy(&hcon->dst, &bredr_hcon->dst); 5747d5e91192SAndrei Emeltchenko 5748d5e91192SAndrei Emeltchenko hci_conn_hold(hcon); 5749d5e91192SAndrei Emeltchenko hcon->disc_timeout = HCI_DISCONN_TIMEOUT; 575076a68ba0SDavid Herrmann hci_conn_drop(hcon); 5751d5e91192SAndrei Emeltchenko 575223b9ceb7SMarcel Holtmann hci_debugfs_create_conn(hcon); 5753d5e91192SAndrei Emeltchenko hci_conn_add_sysfs(hcon); 5754d5e91192SAndrei Emeltchenko 5755cf70ff22SAndrei Emeltchenko amp_physical_cfm(bredr_hcon, hcon); 5756cf70ff22SAndrei Emeltchenko 57573ae1dc75SSergey Shtylyov unlock: 5758d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 5759d5e91192SAndrei Emeltchenko } 5760d5e91192SAndrei Emeltchenko 57613e54c589SLuiz Augusto von Dentz static void hci_loglink_complete_evt(struct hci_dev *hdev, void *data, 57623e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 576327695fb4SAndrei Emeltchenko { 57643e54c589SLuiz Augusto von Dentz struct hci_ev_logical_link_complete *ev = data; 576527695fb4SAndrei Emeltchenko struct hci_conn *hcon; 576627695fb4SAndrei Emeltchenko struct hci_chan *hchan; 576727695fb4SAndrei Emeltchenko struct amp_mgr *mgr; 576827695fb4SAndrei Emeltchenko 57693e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x", 57703e54c589SLuiz Augusto von Dentz le16_to_cpu(ev->handle), ev->phy_handle, ev->status); 577127695fb4SAndrei Emeltchenko 577227695fb4SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 577327695fb4SAndrei Emeltchenko if (!hcon) 577427695fb4SAndrei Emeltchenko return; 577527695fb4SAndrei Emeltchenko 577627695fb4SAndrei Emeltchenko /* Create AMP hchan */ 577727695fb4SAndrei Emeltchenko hchan = hci_chan_create(hcon); 577827695fb4SAndrei Emeltchenko if (!hchan) 577927695fb4SAndrei Emeltchenko return; 578027695fb4SAndrei Emeltchenko 578127695fb4SAndrei Emeltchenko hchan->handle = le16_to_cpu(ev->handle); 57825c4c8c95SArchie Pusaka hchan->amp = true; 578327695fb4SAndrei Emeltchenko 578427695fb4SAndrei Emeltchenko BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); 578527695fb4SAndrei Emeltchenko 578627695fb4SAndrei Emeltchenko mgr = hcon->amp_mgr; 578727695fb4SAndrei Emeltchenko if (mgr && mgr->bredr_chan) { 578827695fb4SAndrei Emeltchenko struct l2cap_chan *bredr_chan = mgr->bredr_chan; 578927695fb4SAndrei Emeltchenko 579027695fb4SAndrei Emeltchenko l2cap_chan_lock(bredr_chan); 579127695fb4SAndrei Emeltchenko 579227695fb4SAndrei Emeltchenko bredr_chan->conn->mtu = hdev->block_mtu; 579327695fb4SAndrei Emeltchenko l2cap_logical_cfm(bredr_chan, hchan, 0); 579427695fb4SAndrei Emeltchenko hci_conn_hold(hcon); 579527695fb4SAndrei Emeltchenko 579627695fb4SAndrei Emeltchenko l2cap_chan_unlock(bredr_chan); 579727695fb4SAndrei Emeltchenko } 579827695fb4SAndrei Emeltchenko } 579927695fb4SAndrei Emeltchenko 58003e54c589SLuiz Augusto von Dentz static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, void *data, 5801606e2a10SAndrei Emeltchenko struct sk_buff *skb) 5802606e2a10SAndrei Emeltchenko { 58033e54c589SLuiz Augusto von Dentz struct hci_ev_disconn_logical_link_complete *ev = data; 5804606e2a10SAndrei Emeltchenko struct hci_chan *hchan; 5805606e2a10SAndrei Emeltchenko 58063e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x status 0x%2.2x", 5807606e2a10SAndrei Emeltchenko le16_to_cpu(ev->handle), ev->status); 5808606e2a10SAndrei Emeltchenko 5809606e2a10SAndrei Emeltchenko if (ev->status) 5810606e2a10SAndrei Emeltchenko return; 5811606e2a10SAndrei Emeltchenko 5812606e2a10SAndrei Emeltchenko hci_dev_lock(hdev); 5813606e2a10SAndrei Emeltchenko 5814606e2a10SAndrei Emeltchenko hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle)); 58155c4c8c95SArchie Pusaka if (!hchan || !hchan->amp) 5816606e2a10SAndrei Emeltchenko goto unlock; 5817606e2a10SAndrei Emeltchenko 5818606e2a10SAndrei Emeltchenko amp_destroy_logical_link(hchan, ev->reason); 5819606e2a10SAndrei Emeltchenko 5820606e2a10SAndrei Emeltchenko unlock: 5821606e2a10SAndrei Emeltchenko hci_dev_unlock(hdev); 5822606e2a10SAndrei Emeltchenko } 5823606e2a10SAndrei Emeltchenko 58243e54c589SLuiz Augusto von Dentz static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, void *data, 58259eef6b3aSAndrei Emeltchenko struct sk_buff *skb) 58269eef6b3aSAndrei Emeltchenko { 58273e54c589SLuiz Augusto von Dentz struct hci_ev_disconn_phy_link_complete *ev = data; 58289eef6b3aSAndrei Emeltchenko struct hci_conn *hcon; 58299eef6b3aSAndrei Emeltchenko 58303e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 58319eef6b3aSAndrei Emeltchenko 58329eef6b3aSAndrei Emeltchenko if (ev->status) 58339eef6b3aSAndrei Emeltchenko return; 58349eef6b3aSAndrei Emeltchenko 58359eef6b3aSAndrei Emeltchenko hci_dev_lock(hdev); 58369eef6b3aSAndrei Emeltchenko 58379eef6b3aSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 5838f63d24baSLuiz Augusto von Dentz if (hcon && hcon->type == AMP_LINK) { 58399eef6b3aSAndrei Emeltchenko hcon->state = BT_CLOSED; 5840f63d24baSLuiz Augusto von Dentz hci_disconn_cfm(hcon, ev->reason); 58419eef6b3aSAndrei Emeltchenko hci_conn_del(hcon); 58429eef6b3aSAndrei Emeltchenko } 58439eef6b3aSAndrei Emeltchenko 58449eef6b3aSAndrei Emeltchenko hci_dev_unlock(hdev); 58459eef6b3aSAndrei Emeltchenko } 5846a77a6a14SArron Wang #endif 58479eef6b3aSAndrei Emeltchenko 5848cafae4cdSLuiz Augusto von Dentz static void le_conn_update_addr(struct hci_conn *conn, bdaddr_t *bdaddr, 5849cafae4cdSLuiz Augusto von Dentz u8 bdaddr_type, bdaddr_t *local_rpa) 5850cafae4cdSLuiz Augusto von Dentz { 5851cafae4cdSLuiz Augusto von Dentz if (conn->out) { 5852cafae4cdSLuiz Augusto von Dentz conn->dst_type = bdaddr_type; 5853cafae4cdSLuiz Augusto von Dentz conn->resp_addr_type = bdaddr_type; 5854cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr, bdaddr); 5855cafae4cdSLuiz Augusto von Dentz 5856cafae4cdSLuiz Augusto von Dentz /* Check if the controller has set a Local RPA then it must be 5857cafae4cdSLuiz Augusto von Dentz * used instead or hdev->rpa. 5858cafae4cdSLuiz Augusto von Dentz */ 5859cafae4cdSLuiz Augusto von Dentz if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) { 5860cafae4cdSLuiz Augusto von Dentz conn->init_addr_type = ADDR_LE_DEV_RANDOM; 5861cafae4cdSLuiz Augusto von Dentz bacpy(&conn->init_addr, local_rpa); 5862cafae4cdSLuiz Augusto von Dentz } else if (hci_dev_test_flag(conn->hdev, HCI_PRIVACY)) { 5863cafae4cdSLuiz Augusto von Dentz conn->init_addr_type = ADDR_LE_DEV_RANDOM; 5864cafae4cdSLuiz Augusto von Dentz bacpy(&conn->init_addr, &conn->hdev->rpa); 5865cafae4cdSLuiz Augusto von Dentz } else { 5866cafae4cdSLuiz Augusto von Dentz hci_copy_identity_address(conn->hdev, &conn->init_addr, 5867cafae4cdSLuiz Augusto von Dentz &conn->init_addr_type); 5868cafae4cdSLuiz Augusto von Dentz } 5869cafae4cdSLuiz Augusto von Dentz } else { 5870cafae4cdSLuiz Augusto von Dentz conn->resp_addr_type = conn->hdev->adv_addr_type; 5871cafae4cdSLuiz Augusto von Dentz /* Check if the controller has set a Local RPA then it must be 5872cafae4cdSLuiz Augusto von Dentz * used instead or hdev->rpa. 5873cafae4cdSLuiz Augusto von Dentz */ 5874cafae4cdSLuiz Augusto von Dentz if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) { 5875cafae4cdSLuiz Augusto von Dentz conn->resp_addr_type = ADDR_LE_DEV_RANDOM; 5876cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr, local_rpa); 5877cafae4cdSLuiz Augusto von Dentz } else if (conn->hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) { 5878cafae4cdSLuiz Augusto von Dentz /* In case of ext adv, resp_addr will be updated in 5879cafae4cdSLuiz Augusto von Dentz * Adv Terminated event. 5880cafae4cdSLuiz Augusto von Dentz */ 5881cafae4cdSLuiz Augusto von Dentz if (!ext_adv_capable(conn->hdev)) 5882cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr, 5883cafae4cdSLuiz Augusto von Dentz &conn->hdev->random_addr); 5884cafae4cdSLuiz Augusto von Dentz } else { 5885cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr, &conn->hdev->bdaddr); 5886cafae4cdSLuiz Augusto von Dentz } 5887cafae4cdSLuiz Augusto von Dentz 5888cafae4cdSLuiz Augusto von Dentz conn->init_addr_type = bdaddr_type; 5889cafae4cdSLuiz Augusto von Dentz bacpy(&conn->init_addr, bdaddr); 5890cafae4cdSLuiz Augusto von Dentz 5891cafae4cdSLuiz Augusto von Dentz /* For incoming connections, set the default minimum 5892cafae4cdSLuiz Augusto von Dentz * and maximum connection interval. They will be used 5893cafae4cdSLuiz Augusto von Dentz * to check if the parameters are in range and if not 5894cafae4cdSLuiz Augusto von Dentz * trigger the connection update procedure. 5895cafae4cdSLuiz Augusto von Dentz */ 5896cafae4cdSLuiz Augusto von Dentz conn->le_conn_min_interval = conn->hdev->le_conn_min_interval; 5897cafae4cdSLuiz Augusto von Dentz conn->le_conn_max_interval = conn->hdev->le_conn_max_interval; 5898cafae4cdSLuiz Augusto von Dentz } 5899cafae4cdSLuiz Augusto von Dentz } 5900cafae4cdSLuiz Augusto von Dentz 5901d12fb056SJaganath Kanakkassery static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, 5902cafae4cdSLuiz Augusto von Dentz bdaddr_t *bdaddr, u8 bdaddr_type, 5903cafae4cdSLuiz Augusto von Dentz bdaddr_t *local_rpa, u8 role, u16 handle, 5904cafae4cdSLuiz Augusto von Dentz u16 interval, u16 latency, 5905cafae4cdSLuiz Augusto von Dentz u16 supervision_timeout) 5906fcd89c09SVille Tervo { 5907912b42efSJohan Hedberg struct hci_conn_params *params; 5908fcd89c09SVille Tervo struct hci_conn *conn; 590968d6f6deSJohan Hedberg struct smp_irk *irk; 5910837d502eSJohan Hedberg u8 addr_type; 5911fcd89c09SVille Tervo 5912fcd89c09SVille Tervo hci_dev_lock(hdev); 5913fcd89c09SVille Tervo 5914fbd96c15SJohan Hedberg /* All controllers implicitly stop advertising in the event of a 5915fbd96c15SJohan Hedberg * connection, so ensure that the state bit is cleared. 5916fbd96c15SJohan Hedberg */ 5917a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV); 5918fbd96c15SJohan Hedberg 591953562665SArchie Pusaka conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr); 5920b62f328bSVille Tervo if (!conn) { 5921aef2aa4fSLuiz Augusto von Dentz /* In case of error status and there is no connection pending 5922aef2aa4fSLuiz Augusto von Dentz * just unlock as there is nothing to cleanup. 5923aef2aa4fSLuiz Augusto von Dentz */ 5924aef2aa4fSLuiz Augusto von Dentz if (status) 5925aef2aa4fSLuiz Augusto von Dentz goto unlock; 5926aef2aa4fSLuiz Augusto von Dentz 592784cb0143SZiyang Xuan conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, role); 5928b62f328bSVille Tervo if (!conn) { 59292064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for new connection"); 5930230fd16aSAndre Guedes goto unlock; 5931b62f328bSVille Tervo } 593229b7988aSAndre Guedes 5933d12fb056SJaganath Kanakkassery conn->dst_type = bdaddr_type; 5934b9b343d2SAndre Guedes 5935cb1d68f7SJohan Hedberg /* If we didn't have a hci_conn object previously 593674be523cSArchie Pusaka * but we're in central role this must be something 59373d4f9c00SArchie Pusaka * initiated using an accept list. Since accept list based 5938cb1d68f7SJohan Hedberg * connections are not "first class citizens" we don't 5939cb1d68f7SJohan Hedberg * have full tracking of them. Therefore, we go ahead 5940cb1d68f7SJohan Hedberg * with a "best effort" approach of determining the 5941cb1d68f7SJohan Hedberg * initiator address based on the HCI_PRIVACY flag. 5942cb1d68f7SJohan Hedberg */ 5943cb1d68f7SJohan Hedberg if (conn->out) { 5944d12fb056SJaganath Kanakkassery conn->resp_addr_type = bdaddr_type; 5945d12fb056SJaganath Kanakkassery bacpy(&conn->resp_addr, bdaddr); 5946d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { 5947cb1d68f7SJohan Hedberg conn->init_addr_type = ADDR_LE_DEV_RANDOM; 5948cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->rpa); 5949cb1d68f7SJohan Hedberg } else { 5950cb1d68f7SJohan Hedberg hci_copy_identity_address(hdev, 5951cb1d68f7SJohan Hedberg &conn->init_addr, 5952cb1d68f7SJohan Hedberg &conn->init_addr_type); 5953cb1d68f7SJohan Hedberg } 595480c24ab8SJohan Hedberg } 5955cb1d68f7SJohan Hedberg } else { 595680c24ab8SJohan Hedberg cancel_delayed_work(&conn->le_conn_timeout); 595780c24ab8SJohan Hedberg } 595880c24ab8SJohan Hedberg 5959d5ebaa7cSSoenke Huster /* The HCI_LE_Connection_Complete event is only sent once per connection. 5960d5ebaa7cSSoenke Huster * Processing it more than once per connection can corrupt kernel memory. 5961d5ebaa7cSSoenke Huster * 5962d5ebaa7cSSoenke Huster * As the connection handle is set here for the first time, it indicates 5963d5ebaa7cSSoenke Huster * whether the connection is already set up. 5964d5ebaa7cSSoenke Huster */ 59659f78191cSLuiz Augusto von Dentz if (!HCI_CONN_HANDLE_UNSET(conn->handle)) { 5966d5ebaa7cSSoenke Huster bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection"); 5967d5ebaa7cSSoenke Huster goto unlock; 5968d5ebaa7cSSoenke Huster } 5969d5ebaa7cSSoenke Huster 5970cafae4cdSLuiz Augusto von Dentz le_conn_update_addr(conn, bdaddr, bdaddr_type, local_rpa); 59717be2edbbSJohan Hedberg 5972edb4b466SMarcel Holtmann /* Lookup the identity address from the stored connection 5973edb4b466SMarcel Holtmann * address and address type. 5974edb4b466SMarcel Holtmann * 5975edb4b466SMarcel Holtmann * When establishing connections to an identity address, the 5976edb4b466SMarcel Holtmann * connection procedure will store the resolvable random 5977edb4b466SMarcel Holtmann * address first. Now if it can be converted back into the 5978edb4b466SMarcel Holtmann * identity address, start using the identity address from 5979edb4b466SMarcel Holtmann * now on. 5980edb4b466SMarcel Holtmann */ 5981edb4b466SMarcel Holtmann irk = hci_get_irk(hdev, &conn->dst, conn->dst_type); 598268d6f6deSJohan Hedberg if (irk) { 598368d6f6deSJohan Hedberg bacpy(&conn->dst, &irk->bdaddr); 598468d6f6deSJohan Hedberg conn->dst_type = irk->addr_type; 598568d6f6deSJohan Hedberg } 598668d6f6deSJohan Hedberg 5987d850bf08SLuiz Augusto von Dentz conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL); 598879699a70SSathish Narasimman 5989c9f73a21SLuiz Augusto von Dentz /* All connection failure handling is taken care of by the 5990c9f73a21SLuiz Augusto von Dentz * hci_conn_failed function which is triggered by the HCI 5991c9f73a21SLuiz Augusto von Dentz * request completion callbacks used for connecting. 5992c9f73a21SLuiz Augusto von Dentz */ 599384cb0143SZiyang Xuan if (status || hci_conn_set_handle(conn, handle)) 5994837d502eSJohan Hedberg goto unlock; 5995837d502eSJohan Hedberg 5996b62e7220SLuiz Augusto von Dentz /* Drop the connection if it has been aborted */ 5997b62e7220SLuiz Augusto von Dentz if (test_bit(HCI_CONN_CANCEL, &conn->flags)) { 5998b62e7220SLuiz Augusto von Dentz hci_conn_drop(conn); 5999b62e7220SLuiz Augusto von Dentz goto unlock; 6000b62e7220SLuiz Augusto von Dentz } 6001b62e7220SLuiz Augusto von Dentz 600208853f18SJohan Hedberg if (conn->dst_type == ADDR_LE_DEV_PUBLIC) 600308853f18SJohan Hedberg addr_type = BDADDR_LE_PUBLIC; 600408853f18SJohan Hedberg else 600508853f18SJohan Hedberg addr_type = BDADDR_LE_RANDOM; 600608853f18SJohan Hedberg 60072d3c2260SJohan Hedberg /* Drop the connection if the device is blocked */ 60083d4f9c00SArchie Pusaka if (hci_bdaddr_list_lookup(&hdev->reject_list, &conn->dst, addr_type)) { 60092d3c2260SJohan Hedberg hci_conn_drop(conn); 6010cd17decbSAndre Guedes goto unlock; 6011cd17decbSAndre Guedes } 6012cd17decbSAndre Guedes 60131c6ed31bSYu Liu mgmt_device_connected(hdev, conn, NULL, 0); 601483bc71b4SVinicius Costa Gomes 60157b5c0d52SVinicius Costa Gomes conn->sec_level = BT_SECURITY_LOW; 60160fe29fd1SMarcel Holtmann conn->state = BT_CONFIG; 6017fcd89c09SVille Tervo 60187087c4f6SLuiz Augusto von Dentz /* Store current advertising instance as connection advertising instance 60197087c4f6SLuiz Augusto von Dentz * when sotfware rotation is in use so it can be re-enabled when 60207087c4f6SLuiz Augusto von Dentz * disconnected. 60217087c4f6SLuiz Augusto von Dentz */ 60227087c4f6SLuiz Augusto von Dentz if (!ext_adv_capable(hdev)) 60237087c4f6SLuiz Augusto von Dentz conn->adv_instance = hdev->cur_adv_instance; 60247087c4f6SLuiz Augusto von Dentz 6025d12fb056SJaganath Kanakkassery conn->le_conn_interval = interval; 6026d12fb056SJaganath Kanakkassery conn->le_conn_latency = latency; 6027d12fb056SJaganath Kanakkassery conn->le_supv_timeout = supervision_timeout; 6028e04fde60SMarcel Holtmann 602923b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 6030fcd89c09SVille Tervo hci_conn_add_sysfs(conn); 6031fcd89c09SVille Tervo 6032ef365da1SArchie Pusaka /* The remote features procedure is defined for central 60330fe29fd1SMarcel Holtmann * role only. So only in case of an initiated connection 60340fe29fd1SMarcel Holtmann * request the remote features. 60350fe29fd1SMarcel Holtmann * 6036ef365da1SArchie Pusaka * If the local controller supports peripheral-initiated features 6037ef365da1SArchie Pusaka * exchange, then requesting the remote features in peripheral 60380fe29fd1SMarcel Holtmann * role is possible. Otherwise just transition into the 60390fe29fd1SMarcel Holtmann * connected state without requesting the remote features. 60400fe29fd1SMarcel Holtmann */ 60410fe29fd1SMarcel Holtmann if (conn->out || 6042ef365da1SArchie Pusaka (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) { 60430fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features cp; 60440fe29fd1SMarcel Holtmann 60450fe29fd1SMarcel Holtmann cp.handle = __cpu_to_le16(conn->handle); 60460fe29fd1SMarcel Holtmann 60470fe29fd1SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_LE_READ_REMOTE_FEATURES, 60480fe29fd1SMarcel Holtmann sizeof(cp), &cp); 60490fe29fd1SMarcel Holtmann 60500fe29fd1SMarcel Holtmann hci_conn_hold(conn); 60510fe29fd1SMarcel Holtmann } else { 60520fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED; 6053d12fb056SJaganath Kanakkassery hci_connect_cfm(conn, status); 60540fe29fd1SMarcel Holtmann } 6055fcd89c09SVille Tervo 60565477610fSJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, 60575477610fSJohan Hedberg conn->dst_type); 6058f161dd41SJohan Hedberg if (params) { 6059195ef75eSPauli Virtanen hci_pend_le_list_del_init(params); 6060f161dd41SJohan Hedberg if (params->conn) { 6061f161dd41SJohan Hedberg hci_conn_drop(params->conn); 6062f8aaf9b6SJohan Hedberg hci_conn_put(params->conn); 6063f161dd41SJohan Hedberg params->conn = NULL; 6064f161dd41SJohan Hedberg } 6065f161dd41SJohan Hedberg } 6066a4790dbdSAndre Guedes 6067fcd89c09SVille Tervo unlock: 60685bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev); 6069fcd89c09SVille Tervo hci_dev_unlock(hdev); 6070fcd89c09SVille Tervo } 6071fcd89c09SVille Tervo 607295118dd4SLuiz Augusto von Dentz static void hci_le_conn_complete_evt(struct hci_dev *hdev, void *data, 607395118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 6074d12fb056SJaganath Kanakkassery { 607595118dd4SLuiz Augusto von Dentz struct hci_ev_le_conn_complete *ev = data; 607612cfe417SLuiz Augusto von Dentz 607795118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 6078d12fb056SJaganath Kanakkassery 6079d12fb056SJaganath Kanakkassery le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type, 6080cafae4cdSLuiz Augusto von Dentz NULL, ev->role, le16_to_cpu(ev->handle), 6081d12fb056SJaganath Kanakkassery le16_to_cpu(ev->interval), 6082d12fb056SJaganath Kanakkassery le16_to_cpu(ev->latency), 6083d12fb056SJaganath Kanakkassery le16_to_cpu(ev->supervision_timeout)); 6084d12fb056SJaganath Kanakkassery } 6085d12fb056SJaganath Kanakkassery 608695118dd4SLuiz Augusto von Dentz static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, void *data, 60874d94f95dSJaganath Kanakkassery struct sk_buff *skb) 60884d94f95dSJaganath Kanakkassery { 608995118dd4SLuiz Augusto von Dentz struct hci_ev_le_enh_conn_complete *ev = data; 609012cfe417SLuiz Augusto von Dentz 609195118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 60924d94f95dSJaganath Kanakkassery 60934d94f95dSJaganath Kanakkassery le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type, 6094cafae4cdSLuiz Augusto von Dentz &ev->local_rpa, ev->role, le16_to_cpu(ev->handle), 60954d94f95dSJaganath Kanakkassery le16_to_cpu(ev->interval), 60964d94f95dSJaganath Kanakkassery le16_to_cpu(ev->latency), 60974d94f95dSJaganath Kanakkassery le16_to_cpu(ev->supervision_timeout)); 60984d94f95dSJaganath Kanakkassery } 60994d94f95dSJaganath Kanakkassery 610095118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data, 610195118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 6102acf0aeaeSJaganath Kanakkassery { 610395118dd4SLuiz Augusto von Dentz struct hci_evt_le_ext_adv_set_term *ev = data; 6104acf0aeaeSJaganath Kanakkassery struct hci_conn *conn; 61051f9d5657SArchie Pusaka struct adv_info *adv, *n; 6106acf0aeaeSJaganath Kanakkassery 610795118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 6108acf0aeaeSJaganath Kanakkassery 61090f281a5eSArchie Pusaka /* The Bluetooth Core 5.3 specification clearly states that this event 61100f281a5eSArchie Pusaka * shall not be sent when the Host disables the advertising set. So in 61110f281a5eSArchie Pusaka * case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event. 61120f281a5eSArchie Pusaka * 61130f281a5eSArchie Pusaka * When the Host disables an advertising set, all cleanup is done via 61140f281a5eSArchie Pusaka * its command callback and not needed to be duplicated here. 61150f281a5eSArchie Pusaka */ 61160f281a5eSArchie Pusaka if (ev->status == HCI_ERROR_CANCELLED_BY_HOST) { 61170f281a5eSArchie Pusaka bt_dev_warn_ratelimited(hdev, "Unexpected advertising set terminated event"); 61180f281a5eSArchie Pusaka return; 61190f281a5eSArchie Pusaka } 61200f281a5eSArchie Pusaka 6121728abc01SNiels Dossche hci_dev_lock(hdev); 6122728abc01SNiels Dossche 6123728abc01SNiels Dossche adv = hci_find_adv_instance(hdev, ev->handle); 6124728abc01SNiels Dossche 61257087c4f6SLuiz Augusto von Dentz if (ev->status) { 612623837a6dSLuiz Augusto von Dentz if (!adv) 6127728abc01SNiels Dossche goto unlock; 6128acf0aeaeSJaganath Kanakkassery 612923837a6dSLuiz Augusto von Dentz /* Remove advertising as it has been terminated */ 613023837a6dSLuiz Augusto von Dentz hci_remove_adv_instance(hdev, ev->handle); 613123837a6dSLuiz Augusto von Dentz mgmt_advertising_removed(NULL, hdev, ev->handle); 613223837a6dSLuiz Augusto von Dentz 61331f9d5657SArchie Pusaka list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) { 61341f9d5657SArchie Pusaka if (adv->enabled) 6135728abc01SNiels Dossche goto unlock; 61361f9d5657SArchie Pusaka } 61371f9d5657SArchie Pusaka 61381f9d5657SArchie Pusaka /* We are no longer advertising, clear HCI_LE_ADV */ 61391f9d5657SArchie Pusaka hci_dev_clear_flag(hdev, HCI_LE_ADV); 6140728abc01SNiels Dossche goto unlock; 614123837a6dSLuiz Augusto von Dentz } 614223837a6dSLuiz Augusto von Dentz 61437087c4f6SLuiz Augusto von Dentz if (adv) 61447087c4f6SLuiz Augusto von Dentz adv->enabled = false; 61457087c4f6SLuiz Augusto von Dentz 6146acf0aeaeSJaganath Kanakkassery conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle)); 6147acf0aeaeSJaganath Kanakkassery if (conn) { 61487087c4f6SLuiz Augusto von Dentz /* Store handle in the connection so the correct advertising 61497087c4f6SLuiz Augusto von Dentz * instance can be re-enabled when disconnected. 61507087c4f6SLuiz Augusto von Dentz */ 61517087c4f6SLuiz Augusto von Dentz conn->adv_instance = ev->handle; 6152acf0aeaeSJaganath Kanakkassery 6153cafae4cdSLuiz Augusto von Dentz if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM || 6154cafae4cdSLuiz Augusto von Dentz bacmp(&conn->resp_addr, BDADDR_ANY)) 6155728abc01SNiels Dossche goto unlock; 6156acf0aeaeSJaganath Kanakkassery 615725e70886SDaniel Winkler if (!ev->handle) { 6158acf0aeaeSJaganath Kanakkassery bacpy(&conn->resp_addr, &hdev->random_addr); 6159728abc01SNiels Dossche goto unlock; 6160acf0aeaeSJaganath Kanakkassery } 6161acf0aeaeSJaganath Kanakkassery 61627087c4f6SLuiz Augusto von Dentz if (adv) 61637087c4f6SLuiz Augusto von Dentz bacpy(&conn->resp_addr, &adv->random_addr); 6164acf0aeaeSJaganath Kanakkassery } 6165728abc01SNiels Dossche 6166728abc01SNiels Dossche unlock: 6167728abc01SNiels Dossche hci_dev_unlock(hdev); 6168acf0aeaeSJaganath Kanakkassery } 6169acf0aeaeSJaganath Kanakkassery 617095118dd4SLuiz Augusto von Dentz static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data, 61711855d92dSMarcel Holtmann struct sk_buff *skb) 61721855d92dSMarcel Holtmann { 617395118dd4SLuiz Augusto von Dentz struct hci_ev_le_conn_update_complete *ev = data; 61741855d92dSMarcel Holtmann struct hci_conn *conn; 61751855d92dSMarcel Holtmann 617695118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 61771855d92dSMarcel Holtmann 61781855d92dSMarcel Holtmann if (ev->status) 61791855d92dSMarcel Holtmann return; 61801855d92dSMarcel Holtmann 61811855d92dSMarcel Holtmann hci_dev_lock(hdev); 61821855d92dSMarcel Holtmann 61831855d92dSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 61841855d92dSMarcel Holtmann if (conn) { 61851855d92dSMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval); 61861855d92dSMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency); 61871855d92dSMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout); 61881855d92dSMarcel Holtmann } 61891855d92dSMarcel Holtmann 61901855d92dSMarcel Holtmann hci_dev_unlock(hdev); 61911855d92dSMarcel Holtmann } 61921855d92dSMarcel Holtmann 6193a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */ 6194fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev, 6195fd45ada9SAlfonso Acosta bdaddr_t *addr, 6196d850bf08SLuiz Augusto von Dentz u8 addr_type, bool addr_resolved, 61978e8b92eeSLuiz Augusto von Dentz u8 adv_type) 6198a4790dbdSAndre Guedes { 6199a4790dbdSAndre Guedes struct hci_conn *conn; 62004b9e7e75SMarcel Holtmann struct hci_conn_params *params; 6201a4790dbdSAndre Guedes 62021c1abcabSJohan Hedberg /* If the event is not connectable don't proceed further */ 62031c1abcabSJohan Hedberg if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) 6204fd45ada9SAlfonso Acosta return NULL; 62051c1abcabSJohan Hedberg 6206182ee45dSLuiz Augusto von Dentz /* Ignore if the device is blocked or hdev is suspended */ 6207182ee45dSLuiz Augusto von Dentz if (hci_bdaddr_list_lookup(&hdev->reject_list, addr, addr_type) || 6208182ee45dSLuiz Augusto von Dentz hdev->suspended) 6209fd45ada9SAlfonso Acosta return NULL; 62101c1abcabSJohan Hedberg 6211f99353cfSJohan Hedberg /* Most controller will fail if we try to create new connections 621239bc74caSArchie Pusaka * while we have an existing one in peripheral role. 6213f99353cfSJohan Hedberg */ 621439bc74caSArchie Pusaka if (hdev->conn_hash.le_num_peripheral > 0 && 62154364f2e9SAlain Michaud (!test_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks) || 62164364f2e9SAlain Michaud !(hdev->le_states[3] & 0x10))) 6217fd45ada9SAlfonso Acosta return NULL; 6218f99353cfSJohan Hedberg 62191c1abcabSJohan Hedberg /* If we're not connectable only connect devices that we have in 62201c1abcabSJohan Hedberg * our pend_le_conns list. 62211c1abcabSJohan Hedberg */ 622249c50922SJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr, 622349c50922SJohan Hedberg addr_type); 62244b9e7e75SMarcel Holtmann if (!params) 6225fd45ada9SAlfonso Acosta return NULL; 6226a4790dbdSAndre Guedes 622728a667c9SJakub Pawlowski if (!params->explicit_connect) { 62284b9e7e75SMarcel Holtmann switch (params->auto_connect) { 62294b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 62304b9e7e75SMarcel Holtmann /* Only devices advertising with ADV_DIRECT_IND are 62314b9e7e75SMarcel Holtmann * triggering a connection attempt. This is allowing 623267ffb185SArchie Pusaka * incoming connections from peripheral devices. 62334b9e7e75SMarcel Holtmann */ 62344b9e7e75SMarcel Holtmann if (adv_type != LE_ADV_DIRECT_IND) 6235fd45ada9SAlfonso Acosta return NULL; 62364b9e7e75SMarcel Holtmann break; 62374b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_ALWAYS: 62384b9e7e75SMarcel Holtmann /* Devices advertising with ADV_IND or ADV_DIRECT_IND 62394b9e7e75SMarcel Holtmann * are triggering a connection attempt. This means 624067ffb185SArchie Pusaka * that incoming connections from peripheral device are 624167ffb185SArchie Pusaka * accepted and also outgoing connections to peripheral 62424b9e7e75SMarcel Holtmann * devices are established when found. 62434b9e7e75SMarcel Holtmann */ 62444b9e7e75SMarcel Holtmann break; 62454b9e7e75SMarcel Holtmann default: 6246fd45ada9SAlfonso Acosta return NULL; 62474b9e7e75SMarcel Holtmann } 624828a667c9SJakub Pawlowski } 62494b9e7e75SMarcel Holtmann 6250d850bf08SLuiz Augusto von Dentz conn = hci_connect_le(hdev, addr, addr_type, addr_resolved, 6251d850bf08SLuiz Augusto von Dentz BT_SECURITY_LOW, hdev->def_le_autoconnect_timeout, 62528e8b92eeSLuiz Augusto von Dentz HCI_ROLE_MASTER); 6253f161dd41SJohan Hedberg if (!IS_ERR(conn)) { 625428a667c9SJakub Pawlowski /* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned 625528a667c9SJakub Pawlowski * by higher layer that tried to connect, if no then 625628a667c9SJakub Pawlowski * store the pointer since we don't really have any 6257f161dd41SJohan Hedberg * other owner of the object besides the params that 6258f161dd41SJohan Hedberg * triggered it. This way we can abort the connection if 6259f161dd41SJohan Hedberg * the parameters get removed and keep the reference 6260f161dd41SJohan Hedberg * count consistent once the connection is established. 6261f161dd41SJohan Hedberg */ 626228a667c9SJakub Pawlowski 626328a667c9SJakub Pawlowski if (!params->explicit_connect) 6264f8aaf9b6SJohan Hedberg params->conn = hci_conn_get(conn); 626528a667c9SJakub Pawlowski 6266fd45ada9SAlfonso Acosta return conn; 6267f161dd41SJohan Hedberg } 6268a4790dbdSAndre Guedes 6269a4790dbdSAndre Guedes switch (PTR_ERR(conn)) { 6270a4790dbdSAndre Guedes case -EBUSY: 6271a4790dbdSAndre Guedes /* If hci_connect() returns -EBUSY it means there is already 6272a4790dbdSAndre Guedes * an LE connection attempt going on. Since controllers don't 6273a4790dbdSAndre Guedes * support more than one connection attempt at the time, we 6274a4790dbdSAndre Guedes * don't consider this an error case. 6275a4790dbdSAndre Guedes */ 6276a4790dbdSAndre Guedes break; 6277a4790dbdSAndre Guedes default: 6278a4790dbdSAndre Guedes BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); 6279fd45ada9SAlfonso Acosta return NULL; 6280a4790dbdSAndre Guedes } 6281fd45ada9SAlfonso Acosta 6282fd45ada9SAlfonso Acosta return NULL; 6283a4790dbdSAndre Guedes } 6284a4790dbdSAndre Guedes 62854af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, 62862f010b55SMarcel Holtmann u8 bdaddr_type, bdaddr_t *direct_addr, 6287a2ec905dSAlain Michaud u8 direct_addr_type, s8 rssi, u8 *data, u8 len, 6288b338d917SBrian Gix bool ext_adv, bool ctl_time, u64 instant) 62894af605d8SJohan Hedberg { 6290b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 62911c1abcabSJohan Hedberg struct smp_irk *irk; 6292fd45ada9SAlfonso Acosta struct hci_conn *conn; 6293d850bf08SLuiz Augusto von Dentz bool match, bdaddr_resolved; 6294c70a7e4cSMarcel Holtmann u32 flags; 62951c58e933SSzymon Janc u8 *ptr; 62966818375eSSzymon Janc 629756b40fbfSJohan Hedberg switch (type) { 629856b40fbfSJohan Hedberg case LE_ADV_IND: 629956b40fbfSJohan Hedberg case LE_ADV_DIRECT_IND: 630056b40fbfSJohan Hedberg case LE_ADV_SCAN_IND: 630156b40fbfSJohan Hedberg case LE_ADV_NONCONN_IND: 630256b40fbfSJohan Hedberg case LE_ADV_SCAN_RSP: 630356b40fbfSJohan Hedberg break; 630456b40fbfSJohan Hedberg default: 63052064ee33SMarcel Holtmann bt_dev_err_ratelimited(hdev, "unknown advertising packet " 63062064ee33SMarcel Holtmann "type: 0x%02x", type); 630756b40fbfSJohan Hedberg return; 630856b40fbfSJohan Hedberg } 630956b40fbfSJohan Hedberg 6310112b5090SLuiz Augusto von Dentz if (len > max_adv_len(hdev)) { 6311112b5090SLuiz Augusto von Dentz bt_dev_err_ratelimited(hdev, 6312112b5090SLuiz Augusto von Dentz "adv larger than maximum supported"); 6313a2ec905dSAlain Michaud return; 6314a2ec905dSAlain Michaud } 6315a2ec905dSAlain Michaud 63166818375eSSzymon Janc /* Find the end of the data in case the report contains padded zero 63176818375eSSzymon Janc * bytes at the end causing an invalid length value. 63186818375eSSzymon Janc * 63196818375eSSzymon Janc * When data is NULL, len is 0 so there is no need for extra ptr 63206818375eSSzymon Janc * check as 'ptr < data + 0' is already false in such case. 63216818375eSSzymon Janc */ 63226818375eSSzymon Janc for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) { 63236818375eSSzymon Janc if (ptr + 1 + *ptr > data + len) 63246818375eSSzymon Janc break; 63256818375eSSzymon Janc } 63266818375eSSzymon Janc 63271c58e933SSzymon Janc /* Adjust for actual length. This handles the case when remote 63281c58e933SSzymon Janc * device is advertising with incorrect data length. 63291c58e933SSzymon Janc */ 63301c58e933SSzymon Janc len = ptr - data; 6331b9a6328fSJohan Hedberg 63322f010b55SMarcel Holtmann /* If the direct address is present, then this report is from 63332f010b55SMarcel Holtmann * a LE Direct Advertising Report event. In that case it is 63342f010b55SMarcel Holtmann * important to see if the address is matching the local 63352f010b55SMarcel Holtmann * controller address. 63362f010b55SMarcel Holtmann */ 6337b338d917SBrian Gix if (!hci_dev_test_flag(hdev, HCI_MESH) && direct_addr) { 6338d850bf08SLuiz Augusto von Dentz direct_addr_type = ev_bdaddr_type(hdev, direct_addr_type, 6339d850bf08SLuiz Augusto von Dentz &bdaddr_resolved); 63404ec4d63bSLuiz Augusto von Dentz 63412f010b55SMarcel Holtmann /* Only resolvable random addresses are valid for these 63422f010b55SMarcel Holtmann * kind of reports and others can be ignored. 63432f010b55SMarcel Holtmann */ 63442f010b55SMarcel Holtmann if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type)) 63452f010b55SMarcel Holtmann return; 63462f010b55SMarcel Holtmann 63472f010b55SMarcel Holtmann /* If the controller is not using resolvable random 63482f010b55SMarcel Holtmann * addresses, then this report can be ignored. 63492f010b55SMarcel Holtmann */ 6350d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_PRIVACY)) 63512f010b55SMarcel Holtmann return; 63522f010b55SMarcel Holtmann 63532f010b55SMarcel Holtmann /* If the local IRK of the controller does not match 63542f010b55SMarcel Holtmann * with the resolvable random address provided, then 63552f010b55SMarcel Holtmann * this report can be ignored. 63562f010b55SMarcel Holtmann */ 63572f010b55SMarcel Holtmann if (!smp_irk_matches(hdev, hdev->irk, direct_addr)) 63582f010b55SMarcel Holtmann return; 63592f010b55SMarcel Holtmann } 63602f010b55SMarcel Holtmann 6361435a13d8SJohan Hedberg /* Check if we need to convert to identity address */ 6362435a13d8SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, bdaddr_type); 6363435a13d8SJohan Hedberg if (irk) { 6364435a13d8SJohan Hedberg bdaddr = &irk->bdaddr; 6365435a13d8SJohan Hedberg bdaddr_type = irk->addr_type; 6366435a13d8SJohan Hedberg } 6367435a13d8SJohan Hedberg 6368d850bf08SLuiz Augusto von Dentz bdaddr_type = ev_bdaddr_type(hdev, bdaddr_type, &bdaddr_resolved); 63694ec4d63bSLuiz Augusto von Dentz 6370082f2300SSzymon Janc /* Check if we have been requested to connect to this device. 6371082f2300SSzymon Janc * 6372082f2300SSzymon Janc * direct_addr is set only for directed advertising reports (it is NULL 6373082f2300SSzymon Janc * for advertising reports) and is already verified to be RPA above. 6374082f2300SSzymon Janc */ 6375d850bf08SLuiz Augusto von Dentz conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved, 63768e8b92eeSLuiz Augusto von Dentz type); 6377112b5090SLuiz Augusto von Dentz if (!ext_adv && conn && type == LE_ADV_IND && 6378112b5090SLuiz Augusto von Dentz len <= max_adv_len(hdev)) { 6379fd45ada9SAlfonso Acosta /* Store report for later inclusion by 6380fd45ada9SAlfonso Acosta * mgmt_device_connected 6381fd45ada9SAlfonso Acosta */ 6382fd45ada9SAlfonso Acosta memcpy(conn->le_adv_data, data, len); 6383fd45ada9SAlfonso Acosta conn->le_adv_data_len = len; 6384fd45ada9SAlfonso Acosta } 638599a6768eSJohan Hedberg 6386b338d917SBrian Gix if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND) 6387b338d917SBrian Gix flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 6388b338d917SBrian Gix else 6389b338d917SBrian Gix flags = 0; 6390b338d917SBrian Gix 6391b338d917SBrian Gix /* All scan results should be sent up for Mesh systems */ 6392b338d917SBrian Gix if (hci_dev_test_flag(hdev, HCI_MESH)) { 6393b338d917SBrian Gix mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 6394b338d917SBrian Gix rssi, flags, data, len, NULL, 0, instant); 6395b338d917SBrian Gix return; 6396b338d917SBrian Gix } 6397b338d917SBrian Gix 63981c1abcabSJohan Hedberg /* Passive scanning shouldn't trigger any device found events, 63991c1abcabSJohan Hedberg * except for devices marked as CONN_REPORT for which we do send 64008208f5a9SMiao-chen Chou * device found events, or advertisement monitoring requested. 64011c1abcabSJohan Hedberg */ 64021c1abcabSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_PASSIVE) { 64030d2bf134SJohan Hedberg if (type == LE_ADV_DIRECT_IND) 64040d2bf134SJohan Hedberg return; 64050d2bf134SJohan Hedberg 64063a19b6feSJohan Hedberg if (!hci_pend_le_action_lookup(&hdev->pend_le_reports, 64078208f5a9SMiao-chen Chou bdaddr, bdaddr_type) && 64088208f5a9SMiao-chen Chou idr_is_empty(&hdev->adv_monitors_idr)) 64090d2bf134SJohan Hedberg return; 64100d2bf134SJohan Hedberg 64110d2bf134SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 6412b338d917SBrian Gix rssi, flags, data, len, NULL, 0, 0); 641397bf2e99SJohan Hedberg return; 6414ca5c4be7SJohan Hedberg } 64154af605d8SJohan Hedberg 641673f55453SLuiz Augusto von Dentz /* When receiving a scan response, then there is no way to 6417c70a7e4cSMarcel Holtmann * know if the remote device is connectable or not. However 6418c70a7e4cSMarcel Holtmann * since scan responses are merged with a previously seen 6419c70a7e4cSMarcel Holtmann * advertising report, the flags field from that report 6420c70a7e4cSMarcel Holtmann * will be used. 6421c70a7e4cSMarcel Holtmann * 642273f55453SLuiz Augusto von Dentz * In the unlikely case that a controller just sends a scan 642373f55453SLuiz Augusto von Dentz * response event that doesn't match the pending report, then 642473f55453SLuiz Augusto von Dentz * it is marked as a standalone SCAN_RSP. 6425c70a7e4cSMarcel Holtmann */ 6426b338d917SBrian Gix if (type == LE_ADV_SCAN_RSP) 642773f55453SLuiz Augusto von Dentz flags = MGMT_DEV_FOUND_SCAN_RSP; 6428c70a7e4cSMarcel Holtmann 6429b9a6328fSJohan Hedberg /* If there's nothing pending either store the data from this 6430b9a6328fSJohan Hedberg * event or send an immediate device found event if the data 6431b9a6328fSJohan Hedberg * should not be stored for later. 6432b9a6328fSJohan Hedberg */ 6433a2ec905dSAlain Michaud if (!ext_adv && !has_pending_adv_report(hdev)) { 6434b9a6328fSJohan Hedberg /* If the report will trigger a SCAN_REQ store it for 6435b9a6328fSJohan Hedberg * later merging. 6436b9a6328fSJohan Hedberg */ 6437b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 6438b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 6439c70a7e4cSMarcel Holtmann rssi, flags, data, len); 6440b9a6328fSJohan Hedberg return; 6441b9a6328fSJohan Hedberg } 6442b9a6328fSJohan Hedberg 6443b9a6328fSJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 6444b338d917SBrian Gix rssi, flags, data, len, NULL, 0, 0); 6445b9a6328fSJohan Hedberg return; 6446b9a6328fSJohan Hedberg } 6447b9a6328fSJohan Hedberg 6448474ee066SJohan Hedberg /* Check if the pending report is for the same device as the new one */ 6449474ee066SJohan Hedberg match = (!bacmp(bdaddr, &d->last_adv_addr) && 6450474ee066SJohan Hedberg bdaddr_type == d->last_adv_addr_type); 6451474ee066SJohan Hedberg 6452b9a6328fSJohan Hedberg /* If the pending data doesn't match this report or this isn't a 6453b9a6328fSJohan Hedberg * scan response (e.g. we got a duplicate ADV_IND) then force 6454b9a6328fSJohan Hedberg * sending of the pending data. 6455b9a6328fSJohan Hedberg */ 6456474ee066SJohan Hedberg if (type != LE_ADV_SCAN_RSP || !match) { 6457474ee066SJohan Hedberg /* Send out whatever is in the cache, but skip duplicates */ 6458474ee066SJohan Hedberg if (!match) 6459b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 6460ff5cd29fSJohan Hedberg d->last_adv_addr_type, NULL, 6461c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 6462ff5cd29fSJohan Hedberg d->last_adv_data, 6463b338d917SBrian Gix d->last_adv_data_len, NULL, 0, 0); 6464b9a6328fSJohan Hedberg 6465b9a6328fSJohan Hedberg /* If the new report will trigger a SCAN_REQ store it for 6466b9a6328fSJohan Hedberg * later merging. 6467b9a6328fSJohan Hedberg */ 6468a2ec905dSAlain Michaud if (!ext_adv && (type == LE_ADV_IND || 6469a2ec905dSAlain Michaud type == LE_ADV_SCAN_IND)) { 6470b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 6471c70a7e4cSMarcel Holtmann rssi, flags, data, len); 6472b9a6328fSJohan Hedberg return; 6473b9a6328fSJohan Hedberg } 6474b9a6328fSJohan Hedberg 6475b9a6328fSJohan Hedberg /* The advertising reports cannot be merged, so clear 6476b9a6328fSJohan Hedberg * the pending report and send out a device found event. 6477b9a6328fSJohan Hedberg */ 6478b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 64795c5b93e4SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 6480b338d917SBrian Gix rssi, flags, data, len, NULL, 0, 0); 6481b9a6328fSJohan Hedberg return; 6482b9a6328fSJohan Hedberg } 6483b9a6328fSJohan Hedberg 6484b9a6328fSJohan Hedberg /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and 6485b9a6328fSJohan Hedberg * the new event is a SCAN_RSP. We can therefore proceed with 6486b9a6328fSJohan Hedberg * sending a merged device found event. 6487b9a6328fSJohan Hedberg */ 6488b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 6489c70a7e4cSMarcel Holtmann d->last_adv_addr_type, NULL, rssi, d->last_adv_flags, 6490b338d917SBrian Gix d->last_adv_data, d->last_adv_data_len, data, len, 0); 6491b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 64924af605d8SJohan Hedberg } 64934af605d8SJohan Hedberg 649495118dd4SLuiz Augusto von Dentz static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data, 649595118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 64969aa04c91SAndre Guedes { 649795118dd4SLuiz Augusto von Dentz struct hci_ev_le_advertising_report *ev = data; 6498b338d917SBrian Gix u64 instant = jiffies; 649947afe93cSLuiz Augusto von Dentz 650047afe93cSLuiz Augusto von Dentz if (!ev->num) 650147afe93cSLuiz Augusto von Dentz return; 65029aa04c91SAndre Guedes 6503a4790dbdSAndre Guedes hci_dev_lock(hdev); 6504a4790dbdSAndre Guedes 650547afe93cSLuiz Augusto von Dentz while (ev->num--) { 650647afe93cSLuiz Augusto von Dentz struct hci_ev_le_advertising_info *info; 65074af605d8SJohan Hedberg s8 rssi; 6508a4790dbdSAndre Guedes 650947afe93cSLuiz Augusto von Dentz info = hci_le_ev_skb_pull(hdev, skb, 651047afe93cSLuiz Augusto von Dentz HCI_EV_LE_ADVERTISING_REPORT, 651147afe93cSLuiz Augusto von Dentz sizeof(*info)); 651247afe93cSLuiz Augusto von Dentz if (!info) 6513899663beSBrian Gix break; 6514899663beSBrian Gix 651547afe93cSLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_ADVERTISING_REPORT, 651647afe93cSLuiz Augusto von Dentz info->length + 1)) 651747afe93cSLuiz Augusto von Dentz break; 651847afe93cSLuiz Augusto von Dentz 6519112b5090SLuiz Augusto von Dentz if (info->length <= max_adv_len(hdev)) { 652047afe93cSLuiz Augusto von Dentz rssi = info->data[info->length]; 652147afe93cSLuiz Augusto von Dentz process_adv_report(hdev, info->type, &info->bdaddr, 652247afe93cSLuiz Augusto von Dentz info->bdaddr_type, NULL, 0, rssi, 6523b338d917SBrian Gix info->data, info->length, false, 6524b338d917SBrian Gix false, instant); 6525ee649346SChriz Chow } else { 6526ee649346SChriz Chow bt_dev_err(hdev, "Dropping invalid advertising data"); 6527ee649346SChriz Chow } 65289aa04c91SAndre Guedes } 6529a4790dbdSAndre Guedes 6530a4790dbdSAndre Guedes hci_dev_unlock(hdev); 65319aa04c91SAndre Guedes } 65329aa04c91SAndre Guedes 6533657cc646SMarcel Holtmann static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type) 6534c215e939SJaganath Kanakkassery { 6535b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_LEGACY_PDU) { 6536c215e939SJaganath Kanakkassery switch (evt_type) { 6537c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_IND: 6538c215e939SJaganath Kanakkassery return LE_ADV_IND; 6539c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_DIRECT_IND: 6540c215e939SJaganath Kanakkassery return LE_ADV_DIRECT_IND; 6541c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_SCAN_IND: 6542c215e939SJaganath Kanakkassery return LE_ADV_SCAN_IND; 6543c215e939SJaganath Kanakkassery case LE_LEGACY_NONCONN_IND: 6544c215e939SJaganath Kanakkassery return LE_ADV_NONCONN_IND; 6545c215e939SJaganath Kanakkassery case LE_LEGACY_SCAN_RSP_ADV: 6546c215e939SJaganath Kanakkassery case LE_LEGACY_SCAN_RSP_ADV_SCAN: 6547c215e939SJaganath Kanakkassery return LE_ADV_SCAN_RSP; 6548c215e939SJaganath Kanakkassery } 6549c215e939SJaganath Kanakkassery 6550657cc646SMarcel Holtmann goto invalid; 6551c215e939SJaganath Kanakkassery } 6552c215e939SJaganath Kanakkassery 6553b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_CONN_IND) { 6554b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_DIRECT_IND) 6555b2cc9761SJaganath Kanakkassery return LE_ADV_DIRECT_IND; 6556b2cc9761SJaganath Kanakkassery 6557b2cc9761SJaganath Kanakkassery return LE_ADV_IND; 6558b2cc9761SJaganath Kanakkassery } 6559b2cc9761SJaganath Kanakkassery 6560b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_SCAN_RSP) 6561b2cc9761SJaganath Kanakkassery return LE_ADV_SCAN_RSP; 6562b2cc9761SJaganath Kanakkassery 6563b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_SCAN_IND) 6564b2cc9761SJaganath Kanakkassery return LE_ADV_SCAN_IND; 6565b2cc9761SJaganath Kanakkassery 6566b2cc9761SJaganath Kanakkassery if (evt_type == LE_EXT_ADV_NON_CONN_IND || 6567b2cc9761SJaganath Kanakkassery evt_type & LE_EXT_ADV_DIRECT_IND) 6568b2cc9761SJaganath Kanakkassery return LE_ADV_NONCONN_IND; 6569b2cc9761SJaganath Kanakkassery 6570657cc646SMarcel Holtmann invalid: 6571657cc646SMarcel Holtmann bt_dev_err_ratelimited(hdev, "Unknown advertising packet type: 0x%02x", 6572b2cc9761SJaganath Kanakkassery evt_type); 6573b2cc9761SJaganath Kanakkassery 6574b2cc9761SJaganath Kanakkassery return LE_ADV_INVALID; 6575b2cc9761SJaganath Kanakkassery } 6576b2cc9761SJaganath Kanakkassery 657795118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data, 657895118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 6579c215e939SJaganath Kanakkassery { 658095118dd4SLuiz Augusto von Dentz struct hci_ev_le_ext_adv_report *ev = data; 6581b338d917SBrian Gix u64 instant = jiffies; 6582b48b833fSLuiz Augusto von Dentz 6583b48b833fSLuiz Augusto von Dentz if (!ev->num) 6584b48b833fSLuiz Augusto von Dentz return; 6585c215e939SJaganath Kanakkassery 6586c215e939SJaganath Kanakkassery hci_dev_lock(hdev); 6587c215e939SJaganath Kanakkassery 6588b48b833fSLuiz Augusto von Dentz while (ev->num--) { 6589b48b833fSLuiz Augusto von Dentz struct hci_ev_le_ext_adv_info *info; 6590c215e939SJaganath Kanakkassery u8 legacy_evt_type; 6591c215e939SJaganath Kanakkassery u16 evt_type; 6592c215e939SJaganath Kanakkassery 6593b48b833fSLuiz Augusto von Dentz info = hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT, 6594b48b833fSLuiz Augusto von Dentz sizeof(*info)); 6595b48b833fSLuiz Augusto von Dentz if (!info) 6596b48b833fSLuiz Augusto von Dentz break; 6597b48b833fSLuiz Augusto von Dentz 6598b48b833fSLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT, 6599b48b833fSLuiz Augusto von Dentz info->length)) 6600b48b833fSLuiz Augusto von Dentz break; 6601b48b833fSLuiz Augusto von Dentz 6602ad38e55eSSven Peter evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK; 6603657cc646SMarcel Holtmann legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type); 6604c215e939SJaganath Kanakkassery if (legacy_evt_type != LE_ADV_INVALID) { 6605b48b833fSLuiz Augusto von Dentz process_adv_report(hdev, legacy_evt_type, &info->bdaddr, 6606b48b833fSLuiz Augusto von Dentz info->bdaddr_type, NULL, 0, 6607b48b833fSLuiz Augusto von Dentz info->rssi, info->data, info->length, 6608b338d917SBrian Gix !(evt_type & LE_EXT_ADV_LEGACY_PDU), 6609b338d917SBrian Gix false, instant); 6610c215e939SJaganath Kanakkassery } 6611c215e939SJaganath Kanakkassery } 6612c215e939SJaganath Kanakkassery 6613c215e939SJaganath Kanakkassery hci_dev_unlock(hdev); 6614c215e939SJaganath Kanakkassery } 6615c215e939SJaganath Kanakkassery 6616eca0ae4aSLuiz Augusto von Dentz static int hci_le_pa_term_sync(struct hci_dev *hdev, __le16 handle) 6617eca0ae4aSLuiz Augusto von Dentz { 6618eca0ae4aSLuiz Augusto von Dentz struct hci_cp_le_pa_term_sync cp; 6619eca0ae4aSLuiz Augusto von Dentz 6620eca0ae4aSLuiz Augusto von Dentz memset(&cp, 0, sizeof(cp)); 6621eca0ae4aSLuiz Augusto von Dentz cp.handle = handle; 6622eca0ae4aSLuiz Augusto von Dentz 6623eca0ae4aSLuiz Augusto von Dentz return hci_send_cmd(hdev, HCI_OP_LE_PA_TERM_SYNC, sizeof(cp), &cp); 6624eca0ae4aSLuiz Augusto von Dentz } 6625eca0ae4aSLuiz Augusto von Dentz 6626eca0ae4aSLuiz Augusto von Dentz static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, 6627eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb) 6628eca0ae4aSLuiz Augusto von Dentz { 6629eca0ae4aSLuiz Augusto von Dentz struct hci_ev_le_pa_sync_established *ev = data; 6630eca0ae4aSLuiz Augusto von Dentz int mask = hdev->link_mode; 6631eca0ae4aSLuiz Augusto von Dentz __u8 flags = 0; 663223417475SIulia Tanasescu struct hci_conn *pa_sync; 6633eca0ae4aSLuiz Augusto von Dentz 6634eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 6635eca0ae4aSLuiz Augusto von Dentz 6636eca0ae4aSLuiz Augusto von Dentz hci_dev_lock(hdev); 6637eca0ae4aSLuiz Augusto von Dentz 6638eca0ae4aSLuiz Augusto von Dentz hci_dev_clear_flag(hdev, HCI_PA_SYNC); 6639eca0ae4aSLuiz Augusto von Dentz 6640eca0ae4aSLuiz Augusto von Dentz mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ISO_LINK, &flags); 6641fbdc4bc4SIulia Tanasescu if (!(mask & HCI_LM_ACCEPT)) { 6642eca0ae4aSLuiz Augusto von Dentz hci_le_pa_term_sync(hdev, ev->handle); 6643fbdc4bc4SIulia Tanasescu goto unlock; 6644fbdc4bc4SIulia Tanasescu } 6645eca0ae4aSLuiz Augusto von Dentz 6646fbdc4bc4SIulia Tanasescu if (!(flags & HCI_PROTO_DEFER)) 6647fbdc4bc4SIulia Tanasescu goto unlock; 6648fbdc4bc4SIulia Tanasescu 664923417475SIulia Tanasescu if (ev->status) { 665023417475SIulia Tanasescu /* Add connection to indicate the failed PA sync event */ 665184cb0143SZiyang Xuan pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY, 6652fbdc4bc4SIulia Tanasescu HCI_ROLE_SLAVE); 6653fbdc4bc4SIulia Tanasescu 665423417475SIulia Tanasescu if (!pa_sync) 6655fbdc4bc4SIulia Tanasescu goto unlock; 6656fbdc4bc4SIulia Tanasescu 665723417475SIulia Tanasescu set_bit(HCI_CONN_PA_SYNC_FAILED, &pa_sync->flags); 6658fbdc4bc4SIulia Tanasescu 665923417475SIulia Tanasescu /* Notify iso layer */ 666023417475SIulia Tanasescu hci_connect_cfm(pa_sync, ev->status); 666123417475SIulia Tanasescu } 6662fbdc4bc4SIulia Tanasescu 6663fbdc4bc4SIulia Tanasescu unlock: 6664eca0ae4aSLuiz Augusto von Dentz hci_dev_unlock(hdev); 6665eca0ae4aSLuiz Augusto von Dentz } 6666eca0ae4aSLuiz Augusto von Dentz 66679c082631SClaudia Draghicescu static void hci_le_per_adv_report_evt(struct hci_dev *hdev, void *data, 66689c082631SClaudia Draghicescu struct sk_buff *skb) 66699c082631SClaudia Draghicescu { 66709c082631SClaudia Draghicescu struct hci_ev_le_per_adv_report *ev = data; 66719c082631SClaudia Draghicescu int mask = hdev->link_mode; 66729c082631SClaudia Draghicescu __u8 flags = 0; 66739c082631SClaudia Draghicescu 66749c082631SClaudia Draghicescu bt_dev_dbg(hdev, "sync_handle 0x%4.4x", le16_to_cpu(ev->sync_handle)); 66759c082631SClaudia Draghicescu 66769c082631SClaudia Draghicescu hci_dev_lock(hdev); 66779c082631SClaudia Draghicescu 66789c082631SClaudia Draghicescu mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags); 66799c082631SClaudia Draghicescu if (!(mask & HCI_LM_ACCEPT)) 66809c082631SClaudia Draghicescu hci_le_pa_term_sync(hdev, ev->sync_handle); 66819c082631SClaudia Draghicescu 66829c082631SClaudia Draghicescu hci_dev_unlock(hdev); 66839c082631SClaudia Draghicescu } 66849c082631SClaudia Draghicescu 668595118dd4SLuiz Augusto von Dentz static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, void *data, 66860fe29fd1SMarcel Holtmann struct sk_buff *skb) 66870fe29fd1SMarcel Holtmann { 668895118dd4SLuiz Augusto von Dentz struct hci_ev_le_remote_feat_complete *ev = data; 66890fe29fd1SMarcel Holtmann struct hci_conn *conn; 66900fe29fd1SMarcel Holtmann 669195118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 66920fe29fd1SMarcel Holtmann 66930fe29fd1SMarcel Holtmann hci_dev_lock(hdev); 66940fe29fd1SMarcel Holtmann 66950fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 66960fe29fd1SMarcel Holtmann if (conn) { 66970fe29fd1SMarcel Holtmann if (!ev->status) 66980fe29fd1SMarcel Holtmann memcpy(conn->features[0], ev->features, 8); 66990fe29fd1SMarcel Holtmann 67000fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) { 67010fe29fd1SMarcel Holtmann __u8 status; 67020fe29fd1SMarcel Holtmann 6703ef365da1SArchie Pusaka /* If the local controller supports peripheral-initiated 67040fe29fd1SMarcel Holtmann * features exchange, but the remote controller does 67050fe29fd1SMarcel Holtmann * not, then it is possible that the error code 0x1a 67060fe29fd1SMarcel Holtmann * for unsupported remote feature gets returned. 67070fe29fd1SMarcel Holtmann * 67080fe29fd1SMarcel Holtmann * In this specific case, allow the connection to 67090fe29fd1SMarcel Holtmann * transition into connected state and mark it as 67100fe29fd1SMarcel Holtmann * successful. 67110fe29fd1SMarcel Holtmann */ 6712ef365da1SArchie Pusaka if (!conn->out && ev->status == 0x1a && 6713ef365da1SArchie Pusaka (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) 67140fe29fd1SMarcel Holtmann status = 0x00; 67150fe29fd1SMarcel Holtmann else 67160fe29fd1SMarcel Holtmann status = ev->status; 67170fe29fd1SMarcel Holtmann 67180fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED; 67190fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status); 67200fe29fd1SMarcel Holtmann hci_conn_drop(conn); 67210fe29fd1SMarcel Holtmann } 67220fe29fd1SMarcel Holtmann } 67230fe29fd1SMarcel Holtmann 67240fe29fd1SMarcel Holtmann hci_dev_unlock(hdev); 67250fe29fd1SMarcel Holtmann } 67260fe29fd1SMarcel Holtmann 672795118dd4SLuiz Augusto von Dentz static void hci_le_ltk_request_evt(struct hci_dev *hdev, void *data, 672895118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 6729a7a595f6SVinicius Costa Gomes { 673095118dd4SLuiz Augusto von Dentz struct hci_ev_le_ltk_req *ev = data; 6731a7a595f6SVinicius Costa Gomes struct hci_cp_le_ltk_reply cp; 6732bea710feSVinicius Costa Gomes struct hci_cp_le_ltk_neg_reply neg; 6733a7a595f6SVinicius Costa Gomes struct hci_conn *conn; 6734c9839a11SVinicius Costa Gomes struct smp_ltk *ltk; 6735a7a595f6SVinicius Costa Gomes 673695118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle)); 6737a7a595f6SVinicius Costa Gomes 6738a7a595f6SVinicius Costa Gomes hci_dev_lock(hdev); 6739a7a595f6SVinicius Costa Gomes 6740a7a595f6SVinicius Costa Gomes conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 6741bea710feSVinicius Costa Gomes if (conn == NULL) 6742bea710feSVinicius Costa Gomes goto not_found; 6743a7a595f6SVinicius Costa Gomes 6744f3a73d97SJohan Hedberg ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role); 67455378bc56SJohan Hedberg if (!ltk) 6746bea710feSVinicius Costa Gomes goto not_found; 6747bea710feSVinicius Costa Gomes 67485378bc56SJohan Hedberg if (smp_ltk_is_sc(ltk)) { 67495378bc56SJohan Hedberg /* With SC both EDiv and Rand are set to zero */ 67505378bc56SJohan Hedberg if (ev->ediv || ev->rand) 67515378bc56SJohan Hedberg goto not_found; 67525378bc56SJohan Hedberg } else { 67535378bc56SJohan Hedberg /* For non-SC keys check that EDiv and Rand match */ 67545378bc56SJohan Hedberg if (ev->ediv != ltk->ediv || ev->rand != ltk->rand) 67555378bc56SJohan Hedberg goto not_found; 67565378bc56SJohan Hedberg } 67575378bc56SJohan Hedberg 67588b76ce34SJohan Hedberg memcpy(cp.ltk, ltk->val, ltk->enc_size); 67598b76ce34SJohan Hedberg memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size); 6760a7a595f6SVinicius Costa Gomes cp.handle = cpu_to_le16(conn->handle); 6761c9839a11SVinicius Costa Gomes 6762a6f7833cSJohan Hedberg conn->pending_sec_level = smp_ltk_sec_level(ltk); 6763a7a595f6SVinicius Costa Gomes 676489cbb4daSAndre Guedes conn->enc_key_size = ltk->enc_size; 6765a7a595f6SVinicius Costa Gomes 6766a7a595f6SVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); 6767a7a595f6SVinicius Costa Gomes 67685981a882SClaudio Takahasi /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a 67695981a882SClaudio Takahasi * temporary key used to encrypt a connection following 67705981a882SClaudio Takahasi * pairing. It is used during the Encrypted Session Setup to 67715981a882SClaudio Takahasi * distribute the keys. Later, security can be re-established 67725981a882SClaudio Takahasi * using a distributed LTK. 67735981a882SClaudio Takahasi */ 67742ceba539SJohan Hedberg if (ltk->type == SMP_STK) { 6775fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 6776970d0f1bSJohan Hedberg list_del_rcu(<k->list); 6777970d0f1bSJohan Hedberg kfree_rcu(ltk, rcu); 6778fe59a05fSJohan Hedberg } else { 6779fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 6780c9839a11SVinicius Costa Gomes } 6781c9839a11SVinicius Costa Gomes 6782a7a595f6SVinicius Costa Gomes hci_dev_unlock(hdev); 6783bea710feSVinicius Costa Gomes 6784bea710feSVinicius Costa Gomes return; 6785bea710feSVinicius Costa Gomes 6786bea710feSVinicius Costa Gomes not_found: 6787bea710feSVinicius Costa Gomes neg.handle = ev->handle; 6788bea710feSVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); 6789bea710feSVinicius Costa Gomes hci_dev_unlock(hdev); 6790a7a595f6SVinicius Costa Gomes } 6791a7a595f6SVinicius Costa Gomes 67928e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle, 67938e75b46aSAndre Guedes u8 reason) 67948e75b46aSAndre Guedes { 67958e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_neg_reply cp; 67968e75b46aSAndre Guedes 67978e75b46aSAndre Guedes cp.handle = cpu_to_le16(handle); 67988e75b46aSAndre Guedes cp.reason = reason; 67998e75b46aSAndre Guedes 68008e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp), 68018e75b46aSAndre Guedes &cp); 68028e75b46aSAndre Guedes } 68038e75b46aSAndre Guedes 680495118dd4SLuiz Augusto von Dentz static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data, 68058e75b46aSAndre Guedes struct sk_buff *skb) 68068e75b46aSAndre Guedes { 680795118dd4SLuiz Augusto von Dentz struct hci_ev_le_remote_conn_param_req *ev = data; 68088e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_reply cp; 68098e75b46aSAndre Guedes struct hci_conn *hcon; 68108e75b46aSAndre Guedes u16 handle, min, max, latency, timeout; 68118e75b46aSAndre Guedes 681295118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle)); 681312cfe417SLuiz Augusto von Dentz 68148e75b46aSAndre Guedes handle = le16_to_cpu(ev->handle); 68158e75b46aSAndre Guedes min = le16_to_cpu(ev->interval_min); 68168e75b46aSAndre Guedes max = le16_to_cpu(ev->interval_max); 68178e75b46aSAndre Guedes latency = le16_to_cpu(ev->latency); 68188e75b46aSAndre Guedes timeout = le16_to_cpu(ev->timeout); 68198e75b46aSAndre Guedes 68208e75b46aSAndre Guedes hcon = hci_conn_hash_lookup_handle(hdev, handle); 68218e75b46aSAndre Guedes if (!hcon || hcon->state != BT_CONNECTED) 68228e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 68238e75b46aSAndre Guedes HCI_ERROR_UNKNOWN_CONN_ID); 68248e75b46aSAndre Guedes 6825dcd646f4SKai-Heng Feng if (max > hcon->le_conn_max_interval) 6826dcd646f4SKai-Heng Feng return send_conn_param_neg_reply(hdev, handle, 6827dcd646f4SKai-Heng Feng HCI_ERROR_INVALID_LL_PARAMS); 6828dcd646f4SKai-Heng Feng 68298e75b46aSAndre Guedes if (hci_check_conn_params(min, max, latency, timeout)) 68308e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 68318e75b46aSAndre Guedes HCI_ERROR_INVALID_LL_PARAMS); 68328e75b46aSAndre Guedes 683340bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) { 6834348d50b8SJohan Hedberg struct hci_conn_params *params; 6835f4869e2aSJohan Hedberg u8 store_hint; 6836348d50b8SJohan Hedberg 6837348d50b8SJohan Hedberg hci_dev_lock(hdev); 6838348d50b8SJohan Hedberg 6839348d50b8SJohan Hedberg params = hci_conn_params_lookup(hdev, &hcon->dst, 6840348d50b8SJohan Hedberg hcon->dst_type); 6841348d50b8SJohan Hedberg if (params) { 6842348d50b8SJohan Hedberg params->conn_min_interval = min; 6843348d50b8SJohan Hedberg params->conn_max_interval = max; 6844348d50b8SJohan Hedberg params->conn_latency = latency; 6845348d50b8SJohan Hedberg params->supervision_timeout = timeout; 6846f4869e2aSJohan Hedberg store_hint = 0x01; 6847f4869e2aSJohan Hedberg } else { 6848f4869e2aSJohan Hedberg store_hint = 0x00; 6849348d50b8SJohan Hedberg } 6850348d50b8SJohan Hedberg 6851348d50b8SJohan Hedberg hci_dev_unlock(hdev); 6852348d50b8SJohan Hedberg 6853f4869e2aSJohan Hedberg mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type, 6854f4869e2aSJohan Hedberg store_hint, min, max, latency, timeout); 6855348d50b8SJohan Hedberg } 6856ffb5a827SAndre Guedes 68578e75b46aSAndre Guedes cp.handle = ev->handle; 68588e75b46aSAndre Guedes cp.interval_min = ev->interval_min; 68598e75b46aSAndre Guedes cp.interval_max = ev->interval_max; 68608e75b46aSAndre Guedes cp.latency = ev->latency; 68618e75b46aSAndre Guedes cp.timeout = ev->timeout; 68628e75b46aSAndre Guedes cp.min_ce_len = 0; 68638e75b46aSAndre Guedes cp.max_ce_len = 0; 68648e75b46aSAndre Guedes 68658e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp); 68668e75b46aSAndre Guedes } 68678e75b46aSAndre Guedes 686895118dd4SLuiz Augusto von Dentz static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data, 68692f010b55SMarcel Holtmann struct sk_buff *skb) 68702f010b55SMarcel Holtmann { 687195118dd4SLuiz Augusto von Dentz struct hci_ev_le_direct_adv_report *ev = data; 6872b338d917SBrian Gix u64 instant = jiffies; 6873a3679649SLuiz Augusto von Dentz int i; 6874f7e0e8b2SPeilin Ye 6875a3679649SLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_DIRECT_ADV_REPORT, 6876a3679649SLuiz Augusto von Dentz flex_array_size(ev, info, ev->num))) 6877a3679649SLuiz Augusto von Dentz return; 6878a3679649SLuiz Augusto von Dentz 6879a3679649SLuiz Augusto von Dentz if (!ev->num) 6880f7e0e8b2SPeilin Ye return; 68812f010b55SMarcel Holtmann 68822f010b55SMarcel Holtmann hci_dev_lock(hdev); 68832f010b55SMarcel Holtmann 6884a3679649SLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) { 6885a3679649SLuiz Augusto von Dentz struct hci_ev_le_direct_adv_info *info = &ev->info[i]; 6886a3679649SLuiz Augusto von Dentz 6887a3679649SLuiz Augusto von Dentz process_adv_report(hdev, info->type, &info->bdaddr, 6888a3679649SLuiz Augusto von Dentz info->bdaddr_type, &info->direct_addr, 6889a3679649SLuiz Augusto von Dentz info->direct_addr_type, info->rssi, NULL, 0, 6890b338d917SBrian Gix false, false, instant); 6891a3679649SLuiz Augusto von Dentz } 68922f010b55SMarcel Holtmann 68932f010b55SMarcel Holtmann hci_dev_unlock(hdev); 68942f010b55SMarcel Holtmann } 68952f010b55SMarcel Holtmann 689695118dd4SLuiz Augusto von Dentz static void hci_le_phy_update_evt(struct hci_dev *hdev, void *data, 689795118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 68981efd927dSLuiz Augusto von Dentz { 689995118dd4SLuiz Augusto von Dentz struct hci_ev_le_phy_update_complete *ev = data; 69001efd927dSLuiz Augusto von Dentz struct hci_conn *conn; 69011efd927dSLuiz Augusto von Dentz 690295118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 69031efd927dSLuiz Augusto von Dentz 690487df8bccSAyush Garg if (ev->status) 69051efd927dSLuiz Augusto von Dentz return; 69061efd927dSLuiz Augusto von Dentz 69071efd927dSLuiz Augusto von Dentz hci_dev_lock(hdev); 69081efd927dSLuiz Augusto von Dentz 69091efd927dSLuiz Augusto von Dentz conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 69101efd927dSLuiz Augusto von Dentz if (!conn) 69111efd927dSLuiz Augusto von Dentz goto unlock; 69121efd927dSLuiz Augusto von Dentz 69131efd927dSLuiz Augusto von Dentz conn->le_tx_phy = ev->tx_phy; 69141efd927dSLuiz Augusto von Dentz conn->le_rx_phy = ev->rx_phy; 69151efd927dSLuiz Augusto von Dentz 69161efd927dSLuiz Augusto von Dentz unlock: 69171efd927dSLuiz Augusto von Dentz hci_dev_unlock(hdev); 69181efd927dSLuiz Augusto von Dentz } 69191efd927dSLuiz Augusto von Dentz 692026afbd82SLuiz Augusto von Dentz static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data, 692126afbd82SLuiz Augusto von Dentz struct sk_buff *skb) 692226afbd82SLuiz Augusto von Dentz { 692326afbd82SLuiz Augusto von Dentz struct hci_evt_le_cis_established *ev = data; 692426afbd82SLuiz Augusto von Dentz struct hci_conn *conn; 69252be22f19SLuiz Augusto von Dentz struct bt_iso_qos *qos; 69267f74563eSPauli Virtanen bool pending = false; 692726afbd82SLuiz Augusto von Dentz u16 handle = __le16_to_cpu(ev->handle); 692826afbd82SLuiz Augusto von Dentz 692926afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 693026afbd82SLuiz Augusto von Dentz 693126afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev); 693226afbd82SLuiz Augusto von Dentz 693326afbd82SLuiz Augusto von Dentz conn = hci_conn_hash_lookup_handle(hdev, handle); 693426afbd82SLuiz Augusto von Dentz if (!conn) { 693526afbd82SLuiz Augusto von Dentz bt_dev_err(hdev, 693626afbd82SLuiz Augusto von Dentz "Unable to find connection with handle 0x%4.4x", 693726afbd82SLuiz Augusto von Dentz handle); 693826afbd82SLuiz Augusto von Dentz goto unlock; 693926afbd82SLuiz Augusto von Dentz } 694026afbd82SLuiz Augusto von Dentz 6941ed680f92SLuiz Augusto von Dentz if (conn->type != ISO_LINK) { 6942ed680f92SLuiz Augusto von Dentz bt_dev_err(hdev, 6943ed680f92SLuiz Augusto von Dentz "Invalid connection link type handle 0x%4.4x", 6944ed680f92SLuiz Augusto von Dentz handle); 6945ed680f92SLuiz Augusto von Dentz goto unlock; 6946ed680f92SLuiz Augusto von Dentz } 6947ed680f92SLuiz Augusto von Dentz 69482be22f19SLuiz Augusto von Dentz qos = &conn->iso_qos; 694926afbd82SLuiz Augusto von Dentz 69507f74563eSPauli Virtanen pending = test_and_clear_bit(HCI_CONN_CREATE_CIS, &conn->flags); 69517f74563eSPauli Virtanen 69522be22f19SLuiz Augusto von Dentz /* Convert ISO Interval (1.25 ms slots) to SDU Interval (us) */ 69532be22f19SLuiz Augusto von Dentz qos->ucast.in.interval = le16_to_cpu(ev->interval) * 1250; 69542be22f19SLuiz Augusto von Dentz qos->ucast.out.interval = qos->ucast.in.interval; 695526afbd82SLuiz Augusto von Dentz 69562be22f19SLuiz Augusto von Dentz switch (conn->role) { 69572be22f19SLuiz Augusto von Dentz case HCI_ROLE_SLAVE: 69582be22f19SLuiz Augusto von Dentz /* Convert Transport Latency (us) to Latency (msec) */ 69592be22f19SLuiz Augusto von Dentz qos->ucast.in.latency = 69602be22f19SLuiz Augusto von Dentz DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency), 69612be22f19SLuiz Augusto von Dentz 1000); 69622be22f19SLuiz Augusto von Dentz qos->ucast.out.latency = 69632be22f19SLuiz Augusto von Dentz DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency), 69642be22f19SLuiz Augusto von Dentz 1000); 69652be22f19SLuiz Augusto von Dentz qos->ucast.in.sdu = le16_to_cpu(ev->c_mtu); 69662be22f19SLuiz Augusto von Dentz qos->ucast.out.sdu = le16_to_cpu(ev->p_mtu); 69672be22f19SLuiz Augusto von Dentz qos->ucast.in.phy = ev->c_phy; 69682be22f19SLuiz Augusto von Dentz qos->ucast.out.phy = ev->p_phy; 69692be22f19SLuiz Augusto von Dentz break; 69702be22f19SLuiz Augusto von Dentz case HCI_ROLE_MASTER: 69712be22f19SLuiz Augusto von Dentz /* Convert Transport Latency (us) to Latency (msec) */ 69722be22f19SLuiz Augusto von Dentz qos->ucast.out.latency = 69732be22f19SLuiz Augusto von Dentz DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency), 69742be22f19SLuiz Augusto von Dentz 1000); 69752be22f19SLuiz Augusto von Dentz qos->ucast.in.latency = 69762be22f19SLuiz Augusto von Dentz DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency), 69772be22f19SLuiz Augusto von Dentz 1000); 69782be22f19SLuiz Augusto von Dentz qos->ucast.out.sdu = le16_to_cpu(ev->c_mtu); 69792be22f19SLuiz Augusto von Dentz qos->ucast.in.sdu = le16_to_cpu(ev->p_mtu); 69802be22f19SLuiz Augusto von Dentz qos->ucast.out.phy = ev->c_phy; 69812be22f19SLuiz Augusto von Dentz qos->ucast.in.phy = ev->p_phy; 69822be22f19SLuiz Augusto von Dentz break; 698326afbd82SLuiz Augusto von Dentz } 698426afbd82SLuiz Augusto von Dentz 698526afbd82SLuiz Augusto von Dentz if (!ev->status) { 698626afbd82SLuiz Augusto von Dentz conn->state = BT_CONNECTED; 698726afbd82SLuiz Augusto von Dentz hci_debugfs_create_conn(conn); 698826afbd82SLuiz Augusto von Dentz hci_conn_add_sysfs(conn); 698926afbd82SLuiz Augusto von Dentz hci_iso_setup_path(conn); 699026afbd82SLuiz Augusto von Dentz goto unlock; 699126afbd82SLuiz Augusto von Dentz } 699226afbd82SLuiz Augusto von Dentz 69937f74563eSPauli Virtanen conn->state = BT_CLOSED; 699426afbd82SLuiz Augusto von Dentz hci_connect_cfm(conn, ev->status); 699526afbd82SLuiz Augusto von Dentz hci_conn_del(conn); 699626afbd82SLuiz Augusto von Dentz 699726afbd82SLuiz Augusto von Dentz unlock: 69987f74563eSPauli Virtanen if (pending) 69997f74563eSPauli Virtanen hci_le_create_cis_pending(hdev); 70007f74563eSPauli Virtanen 700126afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev); 700226afbd82SLuiz Augusto von Dentz } 700326afbd82SLuiz Augusto von Dentz 700426afbd82SLuiz Augusto von Dentz static void hci_le_reject_cis(struct hci_dev *hdev, __le16 handle) 700526afbd82SLuiz Augusto von Dentz { 700626afbd82SLuiz Augusto von Dentz struct hci_cp_le_reject_cis cp; 700726afbd82SLuiz Augusto von Dentz 700826afbd82SLuiz Augusto von Dentz memset(&cp, 0, sizeof(cp)); 700926afbd82SLuiz Augusto von Dentz cp.handle = handle; 701026afbd82SLuiz Augusto von Dentz cp.reason = HCI_ERROR_REJ_BAD_ADDR; 701126afbd82SLuiz Augusto von Dentz hci_send_cmd(hdev, HCI_OP_LE_REJECT_CIS, sizeof(cp), &cp); 701226afbd82SLuiz Augusto von Dentz } 701326afbd82SLuiz Augusto von Dentz 701426afbd82SLuiz Augusto von Dentz static void hci_le_accept_cis(struct hci_dev *hdev, __le16 handle) 701526afbd82SLuiz Augusto von Dentz { 701626afbd82SLuiz Augusto von Dentz struct hci_cp_le_accept_cis cp; 701726afbd82SLuiz Augusto von Dentz 701826afbd82SLuiz Augusto von Dentz memset(&cp, 0, sizeof(cp)); 701926afbd82SLuiz Augusto von Dentz cp.handle = handle; 702026afbd82SLuiz Augusto von Dentz hci_send_cmd(hdev, HCI_OP_LE_ACCEPT_CIS, sizeof(cp), &cp); 702126afbd82SLuiz Augusto von Dentz } 702226afbd82SLuiz Augusto von Dentz 702326afbd82SLuiz Augusto von Dentz static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data, 702426afbd82SLuiz Augusto von Dentz struct sk_buff *skb) 702526afbd82SLuiz Augusto von Dentz { 702626afbd82SLuiz Augusto von Dentz struct hci_evt_le_cis_req *ev = data; 702726afbd82SLuiz Augusto von Dentz u16 acl_handle, cis_handle; 702826afbd82SLuiz Augusto von Dentz struct hci_conn *acl, *cis; 702926afbd82SLuiz Augusto von Dentz int mask; 703026afbd82SLuiz Augusto von Dentz __u8 flags = 0; 703126afbd82SLuiz Augusto von Dentz 703226afbd82SLuiz Augusto von Dentz acl_handle = __le16_to_cpu(ev->acl_handle); 703326afbd82SLuiz Augusto von Dentz cis_handle = __le16_to_cpu(ev->cis_handle); 703426afbd82SLuiz Augusto von Dentz 703526afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "acl 0x%4.4x handle 0x%4.4x cig 0x%2.2x cis 0x%2.2x", 703626afbd82SLuiz Augusto von Dentz acl_handle, cis_handle, ev->cig_id, ev->cis_id); 703726afbd82SLuiz Augusto von Dentz 703826afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev); 703926afbd82SLuiz Augusto von Dentz 704026afbd82SLuiz Augusto von Dentz acl = hci_conn_hash_lookup_handle(hdev, acl_handle); 704126afbd82SLuiz Augusto von Dentz if (!acl) 704226afbd82SLuiz Augusto von Dentz goto unlock; 704326afbd82SLuiz Augusto von Dentz 704426afbd82SLuiz Augusto von Dentz mask = hci_proto_connect_ind(hdev, &acl->dst, ISO_LINK, &flags); 704526afbd82SLuiz Augusto von Dentz if (!(mask & HCI_LM_ACCEPT)) { 704626afbd82SLuiz Augusto von Dentz hci_le_reject_cis(hdev, ev->cis_handle); 704726afbd82SLuiz Augusto von Dentz goto unlock; 704826afbd82SLuiz Augusto von Dentz } 704926afbd82SLuiz Augusto von Dentz 705026afbd82SLuiz Augusto von Dentz cis = hci_conn_hash_lookup_handle(hdev, cis_handle); 705126afbd82SLuiz Augusto von Dentz if (!cis) { 705284cb0143SZiyang Xuan cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE, 705384cb0143SZiyang Xuan cis_handle); 705426afbd82SLuiz Augusto von Dentz if (!cis) { 705526afbd82SLuiz Augusto von Dentz hci_le_reject_cis(hdev, ev->cis_handle); 705626afbd82SLuiz Augusto von Dentz goto unlock; 705726afbd82SLuiz Augusto von Dentz } 705826afbd82SLuiz Augusto von Dentz } 705926afbd82SLuiz Augusto von Dentz 70600fe8c8d0SIulia Tanasescu cis->iso_qos.ucast.cig = ev->cig_id; 70610fe8c8d0SIulia Tanasescu cis->iso_qos.ucast.cis = ev->cis_id; 706226afbd82SLuiz Augusto von Dentz 706326afbd82SLuiz Augusto von Dentz if (!(flags & HCI_PROTO_DEFER)) { 706426afbd82SLuiz Augusto von Dentz hci_le_accept_cis(hdev, ev->cis_handle); 706526afbd82SLuiz Augusto von Dentz } else { 706626afbd82SLuiz Augusto von Dentz cis->state = BT_CONNECT2; 706726afbd82SLuiz Augusto von Dentz hci_connect_cfm(cis, 0); 706826afbd82SLuiz Augusto von Dentz } 706926afbd82SLuiz Augusto von Dentz 707026afbd82SLuiz Augusto von Dentz unlock: 707126afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev); 707226afbd82SLuiz Augusto von Dentz } 707326afbd82SLuiz Augusto von Dentz 7074acab8ff2SIulia Tanasescu static int hci_iso_term_big_sync(struct hci_dev *hdev, void *data) 7075acab8ff2SIulia Tanasescu { 7076acab8ff2SIulia Tanasescu u8 handle = PTR_UINT(data); 7077acab8ff2SIulia Tanasescu 7078acab8ff2SIulia Tanasescu return hci_le_terminate_big_sync(hdev, handle, 7079acab8ff2SIulia Tanasescu HCI_ERROR_LOCAL_HOST_TERM); 7080acab8ff2SIulia Tanasescu } 7081acab8ff2SIulia Tanasescu 7082eca0ae4aSLuiz Augusto von Dentz static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data, 7083eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb) 7084eca0ae4aSLuiz Augusto von Dentz { 7085eca0ae4aSLuiz Augusto von Dentz struct hci_evt_le_create_big_complete *ev = data; 7086eca0ae4aSLuiz Augusto von Dentz struct hci_conn *conn; 708716e3b642SLuiz Augusto von Dentz __u8 i = 0; 7088eca0ae4aSLuiz Augusto von Dentz 7089eca0ae4aSLuiz Augusto von Dentz BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 7090eca0ae4aSLuiz Augusto von Dentz 7091eca0ae4aSLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_CREATE_BIG_COMPLETE, 7092eca0ae4aSLuiz Augusto von Dentz flex_array_size(ev, bis_handle, ev->num_bis))) 7093eca0ae4aSLuiz Augusto von Dentz return; 7094eca0ae4aSLuiz Augusto von Dentz 7095eca0ae4aSLuiz Augusto von Dentz hci_dev_lock(hdev); 7096a0bfde16SIulia Tanasescu rcu_read_lock(); 7097eca0ae4aSLuiz Augusto von Dentz 7098a0bfde16SIulia Tanasescu /* Connect all BISes that are bound to the BIG */ 7099a0bfde16SIulia Tanasescu list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) { 7100a0bfde16SIulia Tanasescu if (bacmp(&conn->dst, BDADDR_ANY) || 7101a0bfde16SIulia Tanasescu conn->type != ISO_LINK || 7102a0bfde16SIulia Tanasescu conn->iso_qos.bcast.big != ev->handle) 7103a0bfde16SIulia Tanasescu continue; 7104eca0ae4aSLuiz Augusto von Dentz 710516e3b642SLuiz Augusto von Dentz if (hci_conn_set_handle(conn, 710616e3b642SLuiz Augusto von Dentz __le16_to_cpu(ev->bis_handle[i++]))) 710716e3b642SLuiz Augusto von Dentz continue; 7108eca0ae4aSLuiz Augusto von Dentz 7109eca0ae4aSLuiz Augusto von Dentz if (!ev->status) { 7110eca0ae4aSLuiz Augusto von Dentz conn->state = BT_CONNECTED; 7111a0bfde16SIulia Tanasescu set_bit(HCI_CONN_BIG_CREATED, &conn->flags); 7112a0bfde16SIulia Tanasescu rcu_read_unlock(); 7113eca0ae4aSLuiz Augusto von Dentz hci_debugfs_create_conn(conn); 7114eca0ae4aSLuiz Augusto von Dentz hci_conn_add_sysfs(conn); 7115eca0ae4aSLuiz Augusto von Dentz hci_iso_setup_path(conn); 7116a0bfde16SIulia Tanasescu rcu_read_lock(); 7117a0bfde16SIulia Tanasescu continue; 7118eca0ae4aSLuiz Augusto von Dentz } 7119eca0ae4aSLuiz Augusto von Dentz 7120eca0ae4aSLuiz Augusto von Dentz hci_connect_cfm(conn, ev->status); 7121a0bfde16SIulia Tanasescu rcu_read_unlock(); 7122eca0ae4aSLuiz Augusto von Dentz hci_conn_del(conn); 7123a0bfde16SIulia Tanasescu rcu_read_lock(); 7124a0bfde16SIulia Tanasescu } 7125eca0ae4aSLuiz Augusto von Dentz 7126acab8ff2SIulia Tanasescu rcu_read_unlock(); 7127acab8ff2SIulia Tanasescu 712816e3b642SLuiz Augusto von Dentz if (!ev->status && !i) 7129a0bfde16SIulia Tanasescu /* If no BISes have been connected for the BIG, 7130a0bfde16SIulia Tanasescu * terminate. This is in case all bound connections 7131a0bfde16SIulia Tanasescu * have been closed before the BIG creation 7132a0bfde16SIulia Tanasescu * has completed. 7133a0bfde16SIulia Tanasescu */ 7134acab8ff2SIulia Tanasescu hci_cmd_sync_queue(hdev, hci_iso_term_big_sync, 7135acab8ff2SIulia Tanasescu UINT_PTR(ev->handle), NULL); 7136a0bfde16SIulia Tanasescu 7137eca0ae4aSLuiz Augusto von Dentz hci_dev_unlock(hdev); 7138eca0ae4aSLuiz Augusto von Dentz } 7139eca0ae4aSLuiz Augusto von Dentz 7140eca0ae4aSLuiz Augusto von Dentz static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, 7141eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb) 7142eca0ae4aSLuiz Augusto von Dentz { 7143eca0ae4aSLuiz Augusto von Dentz struct hci_evt_le_big_sync_estabilished *ev = data; 7144eca0ae4aSLuiz Augusto von Dentz struct hci_conn *bis; 7145fbdc4bc4SIulia Tanasescu struct hci_conn *pa_sync; 7146eca0ae4aSLuiz Augusto von Dentz int i; 7147eca0ae4aSLuiz Augusto von Dentz 7148eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 7149eca0ae4aSLuiz Augusto von Dentz 7150eca0ae4aSLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABILISHED, 7151eca0ae4aSLuiz Augusto von Dentz flex_array_size(ev, bis, ev->num_bis))) 7152eca0ae4aSLuiz Augusto von Dentz return; 7153eca0ae4aSLuiz Augusto von Dentz 7154eca0ae4aSLuiz Augusto von Dentz hci_dev_lock(hdev); 7155eca0ae4aSLuiz Augusto von Dentz 7156fbdc4bc4SIulia Tanasescu if (!ev->status) { 715723417475SIulia Tanasescu pa_sync = hci_conn_hash_lookup_pa_sync_big_handle(hdev, ev->handle); 7158fbdc4bc4SIulia Tanasescu if (pa_sync) 7159fbdc4bc4SIulia Tanasescu /* Also mark the BIG sync established event on the 7160fbdc4bc4SIulia Tanasescu * associated PA sync hcon 7161fbdc4bc4SIulia Tanasescu */ 7162fbdc4bc4SIulia Tanasescu set_bit(HCI_CONN_BIG_SYNC, &pa_sync->flags); 7163fbdc4bc4SIulia Tanasescu } 7164fbdc4bc4SIulia Tanasescu 7165eca0ae4aSLuiz Augusto von Dentz for (i = 0; i < ev->num_bis; i++) { 7166eca0ae4aSLuiz Augusto von Dentz u16 handle = le16_to_cpu(ev->bis[i]); 7167eca0ae4aSLuiz Augusto von Dentz __le32 interval; 7168eca0ae4aSLuiz Augusto von Dentz 7169eca0ae4aSLuiz Augusto von Dentz bis = hci_conn_hash_lookup_handle(hdev, handle); 7170eca0ae4aSLuiz Augusto von Dentz if (!bis) { 7171eca0ae4aSLuiz Augusto von Dentz bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY, 717284cb0143SZiyang Xuan HCI_ROLE_SLAVE, handle); 7173eca0ae4aSLuiz Augusto von Dentz if (!bis) 7174eca0ae4aSLuiz Augusto von Dentz continue; 7175eca0ae4aSLuiz Augusto von Dentz } 7176eca0ae4aSLuiz Augusto von Dentz 7177fbdc4bc4SIulia Tanasescu if (ev->status != 0x42) 7178fbdc4bc4SIulia Tanasescu /* Mark PA sync as established */ 7179fbdc4bc4SIulia Tanasescu set_bit(HCI_CONN_PA_SYNC, &bis->flags); 7180fbdc4bc4SIulia Tanasescu 71810fe8c8d0SIulia Tanasescu bis->iso_qos.bcast.big = ev->handle; 7182eca0ae4aSLuiz Augusto von Dentz memset(&interval, 0, sizeof(interval)); 7183eca0ae4aSLuiz Augusto von Dentz memcpy(&interval, ev->latency, sizeof(ev->latency)); 71840fe8c8d0SIulia Tanasescu bis->iso_qos.bcast.in.interval = le32_to_cpu(interval); 7185eca0ae4aSLuiz Augusto von Dentz /* Convert ISO Interval (1.25 ms slots) to latency (ms) */ 71860fe8c8d0SIulia Tanasescu bis->iso_qos.bcast.in.latency = le16_to_cpu(ev->interval) * 125 / 100; 71870fe8c8d0SIulia Tanasescu bis->iso_qos.bcast.in.sdu = le16_to_cpu(ev->max_pdu); 7188eca0ae4aSLuiz Augusto von Dentz 7189f777d882SIulia Tanasescu if (!ev->status) { 7190f777d882SIulia Tanasescu set_bit(HCI_CONN_BIG_SYNC, &bis->flags); 7191d2e4f1b1SClaudia Draghicescu hci_iso_setup_path(bis); 7192eca0ae4aSLuiz Augusto von Dentz } 7193f777d882SIulia Tanasescu } 7194f777d882SIulia Tanasescu 7195f777d882SIulia Tanasescu /* In case BIG sync failed, notify each failed connection to 7196f777d882SIulia Tanasescu * the user after all hci connections have been added 7197f777d882SIulia Tanasescu */ 7198f777d882SIulia Tanasescu if (ev->status) 7199f777d882SIulia Tanasescu for (i = 0; i < ev->num_bis; i++) { 7200f777d882SIulia Tanasescu u16 handle = le16_to_cpu(ev->bis[i]); 7201f777d882SIulia Tanasescu 7202f777d882SIulia Tanasescu bis = hci_conn_hash_lookup_handle(hdev, handle); 7203f777d882SIulia Tanasescu 7204f777d882SIulia Tanasescu set_bit(HCI_CONN_BIG_SYNC_FAILED, &bis->flags); 7205f777d882SIulia Tanasescu hci_connect_cfm(bis, ev->status); 7206f777d882SIulia Tanasescu } 7207eca0ae4aSLuiz Augusto von Dentz 7208eca0ae4aSLuiz Augusto von Dentz hci_dev_unlock(hdev); 7209eca0ae4aSLuiz Augusto von Dentz } 7210eca0ae4aSLuiz Augusto von Dentz 7211eca0ae4aSLuiz Augusto von Dentz static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, 7212eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb) 7213eca0ae4aSLuiz Augusto von Dentz { 7214eca0ae4aSLuiz Augusto von Dentz struct hci_evt_le_big_info_adv_report *ev = data; 7215eca0ae4aSLuiz Augusto von Dentz int mask = hdev->link_mode; 7216eca0ae4aSLuiz Augusto von Dentz __u8 flags = 0; 721723417475SIulia Tanasescu struct hci_conn *pa_sync; 7218eca0ae4aSLuiz Augusto von Dentz 7219eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "sync_handle 0x%4.4x", le16_to_cpu(ev->sync_handle)); 7220eca0ae4aSLuiz Augusto von Dentz 7221eca0ae4aSLuiz Augusto von Dentz hci_dev_lock(hdev); 7222eca0ae4aSLuiz Augusto von Dentz 7223eca0ae4aSLuiz Augusto von Dentz mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags); 722423417475SIulia Tanasescu if (!(mask & HCI_LM_ACCEPT)) { 7225eca0ae4aSLuiz Augusto von Dentz hci_le_pa_term_sync(hdev, ev->sync_handle); 722623417475SIulia Tanasescu goto unlock; 722723417475SIulia Tanasescu } 7228eca0ae4aSLuiz Augusto von Dentz 722923417475SIulia Tanasescu if (!(flags & HCI_PROTO_DEFER)) 723023417475SIulia Tanasescu goto unlock; 723123417475SIulia Tanasescu 723223417475SIulia Tanasescu pa_sync = hci_conn_hash_lookup_pa_sync_handle 723323417475SIulia Tanasescu (hdev, 723423417475SIulia Tanasescu le16_to_cpu(ev->sync_handle)); 723523417475SIulia Tanasescu 723623417475SIulia Tanasescu if (pa_sync) 723723417475SIulia Tanasescu goto unlock; 723823417475SIulia Tanasescu 723923417475SIulia Tanasescu /* Add connection to indicate the PA sync event */ 724084cb0143SZiyang Xuan pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY, 724123417475SIulia Tanasescu HCI_ROLE_SLAVE); 724223417475SIulia Tanasescu 724323417475SIulia Tanasescu if (!pa_sync) 724423417475SIulia Tanasescu goto unlock; 724523417475SIulia Tanasescu 724623417475SIulia Tanasescu pa_sync->sync_handle = le16_to_cpu(ev->sync_handle); 724723417475SIulia Tanasescu set_bit(HCI_CONN_PA_SYNC, &pa_sync->flags); 724823417475SIulia Tanasescu 724923417475SIulia Tanasescu /* Notify iso layer */ 725023417475SIulia Tanasescu hci_connect_cfm(pa_sync, 0x00); 725123417475SIulia Tanasescu 72520b3df53cSLuiz Augusto von Dentz /* Notify MGMT layer */ 72530b3df53cSLuiz Augusto von Dentz mgmt_device_connected(hdev, pa_sync, NULL, 0); 72540b3df53cSLuiz Augusto von Dentz 725523417475SIulia Tanasescu unlock: 7256eca0ae4aSLuiz Augusto von Dentz hci_dev_unlock(hdev); 7257eca0ae4aSLuiz Augusto von Dentz } 7258eca0ae4aSLuiz Augusto von Dentz 725995118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_VL(_op, _func, _min_len, _max_len) \ 726095118dd4SLuiz Augusto von Dentz [_op] = { \ 726195118dd4SLuiz Augusto von Dentz .func = _func, \ 726295118dd4SLuiz Augusto von Dentz .min_len = _min_len, \ 726395118dd4SLuiz Augusto von Dentz .max_len = _max_len, \ 726495118dd4SLuiz Augusto von Dentz } 726595118dd4SLuiz Augusto von Dentz 726695118dd4SLuiz Augusto von Dentz #define HCI_LE_EV(_op, _func, _len) \ 726795118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(_op, _func, _len, _len) 726895118dd4SLuiz Augusto von Dentz 726995118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_STATUS(_op, _func) \ 727095118dd4SLuiz Augusto von Dentz HCI_LE_EV(_op, _func, sizeof(struct hci_ev_status)) 727195118dd4SLuiz Augusto von Dentz 727295118dd4SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the subevent 727395118dd4SLuiz Augusto von Dentz * opcode they handle so the use of the macros above is recommend since it does 727495118dd4SLuiz Augusto von Dentz * attempt to initialize at its proper index using Designated Initializers that 727595118dd4SLuiz Augusto von Dentz * way events without a callback function can be ommited. 727695118dd4SLuiz Augusto von Dentz */ 727795118dd4SLuiz Augusto von Dentz static const struct hci_le_ev { 727895118dd4SLuiz Augusto von Dentz void (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb); 727995118dd4SLuiz Augusto von Dentz u16 min_len; 728095118dd4SLuiz Augusto von Dentz u16 max_len; 728195118dd4SLuiz Augusto von Dentz } hci_le_ev_table[U8_MAX + 1] = { 728295118dd4SLuiz Augusto von Dentz /* [0x01 = HCI_EV_LE_CONN_COMPLETE] */ 728395118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_CONN_COMPLETE, hci_le_conn_complete_evt, 728495118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_conn_complete)), 728595118dd4SLuiz Augusto von Dentz /* [0x02 = HCI_EV_LE_ADVERTISING_REPORT] */ 728695118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EV_LE_ADVERTISING_REPORT, hci_le_adv_report_evt, 728795118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_advertising_report), 728895118dd4SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE), 728995118dd4SLuiz Augusto von Dentz /* [0x03 = HCI_EV_LE_CONN_UPDATE_COMPLETE] */ 729095118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_CONN_UPDATE_COMPLETE, 729195118dd4SLuiz Augusto von Dentz hci_le_conn_update_complete_evt, 729295118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_conn_update_complete)), 729395118dd4SLuiz Augusto von Dentz /* [0x04 = HCI_EV_LE_REMOTE_FEAT_COMPLETE] */ 729495118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_REMOTE_FEAT_COMPLETE, 729595118dd4SLuiz Augusto von Dentz hci_le_remote_feat_complete_evt, 729695118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_remote_feat_complete)), 729795118dd4SLuiz Augusto von Dentz /* [0x05 = HCI_EV_LE_LTK_REQ] */ 729895118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_LTK_REQ, hci_le_ltk_request_evt, 729995118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_ltk_req)), 730095118dd4SLuiz Augusto von Dentz /* [0x06 = HCI_EV_LE_REMOTE_CONN_PARAM_REQ] */ 730195118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_REMOTE_CONN_PARAM_REQ, 730295118dd4SLuiz Augusto von Dentz hci_le_remote_conn_param_req_evt, 730395118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_remote_conn_param_req)), 730495118dd4SLuiz Augusto von Dentz /* [0x0a = HCI_EV_LE_ENHANCED_CONN_COMPLETE] */ 730595118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_ENHANCED_CONN_COMPLETE, 730695118dd4SLuiz Augusto von Dentz hci_le_enh_conn_complete_evt, 730795118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_enh_conn_complete)), 730895118dd4SLuiz Augusto von Dentz /* [0x0b = HCI_EV_LE_DIRECT_ADV_REPORT] */ 730995118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EV_LE_DIRECT_ADV_REPORT, hci_le_direct_adv_report_evt, 731095118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_direct_adv_report), 731195118dd4SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE), 731295118dd4SLuiz Augusto von Dentz /* [0x0c = HCI_EV_LE_PHY_UPDATE_COMPLETE] */ 731395118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_PHY_UPDATE_COMPLETE, hci_le_phy_update_evt, 731495118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_phy_update_complete)), 731595118dd4SLuiz Augusto von Dentz /* [0x0d = HCI_EV_LE_EXT_ADV_REPORT] */ 731695118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EV_LE_EXT_ADV_REPORT, hci_le_ext_adv_report_evt, 731795118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_ext_adv_report), 731895118dd4SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE), 7319eca0ae4aSLuiz Augusto von Dentz /* [0x0e = HCI_EV_LE_PA_SYNC_ESTABLISHED] */ 7320eca0ae4aSLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_PA_SYNC_ESTABLISHED, 7321eca0ae4aSLuiz Augusto von Dentz hci_le_pa_sync_estabilished_evt, 7322eca0ae4aSLuiz Augusto von Dentz sizeof(struct hci_ev_le_pa_sync_established)), 73239c082631SClaudia Draghicescu /* [0x0f = HCI_EV_LE_PER_ADV_REPORT] */ 73249c082631SClaudia Draghicescu HCI_LE_EV_VL(HCI_EV_LE_PER_ADV_REPORT, 73259c082631SClaudia Draghicescu hci_le_per_adv_report_evt, 73269c082631SClaudia Draghicescu sizeof(struct hci_ev_le_per_adv_report), 73279c082631SClaudia Draghicescu HCI_MAX_EVENT_SIZE), 732895118dd4SLuiz Augusto von Dentz /* [0x12 = HCI_EV_LE_EXT_ADV_SET_TERM] */ 732995118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_EXT_ADV_SET_TERM, hci_le_ext_adv_term_evt, 733095118dd4SLuiz Augusto von Dentz sizeof(struct hci_evt_le_ext_adv_set_term)), 733126afbd82SLuiz Augusto von Dentz /* [0x19 = HCI_EVT_LE_CIS_ESTABLISHED] */ 733226afbd82SLuiz Augusto von Dentz HCI_LE_EV(HCI_EVT_LE_CIS_ESTABLISHED, hci_le_cis_estabilished_evt, 733326afbd82SLuiz Augusto von Dentz sizeof(struct hci_evt_le_cis_established)), 733426afbd82SLuiz Augusto von Dentz /* [0x1a = HCI_EVT_LE_CIS_REQ] */ 733526afbd82SLuiz Augusto von Dentz HCI_LE_EV(HCI_EVT_LE_CIS_REQ, hci_le_cis_req_evt, 733626afbd82SLuiz Augusto von Dentz sizeof(struct hci_evt_le_cis_req)), 7337eca0ae4aSLuiz Augusto von Dentz /* [0x1b = HCI_EVT_LE_CREATE_BIG_COMPLETE] */ 7338eca0ae4aSLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EVT_LE_CREATE_BIG_COMPLETE, 7339eca0ae4aSLuiz Augusto von Dentz hci_le_create_big_complete_evt, 7340eca0ae4aSLuiz Augusto von Dentz sizeof(struct hci_evt_le_create_big_complete), 7341eca0ae4aSLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE), 7342eca0ae4aSLuiz Augusto von Dentz /* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABILISHED] */ 7343eca0ae4aSLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABILISHED, 7344eca0ae4aSLuiz Augusto von Dentz hci_le_big_sync_established_evt, 7345eca0ae4aSLuiz Augusto von Dentz sizeof(struct hci_evt_le_big_sync_estabilished), 7346eca0ae4aSLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE), 7347eca0ae4aSLuiz Augusto von Dentz /* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */ 7348eca0ae4aSLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT, 7349eca0ae4aSLuiz Augusto von Dentz hci_le_big_info_adv_report_evt, 7350eca0ae4aSLuiz Augusto von Dentz sizeof(struct hci_evt_le_big_info_adv_report), 7351eca0ae4aSLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE), 735295118dd4SLuiz Augusto von Dentz }; 735395118dd4SLuiz Augusto von Dentz 73543e54c589SLuiz Augusto von Dentz static void hci_le_meta_evt(struct hci_dev *hdev, void *data, 735585b56857SLuiz Augusto von Dentz struct sk_buff *skb, u16 *opcode, u8 *status, 735685b56857SLuiz Augusto von Dentz hci_req_complete_t *req_complete, 735785b56857SLuiz Augusto von Dentz hci_req_complete_skb_t *req_complete_skb) 7358fcd89c09SVille Tervo { 73593e54c589SLuiz Augusto von Dentz struct hci_ev_le_meta *ev = data; 736095118dd4SLuiz Augusto von Dentz const struct hci_le_ev *subev; 7361fcd89c09SVille Tervo 736295118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "subevent 0x%2.2x", ev->subevent); 7363fcd89c09SVille Tervo 736485b56857SLuiz Augusto von Dentz /* Only match event if command OGF is for LE */ 73652af7aa66SLuiz Augusto von Dentz if (hdev->req_skb && 73662af7aa66SLuiz Augusto von Dentz hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) == 0x08 && 73672af7aa66SLuiz Augusto von Dentz hci_skb_event(hdev->req_skb) == ev->subevent) { 73682af7aa66SLuiz Augusto von Dentz *opcode = hci_skb_opcode(hdev->req_skb); 736985b56857SLuiz Augusto von Dentz hci_req_cmd_complete(hdev, *opcode, 0x00, req_complete, 737085b56857SLuiz Augusto von Dentz req_complete_skb); 737185b56857SLuiz Augusto von Dentz } 737285b56857SLuiz Augusto von Dentz 737395118dd4SLuiz Augusto von Dentz subev = &hci_le_ev_table[ev->subevent]; 737495118dd4SLuiz Augusto von Dentz if (!subev->func) 737595118dd4SLuiz Augusto von Dentz return; 73761855d92dSMarcel Holtmann 737795118dd4SLuiz Augusto von Dentz if (skb->len < subev->min_len) { 737895118dd4SLuiz Augusto von Dentz bt_dev_err(hdev, "unexpected subevent 0x%2.2x length: %u < %u", 737995118dd4SLuiz Augusto von Dentz ev->subevent, skb->len, subev->min_len); 738095118dd4SLuiz Augusto von Dentz return; 7381fcd89c09SVille Tervo } 738295118dd4SLuiz Augusto von Dentz 738395118dd4SLuiz Augusto von Dentz /* Just warn if the length is over max_len size it still be 738495118dd4SLuiz Augusto von Dentz * possible to partially parse the event so leave to callback to 738595118dd4SLuiz Augusto von Dentz * decide if that is acceptable. 738695118dd4SLuiz Augusto von Dentz */ 738795118dd4SLuiz Augusto von Dentz if (skb->len > subev->max_len) 738895118dd4SLuiz Augusto von Dentz bt_dev_warn(hdev, "unexpected subevent 0x%2.2x length: %u > %u", 738995118dd4SLuiz Augusto von Dentz ev->subevent, skb->len, subev->max_len); 739095118dd4SLuiz Augusto von Dentz data = hci_le_ev_skb_pull(hdev, skb, ev->subevent, subev->min_len); 739195118dd4SLuiz Augusto von Dentz if (!data) 739295118dd4SLuiz Augusto von Dentz return; 739395118dd4SLuiz Augusto von Dentz 739495118dd4SLuiz Augusto von Dentz subev->func(hdev, data, skb); 7395fcd89c09SVille Tervo } 7396fcd89c09SVille Tervo 7397757aa0b5SJohan Hedberg static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 7398757aa0b5SJohan Hedberg u8 event, struct sk_buff *skb) 7399757aa0b5SJohan Hedberg { 7400757aa0b5SJohan Hedberg struct hci_ev_cmd_complete *ev; 7401757aa0b5SJohan Hedberg struct hci_event_hdr *hdr; 7402757aa0b5SJohan Hedberg 7403757aa0b5SJohan Hedberg if (!skb) 7404757aa0b5SJohan Hedberg return false; 7405757aa0b5SJohan Hedberg 7406e3f3a1aeSLuiz Augusto von Dentz hdr = hci_ev_skb_pull(hdev, skb, event, sizeof(*hdr)); 7407e3f3a1aeSLuiz Augusto von Dentz if (!hdr) 7408757aa0b5SJohan Hedberg return false; 7409757aa0b5SJohan Hedberg 7410757aa0b5SJohan Hedberg if (event) { 7411757aa0b5SJohan Hedberg if (hdr->evt != event) 7412757aa0b5SJohan Hedberg return false; 7413757aa0b5SJohan Hedberg return true; 7414757aa0b5SJohan Hedberg } 7415757aa0b5SJohan Hedberg 741691641b79SZheng Yongjun /* Check if request ended in Command Status - no way to retrieve 74171629db9cSJohan Hedberg * any extra parameters in this case. 74181629db9cSJohan Hedberg */ 74191629db9cSJohan Hedberg if (hdr->evt == HCI_EV_CMD_STATUS) 74201629db9cSJohan Hedberg return false; 74211629db9cSJohan Hedberg 7422757aa0b5SJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 74232064ee33SMarcel Holtmann bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)", 74242064ee33SMarcel Holtmann hdr->evt); 7425757aa0b5SJohan Hedberg return false; 7426757aa0b5SJohan Hedberg } 7427757aa0b5SJohan Hedberg 7428e3f3a1aeSLuiz Augusto von Dentz ev = hci_cc_skb_pull(hdev, skb, opcode, sizeof(*ev)); 7429e3f3a1aeSLuiz Augusto von Dentz if (!ev) 7430757aa0b5SJohan Hedberg return false; 7431757aa0b5SJohan Hedberg 7432757aa0b5SJohan Hedberg if (opcode != __le16_to_cpu(ev->opcode)) { 7433757aa0b5SJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 7434757aa0b5SJohan Hedberg __le16_to_cpu(ev->opcode)); 7435757aa0b5SJohan Hedberg return false; 7436757aa0b5SJohan Hedberg } 7437757aa0b5SJohan Hedberg 7438757aa0b5SJohan Hedberg return true; 7439757aa0b5SJohan Hedberg } 7440757aa0b5SJohan Hedberg 74412f20216cSAbhishek Pandit-Subedi static void hci_store_wake_reason(struct hci_dev *hdev, u8 event, 74422f20216cSAbhishek Pandit-Subedi struct sk_buff *skb) 74432f20216cSAbhishek Pandit-Subedi { 74442f20216cSAbhishek Pandit-Subedi struct hci_ev_le_advertising_info *adv; 74452f20216cSAbhishek Pandit-Subedi struct hci_ev_le_direct_adv_info *direct_adv; 7446b48b833fSLuiz Augusto von Dentz struct hci_ev_le_ext_adv_info *ext_adv; 74472f20216cSAbhishek Pandit-Subedi const struct hci_ev_conn_complete *conn_complete = (void *)skb->data; 74482f20216cSAbhishek Pandit-Subedi const struct hci_ev_conn_request *conn_request = (void *)skb->data; 74492f20216cSAbhishek Pandit-Subedi 74502f20216cSAbhishek Pandit-Subedi hci_dev_lock(hdev); 74512f20216cSAbhishek Pandit-Subedi 74522f20216cSAbhishek Pandit-Subedi /* If we are currently suspended and this is the first BT event seen, 74532f20216cSAbhishek Pandit-Subedi * save the wake reason associated with the event. 74542f20216cSAbhishek Pandit-Subedi */ 74552f20216cSAbhishek Pandit-Subedi if (!hdev->suspended || hdev->wake_reason) 74562f20216cSAbhishek Pandit-Subedi goto unlock; 74572f20216cSAbhishek Pandit-Subedi 74582f20216cSAbhishek Pandit-Subedi /* Default to remote wake. Values for wake_reason are documented in the 74592f20216cSAbhishek Pandit-Subedi * Bluez mgmt api docs. 74602f20216cSAbhishek Pandit-Subedi */ 74612f20216cSAbhishek Pandit-Subedi hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE; 74622f20216cSAbhishek Pandit-Subedi 74632f20216cSAbhishek Pandit-Subedi /* Once configured for remote wakeup, we should only wake up for 74642f20216cSAbhishek Pandit-Subedi * reconnections. It's useful to see which device is waking us up so 74652f20216cSAbhishek Pandit-Subedi * keep track of the bdaddr of the connection event that woke us up. 74662f20216cSAbhishek Pandit-Subedi */ 74672f20216cSAbhishek Pandit-Subedi if (event == HCI_EV_CONN_REQUEST) { 74684a913967SZijun Hu bacpy(&hdev->wake_addr, &conn_request->bdaddr); 74692f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = BDADDR_BREDR; 74702f20216cSAbhishek Pandit-Subedi } else if (event == HCI_EV_CONN_COMPLETE) { 74714a913967SZijun Hu bacpy(&hdev->wake_addr, &conn_complete->bdaddr); 74722f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = BDADDR_BREDR; 74732f20216cSAbhishek Pandit-Subedi } else if (event == HCI_EV_LE_META) { 74742f20216cSAbhishek Pandit-Subedi struct hci_ev_le_meta *le_ev = (void *)skb->data; 74752f20216cSAbhishek Pandit-Subedi u8 subevent = le_ev->subevent; 74762f20216cSAbhishek Pandit-Subedi u8 *ptr = &skb->data[sizeof(*le_ev)]; 74772f20216cSAbhishek Pandit-Subedi u8 num_reports = *ptr; 74782f20216cSAbhishek Pandit-Subedi 74792f20216cSAbhishek Pandit-Subedi if ((subevent == HCI_EV_LE_ADVERTISING_REPORT || 74802f20216cSAbhishek Pandit-Subedi subevent == HCI_EV_LE_DIRECT_ADV_REPORT || 74812f20216cSAbhishek Pandit-Subedi subevent == HCI_EV_LE_EXT_ADV_REPORT) && 74822f20216cSAbhishek Pandit-Subedi num_reports) { 74832f20216cSAbhishek Pandit-Subedi adv = (void *)(ptr + 1); 74842f20216cSAbhishek Pandit-Subedi direct_adv = (void *)(ptr + 1); 74852f20216cSAbhishek Pandit-Subedi ext_adv = (void *)(ptr + 1); 74862f20216cSAbhishek Pandit-Subedi 74872f20216cSAbhishek Pandit-Subedi switch (subevent) { 74882f20216cSAbhishek Pandit-Subedi case HCI_EV_LE_ADVERTISING_REPORT: 74892f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, &adv->bdaddr); 74902f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = adv->bdaddr_type; 74912f20216cSAbhishek Pandit-Subedi break; 74922f20216cSAbhishek Pandit-Subedi case HCI_EV_LE_DIRECT_ADV_REPORT: 74932f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, &direct_adv->bdaddr); 74942f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = direct_adv->bdaddr_type; 74952f20216cSAbhishek Pandit-Subedi break; 74962f20216cSAbhishek Pandit-Subedi case HCI_EV_LE_EXT_ADV_REPORT: 74972f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, &ext_adv->bdaddr); 74982f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = ext_adv->bdaddr_type; 74992f20216cSAbhishek Pandit-Subedi break; 75002f20216cSAbhishek Pandit-Subedi } 75012f20216cSAbhishek Pandit-Subedi } 75022f20216cSAbhishek Pandit-Subedi } else { 75032f20216cSAbhishek Pandit-Subedi hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED; 75042f20216cSAbhishek Pandit-Subedi } 75052f20216cSAbhishek Pandit-Subedi 75062f20216cSAbhishek Pandit-Subedi unlock: 75072f20216cSAbhishek Pandit-Subedi hci_dev_unlock(hdev); 75082f20216cSAbhishek Pandit-Subedi } 75092f20216cSAbhishek Pandit-Subedi 75103e54c589SLuiz Augusto von Dentz #define HCI_EV_VL(_op, _func, _min_len, _max_len) \ 75113e54c589SLuiz Augusto von Dentz [_op] = { \ 75123e54c589SLuiz Augusto von Dentz .req = false, \ 75133e54c589SLuiz Augusto von Dentz .func = _func, \ 75143e54c589SLuiz Augusto von Dentz .min_len = _min_len, \ 75153e54c589SLuiz Augusto von Dentz .max_len = _max_len, \ 75163e54c589SLuiz Augusto von Dentz } 75173e54c589SLuiz Augusto von Dentz 75183e54c589SLuiz Augusto von Dentz #define HCI_EV(_op, _func, _len) \ 75193e54c589SLuiz Augusto von Dentz HCI_EV_VL(_op, _func, _len, _len) 75203e54c589SLuiz Augusto von Dentz 75213e54c589SLuiz Augusto von Dentz #define HCI_EV_STATUS(_op, _func) \ 75223e54c589SLuiz Augusto von Dentz HCI_EV(_op, _func, sizeof(struct hci_ev_status)) 75233e54c589SLuiz Augusto von Dentz 75243e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ_VL(_op, _func, _min_len, _max_len) \ 75253e54c589SLuiz Augusto von Dentz [_op] = { \ 75263e54c589SLuiz Augusto von Dentz .req = true, \ 75273e54c589SLuiz Augusto von Dentz .func_req = _func, \ 75283e54c589SLuiz Augusto von Dentz .min_len = _min_len, \ 75293e54c589SLuiz Augusto von Dentz .max_len = _max_len, \ 75303e54c589SLuiz Augusto von Dentz } 75313e54c589SLuiz Augusto von Dentz 75323e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ(_op, _func, _len) \ 75333e54c589SLuiz Augusto von Dentz HCI_EV_REQ_VL(_op, _func, _len, _len) 75343e54c589SLuiz Augusto von Dentz 75353e54c589SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the event opcode 75363e54c589SLuiz Augusto von Dentz * they handle so the use of the macros above is recommend since it does attempt 75373e54c589SLuiz Augusto von Dentz * to initialize at its proper index using Designated Initializers that way 75383e54c589SLuiz Augusto von Dentz * events without a callback function don't have entered. 75393e54c589SLuiz Augusto von Dentz */ 75403e54c589SLuiz Augusto von Dentz static const struct hci_ev { 75413e54c589SLuiz Augusto von Dentz bool req; 75423e54c589SLuiz Augusto von Dentz union { 75433e54c589SLuiz Augusto von Dentz void (*func)(struct hci_dev *hdev, void *data, 75443e54c589SLuiz Augusto von Dentz struct sk_buff *skb); 75453e54c589SLuiz Augusto von Dentz void (*func_req)(struct hci_dev *hdev, void *data, 75463e54c589SLuiz Augusto von Dentz struct sk_buff *skb, u16 *opcode, u8 *status, 75473e54c589SLuiz Augusto von Dentz hci_req_complete_t *req_complete, 75483e54c589SLuiz Augusto von Dentz hci_req_complete_skb_t *req_complete_skb); 75493e54c589SLuiz Augusto von Dentz }; 75503e54c589SLuiz Augusto von Dentz u16 min_len; 75513e54c589SLuiz Augusto von Dentz u16 max_len; 75523e54c589SLuiz Augusto von Dentz } hci_ev_table[U8_MAX + 1] = { 75533e54c589SLuiz Augusto von Dentz /* [0x01 = HCI_EV_INQUIRY_COMPLETE] */ 75543e54c589SLuiz Augusto von Dentz HCI_EV_STATUS(HCI_EV_INQUIRY_COMPLETE, hci_inquiry_complete_evt), 75553e54c589SLuiz Augusto von Dentz /* [0x02 = HCI_EV_INQUIRY_RESULT] */ 75563e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_INQUIRY_RESULT, hci_inquiry_result_evt, 75573e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_inquiry_result), HCI_MAX_EVENT_SIZE), 75583e54c589SLuiz Augusto von Dentz /* [0x03 = HCI_EV_CONN_COMPLETE] */ 75593e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CONN_COMPLETE, hci_conn_complete_evt, 75603e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_conn_complete)), 75613e54c589SLuiz Augusto von Dentz /* [0x04 = HCI_EV_CONN_REQUEST] */ 75623e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CONN_REQUEST, hci_conn_request_evt, 75633e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_conn_request)), 75643e54c589SLuiz Augusto von Dentz /* [0x05 = HCI_EV_DISCONN_COMPLETE] */ 75653e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_DISCONN_COMPLETE, hci_disconn_complete_evt, 75663e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_disconn_complete)), 75673e54c589SLuiz Augusto von Dentz /* [0x06 = HCI_EV_AUTH_COMPLETE] */ 75683e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_AUTH_COMPLETE, hci_auth_complete_evt, 75693e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_auth_complete)), 75703e54c589SLuiz Augusto von Dentz /* [0x07 = HCI_EV_REMOTE_NAME] */ 75713e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_NAME, hci_remote_name_evt, 75723e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_name)), 75733e54c589SLuiz Augusto von Dentz /* [0x08 = HCI_EV_ENCRYPT_CHANGE] */ 75743e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_ENCRYPT_CHANGE, hci_encrypt_change_evt, 75753e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_encrypt_change)), 75763e54c589SLuiz Augusto von Dentz /* [0x09 = HCI_EV_CHANGE_LINK_KEY_COMPLETE] */ 75773e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CHANGE_LINK_KEY_COMPLETE, 75783e54c589SLuiz Augusto von Dentz hci_change_link_key_complete_evt, 75793e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_change_link_key_complete)), 75803e54c589SLuiz Augusto von Dentz /* [0x0b = HCI_EV_REMOTE_FEATURES] */ 75813e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_FEATURES, hci_remote_features_evt, 75823e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_features)), 75833e54c589SLuiz Augusto von Dentz /* [0x0e = HCI_EV_CMD_COMPLETE] */ 75843e54c589SLuiz Augusto von Dentz HCI_EV_REQ_VL(HCI_EV_CMD_COMPLETE, hci_cmd_complete_evt, 75853e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_cmd_complete), HCI_MAX_EVENT_SIZE), 75863e54c589SLuiz Augusto von Dentz /* [0x0f = HCI_EV_CMD_STATUS] */ 75873e54c589SLuiz Augusto von Dentz HCI_EV_REQ(HCI_EV_CMD_STATUS, hci_cmd_status_evt, 75883e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_cmd_status)), 75893e54c589SLuiz Augusto von Dentz /* [0x10 = HCI_EV_CMD_STATUS] */ 75903e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_HARDWARE_ERROR, hci_hardware_error_evt, 75913e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_hardware_error)), 75923e54c589SLuiz Augusto von Dentz /* [0x12 = HCI_EV_ROLE_CHANGE] */ 75933e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_ROLE_CHANGE, hci_role_change_evt, 75943e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_role_change)), 75953e54c589SLuiz Augusto von Dentz /* [0x13 = HCI_EV_NUM_COMP_PKTS] */ 75963e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_NUM_COMP_PKTS, hci_num_comp_pkts_evt, 75973e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_num_comp_pkts), HCI_MAX_EVENT_SIZE), 75983e54c589SLuiz Augusto von Dentz /* [0x14 = HCI_EV_MODE_CHANGE] */ 75993e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_MODE_CHANGE, hci_mode_change_evt, 76003e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_mode_change)), 76013e54c589SLuiz Augusto von Dentz /* [0x16 = HCI_EV_PIN_CODE_REQ] */ 76023e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_PIN_CODE_REQ, hci_pin_code_request_evt, 76033e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_pin_code_req)), 76043e54c589SLuiz Augusto von Dentz /* [0x17 = HCI_EV_LINK_KEY_REQ] */ 76053e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_LINK_KEY_REQ, hci_link_key_request_evt, 76063e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_link_key_req)), 76073e54c589SLuiz Augusto von Dentz /* [0x18 = HCI_EV_LINK_KEY_NOTIFY] */ 76083e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_LINK_KEY_NOTIFY, hci_link_key_notify_evt, 76093e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_link_key_notify)), 76103e54c589SLuiz Augusto von Dentz /* [0x1c = HCI_EV_CLOCK_OFFSET] */ 76113e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CLOCK_OFFSET, hci_clock_offset_evt, 76123e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_clock_offset)), 76133e54c589SLuiz Augusto von Dentz /* [0x1d = HCI_EV_PKT_TYPE_CHANGE] */ 76143e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_PKT_TYPE_CHANGE, hci_pkt_type_change_evt, 76153e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_pkt_type_change)), 76163e54c589SLuiz Augusto von Dentz /* [0x20 = HCI_EV_PSCAN_REP_MODE] */ 76173e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_PSCAN_REP_MODE, hci_pscan_rep_mode_evt, 76183e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_pscan_rep_mode)), 76193e54c589SLuiz Augusto von Dentz /* [0x22 = HCI_EV_INQUIRY_RESULT_WITH_RSSI] */ 76203e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_INQUIRY_RESULT_WITH_RSSI, 76213e54c589SLuiz Augusto von Dentz hci_inquiry_result_with_rssi_evt, 76223e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_inquiry_result_rssi), 76233e54c589SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE), 76243e54c589SLuiz Augusto von Dentz /* [0x23 = HCI_EV_REMOTE_EXT_FEATURES] */ 76253e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_EXT_FEATURES, hci_remote_ext_features_evt, 76263e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_ext_features)), 76273e54c589SLuiz Augusto von Dentz /* [0x2c = HCI_EV_SYNC_CONN_COMPLETE] */ 76283e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_SYNC_CONN_COMPLETE, hci_sync_conn_complete_evt, 76293e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_sync_conn_complete)), 76303e54c589SLuiz Augusto von Dentz /* [0x2d = HCI_EV_EXTENDED_INQUIRY_RESULT] */ 76313e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_EXTENDED_INQUIRY_RESULT, 76323e54c589SLuiz Augusto von Dentz hci_extended_inquiry_result_evt, 76333e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_ext_inquiry_result), HCI_MAX_EVENT_SIZE), 76343e54c589SLuiz Augusto von Dentz /* [0x30 = HCI_EV_KEY_REFRESH_COMPLETE] */ 76353e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_KEY_REFRESH_COMPLETE, hci_key_refresh_complete_evt, 76363e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_key_refresh_complete)), 76373e54c589SLuiz Augusto von Dentz /* [0x31 = HCI_EV_IO_CAPA_REQUEST] */ 76383e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_IO_CAPA_REQUEST, hci_io_capa_request_evt, 76393e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_io_capa_request)), 76403e54c589SLuiz Augusto von Dentz /* [0x32 = HCI_EV_IO_CAPA_REPLY] */ 76413e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_IO_CAPA_REPLY, hci_io_capa_reply_evt, 76423e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_io_capa_reply)), 76433e54c589SLuiz Augusto von Dentz /* [0x33 = HCI_EV_USER_CONFIRM_REQUEST] */ 76443e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_USER_CONFIRM_REQUEST, hci_user_confirm_request_evt, 76453e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_user_confirm_req)), 76463e54c589SLuiz Augusto von Dentz /* [0x34 = HCI_EV_USER_PASSKEY_REQUEST] */ 76473e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_USER_PASSKEY_REQUEST, hci_user_passkey_request_evt, 76483e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_user_passkey_req)), 76493e54c589SLuiz Augusto von Dentz /* [0x35 = HCI_EV_REMOTE_OOB_DATA_REQUEST] */ 76503e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_OOB_DATA_REQUEST, hci_remote_oob_data_request_evt, 76513e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_oob_data_request)), 76523e54c589SLuiz Augusto von Dentz /* [0x36 = HCI_EV_SIMPLE_PAIR_COMPLETE] */ 76533e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_SIMPLE_PAIR_COMPLETE, hci_simple_pair_complete_evt, 76543e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_simple_pair_complete)), 76553e54c589SLuiz Augusto von Dentz /* [0x3b = HCI_EV_USER_PASSKEY_NOTIFY] */ 76563e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_USER_PASSKEY_NOTIFY, hci_user_passkey_notify_evt, 76573e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_user_passkey_notify)), 76583e54c589SLuiz Augusto von Dentz /* [0x3c = HCI_EV_KEYPRESS_NOTIFY] */ 76593e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_KEYPRESS_NOTIFY, hci_keypress_notify_evt, 76603e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_keypress_notify)), 76613e54c589SLuiz Augusto von Dentz /* [0x3d = HCI_EV_REMOTE_HOST_FEATURES] */ 76623e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_HOST_FEATURES, hci_remote_host_features_evt, 76633e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_host_features)), 76643e54c589SLuiz Augusto von Dentz /* [0x3e = HCI_EV_LE_META] */ 766585b56857SLuiz Augusto von Dentz HCI_EV_REQ_VL(HCI_EV_LE_META, hci_le_meta_evt, 76663e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE), 76673e54c589SLuiz Augusto von Dentz #if IS_ENABLED(CONFIG_BT_HS) 76683e54c589SLuiz Augusto von Dentz /* [0x40 = HCI_EV_PHY_LINK_COMPLETE] */ 76693e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_PHY_LINK_COMPLETE, hci_phy_link_complete_evt, 76703e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_phy_link_complete)), 76713e54c589SLuiz Augusto von Dentz /* [0x41 = HCI_EV_CHANNEL_SELECTED] */ 76723e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CHANNEL_SELECTED, hci_chan_selected_evt, 76733e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_channel_selected)), 76743e54c589SLuiz Augusto von Dentz /* [0x42 = HCI_EV_DISCONN_PHY_LINK_COMPLETE] */ 76753e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE, 76763e54c589SLuiz Augusto von Dentz hci_disconn_loglink_complete_evt, 76773e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_disconn_logical_link_complete)), 76783e54c589SLuiz Augusto von Dentz /* [0x45 = HCI_EV_LOGICAL_LINK_COMPLETE] */ 76793e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_LOGICAL_LINK_COMPLETE, hci_loglink_complete_evt, 76803e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_logical_link_complete)), 76813e54c589SLuiz Augusto von Dentz /* [0x46 = HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE] */ 76823e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_DISCONN_PHY_LINK_COMPLETE, 76833e54c589SLuiz Augusto von Dentz hci_disconn_phylink_complete_evt, 76843e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_disconn_phy_link_complete)), 76853e54c589SLuiz Augusto von Dentz #endif 76863e54c589SLuiz Augusto von Dentz /* [0x48 = HCI_EV_NUM_COMP_BLOCKS] */ 76873e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_NUM_COMP_BLOCKS, hci_num_comp_blocks_evt, 76883e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_num_comp_blocks)), 76893e54c589SLuiz Augusto von Dentz /* [0xff = HCI_EV_VENDOR] */ 7690314d8cd2SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_VENDOR, msft_vendor_evt, 0, HCI_MAX_EVENT_SIZE), 76913e54c589SLuiz Augusto von Dentz }; 76923e54c589SLuiz Augusto von Dentz 76933e54c589SLuiz Augusto von Dentz static void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb, 76943e54c589SLuiz Augusto von Dentz u16 *opcode, u8 *status, 76953e54c589SLuiz Augusto von Dentz hci_req_complete_t *req_complete, 76963e54c589SLuiz Augusto von Dentz hci_req_complete_skb_t *req_complete_skb) 76973e54c589SLuiz Augusto von Dentz { 76983e54c589SLuiz Augusto von Dentz const struct hci_ev *ev = &hci_ev_table[event]; 76993e54c589SLuiz Augusto von Dentz void *data; 77003e54c589SLuiz Augusto von Dentz 77013e54c589SLuiz Augusto von Dentz if (!ev->func) 77023e54c589SLuiz Augusto von Dentz return; 77033e54c589SLuiz Augusto von Dentz 77043e54c589SLuiz Augusto von Dentz if (skb->len < ev->min_len) { 77053e54c589SLuiz Augusto von Dentz bt_dev_err(hdev, "unexpected event 0x%2.2x length: %u < %u", 77063e54c589SLuiz Augusto von Dentz event, skb->len, ev->min_len); 77073e54c589SLuiz Augusto von Dentz return; 77083e54c589SLuiz Augusto von Dentz } 77093e54c589SLuiz Augusto von Dentz 77103e54c589SLuiz Augusto von Dentz /* Just warn if the length is over max_len size it still be 77113e54c589SLuiz Augusto von Dentz * possible to partially parse the event so leave to callback to 77123e54c589SLuiz Augusto von Dentz * decide if that is acceptable. 77133e54c589SLuiz Augusto von Dentz */ 77143e54c589SLuiz Augusto von Dentz if (skb->len > ev->max_len) 7715314d8cd2SLuiz Augusto von Dentz bt_dev_warn_ratelimited(hdev, 7716314d8cd2SLuiz Augusto von Dentz "unexpected event 0x%2.2x length: %u > %u", 77173e54c589SLuiz Augusto von Dentz event, skb->len, ev->max_len); 77183e54c589SLuiz Augusto von Dentz 77193e54c589SLuiz Augusto von Dentz data = hci_ev_skb_pull(hdev, skb, event, ev->min_len); 77203e54c589SLuiz Augusto von Dentz if (!data) 77213e54c589SLuiz Augusto von Dentz return; 77223e54c589SLuiz Augusto von Dentz 77233e54c589SLuiz Augusto von Dentz if (ev->req) 77243e54c589SLuiz Augusto von Dentz ev->func_req(hdev, data, skb, opcode, status, req_complete, 77253e54c589SLuiz Augusto von Dentz req_complete_skb); 77263e54c589SLuiz Augusto von Dentz else 77273e54c589SLuiz Augusto von Dentz ev->func(hdev, data, skb); 77283e54c589SLuiz Augusto von Dentz } 77293e54c589SLuiz Augusto von Dentz 77301da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 77311da177e4SLinus Torvalds { 7732a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data; 7733e6214487SJohan Hedberg hci_req_complete_t req_complete = NULL; 7734e6214487SJohan Hedberg hci_req_complete_skb_t req_complete_skb = NULL; 7735e6214487SJohan Hedberg struct sk_buff *orig_skb = NULL; 7736e3f3a1aeSLuiz Augusto von Dentz u8 status = 0, event, req_evt = 0; 7737e6214487SJohan Hedberg u16 opcode = HCI_OP_NOP; 77381da177e4SLinus Torvalds 7739e3f3a1aeSLuiz Augusto von Dentz if (skb->len < sizeof(*hdr)) { 7740e3f3a1aeSLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed HCI Event"); 7741e3f3a1aeSLuiz Augusto von Dentz goto done; 7742e3f3a1aeSLuiz Augusto von Dentz } 7743e3f3a1aeSLuiz Augusto von Dentz 7744dfe6d5c3SLuiz Augusto von Dentz kfree_skb(hdev->recv_event); 7745dfe6d5c3SLuiz Augusto von Dentz hdev->recv_event = skb_clone(skb, GFP_KERNEL); 7746dfe6d5c3SLuiz Augusto von Dentz 7747e3f3a1aeSLuiz Augusto von Dentz event = hdr->evt; 774808bb4da9SAlain Michaud if (!event) { 77493e54c589SLuiz Augusto von Dentz bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x", 77503e54c589SLuiz Augusto von Dentz event); 775108bb4da9SAlain Michaud goto done; 775208bb4da9SAlain Michaud } 775308bb4da9SAlain Michaud 775485b56857SLuiz Augusto von Dentz /* Only match event if command OGF is not for LE */ 77552af7aa66SLuiz Augusto von Dentz if (hdev->req_skb && 77562af7aa66SLuiz Augusto von Dentz hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 && 77572af7aa66SLuiz Augusto von Dentz hci_skb_event(hdev->req_skb) == event) { 77582af7aa66SLuiz Augusto von Dentz hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->req_skb), 775985b56857SLuiz Augusto von Dentz status, &req_complete, &req_complete_skb); 7760757aa0b5SJohan Hedberg req_evt = event; 776102350a72SJohan Hedberg } 776202350a72SJohan Hedberg 7763e6214487SJohan Hedberg /* If it looks like we might end up having to call 7764e6214487SJohan Hedberg * req_complete_skb, store a pristine copy of the skb since the 7765e6214487SJohan Hedberg * various handlers may modify the original one through 7766e6214487SJohan Hedberg * skb_pull() calls, etc. 7767e6214487SJohan Hedberg */ 7768e6214487SJohan Hedberg if (req_complete_skb || event == HCI_EV_CMD_STATUS || 7769e6214487SJohan Hedberg event == HCI_EV_CMD_COMPLETE) 7770e6214487SJohan Hedberg orig_skb = skb_clone(skb, GFP_KERNEL); 7771e6214487SJohan Hedberg 7772e6214487SJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 7773e6214487SJohan Hedberg 77742f20216cSAbhishek Pandit-Subedi /* Store wake reason if we're suspended */ 77752f20216cSAbhishek Pandit-Subedi hci_store_wake_reason(hdev, event, skb); 77762f20216cSAbhishek Pandit-Subedi 77773e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "event 0x%2.2x", event); 77781da177e4SLinus Torvalds 77793e54c589SLuiz Augusto von Dentz hci_event_func(hdev, event, skb, &opcode, &status, &req_complete, 7780e6214487SJohan Hedberg &req_complete_skb); 77811da177e4SLinus Torvalds 7782757aa0b5SJohan Hedberg if (req_complete) { 7783e6214487SJohan Hedberg req_complete(hdev, status, opcode); 7784757aa0b5SJohan Hedberg } else if (req_complete_skb) { 7785757aa0b5SJohan Hedberg if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) { 7786757aa0b5SJohan Hedberg kfree_skb(orig_skb); 7787757aa0b5SJohan Hedberg orig_skb = NULL; 7788757aa0b5SJohan Hedberg } 7789e6214487SJohan Hedberg req_complete_skb(hdev, status, opcode, orig_skb); 7790757aa0b5SJohan Hedberg } 7791e6214487SJohan Hedberg 779208bb4da9SAlain Michaud done: 7793e6214487SJohan Hedberg kfree_skb(orig_skb); 77941da177e4SLinus Torvalds kfree_skb(skb); 77951da177e4SLinus Torvalds hdev->stat.evt_rx++; 77961da177e4SLinus Torvalds } 7797